From 0298141998ea3e19fd86b5a7122aab2fd1ebad51 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Wed, 9 Mar 2011 18:21:09 +0100
Subject: [PATCH 001/386] extract I/O handler lists to iohandler.c

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 Makefile.objs |   2 +-
 iohandler.c   | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++
 qemu-common.h |   3 ++
 vl.c          | 106 ++---------------------------------------
 4 files changed, 138 insertions(+), 102 deletions(-)
 create mode 100644 iohandler.c

diff --git a/Makefile.objs b/Makefile.objs
index f8cf199e14..42301fdf0c 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -98,7 +98,7 @@ common-obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o
 common-obj-y += qemu-char.o savevm.o #aio.o
 common-obj-y += msmouse.o ps2.o
 common-obj-y += qdev.o qdev-properties.o
-common-obj-y += block-migration.o
+common-obj-y += block-migration.o iohandler.o
 common-obj-y += pflib.o
 common-obj-y += bitmap.o bitops.o
 
diff --git a/iohandler.c b/iohandler.c
new file mode 100644
index 0000000000..2e30fe3bcb
--- /dev/null
+++ b/iohandler.c
@@ -0,0 +1,129 @@
+/*
+ * QEMU System Emulator - managing I/O handler
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "config-host.h"
+#include "qemu-common.h"
+#include "qemu-char.h"
+#include "qemu-queue.h"
+
+typedef struct IOHandlerRecord {
+    int fd;
+    IOCanReadHandler *fd_read_poll;
+    IOHandler *fd_read;
+    IOHandler *fd_write;
+    int deleted;
+    void *opaque;
+    QLIST_ENTRY(IOHandlerRecord) next;
+} IOHandlerRecord;
+
+static QLIST_HEAD(, IOHandlerRecord) io_handlers =
+    QLIST_HEAD_INITIALIZER(io_handlers);
+
+
+/* XXX: fd_read_poll should be suppressed, but an API change is
+   necessary in the character devices to suppress fd_can_read(). */
+int qemu_set_fd_handler2(int fd,
+                         IOCanReadHandler *fd_read_poll,
+                         IOHandler *fd_read,
+                         IOHandler *fd_write,
+                         void *opaque)
+{
+    IOHandlerRecord *ioh;
+
+    if (!fd_read && !fd_write) {
+        QLIST_FOREACH(ioh, &io_handlers, next) {
+            if (ioh->fd == fd) {
+                ioh->deleted = 1;
+                break;
+            }
+        }
+    } else {
+        QLIST_FOREACH(ioh, &io_handlers, next) {
+            if (ioh->fd == fd)
+                goto found;
+        }
+        ioh = qemu_mallocz(sizeof(IOHandlerRecord));
+        QLIST_INSERT_HEAD(&io_handlers, ioh, next);
+    found:
+        ioh->fd = fd;
+        ioh->fd_read_poll = fd_read_poll;
+        ioh->fd_read = fd_read;
+        ioh->fd_write = fd_write;
+        ioh->opaque = opaque;
+        ioh->deleted = 0;
+    }
+    return 0;
+}
+
+int qemu_set_fd_handler(int fd,
+                        IOHandler *fd_read,
+                        IOHandler *fd_write,
+                        void *opaque)
+{
+    return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
+}
+
+void qemu_iohandler_fill(int *pnfds, fd_set *readfds, fd_set *writefds, fd_set *xfds)
+{
+    IOHandlerRecord *ioh;
+
+    QLIST_FOREACH(ioh, &io_handlers, next) {
+        if (ioh->deleted)
+            continue;
+        if (ioh->fd_read &&
+            (!ioh->fd_read_poll ||
+             ioh->fd_read_poll(ioh->opaque) != 0)) {
+            FD_SET(ioh->fd, readfds);
+            if (ioh->fd > *pnfds)
+                *pnfds = ioh->fd;
+        }
+        if (ioh->fd_write) {
+            FD_SET(ioh->fd, writefds);
+            if (ioh->fd > *pnfds)
+                *pnfds = ioh->fd;
+        }
+    }
+}
+
+void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, int ret)
+{
+    if (ret > 0) {
+        IOHandlerRecord *pioh, *ioh;
+
+        QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) {
+            if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, readfds)) {
+                ioh->fd_read(ioh->opaque);
+            }
+            if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, writefds)) {
+                ioh->fd_write(ioh->opaque);
+            }
+
+            /* Do this last in case read/write handlers marked it for deletion */
+            if (ioh->deleted) {
+                QLIST_REMOVE(ioh, next);
+                qemu_free(ioh);
+            }
+        }
+    }
+}
diff --git a/qemu-common.h b/qemu-common.h
index 7a96dd14e8..665c89380b 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -227,6 +227,9 @@ typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
 typedef int IOCanReadHandler(void *opaque);
 typedef void IOHandler(void *opaque);
 
+void qemu_iohandler_fill(int *pnfds, fd_set *readfds, fd_set *writefds, fd_set *xfds);
+void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, int rc);
+
 struct ParallelIOArg {
     void *buffer;
     int count;
diff --git a/vl.c b/vl.c
index 192a240b52..d3d81e08fb 100644
--- a/vl.c
+++ b/vl.c
@@ -1022,68 +1022,6 @@ void pcmcia_info(Monitor *mon)
                        "Empty");
 }
 
-/***********************************************************/
-/* I/O handling */
-
-typedef struct IOHandlerRecord {
-    int fd;
-    IOCanReadHandler *fd_read_poll;
-    IOHandler *fd_read;
-    IOHandler *fd_write;
-    int deleted;
-    void *opaque;
-    /* temporary data */
-    struct pollfd *ufd;
-    QLIST_ENTRY(IOHandlerRecord) next;
-} IOHandlerRecord;
-
-static QLIST_HEAD(, IOHandlerRecord) io_handlers =
-    QLIST_HEAD_INITIALIZER(io_handlers);
-
-
-/* XXX: fd_read_poll should be suppressed, but an API change is
-   necessary in the character devices to suppress fd_can_read(). */
-int qemu_set_fd_handler2(int fd,
-                         IOCanReadHandler *fd_read_poll,
-                         IOHandler *fd_read,
-                         IOHandler *fd_write,
-                         void *opaque)
-{
-    IOHandlerRecord *ioh;
-
-    if (!fd_read && !fd_write) {
-        QLIST_FOREACH(ioh, &io_handlers, next) {
-            if (ioh->fd == fd) {
-                ioh->deleted = 1;
-                break;
-            }
-        }
-    } else {
-        QLIST_FOREACH(ioh, &io_handlers, next) {
-            if (ioh->fd == fd)
-                goto found;
-        }
-        ioh = qemu_mallocz(sizeof(IOHandlerRecord));
-        QLIST_INSERT_HEAD(&io_handlers, ioh, next);
-    found:
-        ioh->fd = fd;
-        ioh->fd_read_poll = fd_read_poll;
-        ioh->fd_read = fd_read;
-        ioh->fd_write = fd_write;
-        ioh->opaque = opaque;
-        ioh->deleted = 0;
-    }
-    return 0;
-}
-
-int qemu_set_fd_handler(int fd,
-                        IOHandler *fd_read,
-                        IOHandler *fd_write,
-                        void *opaque)
-{
-    return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
-}
-
 /***********************************************************/
 /* machine registration */
 
@@ -1343,7 +1281,6 @@ void qemu_system_vmstop_request(int reason)
 
 void main_loop_wait(int nonblocking)
 {
-    IOHandlerRecord *ioh;
     fd_set rfds, wfds, xfds;
     int ret, nfds;
     struct timeval tv;
@@ -1358,56 +1295,23 @@ void main_loop_wait(int nonblocking)
 
     os_host_main_loop_wait(&timeout);
 
+    tv.tv_sec = timeout / 1000;
+    tv.tv_usec = (timeout % 1000) * 1000;
+
     /* poll any events */
     /* XXX: separate device handlers from system ones */
     nfds = -1;
     FD_ZERO(&rfds);
     FD_ZERO(&wfds);
     FD_ZERO(&xfds);
-    QLIST_FOREACH(ioh, &io_handlers, next) {
-        if (ioh->deleted)
-            continue;
-        if (ioh->fd_read &&
-            (!ioh->fd_read_poll ||
-             ioh->fd_read_poll(ioh->opaque) != 0)) {
-            FD_SET(ioh->fd, &rfds);
-            if (ioh->fd > nfds)
-                nfds = ioh->fd;
-        }
-        if (ioh->fd_write) {
-            FD_SET(ioh->fd, &wfds);
-            if (ioh->fd > nfds)
-                nfds = ioh->fd;
-        }
-    }
-
-    tv.tv_sec = timeout / 1000;
-    tv.tv_usec = (timeout % 1000) * 1000;
-
+    qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds);
     slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
 
     qemu_mutex_unlock_iothread();
     ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
     qemu_mutex_lock_iothread();
-    if (ret > 0) {
-        IOHandlerRecord *pioh;
-
-        QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) {
-            if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
-                ioh->fd_read(ioh->opaque);
-            }
-            if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
-                ioh->fd_write(ioh->opaque);
-            }
-
-            /* Do this last in case read/write handlers marked it for deletion */
-            if (ioh->deleted) {
-                QLIST_REMOVE(ioh, next);
-                qemu_free(ioh);
-            }
-        }
-    }
 
+    qemu_iohandler_poll(&rfds, &wfds, &xfds, ret);
     slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0));
 
     qemu_run_all_timers();

From 4d54ec7898bd951007cb6122d5315584bd41d0c4 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Wed, 9 Mar 2011 18:21:10 +0100
Subject: [PATCH 002/386] add a service to reap zombies, use it in SLIRP

SLIRP -smb support wants to fork a process and forget about reaping it.
To please it, add a generic service to register a process id and let
QEMU reap it.  In the future it could be enhanced to pass a status,
but this would be unused.

With this in place, the SIGCHLD signal handler would not stomp on pclose
anymore.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 iohandler.c   | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++
 os-posix.c    |  9 --------
 qemu-common.h |  1 +
 slirp/misc.c  |  5 +++-
 4 files changed, 69 insertions(+), 10 deletions(-)

diff --git a/iohandler.c b/iohandler.c
index 2e30fe3bcb..2b824218e5 100644
--- a/iohandler.c
+++ b/iohandler.c
@@ -27,6 +27,10 @@
 #include "qemu-char.h"
 #include "qemu-queue.h"
 
+#ifndef _WIN32
+#include <sys/wait.h>
+#endif
+
 typedef struct IOHandlerRecord {
     int fd;
     IOCanReadHandler *fd_read_poll;
@@ -127,3 +131,63 @@ void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, int re
         }
     }
 }
+
+/* reaping of zombies.  right now we're not passing the status to
+   anyone, but it would be possible to add a callback.  */
+#ifndef _WIN32
+typedef struct ChildProcessRecord {
+    int pid;
+    QLIST_ENTRY(ChildProcessRecord) next;
+} ChildProcessRecord;
+
+static QLIST_HEAD(, ChildProcessRecord) child_watches =
+    QLIST_HEAD_INITIALIZER(child_watches);
+
+static QEMUBH *sigchld_bh;
+
+static void sigchld_handler(int signal)
+{
+    qemu_bh_schedule(sigchld_bh);
+}
+
+static void sigchld_bh_handler(void *opaque)
+{
+    ChildProcessRecord *rec, *next;
+
+    QLIST_FOREACH_SAFE(rec, &child_watches, next, next) {
+        if (waitpid(rec->pid, NULL, WNOHANG) == rec->pid) {
+            QLIST_REMOVE(rec, next);
+            qemu_free(rec);
+        }
+    }
+}
+
+static void qemu_init_child_watch(void)
+{
+    struct sigaction act;
+    sigchld_bh = qemu_bh_new(sigchld_bh_handler, NULL);
+
+    act.sa_handler = sigchld_handler;
+    act.sa_flags = SA_NOCLDSTOP;
+    sigaction(SIGCHLD, &act, NULL);
+}
+
+int qemu_add_child_watch(pid_t pid)
+{
+    ChildProcessRecord *rec;
+
+    if (!sigchld_bh) {
+        qemu_init_child_watch();
+    }
+
+    QLIST_FOREACH(rec, &child_watches, next) {
+        if (rec->pid == pid) {
+            return 1;
+        }
+    }
+    rec = qemu_mallocz(sizeof(ChildProcessRecord));
+    rec->pid = pid;
+    QLIST_INSERT_HEAD(&child_watches, rec, next);
+    return 0;
+}
+#endif
diff --git a/os-posix.c b/os-posix.c
index eb49e2f177..320419793a 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -67,11 +67,6 @@ static void termsig_handler(int signal, siginfo_t *info, void *c)
     qemu_system_killed(info->si_signo, info->si_pid);
 }
 
-static void sigchld_handler(int signal)
-{
-    waitpid(-1, NULL, WNOHANG);
-}
-
 void os_setup_signal_handling(void)
 {
     struct sigaction act;
@@ -82,10 +77,6 @@ void os_setup_signal_handling(void)
     sigaction(SIGINT,  &act, NULL);
     sigaction(SIGHUP,  &act, NULL);
     sigaction(SIGTERM, &act, NULL);
-
-    act.sa_handler = sigchld_handler;
-    act.sa_flags = SA_NOCLDSTOP;
-    sigaction(SIGCHLD, &act, NULL);
 }
 
 /* Find a likely location for support files using the location of the binary.
diff --git a/qemu-common.h b/qemu-common.h
index 665c89380b..8ecb48820a 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -214,6 +214,7 @@ ssize_t qemu_write_full(int fd, const void *buf, size_t count)
 void qemu_set_cloexec(int fd);
 
 #ifndef _WIN32
+int qemu_add_child_watch(pid_t pid);
 int qemu_eventfd(int pipefd[2]);
 int qemu_pipe(int pipefd[2]);
 #endif
diff --git a/slirp/misc.c b/slirp/misc.c
index 19dbec491f..08eba6adc0 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -119,6 +119,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
 	char *bptr;
 	const char *curarg;
 	int c, i, ret;
+	pid_t pid;
 
 	DEBUG_CALL("fork_exec");
 	DEBUG_ARG("so = %lx", (long)so);
@@ -142,7 +143,8 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
 		}
 	}
 
-	switch(fork()) {
+	pid = fork();
+	switch(pid) {
 	 case -1:
 		lprint("Error: fork failed: %s\n", strerror(errno));
 		close(s);
@@ -206,6 +208,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
 		exit(1);
 
 	 default:
+		qemu_add_child_watch(pid);
 		if (do_pty == 2) {
 			close(s);
 			so->s = master;

From fcda98630b121a63c9de0705df02e59f4dc2fecc Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Mon, 7 Mar 2011 23:00:13 +0100
Subject: [PATCH 003/386] lm32: rename raise opcode to scall

To be consistent with the new reference manual.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 target-lm32/lm32-decode.h | 2 +-
 target-lm32/translate.c   | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/target-lm32/lm32-decode.h b/target-lm32/lm32-decode.h
index f745b39626..42205d931e 100644
--- a/target-lm32/lm32-decode.h
+++ b/target-lm32/lm32-decode.h
@@ -60,7 +60,7 @@
 #define DEC_NOR     {B8(00000001), B8(00011111)}
 #define DEC_OR      {B8(00001110), B8(00011111)}
 #define DEC_ORHI    {B8(00011110), B8(00111111)}
-#define DEC_RAISE   {B8(00101011), B8(00111111)}
+#define DEC_SCALL   {B8(00101011), B8(00111111)}
 #define DEC_RCSR    {B8(00100100), B8(00111111)}
 #define DEC_SB      {B8(00001100), B8(00111111)}
 #define DEC_SEXTB   {B8(00101100), B8(00111111)}
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 0b0e405fe7..aa08a142e2 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -583,7 +583,7 @@ static void dec_orhi(DisasContext *dc)
     tcg_gen_ori_tl(cpu_R[dc->r1], cpu_R[dc->r0], (dc->imm16 << 16));
 }
 
-static void dec_raise(DisasContext *dc)
+static void dec_scall(DisasContext *dc)
 {
     TCGv t0;
     int l1;
@@ -1002,7 +1002,7 @@ static const DecoderInfo decinfo[] = {
     {DEC_NOR, dec_nor},
     {DEC_OR, dec_or},
     {DEC_ORHI, dec_orhi},
-    {DEC_RAISE, dec_raise},
+    {DEC_SCALL, dec_scall},
     {DEC_RCSR, dec_rcsr},
     {DEC_SB, dec_sb},
     {DEC_SEXTB, dec_sextb},

From a5086f95421e43c7b9e1b28a111aae0be4848117 Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Mon, 7 Mar 2011 23:01:04 +0100
Subject: [PATCH 004/386] lm32: use lookup table for opcodes

Instead of a for loop use a faster lookup table.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 target-lm32/lm32-decode.h | 78 --------------------------------------
 target-lm32/translate.c   | 80 +++++++++------------------------------
 2 files changed, 18 insertions(+), 140 deletions(-)
 delete mode 100644 target-lm32/lm32-decode.h

diff --git a/target-lm32/lm32-decode.h b/target-lm32/lm32-decode.h
deleted file mode 100644
index 42205d931e..0000000000
--- a/target-lm32/lm32-decode.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *  LatticeMico32 instruction decoding macros.
- *
- *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Convenient binary macros */
-#define HEX__(n) 0x##n##LU
-#define B8__(x) (((x&0x0000000FLU) ? 1 : 0) \
-                  + ((x&0x000000F0LU) ? 2 : 0) \
-                  + ((x&0x00000F00LU) ? 4 : 0) \
-                  + ((x&0x0000F000LU) ? 8 : 0) \
-                  + ((x&0x000F0000LU) ? 16 : 0) \
-                  + ((x&0x00F00000LU) ? 32 : 0) \
-                  + ((x&0x0F000000LU) ? 64 : 0) \
-                  + ((x&0xF0000000LU) ? 128 : 0))
-#define B8(d) ((unsigned char)B8__(HEX__(d)))
-
-/* Decode logic, value and mask.  */
-#define DEC_ADD     {B8(00001101), B8(00011111)}
-#define DEC_AND     {B8(00001000), B8(00011111)}
-#define DEC_ANDHI   {B8(00011000), B8(00111111)}
-#define DEC_B       {B8(00110000), B8(00111111)}
-#define DEC_BI      {B8(00111000), B8(00111111)}
-#define DEC_BE      {B8(00010001), B8(00111111)}
-#define DEC_BG      {B8(00010010), B8(00111111)}
-#define DEC_BGE     {B8(00010011), B8(00111111)}
-#define DEC_BGEU    {B8(00010100), B8(00111111)}
-#define DEC_BGU     {B8(00010101), B8(00111111)}
-#define DEC_BNE     {B8(00010111), B8(00111111)}
-#define DEC_CALL    {B8(00110110), B8(00111111)}
-#define DEC_CALLI   {B8(00111110), B8(00111111)}
-#define DEC_CMPE    {B8(00011001), B8(00011111)}
-#define DEC_CMPG    {B8(00011010), B8(00011111)}
-#define DEC_CMPGE   {B8(00011011), B8(00011111)}
-#define DEC_CMPGEU  {B8(00011100), B8(00011111)}
-#define DEC_CMPGU   {B8(00011101), B8(00011111)}
-#define DEC_CMPNE   {B8(00011111), B8(00011111)}
-#define DEC_DIVU    {B8(00100011), B8(00111111)}
-#define DEC_LB      {B8(00000100), B8(00111111)}
-#define DEC_LBU     {B8(00010000), B8(00111111)}
-#define DEC_LH      {B8(00000111), B8(00111111)}
-#define DEC_LHU     {B8(00001011), B8(00111111)}
-#define DEC_LW      {B8(00001010), B8(00111111)}
-#define DEC_MODU    {B8(00110001), B8(00111111)}
-#define DEC_MUL     {B8(00000010), B8(00011111)}
-#define DEC_NOR     {B8(00000001), B8(00011111)}
-#define DEC_OR      {B8(00001110), B8(00011111)}
-#define DEC_ORHI    {B8(00011110), B8(00111111)}
-#define DEC_SCALL   {B8(00101011), B8(00111111)}
-#define DEC_RCSR    {B8(00100100), B8(00111111)}
-#define DEC_SB      {B8(00001100), B8(00111111)}
-#define DEC_SEXTB   {B8(00101100), B8(00111111)}
-#define DEC_SEXTH   {B8(00110111), B8(00111111)}
-#define DEC_SH      {B8(00000011), B8(00111111)}
-#define DEC_SL      {B8(00001111), B8(00011111)}
-#define DEC_SR      {B8(00000101), B8(00011111)}
-#define DEC_SRU     {B8(00000000), B8(00011111)}
-#define DEC_SUB     {B8(00110010), B8(00111111)}
-#define DEC_SW      {B8(00010110), B8(00111111)}
-#define DEC_USER    {B8(00110011), B8(00111111)}
-#define DEC_WCSR    {B8(00110100), B8(00111111)}
-#define DEC_XNOR    {B8(00001001), B8(00011111)}
-#define DEC_XOR     {B8(00000110), B8(00011111)}
-
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index aa08a142e2..666d5f4dc3 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -29,7 +29,6 @@
 #include "disas.h"
 #include "helper.h"
 #include "tcg-op.h"
-#include "lm32-decode.h"
 #include "qemu-common.h"
 
 #include "hw/lm32_pic.h"
@@ -963,66 +962,28 @@ static void dec_xor(DisasContext *dc)
     }
 }
 
-typedef struct {
-    struct {
-        uint32_t bits;
-        uint32_t mask;
-    };
-    void (*dec)(DisasContext *dc);
-} DecoderInfo;
+static void dec_ill(DisasContext *dc)
+{
+    cpu_abort(dc->env, "unknown opcode 0x%02x\n", dc->opcode);
+}
 
+typedef void (*DecoderInfo)(DisasContext *dc);
 static const DecoderInfo decinfo[] = {
-    {DEC_ADD, dec_add},
-    {DEC_AND, dec_and},
-    {DEC_ANDHI, dec_andhi},
-    {DEC_B, dec_b},
-    {DEC_BI, dec_bi},
-    {DEC_BE, dec_be},
-    {DEC_BG, dec_bg},
-    {DEC_BGE, dec_bge},
-    {DEC_BGEU, dec_bgeu},
-    {DEC_BGU, dec_bgu},
-    {DEC_BNE, dec_bne},
-    {DEC_CALL, dec_call},
-    {DEC_CALLI, dec_calli},
-    {DEC_CMPE, dec_cmpe},
-    {DEC_CMPG, dec_cmpg},
-    {DEC_CMPGE, dec_cmpge},
-    {DEC_CMPGEU, dec_cmpgeu},
-    {DEC_CMPGU, dec_cmpgu},
-    {DEC_CMPNE, dec_cmpne},
-    {DEC_DIVU, dec_divu},
-    {DEC_LB, dec_lb},
-    {DEC_LBU, dec_lbu},
-    {DEC_LH, dec_lh},
-    {DEC_LHU, dec_lhu},
-    {DEC_LW, dec_lw},
-    {DEC_MODU, dec_modu},
-    {DEC_MUL, dec_mul},
-    {DEC_NOR, dec_nor},
-    {DEC_OR, dec_or},
-    {DEC_ORHI, dec_orhi},
-    {DEC_SCALL, dec_scall},
-    {DEC_RCSR, dec_rcsr},
-    {DEC_SB, dec_sb},
-    {DEC_SEXTB, dec_sextb},
-    {DEC_SEXTH, dec_sexth},
-    {DEC_SH, dec_sh},
-    {DEC_SL, dec_sl},
-    {DEC_SR, dec_sr},
-    {DEC_SRU, dec_sru},
-    {DEC_SUB, dec_sub},
-    {DEC_SW, dec_sw},
-    {DEC_USER, dec_user},
-    {DEC_WCSR, dec_wcsr},
-    {DEC_XNOR, dec_xnor},
-    {DEC_XOR, dec_xor},
+    dec_sru, dec_nor, dec_mul, dec_sh, dec_lb, dec_sr, dec_xor, dec_lh,
+    dec_and, dec_xnor, dec_lw, dec_lhu, dec_sb, dec_add, dec_or, dec_sl,
+    dec_lbu, dec_be, dec_bg, dec_bge, dec_bgeu, dec_bgu, dec_sw, dec_bne,
+    dec_andhi, dec_cmpe, dec_cmpg, dec_cmpge, dec_cmpgeu, dec_cmpgu, dec_orhi,
+    dec_cmpne,
+    dec_sru, dec_nor, dec_mul, dec_divu, dec_rcsr, dec_sr, dec_xor, dec_ill,
+    dec_and, dec_xnor, dec_ill, dec_scall, dec_sextb, dec_add, dec_or, dec_sl,
+    dec_b, dec_modu, dec_sub, dec_user, dec_wcsr, dec_ill, dec_call, dec_sexth,
+    dec_bi, dec_cmpe, dec_cmpg, dec_cmpge, dec_cmpgeu, dec_cmpgu, dec_calli,
+    dec_cmpne
 };
 
 static inline void decode(DisasContext *dc)
 {
     uint32_t ir;
-    int i;
 
     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
         tcg_gen_debug_insn_start(dc->pc);
@@ -1061,15 +1022,10 @@ static inline void decode(DisasContext *dc)
         dc->format = OP_FMT_RI;
     }
 
-    /* Large switch for all insns.  */
-    for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
-        if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
-            decinfo[i].dec(dc);
-            return;
-        }
-    }
+    assert(ARRAY_SIZE(decinfo) == 64);
+    assert(dc->opcode < 64);
 
-    cpu_abort(dc->env, "unknown opcode 0x%02x\n", dc->opcode);
+    decinfo[dc->opcode](dc);
 }
 
 static void check_breakpoint(CPUState *env, DisasContext *dc)

From 17d9b3af5b7f93e43d7fbdcb6f14cad54de9f1ae Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Tue, 22 Mar 2011 07:41:29 +0100
Subject: [PATCH 005/386] target-ppc: ext32u instead of andi with constant

Cc: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 3d265e3b11..49eab284a4 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -6975,7 +6975,7 @@ static inline void gen_evmergelo(DisasContext *ctx)
 #if defined(TARGET_PPC64)
     TCGv t0 = tcg_temp_new();
     TCGv t1 = tcg_temp_new();
-    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL);
+    tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
     tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
     tcg_temp_free(t0);
@@ -6994,7 +6994,7 @@ static inline void gen_evmergehilo(DisasContext *ctx)
 #if defined(TARGET_PPC64)
     TCGv t0 = tcg_temp_new();
     TCGv t1 = tcg_temp_new();
-    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL);
+    tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
     tcg_temp_free(t0);
@@ -7083,14 +7083,14 @@ static inline void gen_evsel(DisasContext *ctx)
     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2);
     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3);
 #if defined(TARGET_PPC64)
-    tcg_gen_andi_tl(t2, cpu_gpr[rA(ctx->opcode)], 0x00000000FFFFFFFFULL);
+    tcg_gen_ext32u_tl(t2, cpu_gpr[rA(ctx->opcode)]);
 #else
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
 #endif
     tcg_gen_br(l4);
     gen_set_label(l3);
 #if defined(TARGET_PPC64)
-    tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFULL);
+    tcg_gen_ext32u_tl(t2, cpu_gpr[rB(ctx->opcode)]);
 #else
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
 #endif

From 81762d6dd0d430d87024f2c83e9c4dcc4329fb7d Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:08 +1100
Subject: [PATCH 006/386] Clean up PowerPC SLB handling code

Currently the SLB information when emulating a PowerPC 970 is
storeed in a structure with the unhelpfully named fields 'tmp'
and 'tmp64'.  While the layout in these fields does match the
description of the SLB in the architecture document, it is not
convenient either for looking up the SLB, or for emulating the
slbmte instruction.

This patch, therefore, reorganizes the SLB entry structure to be
divided in the the "ESID related" and "VSID related" fields as
they are divided in instructions accessing the SLB.

In addition to making the code smaller and more readable, this will
make it easier to implement for the 1TB segments used in more
recent PowerPC chips.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h       |  29 ++++++-
 target-ppc/helper.c    | 188 ++++++++++++-----------------------------
 target-ppc/helper.h    |   1 -
 target-ppc/op_helper.c |   9 +-
 4 files changed, 85 insertions(+), 142 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index deb8d7c9c5..124bbbf650 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -43,6 +43,8 @@
 # define TARGET_VIRT_ADDR_SPACE_BITS 64
 #endif
 
+#define TARGET_PAGE_BITS_16M 24
+
 #else /* defined (TARGET_PPC64) */
 /* PowerPC 32 definitions */
 #define TARGET_LONG_BITS 32
@@ -359,10 +361,31 @@ union ppc_tlb_t {
 
 typedef struct ppc_slb_t ppc_slb_t;
 struct ppc_slb_t {
-    uint64_t tmp64;
-    uint32_t tmp;
+    uint64_t esid;
+    uint64_t vsid;
 };
 
+/* Bits in the SLB ESID word */
+#define SLB_ESID_ESID           0xFFFFFFFFF0000000ULL
+#define SLB_ESID_V              0x0000000008000000ULL /* valid */
+
+/* Bits in the SLB VSID word */
+#define SLB_VSID_SHIFT          12
+#define SLB_VSID_SSIZE_SHIFT    62
+#define SLB_VSID_B              0xc000000000000000ULL
+#define SLB_VSID_B_256M         0x0000000000000000ULL
+#define SLB_VSID_VSID           0x3FFFFFFFFFFFF000ULL
+#define SLB_VSID_KS             0x0000000000000800ULL
+#define SLB_VSID_KP             0x0000000000000400ULL
+#define SLB_VSID_N              0x0000000000000200ULL /* no-execute */
+#define SLB_VSID_L              0x0000000000000100ULL
+#define SLB_VSID_C              0x0000000000000080ULL /* class */
+#define SLB_VSID_LP             0x0000000000000030ULL
+#define SLB_VSID_ATTR           0x0000000000000FFFULL
+
+#define SEGMENT_SHIFT_256M      28
+#define SEGMENT_MASK_256M       (~((1ULL << SEGMENT_SHIFT_256M) - 1))
+
 /*****************************************************************************/
 /* Machine state register bits definition                                    */
 #define MSR_SF   63 /* Sixty-four-bit mode                            hflags */
@@ -755,7 +778,7 @@ void ppc_store_sdr1 (CPUPPCState *env, target_ulong value);
 void ppc_store_asr (CPUPPCState *env, target_ulong value);
 target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr);
 target_ulong ppc_load_sr (CPUPPCState *env, int sr_nr);
-void ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs);
+int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs);
 #endif /* defined(TARGET_PPC64) */
 void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value);
 #endif /* !defined(CONFIG_USER_ONLY) */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 4b491012d7..2094ca36f9 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -672,85 +672,36 @@ static inline int find_pte(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
 }
 
 #if defined(TARGET_PPC64)
-static ppc_slb_t *slb_get_entry(CPUPPCState *env, int nr)
-{
-    ppc_slb_t *retval = &env->slb[nr];
-
-#if 0 // XXX implement bridge mode?
-    if (env->spr[SPR_ASR] & 1) {
-        target_phys_addr_t sr_base;
-
-        sr_base = env->spr[SPR_ASR] & 0xfffffffffffff000;
-        sr_base += (12 * nr);
-
-        retval->tmp64 = ldq_phys(sr_base);
-        retval->tmp = ldl_phys(sr_base + 8);
-    }
-#endif
-
-    return retval;
-}
-
-static void slb_set_entry(CPUPPCState *env, int nr, ppc_slb_t *slb)
-{
-    ppc_slb_t *entry = &env->slb[nr];
-
-    if (slb == entry)
-        return;
-
-    entry->tmp64 = slb->tmp64;
-    entry->tmp = slb->tmp;
-}
-
-static inline int slb_is_valid(ppc_slb_t *slb)
-{
-    return (int)(slb->tmp64 & 0x0000000008000000ULL);
-}
-
-static inline void slb_invalidate(ppc_slb_t *slb)
-{
-    slb->tmp64 &= ~0x0000000008000000ULL;
-}
-
 static inline int slb_lookup(CPUPPCState *env, target_ulong eaddr,
                              target_ulong *vsid, target_ulong *page_mask,
                              int *attr, int *target_page_bits)
 {
-    target_ulong mask;
-    int n, ret;
+    uint64_t esid;
+    int n;
 
-    ret = -5;
     LOG_SLB("%s: eaddr " TARGET_FMT_lx "\n", __func__, eaddr);
-    mask = 0x0000000000000000ULL; /* Avoid gcc warning */
-    for (n = 0; n < env->slb_nr; n++) {
-        ppc_slb_t *slb = slb_get_entry(env, n);
 
-        LOG_SLB("%s: seg %d %016" PRIx64 " %08"
-                    PRIx32 "\n", __func__, n, slb->tmp64, slb->tmp);
-        if (slb_is_valid(slb)) {
-            /* SLB entry is valid */
-            mask = 0xFFFFFFFFF0000000ULL;
-            if (slb->tmp & 0x8) {
-                /* 16 MB PTEs */
-                if (target_page_bits)
-                    *target_page_bits = 24;
-            } else {
-                /* 4 KB PTEs */
-                if (target_page_bits)
-                    *target_page_bits = TARGET_PAGE_BITS;
-            }
-            if ((eaddr & mask) == (slb->tmp64 & mask)) {
-                /* SLB match */
-                *vsid = ((slb->tmp64 << 24) | (slb->tmp >> 8)) & 0x0003FFFFFFFFFFFFULL;
-                *page_mask = ~mask;
-                *attr = slb->tmp & 0xFF;
-                ret = n;
-                break;
+    esid = (eaddr & SEGMENT_MASK_256M) | SLB_ESID_V;
+
+    for (n = 0; n < env->slb_nr; n++) {
+        ppc_slb_t *slb = &env->slb[n];
+
+        LOG_SLB("%s: slot %d %016" PRIx64 " %016"
+                    PRIx64 "\n", __func__, n, slb->esid, slb->vsid);
+        if (slb->esid == esid) {
+            *vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
+            *page_mask = ~SEGMENT_MASK_256M;
+            *attr = slb->vsid & SLB_VSID_ATTR;
+            if (target_page_bits) {
+                *target_page_bits = (slb->vsid & SLB_VSID_L)
+                    ? TARGET_PAGE_BITS_16M
+                    : TARGET_PAGE_BITS;
             }
+            return n;
         }
     }
 
-    return ret;
+    return -5;
 }
 
 void ppc_slb_invalidate_all (CPUPPCState *env)
@@ -760,11 +711,10 @@ void ppc_slb_invalidate_all (CPUPPCState *env)
     do_invalidate = 0;
     /* XXX: Warning: slbia never invalidates the first segment */
     for (n = 1; n < env->slb_nr; n++) {
-        ppc_slb_t *slb = slb_get_entry(env, n);
+        ppc_slb_t *slb = &env->slb[n];
 
-        if (slb_is_valid(slb)) {
-            slb_invalidate(slb);
-            slb_set_entry(env, n, slb);
+        if (slb->esid & SLB_ESID_V) {
+            slb->esid &= ~SLB_ESID_V;
             /* XXX: given the fact that segment size is 256 MB or 1TB,
              *      and we still don't have a tlb_flush_mask(env, n, mask)
              *      in Qemu, we just invalidate all TLBs
@@ -781,68 +731,44 @@ void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
     target_ulong vsid, page_mask;
     int attr;
     int n;
-
-    n = slb_lookup(env, T0, &vsid, &page_mask, &attr, NULL);
-    if (n >= 0) {
-        ppc_slb_t *slb = slb_get_entry(env, n);
-
-        if (slb_is_valid(slb)) {
-            slb_invalidate(slb);
-            slb_set_entry(env, n, slb);
-            /* XXX: given the fact that segment size is 256 MB or 1TB,
-             *      and we still don't have a tlb_flush_mask(env, n, mask)
-             *      in Qemu, we just invalidate all TLBs
-             */
-            tlb_flush(env, 1);
-        }
-    }
-}
-
-target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr)
-{
-    target_ulong rt;
-    ppc_slb_t *slb = slb_get_entry(env, slb_nr);
-
-    if (slb_is_valid(slb)) {
-        /* SLB entry is valid */
-        /* Copy SLB bits 62:88 to Rt 37:63 (VSID 23:49) */
-        rt = slb->tmp >> 8;             /* 65:88 => 40:63 */
-        rt |= (slb->tmp64 & 0x7) << 24; /* 62:64 => 37:39 */
-        /* Copy SLB bits 89:92 to Rt 33:36 (KsKpNL) */
-        rt |= ((slb->tmp >> 4) & 0xF) << 27;
-    } else {
-        rt = 0;
-    }
-    LOG_SLB("%s: %016" PRIx64 " %08" PRIx32 " => %d "
-            TARGET_FMT_lx "\n", __func__, slb->tmp64, slb->tmp, slb_nr, rt);
-
-    return rt;
-}
-
-void ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs)
-{
     ppc_slb_t *slb;
 
-    uint64_t vsid;
-    uint64_t esid;
-    int flags, valid, slb_nr;
+    n = slb_lookup(env, T0, &vsid, &page_mask, &attr, NULL);
+    if (n < 0) {
+        return;
+    }
 
-    vsid = rs >> 12;
-    flags = ((rs >> 8) & 0xf);
+    slb = &env->slb[n];
 
-    esid = rb >> 28;
-    valid = (rb & (1 << 27));
-    slb_nr = rb & 0xfff;
+    if (slb->esid & SLB_ESID_V) {
+        slb->esid &= ~SLB_ESID_V;
 
-    slb = slb_get_entry(env, slb_nr);
-    slb->tmp64 = (esid << 28) | valid | (vsid >> 24);
-    slb->tmp = (vsid << 8) | (flags << 3);
+        /* XXX: given the fact that segment size is 256 MB or 1TB,
+         *      and we still don't have a tlb_flush_mask(env, n, mask)
+         *      in Qemu, we just invalidate all TLBs
+         */
+        tlb_flush(env, 1);
+    }
+}
+
+int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs)
+{
+    int slot = rb & 0xfff;
+    uint64_t esid = rb & ~0xfff;
+    ppc_slb_t *slb = &env->slb[slot];
+
+    if (slot >= env->slb_nr) {
+        return -1;
+    }
+
+    slb->esid = esid;
+    slb->vsid = rs;
 
     LOG_SLB("%s: %d " TARGET_FMT_lx " - " TARGET_FMT_lx " => %016" PRIx64
-            " %08" PRIx32 "\n", __func__, slb_nr, rb, rs, slb->tmp64,
-            slb->tmp);
+            " %016" PRIx64 "\n", __func__, slot, rb, rs,
+            slb->esid, slb->vsid);
 
-    slb_set_entry(env, slb_nr, slb);
+    return 0;
 }
 #endif /* defined(TARGET_PPC64) */
 
@@ -860,24 +786,22 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
 {
     target_phys_addr_t sdr, hash, mask, sdr_mask, htab_mask;
     target_ulong sr, vsid, vsid_mask, pgidx, page_mask;
-#if defined(TARGET_PPC64)
-    int attr;
-#endif
     int ds, vsid_sh, sdr_sh, pr, target_page_bits;
     int ret, ret2;
 
     pr = msr_pr;
 #if defined(TARGET_PPC64)
     if (env->mmu_model & POWERPC_MMU_64) {
+        int attr;
+
         LOG_MMU("Check SLBs\n");
         ret = slb_lookup(env, eaddr, &vsid, &page_mask, &attr,
                          &target_page_bits);
         if (ret < 0)
             return ret;
-        ctx->key = ((attr & 0x40) && (pr != 0)) ||
-            ((attr & 0x80) && (pr == 0)) ? 1 : 0;
+        ctx->key = !!(pr ? (attr & SLB_VSID_KP) : (attr & SLB_VSID_KS));
         ds = 0;
-        ctx->nx = attr & 0x10 ? 1 : 0;
+        ctx->nx = !!(attr & SLB_VSID_N);
         ctx->eaddr = eaddr;
         vsid_mask = 0x00003FFFFFFFFF80ULL;
         vsid_sh = 7;
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 2bf9283486..d512cb00e2 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -340,7 +340,6 @@ DEF_HELPER_1(74xx_tlbi, void, tl)
 DEF_HELPER_FLAGS_0(tlbia, TCG_CALL_CONST, void)
 DEF_HELPER_FLAGS_1(tlbie, TCG_CALL_CONST, void, tl)
 #if defined(TARGET_PPC64)
-DEF_HELPER_FLAGS_1(load_slb, TCG_CALL_CONST, tl, tl)
 DEF_HELPER_FLAGS_2(store_slb, TCG_CALL_CONST, void, tl, tl)
 DEF_HELPER_FLAGS_0(slbia, TCG_CALL_CONST, void)
 DEF_HELPER_FLAGS_1(slbie, TCG_CALL_CONST, void, tl)
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 17e070ae75..bf41627b21 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -3746,14 +3746,11 @@ void helper_store_sr (target_ulong sr_num, target_ulong val)
 
 /* SLB management */
 #if defined(TARGET_PPC64)
-target_ulong helper_load_slb (target_ulong slb_nr)
-{
-    return ppc_load_slb(env, slb_nr);
-}
-
 void helper_store_slb (target_ulong rb, target_ulong rs)
 {
-    ppc_store_slb(env, rb, rs);
+    if (ppc_store_slb(env, rb, rs) < 0) {
+        helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL);
+    }
 }
 
 void helper_slbia (void)

From c48974903051ceb7cfbda23c22c159ea4b482d93 Mon Sep 17 00:00:00 2001
From: David Gibson <dwg@au1.ibm.com>
Date: Fri, 1 Apr 2011 15:15:09 +1100
Subject: [PATCH 007/386] Allow qemu_devtree_setprop() to take arbitrary values

Currently qemu_devtree_setprop() expects the new property value to be
given as a uint32_t *.  While property values consisting of u32s are
common, in general they can have any bytestring value.

Therefore, this patch alters the function to take a void * instead,
allowing callers to easily give anything as the property value.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 device_tree.c | 2 +-
 device_tree.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/device_tree.c b/device_tree.c
index 426a63155c..21be070759 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -74,7 +74,7 @@ fail:
 }
 
 int qemu_devtree_setprop(void *fdt, const char *node_path,
-                         const char *property, uint32_t *val_array, int size)
+                         const char *property, void *val_array, int size)
 {
     int offset;
 
diff --git a/device_tree.h b/device_tree.h
index f05c4e7311..cecd98f042 100644
--- a/device_tree.h
+++ b/device_tree.h
@@ -17,7 +17,7 @@
 void *load_device_tree(const char *filename_path, int *sizep);
 
 int qemu_devtree_setprop(void *fdt, const char *node_path,
-                         const char *property, uint32_t *val_array, int size);
+                         const char *property, void *val_array, int size);
 int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
                               const char *property, uint32_t val);
 int qemu_devtree_setprop_string(void *fdt, const char *node_path,

From d569956eaff4be808419f1f259a5c388d8789db4 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:10 +1100
Subject: [PATCH 008/386] Add a hook to allow hypercalls to be emulated on
 PowerPC

PowerPC and POWER chips since the POWER4 and 970 have a special
hypervisor mode, and a corresponding form of the system call
instruction which traps to the hypervisor.

qemu currently has stub implementations of hypervisor mode.  That
is, the outline is there to allow qemu to run a PowerPC hypervisor
under emulation.  There are a number of details missing so this
won't actually work at present, but the idea is there.

What there is no provision at all, is for qemu to instead emulate
the hypervisor itself.  That is to have hypercalls trap into qemu
and their result be emulated from qemu, rather than running
hypervisor code within the emulated system.

Hypervisor hardware aware KVM implementations are in the works and
it would  be useful for debugging and development to also allow
full emulation of the same para-virtualized guests as such a KVM.

Therefore, this patch adds a hook which will allow a machine to
set up emulation of hypervisor calls.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h    | 2 ++
 target-ppc/helper.c | 8 ++++++++
 2 files changed, 10 insertions(+)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 124bbbf650..36ca342286 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1646,4 +1646,6 @@ static inline void cpu_set_tls(CPUState *env, target_ulong newtls)
 #endif
 }
 
+extern void (*cpu_ppc_hypercall)(CPUState *);
+
 #endif /* !defined (__CPU_PPC_H__) */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 2094ca36f9..452a35cb48 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -70,6 +70,10 @@
 #  define LOG_EXCP(...) do { } while (0)
 #endif
 
+/*****************************************************************************/
+/* PowerPC Hypercall emulation */
+
+void (*cpu_ppc_hypercall)(CPUState *);
 
 /*****************************************************************************/
 /* PowerPC MMU emulation */
@@ -2152,6 +2156,10 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
         dump_syscall(env);
         lev = env->error_code;
+        if ((lev == 1) && cpu_ppc_hypercall) {
+            cpu_ppc_hypercall(env);
+            return;
+        }
         if (lev == 1 || (lpes0 == 0 && lpes1 == 0))
             new_msr |= (target_ulong)MSR_HVB;
         goto store_next;

From efdef95fee7e150ac065e7b33ffbebd09a5ac83c Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:11 +1100
Subject: [PATCH 009/386] Implement PowerPC slbmfee and slbmfev instructions

For a 64-bit PowerPC target, qemu correctly implements translation
through the segment lookaside buffer.  Likewise it supports the
slbmte instruction which is used to load entries into the SLB.

However, it does not emulate the slbmfee and slbmfev instructions
which read SLB entries back into registers.  Because these are
only occasionally used in guests (mostly for debugging) we get
away with it.

However, given the recent SLB cleanups, it becomes quite easy to
implement these, and thereby allow, amongst other things, a guest
Linux to use xmon's command to dump the SLB.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h       |  2 ++
 target-ppc/helper.c    | 26 ++++++++++++++++++++++++++
 target-ppc/helper.h    |  2 ++
 target-ppc/op_helper.c | 20 ++++++++++++++++++++
 target-ppc/translate.c | 31 ++++++++++++++++++++++++++++++-
 5 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 36ca342286..f293f85976 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -779,6 +779,8 @@ void ppc_store_asr (CPUPPCState *env, target_ulong value);
 target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr);
 target_ulong ppc_load_sr (CPUPPCState *env, int sr_nr);
 int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs);
+int ppc_load_slb_esid (CPUPPCState *env, target_ulong rb, target_ulong *rt);
+int ppc_load_slb_vsid (CPUPPCState *env, target_ulong rb, target_ulong *rt);
 #endif /* defined(TARGET_PPC64) */
 void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value);
 #endif /* !defined(CONFIG_USER_ONLY) */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 452a35cb48..b9621d2dd0 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -774,6 +774,32 @@ int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs)
 
     return 0;
 }
+
+int ppc_load_slb_esid (CPUPPCState *env, target_ulong rb, target_ulong *rt)
+{
+    int slot = rb & 0xfff;
+    ppc_slb_t *slb = &env->slb[slot];
+
+    if (slot >= env->slb_nr) {
+        return -1;
+    }
+
+    *rt = slb->esid;
+    return 0;
+}
+
+int ppc_load_slb_vsid (CPUPPCState *env, target_ulong rb, target_ulong *rt)
+{
+    int slot = rb & 0xfff;
+    ppc_slb_t *slb = &env->slb[slot];
+
+    if (slot >= env->slb_nr) {
+        return -1;
+    }
+
+    *rt = slb->vsid;
+    return 0;
+}
 #endif /* defined(TARGET_PPC64) */
 
 /* Perform segment based translation */
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index d512cb00e2..1a69cf876c 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -341,6 +341,8 @@ DEF_HELPER_FLAGS_0(tlbia, TCG_CALL_CONST, void)
 DEF_HELPER_FLAGS_1(tlbie, TCG_CALL_CONST, void, tl)
 #if defined(TARGET_PPC64)
 DEF_HELPER_FLAGS_2(store_slb, TCG_CALL_CONST, void, tl, tl)
+DEF_HELPER_1(load_slb_esid, tl, tl)
+DEF_HELPER_1(load_slb_vsid, tl, tl)
 DEF_HELPER_FLAGS_0(slbia, TCG_CALL_CONST, void)
 DEF_HELPER_FLAGS_1(slbie, TCG_CALL_CONST, void, tl)
 #endif
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index bf41627b21..bdb1f1732a 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -3753,6 +3753,26 @@ void helper_store_slb (target_ulong rb, target_ulong rs)
     }
 }
 
+target_ulong helper_load_slb_esid (target_ulong rb)
+{
+    target_ulong rt;
+
+    if (ppc_load_slb_esid(env, rb, &rt) < 0) {
+        helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL);
+    }
+    return rt;
+}
+
+target_ulong helper_load_slb_vsid (target_ulong rb)
+{
+    target_ulong rt;
+
+    if (ppc_load_slb_vsid(env, rb, &rt) < 0) {
+        helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL);
+    }
+    return rt;
+}
+
 void helper_slbia (void)
 {
     ppc_slb_invalidate_all(env);
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 49eab284a4..4252508327 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -4227,6 +4227,33 @@ static void gen_slbmte(DisasContext *ctx)
 #endif
 }
 
+static void gen_slbmfee(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+#else
+    if (unlikely(!ctx->mem_idx)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
+    gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)],
+                             cpu_gpr[rB(ctx->opcode)]);
+#endif
+}
+
+static void gen_slbmfev(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+#else
+    if (unlikely(!ctx->mem_idx)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
+    gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)],
+                             cpu_gpr[rB(ctx->opcode)]);
+#endif
+}
 #endif /* defined(TARGET_PPC64) */
 
 /***                      Lookaside buffer management                      ***/
@@ -8300,7 +8327,9 @@ GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
 GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B),
 GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
              PPC_SEGMENT_64B),
-GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x00000000, PPC_SEGMENT_64B),
+GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B),
+GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B),
+GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B),
 #endif
 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
 GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x03FF0001, PPC_MEM_TLBIE),

From 3a7f009abc010827815f10805e3558aa64c98e59 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:12 +1100
Subject: [PATCH 010/386] Implement missing parts of the logic for the POWER
 PURR

The PURR (Processor Utilization Resource Register) is a register found
on recent POWER CPUs.  The guts of implementing it at least enough to
get by are already present in qemu, however some of the helper
functions needed to actually wire it up are missing.

This patch adds the necessary glue, so that the PURR can be wired up
when we implement newer POWER CPU targets which include it.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h         | 1 +
 target-ppc/op_helper.c      | 7 +++++++
 target-ppc/translate_init.c | 8 ++++++++
 3 files changed, 16 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 1a69cf876c..2b4744d331 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -376,6 +376,7 @@ DEF_HELPER_0(load_601_rtcu, tl)
 #if !defined(CONFIG_USER_ONLY)
 #if defined(TARGET_PPC64)
 DEF_HELPER_1(store_asr, void, tl)
+DEF_HELPER_0(load_purr, tl)
 #endif
 DEF_HELPER_1(store_sdr1, void, tl)
 DEF_HELPER_1(store_tbl, void, tl)
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index bdb1f1732a..aa2e8ba415 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -86,6 +86,13 @@ target_ulong helper_load_atbu (void)
     return cpu_ppc_load_atbu(env);
 }
 
+#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
+target_ulong helper_load_purr (void)
+{
+    return (target_ulong)cpu_ppc_load_purr(env);
+}
+#endif
+
 target_ulong helper_load_601_rtcl (void)
 {
     return cpu_ppc601_load_rtcl(env);
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 7c08b1cb09..bca85d5073 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -251,6 +251,14 @@ static void spr_write_atbu (void *opaque, int sprn, int gprn)
 {
     gen_helper_store_atbu(cpu_gpr[gprn]);
 }
+
+#if defined(TARGET_PPC64)
+__attribute__ (( unused ))
+static void spr_read_purr (void *opaque, int gprn, int sprn)
+{
+    gen_helper_load_purr(cpu_gpr[gprn]);
+}
+#endif
 #endif
 
 #if !defined(CONFIG_USER_ONLY)

From eaabeef2688cdc7da462e9389fce64b1178de8ce Mon Sep 17 00:00:00 2001
From: David Gibson <dwg@au1.ibm.com>
Date: Fri, 1 Apr 2011 15:15:13 +1100
Subject: [PATCH 011/386] Correct ppc popcntb logic, implement popcntw and
 popcntd

qemu already includes support for the popcntb instruction introduced
in POWER5 (although it doesn't actually allow you to choose POWER5).

However, the logic is slightly incorrect: it will generate results
truncated to 32-bits when the CPU is in 32-bit mode.  This is not
normal for powerpc - generally arithmetic instructions on a 64-bit
powerpc cpu will generate full 64 bit results, it's just that only the
low 32 bits will be significant for condition codes.

This patch corrects this nit, which actually simplifies the code slightly.

In addition, this patch implements the popcntw and popcntd
instructions added in POWER7, in preparation for allowing POWER7 as an
emulated CPU.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h       |  2 ++
 target-ppc/helper.h    |  3 ++-
 target-ppc/op_helper.c | 55 ++++++++++++++++++++++++++++++++++++++----
 target-ppc/translate.c | 22 ++++++++++++-----
 4 files changed, 70 insertions(+), 12 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index f293f85976..37dde390a8 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1505,6 +1505,8 @@ enum {
     PPC_DCRX           = 0x2000000000000000ULL,
     /* user-mode DCR access, implemented in PowerPC 460                      */
     PPC_DCRUX          = 0x4000000000000000ULL,
+    /* popcntw and popcntd instructions                                      */
+    PPC_POPCNTWD       = 0x8000000000000000ULL,
 };
 
 /*****************************************************************************/
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 2b4744d331..7c02be9cfd 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -38,10 +38,11 @@ DEF_HELPER_2(mulldo, i64, i64, i64)
 
 DEF_HELPER_FLAGS_1(cntlzw, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl)
 DEF_HELPER_FLAGS_1(popcntb, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl)
+DEF_HELPER_FLAGS_1(popcntw, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl)
 DEF_HELPER_2(sraw, tl, tl, tl)
 #if defined(TARGET_PPC64)
 DEF_HELPER_FLAGS_1(cntlzd, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl)
-DEF_HELPER_FLAGS_1(popcntb_64, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl)
+DEF_HELPER_FLAGS_1(popcntd, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl)
 DEF_HELPER_2(srad, tl, tl, tl)
 #endif
 
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index aa2e8ba415..b1b883d0a7 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -499,6 +499,50 @@ target_ulong helper_srad (target_ulong value, target_ulong shift)
 }
 #endif
 
+#if defined(TARGET_PPC64)
+target_ulong helper_popcntb (target_ulong val)
+{
+    val = (val & 0x5555555555555555ULL) + ((val >>  1) &
+                                           0x5555555555555555ULL);
+    val = (val & 0x3333333333333333ULL) + ((val >>  2) &
+                                           0x3333333333333333ULL);
+    val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >>  4) &
+                                           0x0f0f0f0f0f0f0f0fULL);
+    return val;
+}
+
+target_ulong helper_popcntw (target_ulong val)
+{
+    val = (val & 0x5555555555555555ULL) + ((val >>  1) &
+                                           0x5555555555555555ULL);
+    val = (val & 0x3333333333333333ULL) + ((val >>  2) &
+                                           0x3333333333333333ULL);
+    val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >>  4) &
+                                           0x0f0f0f0f0f0f0f0fULL);
+    val = (val & 0x00ff00ff00ff00ffULL) + ((val >>  8) &
+                                           0x00ff00ff00ff00ffULL);
+    val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) &
+                                           0x0000ffff0000ffffULL);
+    return val;
+}
+
+target_ulong helper_popcntd (target_ulong val)
+{
+    val = (val & 0x5555555555555555ULL) + ((val >>  1) &
+                                           0x5555555555555555ULL);
+    val = (val & 0x3333333333333333ULL) + ((val >>  2) &
+                                           0x3333333333333333ULL);
+    val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >>  4) &
+                                           0x0f0f0f0f0f0f0f0fULL);
+    val = (val & 0x00ff00ff00ff00ffULL) + ((val >>  8) &
+                                           0x00ff00ff00ff00ffULL);
+    val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) &
+                                           0x0000ffff0000ffffULL);
+    val = (val & 0x00000000ffffffffULL) + ((val >> 32) &
+                                           0x00000000ffffffffULL);
+    return val;
+}
+#else
 target_ulong helper_popcntb (target_ulong val)
 {
     val = (val & 0x55555555) + ((val >>  1) & 0x55555555);
@@ -507,12 +551,13 @@ target_ulong helper_popcntb (target_ulong val)
     return val;
 }
 
-#if defined(TARGET_PPC64)
-target_ulong helper_popcntb_64 (target_ulong val)
+target_ulong helper_popcntw (target_ulong val)
 {
-    val = (val & 0x5555555555555555ULL) + ((val >>  1) & 0x5555555555555555ULL);
-    val = (val & 0x3333333333333333ULL) + ((val >>  2) & 0x3333333333333333ULL);
-    val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >>  4) & 0x0f0f0f0f0f0f0f0fULL);
+    val = (val & 0x55555555) + ((val >>  1) & 0x55555555);
+    val = (val & 0x33333333) + ((val >>  2) & 0x33333333);
+    val = (val & 0x0f0f0f0f) + ((val >>  4) & 0x0f0f0f0f);
+    val = (val & 0x00ff00ff) + ((val >>  8) & 0x00ff00ff);
+    val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff);
     return val;
 }
 #endif
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 4252508327..88681359c7 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -1483,14 +1483,22 @@ static void gen_xoris(DisasContext *ctx)
 /* popcntb : PowerPC 2.03 specification */
 static void gen_popcntb(DisasContext *ctx)
 {
-#if defined(TARGET_PPC64)
-    if (ctx->sf_mode)
-        gen_helper_popcntb_64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
-    else
-#endif
-        gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
+    gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
 }
 
+static void gen_popcntw(DisasContext *ctx)
+{
+    gen_helper_popcntw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
+}
+
+#if defined(TARGET_PPC64)
+/* popcntd: PowerPC 2.06 specification */
+static void gen_popcntd(DisasContext *ctx)
+{
+    gen_helper_popcntd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
+}
+#endif
+
 #if defined(TARGET_PPC64)
 /* extsw & extsw. */
 GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
@@ -8226,7 +8234,9 @@ GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
 GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB),
+GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD),
 #if defined(TARGET_PPC64)
+GEN_HANDLER(popcntd, 0x1F, 0x1A, 0x0F, 0x0000F801, PPC_POPCNTWD),
 GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
 #endif
 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),

From 8500e3a91292f253002783da267f3b08aead86c1 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:14 +1100
Subject: [PATCH 012/386] Clean up slb_lookup() function

The slb_lookup() function, used in the ppc translation path returns a
number of slb entry fields in reference parameters.  However, only one
of the two callers of slb_lookup() actually wants this information.

This patch, therefore, makes slb_lookup() return a simple pointer to the
located SLB entry (or NULL), and the caller which needs the fields can
extract them itself.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.c | 45 ++++++++++++++++++---------------------------
 1 file changed, 18 insertions(+), 27 deletions(-)

diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index b9621d2dd0..7ca33cbc75 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -676,9 +676,7 @@ static inline int find_pte(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
 }
 
 #if defined(TARGET_PPC64)
-static inline int slb_lookup(CPUPPCState *env, target_ulong eaddr,
-                             target_ulong *vsid, target_ulong *page_mask,
-                             int *attr, int *target_page_bits)
+static inline ppc_slb_t *slb_lookup(CPUPPCState *env, target_ulong eaddr)
 {
     uint64_t esid;
     int n;
@@ -693,19 +691,11 @@ static inline int slb_lookup(CPUPPCState *env, target_ulong eaddr,
         LOG_SLB("%s: slot %d %016" PRIx64 " %016"
                     PRIx64 "\n", __func__, n, slb->esid, slb->vsid);
         if (slb->esid == esid) {
-            *vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
-            *page_mask = ~SEGMENT_MASK_256M;
-            *attr = slb->vsid & SLB_VSID_ATTR;
-            if (target_page_bits) {
-                *target_page_bits = (slb->vsid & SLB_VSID_L)
-                    ? TARGET_PAGE_BITS_16M
-                    : TARGET_PAGE_BITS;
-            }
-            return n;
+            return slb;
         }
     }
 
-    return -5;
+    return NULL;
 }
 
 void ppc_slb_invalidate_all (CPUPPCState *env)
@@ -732,18 +722,13 @@ void ppc_slb_invalidate_all (CPUPPCState *env)
 
 void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
 {
-    target_ulong vsid, page_mask;
-    int attr;
-    int n;
     ppc_slb_t *slb;
 
-    n = slb_lookup(env, T0, &vsid, &page_mask, &attr, NULL);
-    if (n < 0) {
+    slb = slb_lookup(env, T0);
+    if (!slb) {
         return;
     }
 
-    slb = &env->slb[n];
-
     if (slb->esid & SLB_ESID_V) {
         slb->esid &= ~SLB_ESID_V;
 
@@ -822,16 +807,22 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
     pr = msr_pr;
 #if defined(TARGET_PPC64)
     if (env->mmu_model & POWERPC_MMU_64) {
-        int attr;
+        ppc_slb_t *slb;
 
         LOG_MMU("Check SLBs\n");
-        ret = slb_lookup(env, eaddr, &vsid, &page_mask, &attr,
-                         &target_page_bits);
-        if (ret < 0)
-            return ret;
-        ctx->key = !!(pr ? (attr & SLB_VSID_KP) : (attr & SLB_VSID_KS));
+        slb = slb_lookup(env, eaddr);
+        if (!slb) {
+            return -5;
+        }
+
+        vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
+        page_mask = ~SEGMENT_MASK_256M;
+        target_page_bits = (slb->vsid & SLB_VSID_L)
+            ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS;
+        ctx->key = !!(pr ? (slb->vsid & SLB_VSID_KP)
+                      : (slb->vsid & SLB_VSID_KS));
         ds = 0;
-        ctx->nx = !!(attr & SLB_VSID_N);
+        ctx->nx = !!(slb->vsid & SLB_VSID_N);
         ctx->eaddr = eaddr;
         vsid_mask = 0x00003FFFFFFFFF80ULL;
         vsid_sh = 7;

From bb593904c18e22ea0671dfa1b02e24982f2bf0ea Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:15 +1100
Subject: [PATCH 013/386] Parse SDR1 on mtspr instead of at translate time

On ppc machines with hash table MMUs, the special purpose register SDR1
contains both the base address of the encoded size (hashed) page tables.

At present, we interpret the SDR1 value within the address translation
path.  But because the encodings of the size for 32-bit and 64-bit are
different this makes for a confusing branch on the MMU type with a bunch
of curly shifts and masks in the middle of the translate path.

This patch cleans things up by moving the interpretation on SDR1 into the
helper function handling the write to the register.  This leaves a simple
pre-sanitized base address and mask for the hash table in the CPUState
structure which is easier to work with in the translation path.

This makes the translation path more readable.  It addresses the FIXME
comment currently in the mtsdr1 helper, by validating the SDR1 value during
interpretation.  Finally it opens the way for emulating a pSeries-style
partition where the hash table used for translation is not mapped into
the guests's RAM.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 monitor.c                   |  2 +-
 target-ppc/cpu.h            | 11 ++++-
 target-ppc/helper.c         | 80 +++++++++++++++++++++----------------
 target-ppc/kvm.c            |  2 +-
 target-ppc/machine.c        |  6 ++-
 target-ppc/translate.c      |  2 +-
 target-ppc/translate_init.c |  7 +---
 7 files changed, 63 insertions(+), 47 deletions(-)

diff --git a/monitor.c b/monitor.c
index 76a82074ae..f1a08dc486 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3462,7 +3462,7 @@ static const MonitorDef monitor_defs[] = {
     { "asr", offsetof(CPUState, asr) },
 #endif
     /* Segment registers */
-    { "sdr1", offsetof(CPUState, sdr1) },
+    { "sdr1", offsetof(CPUState, spr[SPR_SDR1]) },
     { "sr0", offsetof(CPUState, sr[0]) },
     { "sr1", offsetof(CPUState, sr[1]) },
     { "sr2", offsetof(CPUState, sr[2]) },
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 37dde390a8..ead4566f4f 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -359,6 +359,14 @@ union ppc_tlb_t {
 };
 #endif
 
+#define SDR_32_HTABORG         0xFFFF0000UL
+#define SDR_32_HTABMASK        0x000001FFUL
+
+#if defined(TARGET_PPC64)
+#define SDR_64_HTABORG         0xFFFFFFFFFFFC0000ULL
+#define SDR_64_HTABSIZE        0x000000000000001FULL
+#endif /* defined(TARGET_PPC64 */
+
 typedef struct ppc_slb_t ppc_slb_t;
 struct ppc_slb_t {
     uint64_t esid;
@@ -642,7 +650,8 @@ struct CPUPPCState {
     int slb_nr;
 #endif
     /* segment registers */
-    target_ulong sdr1;
+    target_phys_addr_t htab_base;
+    target_phys_addr_t htab_mask;
     target_ulong sr[32];
     /* BATs */
     int nb_BATs;
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 7ca33cbc75..68d2d9c0e2 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -788,20 +788,19 @@ int ppc_load_slb_vsid (CPUPPCState *env, target_ulong rb, target_ulong *rt)
 #endif /* defined(TARGET_PPC64) */
 
 /* Perform segment based translation */
-static inline target_phys_addr_t get_pgaddr(target_phys_addr_t sdr1,
-                                            int sdr_sh,
-                                            target_phys_addr_t hash,
-                                            target_phys_addr_t mask)
+static inline target_phys_addr_t get_pgaddr(target_phys_addr_t htab_base,
+                                            target_phys_addr_t htab_mask,
+                                            target_phys_addr_t hash)
 {
-    return (sdr1 & ((target_phys_addr_t)(-1ULL) << sdr_sh)) | (hash & mask);
+    return htab_base | (hash & htab_mask);
 }
 
 static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
                               target_ulong eaddr, int rw, int type)
 {
-    target_phys_addr_t sdr, hash, mask, sdr_mask, htab_mask;
+    target_phys_addr_t hash;
     target_ulong sr, vsid, vsid_mask, pgidx, page_mask;
-    int ds, vsid_sh, sdr_sh, pr, target_page_bits;
+    int ds, vsid_sh, pr, target_page_bits;
     int ret, ret2;
 
     pr = msr_pr;
@@ -826,8 +825,6 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
         ctx->eaddr = eaddr;
         vsid_mask = 0x00003FFFFFFFFF80ULL;
         vsid_sh = 7;
-        sdr_sh = 18;
-        sdr_mask = 0x3FF80;
     } else
 #endif /* defined(TARGET_PPC64) */
     {
@@ -840,8 +837,6 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
         vsid = sr & 0x00FFFFFF;
         vsid_mask = 0x01FFFFC0;
         vsid_sh = 6;
-        sdr_sh = 16;
-        sdr_mask = 0xFFC0;
         target_page_bits = TARGET_PAGE_BITS;
         LOG_MMU("Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx " nip="
                 TARGET_FMT_lx " lr=" TARGET_FMT_lx
@@ -857,29 +852,26 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
         if (type != ACCESS_CODE || ctx->nx == 0) {
             /* Page address translation */
             /* Primary table address */
-            sdr = env->sdr1;
             pgidx = (eaddr & page_mask) >> target_page_bits;
 #if defined(TARGET_PPC64)
             if (env->mmu_model & POWERPC_MMU_64) {
-                htab_mask = 0x0FFFFFFF >> (28 - (sdr & 0x1F));
                 /* XXX: this is false for 1 TB segments */
                 hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
             } else
 #endif
             {
-                htab_mask = sdr & 0x000001FF;
                 hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
             }
-            mask = (htab_mask << sdr_sh) | sdr_mask;
-            LOG_MMU("sdr " TARGET_FMT_plx " sh %d hash " TARGET_FMT_plx
-                    " mask " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
-                    sdr, sdr_sh, hash, mask, page_mask);
-            ctx->pg_addr[0] = get_pgaddr(sdr, sdr_sh, hash, mask);
+            LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
+                    " hash " TARGET_FMT_plx "\n",
+                    env->htab_base, env->htab_mask, hash);
+            ctx->pg_addr[0] = get_pgaddr(env->htab_base, env->htab_mask, hash);
             /* Secondary table address */
             hash = (~hash) & vsid_mask;
-            LOG_MMU("sdr " TARGET_FMT_plx " sh %d hash " TARGET_FMT_plx
-                    " mask " TARGET_FMT_plx "\n", sdr, sdr_sh, hash, mask);
-            ctx->pg_addr[1] = get_pgaddr(sdr, sdr_sh, hash, mask);
+            LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
+                    " hash " TARGET_FMT_plx "\n",
+                    env->htab_base, env->htab_mask, hash);
+            ctx->pg_addr[1] = get_pgaddr(env->htab_base, env->htab_mask, hash);
 #if defined(TARGET_PPC64)
             if (env->mmu_model & POWERPC_MMU_64) {
                 /* Only 5 bits of the page index are used in the AVPN */
@@ -901,19 +893,22 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
                 /* Software TLB search */
                 ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
             } else {
-                LOG_MMU("0 sdr1=" TARGET_FMT_plx " vsid=" TARGET_FMT_lx " "
-                        "api=" TARGET_FMT_lx " hash=" TARGET_FMT_plx
-                        " pg_addr=" TARGET_FMT_plx "\n",
-                        sdr, vsid, pgidx, hash, ctx->pg_addr[0]);
+                LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
+                        " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
+                        " hash=" TARGET_FMT_plx " pg_addr=" TARGET_FMT_plx "\n",
+                        env->htab_base, env->htab_mask, vsid, pgidx, hash,
+                        ctx->pg_addr[0]);
                 /* Primary table lookup */
                 ret = find_pte(env, ctx, 0, rw, type, target_page_bits);
                 if (ret < 0) {
                     /* Secondary table lookup */
                     if (eaddr != 0xEFFFFFFF)
-                        LOG_MMU("1 sdr1=" TARGET_FMT_plx " vsid=" TARGET_FMT_lx " "
-                                "api=" TARGET_FMT_lx " hash=" TARGET_FMT_plx
-                                " pg_addr=" TARGET_FMT_plx "\n", sdr, vsid,
-                                pgidx, hash, ctx->pg_addr[1]);
+                        LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
+                                " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
+                                " hash=" TARGET_FMT_plx " pg_addr="
+                                TARGET_FMT_plx "\n", env->htab_base,
+                                env->htab_mask, vsid, pgidx, hash,
+                                ctx->pg_addr[1]);
                     ret2 = find_pte(env, ctx, 1, rw, type,
                                     target_page_bits);
                     if (ret2 != -1)
@@ -1919,11 +1914,26 @@ void ppc_store_asr (CPUPPCState *env, target_ulong value)
 void ppc_store_sdr1 (CPUPPCState *env, target_ulong value)
 {
     LOG_MMU("%s: " TARGET_FMT_lx "\n", __func__, value);
-    if (env->sdr1 != value) {
-        /* XXX: for PowerPC 64, should check that the HTABSIZE value
-         *      is <= 28
-         */
-        env->sdr1 = value;
+    if (env->spr[SPR_SDR1] != value) {
+        env->spr[SPR_SDR1] = value;
+#if defined(TARGET_PPC64)
+        if (env->mmu_model & POWERPC_MMU_64) {
+            target_ulong htabsize = value & SDR_64_HTABSIZE;
+
+            if (htabsize > 28) {
+                fprintf(stderr, "Invalid HTABSIZE 0x" TARGET_FMT_lx
+                        " stored in SDR1\n", htabsize);
+                htabsize = 28;
+            }
+            env->htab_mask = (1ULL << (htabsize + 18)) - 1;
+            env->htab_base = value & SDR_64_HTABORG;
+        } else
+#endif /* defined(TARGET_PPC64) */
+        {
+            /* FIXME: Should check for valid HTABMASK values */
+            env->htab_mask = ((value & SDR_32_HTABMASK) << 16) | 0xFFFF;
+            env->htab_base = value & SDR_32_HTABORG;
+        }
         tlb_flush(env, 1);
     }
 }
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 0e2e67b34d..2cfb24bb1d 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -169,7 +169,7 @@ int kvm_arch_get_registers(CPUState *env)
 
 #ifdef KVM_CAP_PPC_SEGSTATE
     if (kvm_check_extension(env->kvm_state, KVM_CAP_PPC_SEGSTATE)) {
-        env->sdr1 = sregs.u.s.sdr1;
+        ppc_store_sdr1(env, sregs.u.s.sdr1);
 
         /* Sync SLB */
 #ifdef TARGET_PPC64
diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index 67de951959..0c1986e528 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -37,7 +37,7 @@ void cpu_save(QEMUFile *f, void *opaque)
     qemu_put_betls(f, &env->asr);
     qemu_put_sbe32s(f, &env->slb_nr);
 #endif
-    qemu_put_betls(f, &env->sdr1);
+    qemu_put_betls(f, &env->spr[SPR_SDR1]);
     for (i = 0; i < 32; i++)
         qemu_put_betls(f, &env->sr[i]);
     for (i = 0; i < 2; i++)
@@ -93,6 +93,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
 {
     CPUState *env = (CPUState *)opaque;
     unsigned int i, j;
+    target_ulong sdr1;
 
     for (i = 0; i < 32; i++)
         qemu_get_betls(f, &env->gpr[i]);
@@ -124,7 +125,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     qemu_get_betls(f, &env->asr);
     qemu_get_sbe32s(f, &env->slb_nr);
 #endif
-    qemu_get_betls(f, &env->sdr1);
+    qemu_get_betls(f, &sdr1);
     for (i = 0; i < 32; i++)
         qemu_get_betls(f, &env->sr[i]);
     for (i = 0; i < 2; i++)
@@ -152,6 +153,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
 #endif
     for (i = 0; i < 1024; i++)
         qemu_get_betls(f, &env->spr[i]);
+    ppc_store_sdr1(env, sdr1);
     qemu_get_be32s(f, &env->vscr);
     qemu_get_be64s(f, &env->spe_acc);
     qemu_get_be32s(f, &env->spe_fscr);
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 88681359c7..090795b600 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9126,7 +9126,7 @@ void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
 #if !defined(CONFIG_USER_ONLY)
     cpu_fprintf(f, "SRR0 " TARGET_FMT_lx " SRR1 " TARGET_FMT_lx " SDR1 "
                 TARGET_FMT_lx "\n", env->spr[SPR_SRR0], env->spr[SPR_SRR1],
-                env->sdr1);
+                env->spr[SPR_SDR1]);
 #endif
 
 #undef RGPL
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index bca85d5073..63664248a4 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -343,11 +343,6 @@ static void spr_write_dbatl_h (void *opaque, int sprn, int gprn)
 }
 
 /* SDR1 */
-static void spr_read_sdr1 (void *opaque, int gprn, int sprn)
-{
-    tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, sdr1));
-}
-
 static void spr_write_sdr1 (void *opaque, int sprn, int gprn)
 {
     gen_helper_store_sdr1(cpu_gpr[gprn]);
@@ -671,7 +666,7 @@ static void gen_spr_ne_601 (CPUPPCState *env)
     /* Memory management */
     spr_register(env, SPR_SDR1, "SDR1",
                  SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_sdr1, &spr_write_sdr1,
+                 &spr_read_generic, &spr_write_sdr1,
                  0x00000000);
 }
 

From fda6a0ecc61926ea1af6a85ab47a4ae47a6fe0a7 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:16 +1100
Subject: [PATCH 014/386] Use "hash" more consistently in ppc mmu code

Currently, get_segment() has a variable called hash.  However it doesn't
(quite) get the hash value for the ppc hashed page table.  Instead it
gets the hash shifted - effectively the offset of the hash bucket within
the hash page table.

As well, as being different to the normal use of plain "hash" in the
architecture documentation, this usage necessitates some awkward 32/64
dependent masks and shifts which clutter up the path in get_segment().

This patch alters the code to use raw hash values through get_segment()
including storing raw hashes instead of pte group offsets in the ctx
structure.  This cleans up the path noticeably.

This does necessitate 32/64 dependent shifts when the hash values are
taken out of the ctx structure and used, but those paths already have
32/64 bit variants so this is less awkward than it was in get_segment().

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h    |  5 ++-
 target-ppc/helper.c | 97 ++++++++++++++++++++++-----------------------
 2 files changed, 51 insertions(+), 51 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index ead4566f4f..cee1057aeb 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -367,6 +367,9 @@ union ppc_tlb_t {
 #define SDR_64_HTABSIZE        0x000000000000001FULL
 #endif /* defined(TARGET_PPC64 */
 
+#define HASH_PTE_SIZE_32       8
+#define HASH_PTE_SIZE_64       16
+
 typedef struct ppc_slb_t ppc_slb_t;
 struct ppc_slb_t {
     uint64_t esid;
@@ -744,7 +747,7 @@ struct mmu_ctx_t {
     target_phys_addr_t raddr;      /* Real address              */
     target_phys_addr_t eaddr;      /* Effective address         */
     int prot;                      /* Protection bits           */
-    target_phys_addr_t pg_addr[2]; /* PTE tables base addresses */
+    target_phys_addr_t hash[2];    /* Pagetable hash values     */
     target_ulong ptem;             /* Virtual segment ID | API  */
     int key;                       /* Access key                */
     int nx;                        /* Non-execute area          */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 68d2d9c0e2..0efa2a8c3a 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -567,21 +567,30 @@ static inline int get_bat(CPUState *env, mmu_ctx_t *ctx, target_ulong virtual,
     return ret;
 }
 
-/* PTE table lookup */
-static inline int _find_pte(mmu_ctx_t *ctx, int is_64b, int h, int rw,
-                            int type, int target_page_bits)
+static inline target_phys_addr_t get_pteg_offset(CPUState *env,
+                                                 target_phys_addr_t hash,
+                                                 int pte_size)
 {
-    target_ulong base, pte0, pte1;
+    return (hash * pte_size * 8) & env->htab_mask;
+}
+
+/* PTE table lookup */
+static inline int _find_pte(CPUState *env, mmu_ctx_t *ctx, int is_64b, int h,
+                            int rw, int type, int target_page_bits)
+{
+    target_phys_addr_t pteg_off;
+    target_ulong pte0, pte1;
     int i, good = -1;
     int ret, r;
 
     ret = -1; /* No entry found */
-    base = ctx->pg_addr[h];
+    pteg_off = get_pteg_offset(env, ctx->hash[h],
+                               is_64b ? HASH_PTE_SIZE_64 : HASH_PTE_SIZE_32);
     for (i = 0; i < 8; i++) {
 #if defined(TARGET_PPC64)
         if (is_64b) {
-            pte0 = ldq_phys(base + (i * 16));
-            pte1 = ldq_phys(base + (i * 16) + 8);
+            pte0 = ldq_phys(env->htab_base + pteg_off + (i * 16));
+            pte1 = ldq_phys(env->htab_base + pteg_off + (i * 16) + 8);
 
             /* We have a TLB that saves 4K pages, so let's
              * split a huge page to 4k chunks */
@@ -592,17 +601,17 @@ static inline int _find_pte(mmu_ctx_t *ctx, int is_64b, int h, int rw,
             r = pte64_check(ctx, pte0, pte1, h, rw, type);
             LOG_MMU("Load pte from " TARGET_FMT_lx " => " TARGET_FMT_lx " "
                     TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",
-                    base + (i * 16), pte0, pte1, (int)(pte0 & 1), h,
+                    pteg_base + (i * 16), pte0, pte1, (int)(pte0 & 1), h,
                     (int)((pte0 >> 1) & 1), ctx->ptem);
         } else
 #endif
         {
-            pte0 = ldl_phys(base + (i * 8));
-            pte1 =  ldl_phys(base + (i * 8) + 4);
+            pte0 = ldl_phys(env->htab_base + pteg_off + (i * 8));
+            pte1 =  ldl_phys(env->htab_base + pteg_off + (i * 8) + 4);
             r = pte32_check(ctx, pte0, pte1, h, rw, type);
             LOG_MMU("Load pte from " TARGET_FMT_lx " => " TARGET_FMT_lx " "
                     TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",
-                    base + (i * 8), pte0, pte1, (int)(pte0 >> 31), h,
+                    pteg_base + (i * 8), pte0, pte1, (int)(pte0 >> 31), h,
                     (int)((pte0 >> 6) & 1), ctx->ptem);
         }
         switch (r) {
@@ -638,11 +647,13 @@ static inline int _find_pte(mmu_ctx_t *ctx, int is_64b, int h, int rw,
         if (pte_update_flags(ctx, &pte1, ret, rw) == 1) {
 #if defined(TARGET_PPC64)
             if (is_64b) {
-                stq_phys_notdirty(base + (good * 16) + 8, pte1);
+                stq_phys_notdirty(env->htab_base + pteg_off + (good * 16) + 8,
+                                  pte1);
             } else
 #endif
             {
-                stl_phys_notdirty(base + (good * 8) + 4, pte1);
+                stl_phys_notdirty(env->htab_base + pteg_off + (good * 8) + 4,
+                                  pte1);
             }
         }
     }
@@ -650,17 +661,17 @@ static inline int _find_pte(mmu_ctx_t *ctx, int is_64b, int h, int rw,
     return ret;
 }
 
-static inline int find_pte32(mmu_ctx_t *ctx, int h, int rw, int type,
-                             int target_page_bits)
+static inline int find_pte32(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
+                             int type, int target_page_bits)
 {
-    return _find_pte(ctx, 0, h, rw, type, target_page_bits);
+    return _find_pte(env, ctx, 0, h, rw, type, target_page_bits);
 }
 
 #if defined(TARGET_PPC64)
-static inline int find_pte64(mmu_ctx_t *ctx, int h, int rw, int type,
-                             int target_page_bits)
+static inline int find_pte64(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
+                             int type, int target_page_bits)
 {
-    return _find_pte(ctx, 1, h, rw, type, target_page_bits);
+    return _find_pte(env, ctx, 1, h, rw, type, target_page_bits);
 }
 #endif
 
@@ -669,10 +680,10 @@ static inline int find_pte(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
 {
 #if defined(TARGET_PPC64)
     if (env->mmu_model & POWERPC_MMU_64)
-        return find_pte64(ctx, h, rw, type, target_page_bits);
+        return find_pte64(env, ctx, h, rw, type, target_page_bits);
 #endif
 
-    return find_pte32(ctx, h, rw, type, target_page_bits);
+    return find_pte32(env, ctx, h, rw, type, target_page_bits);
 }
 
 #if defined(TARGET_PPC64)
@@ -788,19 +799,12 @@ int ppc_load_slb_vsid (CPUPPCState *env, target_ulong rb, target_ulong *rt)
 #endif /* defined(TARGET_PPC64) */
 
 /* Perform segment based translation */
-static inline target_phys_addr_t get_pgaddr(target_phys_addr_t htab_base,
-                                            target_phys_addr_t htab_mask,
-                                            target_phys_addr_t hash)
-{
-    return htab_base | (hash & htab_mask);
-}
-
 static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
                               target_ulong eaddr, int rw, int type)
 {
     target_phys_addr_t hash;
-    target_ulong sr, vsid, vsid_mask, pgidx, page_mask;
-    int ds, vsid_sh, pr, target_page_bits;
+    target_ulong sr, vsid, pgidx, page_mask;
+    int ds, pr, target_page_bits;
     int ret, ret2;
 
     pr = msr_pr;
@@ -823,8 +827,6 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
         ds = 0;
         ctx->nx = !!(slb->vsid & SLB_VSID_N);
         ctx->eaddr = eaddr;
-        vsid_mask = 0x00003FFFFFFFFF80ULL;
-        vsid_sh = 7;
     } else
 #endif /* defined(TARGET_PPC64) */
     {
@@ -835,8 +837,6 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
         ds = sr & 0x80000000 ? 1 : 0;
         ctx->nx = sr & 0x10000000 ? 1 : 0;
         vsid = sr & 0x00FFFFFF;
-        vsid_mask = 0x01FFFFC0;
-        vsid_sh = 6;
         target_page_bits = TARGET_PAGE_BITS;
         LOG_MMU("Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx " nip="
                 TARGET_FMT_lx " lr=" TARGET_FMT_lx
@@ -851,27 +851,22 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
         /* Check if instruction fetch is allowed, if needed */
         if (type != ACCESS_CODE || ctx->nx == 0) {
             /* Page address translation */
-            /* Primary table address */
             pgidx = (eaddr & page_mask) >> target_page_bits;
 #if defined(TARGET_PPC64)
             if (env->mmu_model & POWERPC_MMU_64) {
                 /* XXX: this is false for 1 TB segments */
-                hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
+                hash = vsid ^ pgidx;
             } else
 #endif
             {
-                hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
+                hash = vsid ^ pgidx;
             }
             LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
                     " hash " TARGET_FMT_plx "\n",
                     env->htab_base, env->htab_mask, hash);
-            ctx->pg_addr[0] = get_pgaddr(env->htab_base, env->htab_mask, hash);
-            /* Secondary table address */
-            hash = (~hash) & vsid_mask;
-            LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
-                    " hash " TARGET_FMT_plx "\n",
-                    env->htab_base, env->htab_mask, hash);
-            ctx->pg_addr[1] = get_pgaddr(env->htab_base, env->htab_mask, hash);
+            ctx->hash[0] = hash;
+            ctx->hash[1] = ~hash;
+
 #if defined(TARGET_PPC64)
             if (env->mmu_model & POWERPC_MMU_64) {
                 /* Only 5 bits of the page index are used in the AVPN */
@@ -895,9 +890,9 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
             } else {
                 LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
                         " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
-                        " hash=" TARGET_FMT_plx " pg_addr=" TARGET_FMT_plx "\n",
-                        env->htab_base, env->htab_mask, vsid, pgidx, hash,
-                        ctx->pg_addr[0]);
+                        " hash=" TARGET_FMT_plx "\n",
+                        env->htab_base, env->htab_mask, vsid, pgidx,
+                        ctx->hash[0]);
                 /* Primary table lookup */
                 ret = find_pte(env, ctx, 0, rw, type, target_page_bits);
                 if (ret < 0) {
@@ -908,7 +903,7 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
                                 " hash=" TARGET_FMT_plx " pg_addr="
                                 TARGET_FMT_plx "\n", env->htab_base,
                                 env->htab_mask, vsid, pgidx, hash,
-                                ctx->pg_addr[1]);
+                                ctx->hash[1]);
                     ret2 = find_pte(env, ctx, 1, rw, type,
                                     target_page_bits);
                     if (ret2 != -1)
@@ -1460,8 +1455,10 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
                     env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
                 tlb_miss:
                     env->error_code |= ctx.key << 19;
-                    env->spr[SPR_HASH1] = ctx.pg_addr[0];
-                    env->spr[SPR_HASH2] = ctx.pg_addr[1];
+                    env->spr[SPR_HASH1] = env->htab_base +
+                        get_pteg_offset(env, ctx.hash[0], HASH_PTE_SIZE_32);
+                    env->spr[SPR_HASH2] = env->htab_base +
+                        get_pteg_offset(env, ctx.hash[1], HASH_PTE_SIZE_32);
                     break;
                 case POWERPC_MMU_SOFT_74xx:
                     if (rw == 1) {

From 256cebe5d17477cd1443f47a9bd5ca35ca0dbc9c Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:17 +1100
Subject: [PATCH 015/386] Better factor the ppc hash translation path

Currently the path handling hash page table translation in get_segment()
has a mix of common and 32 or 64 bit specific code.  However the
division is not done terribly well which results in a lot of messy code
flipping between common and divided paths.

This patch improves the organization, consolidating several divided paths
into one.  This in turn allows simplification of some code in
get_segment(), removing a number of ugly interim variables.

This new factorization will also make it easier to add support for the 1T
segments added in newer CPUs.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h    |  1 +
 target-ppc/helper.c | 67 +++++++++++++--------------------------------
 2 files changed, 20 insertions(+), 48 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index cee1057aeb..fd2dfcd92c 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -386,6 +386,7 @@ struct ppc_slb_t {
 #define SLB_VSID_B              0xc000000000000000ULL
 #define SLB_VSID_B_256M         0x0000000000000000ULL
 #define SLB_VSID_VSID           0x3FFFFFFFFFFFF000ULL
+#define SLB_VSID_PTEM           (SLB_VSID_B | SLB_VSID_VSID)
 #define SLB_VSID_KS             0x0000000000000800ULL
 #define SLB_VSID_KP             0x0000000000000400ULL
 #define SLB_VSID_N              0x0000000000000200ULL /* no-execute */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 0efa2a8c3a..ae8001cd35 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -661,29 +661,15 @@ static inline int _find_pte(CPUState *env, mmu_ctx_t *ctx, int is_64b, int h,
     return ret;
 }
 
-static inline int find_pte32(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
-                             int type, int target_page_bits)
-{
-    return _find_pte(env, ctx, 0, h, rw, type, target_page_bits);
-}
-
-#if defined(TARGET_PPC64)
-static inline int find_pte64(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
-                             int type, int target_page_bits)
-{
-    return _find_pte(env, ctx, 1, h, rw, type, target_page_bits);
-}
-#endif
-
 static inline int find_pte(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
                            int type, int target_page_bits)
 {
 #if defined(TARGET_PPC64)
     if (env->mmu_model & POWERPC_MMU_64)
-        return find_pte64(env, ctx, h, rw, type, target_page_bits);
+        return _find_pte(env, ctx, 1, h, rw, type, target_page_bits);
 #endif
 
-    return find_pte32(env, ctx, h, rw, type, target_page_bits);
+    return _find_pte(env, ctx, 0, h, rw, type, target_page_bits);
 }
 
 #if defined(TARGET_PPC64)
@@ -803,14 +789,16 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
                               target_ulong eaddr, int rw, int type)
 {
     target_phys_addr_t hash;
-    target_ulong sr, vsid, pgidx, page_mask;
+    target_ulong vsid;
     int ds, pr, target_page_bits;
     int ret, ret2;
 
     pr = msr_pr;
+    ctx->eaddr = eaddr;
 #if defined(TARGET_PPC64)
     if (env->mmu_model & POWERPC_MMU_64) {
         ppc_slb_t *slb;
+        target_ulong pageaddr;
 
         LOG_MMU("Check SLBs\n");
         slb = slb_lookup(env, eaddr);
@@ -819,19 +807,24 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
         }
 
         vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
-        page_mask = ~SEGMENT_MASK_256M;
         target_page_bits = (slb->vsid & SLB_VSID_L)
             ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS;
         ctx->key = !!(pr ? (slb->vsid & SLB_VSID_KP)
                       : (slb->vsid & SLB_VSID_KS));
         ds = 0;
         ctx->nx = !!(slb->vsid & SLB_VSID_N);
-        ctx->eaddr = eaddr;
+
+        pageaddr = eaddr & ((1ULL << 28) - (1ULL << target_page_bits));
+        /* XXX: this is false for 1 TB segments */
+        hash = vsid ^ (pageaddr >> target_page_bits);
+        /* Only 5 bits of the page index are used in the AVPN */
+        ctx->ptem = (slb->vsid & SLB_VSID_PTEM) | ((pageaddr >> 16) & 0x0F80);
     } else
 #endif /* defined(TARGET_PPC64) */
     {
+        target_ulong sr, pgidx;
+
         sr = env->sr[eaddr >> 28];
-        page_mask = 0x0FFFFFFF;
         ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
                     ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
         ds = sr & 0x80000000 ? 1 : 0;
@@ -843,6 +836,9 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
                 " ir=%d dr=%d pr=%d %d t=%d\n",
                 eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir,
                 (int)msr_dr, pr != 0 ? 1 : 0, rw, type);
+        pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits;
+        hash = vsid ^ pgidx;
+        ctx->ptem = (vsid << 7) | (pgidx >> 10);
     }
     LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n",
             ctx->key, ds, ctx->nx, vsid);
@@ -851,36 +847,12 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
         /* Check if instruction fetch is allowed, if needed */
         if (type != ACCESS_CODE || ctx->nx == 0) {
             /* Page address translation */
-            pgidx = (eaddr & page_mask) >> target_page_bits;
-#if defined(TARGET_PPC64)
-            if (env->mmu_model & POWERPC_MMU_64) {
-                /* XXX: this is false for 1 TB segments */
-                hash = vsid ^ pgidx;
-            } else
-#endif
-            {
-                hash = vsid ^ pgidx;
-            }
             LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
                     " hash " TARGET_FMT_plx "\n",
                     env->htab_base, env->htab_mask, hash);
             ctx->hash[0] = hash;
             ctx->hash[1] = ~hash;
 
-#if defined(TARGET_PPC64)
-            if (env->mmu_model & POWERPC_MMU_64) {
-                /* Only 5 bits of the page index are used in the AVPN */
-                if (target_page_bits > 23) {
-                    ctx->ptem = (vsid << 12) |
-                                ((pgidx << (target_page_bits - 16)) & 0xF80);
-                } else {
-                    ctx->ptem = (vsid << 12) | ((pgidx >> 4) & 0x0F80);
-                }
-            } else
-#endif
-            {
-                ctx->ptem = (vsid << 7) | (pgidx >> 10);
-            }
             /* Initialize real address with an invalid value */
             ctx->raddr = (target_phys_addr_t)-1ULL;
             if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx ||
@@ -889,9 +861,9 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
                 ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
             } else {
                 LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
-                        " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
+                        " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
                         " hash=" TARGET_FMT_plx "\n",
-                        env->htab_base, env->htab_mask, vsid, pgidx,
+                        env->htab_base, env->htab_mask, vsid, ctx->ptem,
                         ctx->hash[0]);
                 /* Primary table lookup */
                 ret = find_pte(env, ctx, 0, rw, type, target_page_bits);
@@ -902,8 +874,7 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
                                 " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
                                 " hash=" TARGET_FMT_plx " pg_addr="
                                 TARGET_FMT_plx "\n", env->htab_base,
-                                env->htab_mask, vsid, pgidx, hash,
-                                ctx->hash[1]);
+                                env->htab_mask, vsid, ctx->ptem, ctx->hash[1]);
                     ret2 = find_pte(env, ctx, 1, rw, type,
                                     target_page_bits);
                     if (ret2 != -1)

From cdaee00633cfac7338d8dd0ba3e8766d5bdb1cec Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:18 +1100
Subject: [PATCH 016/386] Support 1T segments on ppc

Traditionally, the "segments" used for the two-stage translation used on
powerpc MMUs were 256MB in size.  This was the only option on all hash
page table based 32-bit powerpc cpus, and on the earlier 64-bit hash page
table based cpus.  However, newer 64-bit cpus also permit 1TB segments

This patch adds support for 1TB segment translation to the qemu code.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h    |  7 +++++++
 target-ppc/helper.c | 50 ++++++++++++++++++++++++++++++++++-----------
 2 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index fd2dfcd92c..10341b307f 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -114,6 +114,7 @@ enum powerpc_mmu_t {
     POWERPC_MMU_601        = 0x0000000A,
 #if defined(TARGET_PPC64)
 #define POWERPC_MMU_64       0x00010000
+#define POWERPC_MMU_1TSEG    0x00020000
     /* 64 bits PowerPC MMU                                     */
     POWERPC_MMU_64B        = POWERPC_MMU_64 | 0x00000001,
     /* 620 variant (no segment exceptions)                     */
@@ -382,9 +383,11 @@ struct ppc_slb_t {
 
 /* Bits in the SLB VSID word */
 #define SLB_VSID_SHIFT          12
+#define SLB_VSID_SHIFT_1T       24
 #define SLB_VSID_SSIZE_SHIFT    62
 #define SLB_VSID_B              0xc000000000000000ULL
 #define SLB_VSID_B_256M         0x0000000000000000ULL
+#define SLB_VSID_B_1T           0x4000000000000000ULL
 #define SLB_VSID_VSID           0x3FFFFFFFFFFFF000ULL
 #define SLB_VSID_PTEM           (SLB_VSID_B | SLB_VSID_VSID)
 #define SLB_VSID_KS             0x0000000000000800ULL
@@ -398,6 +401,10 @@ struct ppc_slb_t {
 #define SEGMENT_SHIFT_256M      28
 #define SEGMENT_MASK_256M       (~((1ULL << SEGMENT_SHIFT_256M) - 1))
 
+#define SEGMENT_SHIFT_1T        40
+#define SEGMENT_MASK_1T         (~((1ULL << SEGMENT_SHIFT_1T) - 1))
+
+
 /*****************************************************************************/
 /* Machine state register bits definition                                    */
 #define MSR_SF   63 /* Sixty-four-bit mode                            hflags */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index ae8001cd35..6712fce8ac 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -675,19 +675,26 @@ static inline int find_pte(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
 #if defined(TARGET_PPC64)
 static inline ppc_slb_t *slb_lookup(CPUPPCState *env, target_ulong eaddr)
 {
-    uint64_t esid;
+    uint64_t esid_256M, esid_1T;
     int n;
 
     LOG_SLB("%s: eaddr " TARGET_FMT_lx "\n", __func__, eaddr);
 
-    esid = (eaddr & SEGMENT_MASK_256M) | SLB_ESID_V;
+    esid_256M = (eaddr & SEGMENT_MASK_256M) | SLB_ESID_V;
+    esid_1T = (eaddr & SEGMENT_MASK_1T) | SLB_ESID_V;
 
     for (n = 0; n < env->slb_nr; n++) {
         ppc_slb_t *slb = &env->slb[n];
 
         LOG_SLB("%s: slot %d %016" PRIx64 " %016"
                     PRIx64 "\n", __func__, n, slb->esid, slb->vsid);
-        if (slb->esid == esid) {
+        /* We check for 1T matches on all MMUs here - if the MMU
+         * doesn't have 1T segment support, we will have prevented 1T
+         * entries from being inserted in the slbmte code. */
+        if (((slb->esid == esid_256M) &&
+             ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_256M))
+            || ((slb->esid == esid_1T) &&
+                ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_1T))) {
             return slb;
         }
     }
@@ -740,14 +747,20 @@ void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
 int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs)
 {
     int slot = rb & 0xfff;
-    uint64_t esid = rb & ~0xfff;
     ppc_slb_t *slb = &env->slb[slot];
 
-    if (slot >= env->slb_nr) {
-        return -1;
+    if (rb & (0x1000 - env->slb_nr)) {
+        return -1; /* Reserved bits set or slot too high */
+    }
+    if (rs & (SLB_VSID_B & ~SLB_VSID_B_1T)) {
+        return -1; /* Bad segment size */
+    }
+    if ((rs & SLB_VSID_B) && !(env->mmu_model & POWERPC_MMU_1TSEG)) {
+        return -1; /* 1T segment on MMU that doesn't support it */
     }
 
-    slb->esid = esid;
+    /* Mask out the slot number as we store the entry */
+    slb->esid = rb & (SLB_ESID_ESID | SLB_ESID_V);
     slb->vsid = rs;
 
     LOG_SLB("%s: %d " TARGET_FMT_lx " - " TARGET_FMT_lx " => %016" PRIx64
@@ -799,6 +812,7 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
     if (env->mmu_model & POWERPC_MMU_64) {
         ppc_slb_t *slb;
         target_ulong pageaddr;
+        int segment_bits;
 
         LOG_MMU("Check SLBs\n");
         slb = slb_lookup(env, eaddr);
@@ -806,7 +820,14 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
             return -5;
         }
 
-        vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
+        if (slb->vsid & SLB_VSID_B) {
+            vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT_1T;
+            segment_bits = 40;
+        } else {
+            vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
+            segment_bits = 28;
+        }
+
         target_page_bits = (slb->vsid & SLB_VSID_L)
             ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS;
         ctx->key = !!(pr ? (slb->vsid & SLB_VSID_KP)
@@ -814,11 +835,16 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
         ds = 0;
         ctx->nx = !!(slb->vsid & SLB_VSID_N);
 
-        pageaddr = eaddr & ((1ULL << 28) - (1ULL << target_page_bits));
-        /* XXX: this is false for 1 TB segments */
-        hash = vsid ^ (pageaddr >> target_page_bits);
+        pageaddr = eaddr & ((1ULL << segment_bits)
+                            - (1ULL << target_page_bits));
+        if (slb->vsid & SLB_VSID_B) {
+            hash = vsid ^ (vsid << 25) ^ (pageaddr >> target_page_bits);
+        } else {
+            hash = vsid ^ (pageaddr >> target_page_bits);
+        }
         /* Only 5 bits of the page index are used in the AVPN */
-        ctx->ptem = (slb->vsid & SLB_VSID_PTEM) | ((pageaddr >> 16) & 0x0F80);
+        ctx->ptem = (slb->vsid & SLB_VSID_PTEM) |
+            ((pageaddr >> 16) & ((1ULL << segment_bits) - 0x80));
     } else
 #endif /* defined(TARGET_PPC64) */
     {

From 9d52e9079da4f28abd788faf39e64fbf4b305561 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:19 +1100
Subject: [PATCH 017/386] Add POWER7 support for ppc

This adds emulation support for the recent POWER7 cpu to qemu.  It's far
from perfect - it's missing a number of POWER7 features so far, including
any support for VSX or decimal floating point instructions.  However, it's
close enough to boot a kernel with the POWER7 PVR.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc.c                    |  35 ++++++++++++
 hw/ppc.h                    |   1 +
 target-ppc/cpu.h            |  16 ++++++
 target-ppc/helper.c         |   6 ++
 target-ppc/translate_init.c | 107 ++++++++++++++++++++++++++++++++++++
 5 files changed, 165 insertions(+)

diff --git a/hw/ppc.c b/hw/ppc.c
index b55a84883e..dabb816510 100644
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -247,6 +247,41 @@ void ppc970_irq_init (CPUState *env)
     env->irq_inputs = (void **)qemu_allocate_irqs(&ppc970_set_irq, env,
                                                   PPC970_INPUT_NB);
 }
+
+/* POWER7 internal IRQ controller */
+static void power7_set_irq (void *opaque, int pin, int level)
+{
+    CPUState *env = opaque;
+    int cur_level;
+
+    LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
+                env, pin, level);
+    cur_level = (env->irq_input_state >> pin) & 1;
+
+    switch (pin) {
+    case POWER7_INPUT_INT:
+        /* Level sensitive - active high */
+        LOG_IRQ("%s: set the external IRQ state to %d\n",
+                __func__, level);
+        ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
+        break;
+    default:
+        /* Unknown pin - do nothing */
+        LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
+        return;
+    }
+    if (level) {
+        env->irq_input_state |= 1 << pin;
+    } else {
+        env->irq_input_state &= ~(1 << pin);
+    }
+}
+
+void ppcPOWER7_irq_init (CPUState *env)
+{
+    env->irq_inputs = (void **)qemu_allocate_irqs(&power7_set_irq, env,
+                                                  POWER7_INPUT_NB);
+}
 #endif /* defined(TARGET_PPC64) */
 
 /* PowerPC 40x internal IRQ controller */
diff --git a/hw/ppc.h b/hw/ppc.h
index 34f54cf5da..3ccf13479b 100644
--- a/hw/ppc.h
+++ b/hw/ppc.h
@@ -36,6 +36,7 @@ void ppc40x_irq_init (CPUState *env);
 void ppce500_irq_init (CPUState *env);
 void ppc6xx_irq_init (CPUState *env);
 void ppc970_irq_init (CPUState *env);
+void ppcPOWER7_irq_init (CPUState *env);
 
 /* PPC machines for OpenBIOS */
 enum {
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 10341b307f..25d0658c47 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -119,6 +119,8 @@ enum powerpc_mmu_t {
     POWERPC_MMU_64B        = POWERPC_MMU_64 | 0x00000001,
     /* 620 variant (no segment exceptions)                     */
     POWERPC_MMU_620        = POWERPC_MMU_64 | 0x00000002,
+    /* Architecture 2.06 variant                               */
+    POWERPC_MMU_2_06       = POWERPC_MMU_64 | POWERPC_MMU_1TSEG | 0x00000003,
 #endif /* defined(TARGET_PPC64) */
 };
 
@@ -154,6 +156,8 @@ enum powerpc_excp_t {
 #if defined(TARGET_PPC64)
     /* PowerPC 970 exception model      */
     POWERPC_EXCP_970,
+    /* POWER7 exception model           */
+    POWERPC_EXCP_POWER7,
 #endif /* defined(TARGET_PPC64) */
 };
 
@@ -289,6 +293,8 @@ enum powerpc_input_t {
     PPC_FLAGS_INPUT_405,
     /* PowerPC 970 bus                  */
     PPC_FLAGS_INPUT_970,
+    /* PowerPC POWER7 bus               */
+    PPC_FLAGS_INPUT_POWER7,
     /* PowerPC 401 bus                  */
     PPC_FLAGS_INPUT_401,
     /* Freescale RCPU bus               */
@@ -1001,6 +1007,7 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
 #define SPR_HSPRG1            (0x131)
 #define SPR_HDSISR            (0x132)
 #define SPR_HDAR              (0x133)
+#define SPR_SPURR             (0x134)
 #define SPR_BOOKE_DBCR0       (0x134)
 #define SPR_IBCR              (0x135)
 #define SPR_PURR              (0x135)
@@ -1625,6 +1632,15 @@ enum {
     PPC970_INPUT_THINT      = 6,
     PPC970_INPUT_NB,
 };
+
+enum {
+    /* POWER7 input pins */
+    POWER7_INPUT_INT        = 0,
+    /* POWER7 probably has other inputs, but we don't care about them
+     * for any existing machine.  We can wire these up when we need
+     * them */
+    POWER7_INPUT_NB,
+};
 #endif
 
 /* Hardware exceptions definitions */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 6712fce8ac..278bee4f17 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -1200,6 +1200,7 @@ static inline int check_physical(CPUState *env, mmu_ctx_t *ctx,
 #if defined(TARGET_PPC64)
     case POWERPC_MMU_620:
     case POWERPC_MMU_64B:
+    case POWERPC_MMU_2_06:
         /* Real address are 60 bits long */
         ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL;
         ctx->prot |= PAGE_WRITE;
@@ -1277,6 +1278,7 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
 #if defined(TARGET_PPC64)
         case POWERPC_MMU_620:
         case POWERPC_MMU_64B:
+        case POWERPC_MMU_2_06:
 #endif
             if (ret < 0) {
                 /* We didn't match any BAT entry or don't have BATs */
@@ -1376,6 +1378,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
 #if defined(TARGET_PPC64)
                 case POWERPC_MMU_620:
                 case POWERPC_MMU_64B:
+                case POWERPC_MMU_2_06:
 #endif
                     env->exception_index = POWERPC_EXCP_ISI;
                     env->error_code = 0x40000000;
@@ -1485,6 +1488,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
 #if defined(TARGET_PPC64)
                 case POWERPC_MMU_620:
                 case POWERPC_MMU_64B:
+                case POWERPC_MMU_2_06:
 #endif
                     env->exception_index = POWERPC_EXCP_DSI;
                     env->error_code = 0;
@@ -1808,6 +1812,7 @@ void ppc_tlb_invalidate_all (CPUPPCState *env)
 #if defined(TARGET_PPC64)
     case POWERPC_MMU_620:
     case POWERPC_MMU_64B:
+    case POWERPC_MMU_2_06:
 #endif /* defined(TARGET_PPC64) */
         tlb_flush(env, 1);
         break;
@@ -1875,6 +1880,7 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
 #if defined(TARGET_PPC64)
     case POWERPC_MMU_620:
     case POWERPC_MMU_64B:
+    case POWERPC_MMU_2_06:
         /* tlbie invalidate TLBs for all segments */
         /* XXX: given the fact that there are too many segments to invalidate,
          *      and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 63664248a4..e2a83c5a38 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -61,6 +61,7 @@ void glue(glue(ppc, name),_irq_init) (CPUPPCState *env);
 PPC_IRQ_INIT_FN(40x);
 PPC_IRQ_INIT_FN(6xx);
 PPC_IRQ_INIT_FN(970);
+PPC_IRQ_INIT_FN(POWER7);
 PPC_IRQ_INIT_FN(e500);
 
 /* Generic callbacks:
@@ -3131,6 +3132,35 @@ static void init_excp_970 (CPUPPCState *env)
     env->hreset_vector = 0x0000000000000100ULL;
 #endif
 }
+
+static void init_excp_POWER7 (CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+    env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;
+    env->excp_vectors[POWERPC_EXCP_MCHECK]   = 0x00000200;
+    env->excp_vectors[POWERPC_EXCP_DSI]      = 0x00000300;
+    env->excp_vectors[POWERPC_EXCP_DSEG]     = 0x00000380;
+    env->excp_vectors[POWERPC_EXCP_ISI]      = 0x00000400;
+    env->excp_vectors[POWERPC_EXCP_ISEG]     = 0x00000480;
+    env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
+    env->excp_vectors[POWERPC_EXCP_ALIGN]    = 0x00000600;
+    env->excp_vectors[POWERPC_EXCP_PROGRAM]  = 0x00000700;
+    env->excp_vectors[POWERPC_EXCP_FPU]      = 0x00000800;
+    env->excp_vectors[POWERPC_EXCP_DECR]     = 0x00000900;
+    env->excp_vectors[POWERPC_EXCP_HDECR]    = 0x00000980;
+    env->excp_vectors[POWERPC_EXCP_SYSCALL]  = 0x00000C00;
+    env->excp_vectors[POWERPC_EXCP_TRACE]    = 0x00000D00;
+    env->excp_vectors[POWERPC_EXCP_PERFM]    = 0x00000F00;
+    env->excp_vectors[POWERPC_EXCP_VPU]      = 0x00000F20;
+    env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
+    env->excp_vectors[POWERPC_EXCP_MAINT]    = 0x00001600;
+    env->excp_vectors[POWERPC_EXCP_VPUA]     = 0x00001700;
+    env->excp_vectors[POWERPC_EXCP_THERM]    = 0x00001800;
+    env->hreset_excp_prefix = 0;
+    /* Hardware reset vector */
+    env->hreset_vector = 0x0000000000000100ULL;
+#endif
+}
 #endif
 
 /*****************************************************************************/
@@ -6312,6 +6342,78 @@ static void init_proc_970MP (CPUPPCState *env)
     vscr_init(env, 0x00010000);
 }
 
+#if defined(TARGET_PPC64)
+/* POWER7 */
+#define POWERPC_INSNS_POWER7  (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |        \
+                              PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |   \
+                              PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |           \
+                              PPC_FLOAT_STFIWX |                              \
+                              PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZT |  \
+                              PPC_MEM_SYNC | PPC_MEM_EIEIO |                  \
+                              PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |               \
+                              PPC_64B | PPC_ALTIVEC |                         \
+                              PPC_SEGMENT_64B | PPC_SLBI |                    \
+                              PPC_POPCNTB | PPC_POPCNTWD)
+#define POWERPC_MSRM_POWER7   (0x800000000204FF36ULL)
+#define POWERPC_MMU_POWER7    (POWERPC_MMU_2_06)
+#define POWERPC_EXCP_POWER7   (POWERPC_EXCP_POWER7)
+#define POWERPC_INPUT_POWER7  (PPC_FLAGS_INPUT_POWER7)
+#define POWERPC_BFDM_POWER7   (bfd_mach_ppc64)
+#define POWERPC_FLAG_POWER7   (POWERPC_FLAG_VRE | POWERPC_FLAG_SE |            \
+                              POWERPC_FLAG_BE | POWERPC_FLAG_PMM |            \
+                              POWERPC_FLAG_BUS_CLK)
+#define check_pow_POWER7    check_pow_nocheck
+
+static void init_proc_POWER7 (CPUPPCState *env)
+{
+    gen_spr_ne_601(env);
+    gen_spr_7xx(env);
+    /* Time base */
+    gen_tbl(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
+    spr_register(env, SPR_PURR,   "PURR",
+                 &spr_read_purr, SPR_NOACCESS,
+                 &spr_read_purr, SPR_NOACCESS,
+                 0x00000000);
+    spr_register(env, SPR_SPURR,   "SPURR",
+                 &spr_read_purr, SPR_NOACCESS,
+                 &spr_read_purr, SPR_NOACCESS,
+                 0x00000000);
+#endif /* !CONFIG_USER_ONLY */
+    /* Memory management */
+    /* XXX : not implemented */
+    spr_register(env, SPR_MMUCFG, "MMUCFG",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, SPR_NOACCESS,
+                 0x00000000); /* TOFIX */
+    /* XXX : not implemented */
+    spr_register(env, SPR_CTRL, "SPR_CTRLT",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x80800000);
+    spr_register(env, SPR_UCTRL, "SPR_CTRLF",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x80800000);
+    spr_register(env, SPR_VRSAVE, "SPR_VRSAVE",
+                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+#if !defined(CONFIG_USER_ONLY)
+    env->slb_nr = 32;
+#endif
+    init_excp_POWER7(env);
+    env->dcache_line_size = 128;
+    env->icache_line_size = 128;
+    /* Allocate hardware IRQ controller */
+    ppcPOWER7_irq_init(env);
+    /* Can't find information on what this should be on reset.  This
+     * value is the one used by 74xx processors. */
+    vscr_init(env, 0x00010000);
+}
+#endif /* TARGET_PPC64 */
+
 /* PowerPC 620                                                               */
 #define POWERPC_INSNS_620    (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |        \
                               PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |   \
@@ -7034,6 +7136,8 @@ enum {
     CPU_POWERPC_POWER6             = 0x003E0000,
     CPU_POWERPC_POWER6_5           = 0x0F000001, /* POWER6 in POWER5 mode */
     CPU_POWERPC_POWER6A            = 0x0F000002,
+#define CPU_POWERPC_POWER7           CPU_POWERPC_POWER7_v20
+    CPU_POWERPC_POWER7_v20         = 0x003F0200,
     CPU_POWERPC_970                = 0x00390202,
 #define CPU_POWERPC_970FX            CPU_POWERPC_970FX_v31
     CPU_POWERPC_970FX_v10          = 0x00391100,
@@ -8836,6 +8940,9 @@ static const ppc_def_t ppc_defs[] = {
     /* POWER6A                                                               */
     POWERPC_DEF("POWER6A",       CPU_POWERPC_POWER6A,                POWER6),
 #endif
+    /* POWER7                                                                */
+    POWERPC_DEF("POWER7",        CPU_POWERPC_POWER7,                 POWER7),
+    POWERPC_DEF("POWER7_v2.0",   CPU_POWERPC_POWER7_v20,             POWER7),
     /* PowerPC 970                                                           */
     POWERPC_DEF("970",           CPU_POWERPC_970,                    970),
     /* PowerPC 970FX (G5)                                                    */

From 9fdf0c2995d04a74a22ea4609b2931eef209e53d Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:20 +1100
Subject: [PATCH 018/386] Start implementing pSeries logical partition machine

This patch adds a "pseries" machine to qemu.  This aims to emulate a
logical partition on an IBM pSeries machine, compliant to the
"PowerPC Architecture Platform Requirements" (PAPR) document.

This initial version is quite limited, it implements a basic machine
and PAPR hypercall emulation.  So far only one hypercall is present -
H_PUT_TERM_CHAR - so that a (write-only) console is available.

Multiple CPUs are permitted, with SMP entry handled kexec() style.

The machine so far more resembles an old POWER4 style "full system
partition" rather than a modern LPAR, in that the guest manages the
page tables directly, rather than via hypercalls.

The machine requires qemu to be configured with --enable-fdt.  The
machine can (so far) only be booted with -kernel - i.e. no partition
firmware is provided.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 Makefile.target  |   4 +
 hw/spapr.c       | 313 +++++++++++++++++++++++++++++++++++++++++++++++
 hw/spapr.h       | 257 ++++++++++++++++++++++++++++++++++++++
 hw/spapr_hcall.c |  41 +++++++
 4 files changed, 615 insertions(+)
 create mode 100644 hw/spapr.c
 create mode 100644 hw/spapr.h
 create mode 100644 hw/spapr_hcall.c

diff --git a/Makefile.target b/Makefile.target
index 62b102a7f8..ccf090ba4f 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -231,6 +231,10 @@ obj-ppc-y += ppc_prep.o
 obj-ppc-y += ppc_oldworld.o
 # NewWorld PowerMac
 obj-ppc-y += ppc_newworld.o
+# IBM pSeries (sPAPR)i
+ifeq ($(CONFIG_FDT)$(TARGET_PPC64),yy)
+obj-ppc-y += spapr.o spapr_hcall.o
+endif
 # PowerPC 4xx boards
 obj-ppc-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
 obj-ppc-y += ppc440.o ppc440_bamboo.o
diff --git a/hw/spapr.c b/hw/spapr.c
new file mode 100644
index 0000000000..410213afc8
--- /dev/null
+++ b/hw/spapr.c
@@ -0,0 +1,313 @@
+/*
+ * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
+ *
+ * Copyright (c) 2004-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
+ * Copyright (c) 2010 David Gibson, IBM Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+#include "sysemu.h"
+#include "qemu-char.h"
+#include "hw.h"
+#include "elf.h"
+
+#include "hw/boards.h"
+#include "hw/ppc.h"
+#include "hw/loader.h"
+
+#include "hw/spapr.h"
+
+#include <libfdt.h>
+
+#define KERNEL_LOAD_ADDR        0x00000000
+#define INITRD_LOAD_ADDR        0x02800000
+#define FDT_MAX_SIZE            0x10000
+
+#define TIMEBASE_FREQ           512000000ULL
+
+#define MAX_CPUS                32
+
+sPAPREnvironment *spapr;
+
+static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
+                              const char *cpu_model, CPUState *envs[],
+                              sPAPREnvironment *spapr,
+                              target_phys_addr_t initrd_base,
+                              target_phys_addr_t initrd_size,
+                              const char *kernel_cmdline)
+{
+    void *fdt;
+    uint64_t mem_reg_property[] = { 0, cpu_to_be64(ramsize) };
+    uint32_t start_prop = cpu_to_be32(initrd_base);
+    uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
+    int i;
+    char *modelname;
+
+#define _FDT(exp) \
+    do { \
+        int ret = (exp);                                           \
+        if (ret < 0) {                                             \
+            fprintf(stderr, "qemu: error creating device tree: %s: %s\n", \
+                    #exp, fdt_strerror(ret));                      \
+            exit(1);                                               \
+        }                                                          \
+    } while (0)
+
+    fdt = qemu_mallocz(FDT_MAX_SIZE);
+    _FDT((fdt_create(fdt, FDT_MAX_SIZE)));
+
+    _FDT((fdt_finish_reservemap(fdt)));
+
+    /* Root node */
+    _FDT((fdt_begin_node(fdt, "")));
+    _FDT((fdt_property_string(fdt, "device_type", "chrp")));
+    _FDT((fdt_property_string(fdt, "model", "qemu,emulated-pSeries-LPAR")));
+
+    _FDT((fdt_property_cell(fdt, "#address-cells", 0x2)));
+    _FDT((fdt_property_cell(fdt, "#size-cells", 0x2)));
+
+    /* /chosen */
+    _FDT((fdt_begin_node(fdt, "chosen")));
+
+    _FDT((fdt_property_string(fdt, "bootargs", kernel_cmdline)));
+    _FDT((fdt_property(fdt, "linux,initrd-start",
+                       &start_prop, sizeof(start_prop))));
+    _FDT((fdt_property(fdt, "linux,initrd-end",
+                       &end_prop, sizeof(end_prop))));
+
+    _FDT((fdt_end_node(fdt)));
+
+    /* memory node */
+    _FDT((fdt_begin_node(fdt, "memory@0")));
+
+    _FDT((fdt_property_string(fdt, "device_type", "memory")));
+    _FDT((fdt_property(fdt, "reg",
+                       mem_reg_property, sizeof(mem_reg_property))));
+
+    _FDT((fdt_end_node(fdt)));
+
+    /* cpus */
+    _FDT((fdt_begin_node(fdt, "cpus")));
+
+    _FDT((fdt_property_cell(fdt, "#address-cells", 0x1)));
+    _FDT((fdt_property_cell(fdt, "#size-cells", 0x0)));
+
+    modelname = qemu_strdup(cpu_model);
+
+    for (i = 0; i < strlen(modelname); i++) {
+        modelname[i] = toupper(modelname[i]);
+    }
+
+    for (i = 0; i < smp_cpus; i++) {
+        CPUState *env = envs[i];
+        char *nodename;
+        uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
+                           0xffffffff, 0xffffffff};
+
+        if (asprintf(&nodename, "%s@%x", modelname, i) < 0) {
+            fprintf(stderr, "Allocation failure\n");
+            exit(1);
+        }
+
+        _FDT((fdt_begin_node(fdt, nodename)));
+
+        free(nodename);
+
+        _FDT((fdt_property_cell(fdt, "reg", i)));
+        _FDT((fdt_property_string(fdt, "device_type", "cpu")));
+
+        _FDT((fdt_property_cell(fdt, "cpu-version", env->spr[SPR_PVR])));
+        _FDT((fdt_property_cell(fdt, "dcache-block-size",
+                                env->dcache_line_size)));
+        _FDT((fdt_property_cell(fdt, "icache-block-size",
+                                env->icache_line_size)));
+        _FDT((fdt_property_cell(fdt, "timebase-frequency", TIMEBASE_FREQ)));
+        /* Hardcode CPU frequency for now.  It's kind of arbitrary on
+         * full emu, for kvm we should copy it from the host */
+        _FDT((fdt_property_cell(fdt, "clock-frequency", 1000000000)));
+        _FDT((fdt_property_cell(fdt, "ibm,slb-size", env->slb_nr)));
+        _FDT((fdt_property_string(fdt, "status", "okay")));
+        _FDT((fdt_property(fdt, "64-bit", NULL, 0)));
+
+        if (envs[i]->mmu_model & POWERPC_MMU_1TSEG) {
+            _FDT((fdt_property(fdt, "ibm,processor-segment-sizes",
+                               segs, sizeof(segs))));
+        }
+
+        _FDT((fdt_end_node(fdt)));
+    }
+
+    qemu_free(modelname);
+
+    _FDT((fdt_end_node(fdt)));
+
+    _FDT((fdt_end_node(fdt))); /* close root node */
+    _FDT((fdt_finish(fdt)));
+
+    *fdt_size = fdt_totalsize(fdt);
+
+    return fdt;
+}
+
+static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
+{
+    return (addr & 0x0fffffff) + KERNEL_LOAD_ADDR;
+}
+
+static void emulate_spapr_hypercall(CPUState *env)
+{
+    env->gpr[3] = spapr_hypercall(env, env->gpr[3], &env->gpr[4]);
+}
+
+/* FIXME: hack until we implement the proper VIO console */
+static target_ulong h_put_term_char(CPUState *env, sPAPREnvironment *spapr,
+                                    target_ulong opcode, target_ulong *args)
+{
+    uint8_t buf[16];
+
+    stq_p(buf, args[2]);
+    stq_p(buf + 8, args[3]);
+
+    qemu_chr_write(serial_hds[0], buf, args[1]);
+
+    return 0;
+}
+
+
+/* pSeries LPAR / sPAPR hardware init */
+static void ppc_spapr_init(ram_addr_t ram_size,
+                           const char *boot_device,
+                           const char *kernel_filename,
+                           const char *kernel_cmdline,
+                           const char *initrd_filename,
+                           const char *cpu_model)
+{
+    CPUState *envs[MAX_CPUS];
+    void *fdt;
+    int i;
+    ram_addr_t ram_offset;
+    target_phys_addr_t fdt_addr;
+    uint32_t kernel_base, initrd_base;
+    long kernel_size, initrd_size;
+    int fdt_size;
+
+    spapr = qemu_malloc(sizeof(*spapr));
+    cpu_ppc_hypercall = emulate_spapr_hypercall;
+
+    /* We place the device tree just below either the top of RAM, or
+     * 2GB, so that it can be processed with 32-bit code if
+     * necessary */
+    fdt_addr = MIN(ram_size, 0x80000000) - FDT_MAX_SIZE;
+
+    /* init CPUs */
+    if (cpu_model == NULL) {
+        cpu_model = "POWER7";
+    }
+    for (i = 0; i < smp_cpus; i++) {
+        CPUState *env = cpu_init(cpu_model);
+
+        if (!env) {
+            fprintf(stderr, "Unable to find PowerPC CPU definition\n");
+            exit(1);
+        }
+        /* Set time-base frequency to 512 MHz */
+        cpu_ppc_tb_init(env, TIMEBASE_FREQ);
+        qemu_register_reset((QEMUResetHandler *)&cpu_reset, env);
+
+        env->hreset_vector = 0x60;
+        env->hreset_excp_prefix = 0;
+        env->gpr[3] = i;
+
+        envs[i] = env;
+    }
+
+    /* allocate RAM */
+    ram_offset = qemu_ram_alloc(NULL, "ppc_spapr.ram", ram_size);
+    cpu_register_physical_memory(0, ram_size, ram_offset);
+
+    spapr_register_hypercall(H_PUT_TERM_CHAR, h_put_term_char);
+
+    if (kernel_filename) {
+        uint64_t lowaddr = 0;
+
+        kernel_base = KERNEL_LOAD_ADDR;
+
+        kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
+                               NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0);
+        if (kernel_size < 0) {
+            kernel_size = load_image_targphys(kernel_filename, kernel_base,
+                                              ram_size - kernel_base);
+        }
+        if (kernel_size < 0) {
+            fprintf(stderr, "qemu: could not load kernel '%s'\n",
+                    kernel_filename);
+            exit(1);
+        }
+
+        /* load initrd */
+        if (initrd_filename) {
+            initrd_base = INITRD_LOAD_ADDR;
+            initrd_size = load_image_targphys(initrd_filename, initrd_base,
+                                              ram_size - initrd_base);
+            if (initrd_size < 0) {
+                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
+                        initrd_filename);
+                exit(1);
+            }
+        } else {
+            initrd_base = 0;
+            initrd_size = 0;
+        }
+
+    } else {
+        fprintf(stderr, "pSeries machine needs -kernel for now");
+        exit(1);
+    }
+
+    /* Prepare the device tree */
+    fdt = spapr_create_fdt(&fdt_size, ram_size, cpu_model, envs, spapr,
+                           initrd_base, initrd_size, kernel_cmdline);
+    assert(fdt != NULL);
+
+    cpu_physical_memory_write(fdt_addr, fdt, fdt_size);
+
+    qemu_free(fdt);
+
+    envs[0]->gpr[3] = fdt_addr;
+    envs[0]->gpr[5] = 0;
+    envs[0]->hreset_vector = kernel_base;
+}
+
+static QEMUMachine spapr_machine = {
+    .name = "pseries",
+    .desc = "pSeries Logical Partition (PAPR compliant)",
+    .init = ppc_spapr_init,
+    .max_cpus = MAX_CPUS,
+    .no_vga = 1,
+    .no_parallel = 1,
+};
+
+static void spapr_machine_init(void)
+{
+    qemu_register_machine(&spapr_machine);
+}
+
+machine_init(spapr_machine_init);
diff --git a/hw/spapr.h b/hw/spapr.h
new file mode 100644
index 0000000000..685944b0f4
--- /dev/null
+++ b/hw/spapr.h
@@ -0,0 +1,257 @@
+#if !defined(__HW_SPAPR_H__)
+#define __HW_SPAPR_H__
+
+typedef struct sPAPREnvironment {
+} sPAPREnvironment;
+
+#define H_SUCCESS         0
+#define H_BUSY            1        /* Hardware busy -- retry later */
+#define H_CLOSED          2        /* Resource closed */
+#define H_NOT_AVAILABLE   3
+#define H_CONSTRAINED     4        /* Resource request constrained to max allowed */
+#define H_PARTIAL         5
+#define H_IN_PROGRESS     14       /* Kind of like busy */
+#define H_PAGE_REGISTERED 15
+#define H_PARTIAL_STORE   16
+#define H_PENDING         17       /* returned from H_POLL_PENDING */
+#define H_CONTINUE        18       /* Returned from H_Join on success */
+#define H_LONG_BUSY_START_RANGE         9900  /* Start of long busy range */
+#define H_LONG_BUSY_ORDER_1_MSEC        9900  /* Long busy, hint that 1msec \
+                                                 is a good time to retry */
+#define H_LONG_BUSY_ORDER_10_MSEC       9901  /* Long busy, hint that 10msec \
+                                                 is a good time to retry */
+#define H_LONG_BUSY_ORDER_100_MSEC      9902  /* Long busy, hint that 100msec \
+                                                 is a good time to retry */
+#define H_LONG_BUSY_ORDER_1_SEC         9903  /* Long busy, hint that 1sec \
+                                                 is a good time to retry */
+#define H_LONG_BUSY_ORDER_10_SEC        9904  /* Long busy, hint that 10sec \
+                                                 is a good time to retry */
+#define H_LONG_BUSY_ORDER_100_SEC       9905  /* Long busy, hint that 100sec \
+                                                 is a good time to retry */
+#define H_LONG_BUSY_END_RANGE           9905  /* End of long busy range */
+#define H_HARDWARE        -1       /* Hardware error */
+#define H_FUNCTION        -2       /* Function not supported */
+#define H_PRIVILEGE       -3       /* Caller not privileged */
+#define H_PARAMETER       -4       /* Parameter invalid, out-of-range or conflicting */
+#define H_BAD_MODE        -5       /* Illegal msr value */
+#define H_PTEG_FULL       -6       /* PTEG is full */
+#define H_NOT_FOUND       -7       /* PTE was not found" */
+#define H_RESERVED_DABR   -8       /* DABR address is reserved by the hypervisor on this processor" */
+#define H_NO_MEM          -9
+#define H_AUTHORITY       -10
+#define H_PERMISSION      -11
+#define H_DROPPED         -12
+#define H_SOURCE_PARM     -13
+#define H_DEST_PARM       -14
+#define H_REMOTE_PARM     -15
+#define H_RESOURCE        -16
+#define H_ADAPTER_PARM    -17
+#define H_RH_PARM         -18
+#define H_RCQ_PARM        -19
+#define H_SCQ_PARM        -20
+#define H_EQ_PARM         -21
+#define H_RT_PARM         -22
+#define H_ST_PARM         -23
+#define H_SIGT_PARM       -24
+#define H_TOKEN_PARM      -25
+#define H_MLENGTH_PARM    -27
+#define H_MEM_PARM        -28
+#define H_MEM_ACCESS_PARM -29
+#define H_ATTR_PARM       -30
+#define H_PORT_PARM       -31
+#define H_MCG_PARM        -32
+#define H_VL_PARM         -33
+#define H_TSIZE_PARM      -34
+#define H_TRACE_PARM      -35
+
+#define H_MASK_PARM       -37
+#define H_MCG_FULL        -38
+#define H_ALIAS_EXIST     -39
+#define H_P_COUNTER       -40
+#define H_TABLE_FULL      -41
+#define H_ALT_TABLE       -42
+#define H_MR_CONDITION    -43
+#define H_NOT_ENOUGH_RESOURCES -44
+#define H_R_STATE         -45
+#define H_RESCINDEND      -46
+#define H_MULTI_THREADS_ACTIVE -9005
+
+
+/* Long Busy is a condition that can be returned by the firmware
+ * when a call cannot be completed now, but the identical call
+ * should be retried later.  This prevents calls blocking in the
+ * firmware for long periods of time.  Annoyingly the firmware can return
+ * a range of return codes, hinting at how long we should wait before
+ * retrying.  If you don't care for the hint, the macro below is a good
+ * way to check for the long_busy return codes
+ */
+#define H_IS_LONG_BUSY(x)  ((x >= H_LONG_BUSY_START_RANGE) \
+                            && (x <= H_LONG_BUSY_END_RANGE))
+
+/* Flags */
+#define H_LARGE_PAGE      (1ULL<<(63-16))
+#define H_EXACT           (1ULL<<(63-24))       /* Use exact PTE or return H_PTEG_FULL */
+#define H_R_XLATE         (1ULL<<(63-25))       /* include a valid logical page num in the pte if the valid bit is set */
+#define H_READ_4          (1ULL<<(63-26))       /* Return 4 PTEs */
+#define H_PAGE_STATE_CHANGE (1ULL<<(63-28))
+#define H_PAGE_UNUSED     ((1ULL<<(63-29)) | (1ULL<<(63-30)))
+#define H_PAGE_SET_UNUSED (H_PAGE_STATE_CHANGE | H_PAGE_UNUSED)
+#define H_PAGE_SET_LOANED (H_PAGE_SET_UNUSED | (1ULL<<(63-31)))
+#define H_PAGE_SET_ACTIVE H_PAGE_STATE_CHANGE
+#define H_AVPN            (1ULL<<(63-32))       /* An avpn is provided as a sanity test */
+#define H_ANDCOND         (1ULL<<(63-33))
+#define H_ICACHE_INVALIDATE (1ULL<<(63-40))     /* icbi, etc.  (ignored for IO pages) */
+#define H_ICACHE_SYNCHRONIZE (1ULL<<(63-41))    /* dcbst, icbi, etc (ignored for IO pages */
+#define H_ZERO_PAGE       (1ULL<<(63-48))       /* zero the page before mapping (ignored for IO pages) */
+#define H_COPY_PAGE       (1ULL<<(63-49))
+#define H_N               (1ULL<<(63-61))
+#define H_PP1             (1ULL<<(63-62))
+#define H_PP2             (1ULL<<(63-63))
+
+/* VASI States */
+#define H_VASI_INVALID    0
+#define H_VASI_ENABLED    1
+#define H_VASI_ABORTED    2
+#define H_VASI_SUSPENDING 3
+#define H_VASI_SUSPENDED  4
+#define H_VASI_RESUMED    5
+#define H_VASI_COMPLETED  6
+
+/* DABRX flags */
+#define H_DABRX_HYPERVISOR (1ULL<<(63-61))
+#define H_DABRX_KERNEL     (1ULL<<(63-62))
+#define H_DABRX_USER       (1ULL<<(63-63))
+
+/* Each control block has to be on a 4K bondary */
+#define H_CB_ALIGNMENT     4096
+
+/* pSeries hypervisor opcodes */
+#define H_REMOVE                0x04
+#define H_ENTER                 0x08
+#define H_READ                  0x0c
+#define H_CLEAR_MOD             0x10
+#define H_CLEAR_REF             0x14
+#define H_PROTECT               0x18
+#define H_GET_TCE               0x1c
+#define H_PUT_TCE               0x20
+#define H_SET_SPRG0             0x24
+#define H_SET_DABR              0x28
+#define H_PAGE_INIT             0x2c
+#define H_SET_ASR               0x30
+#define H_ASR_ON                0x34
+#define H_ASR_OFF               0x38
+#define H_LOGICAL_CI_LOAD       0x3c
+#define H_LOGICAL_CI_STORE      0x40
+#define H_LOGICAL_CACHE_LOAD    0x44
+#define H_LOGICAL_CACHE_STORE   0x48
+#define H_LOGICAL_ICBI          0x4c
+#define H_LOGICAL_DCBF          0x50
+#define H_GET_TERM_CHAR         0x54
+#define H_PUT_TERM_CHAR         0x58
+#define H_REAL_TO_LOGICAL       0x5c
+#define H_HYPERVISOR_DATA       0x60
+#define H_EOI                   0x64
+#define H_CPPR                  0x68
+#define H_IPI                   0x6c
+#define H_IPOLL                 0x70
+#define H_XIRR                  0x74
+#define H_PERFMON               0x7c
+#define H_MIGRATE_DMA           0x78
+#define H_REGISTER_VPA          0xDC
+#define H_CEDE                  0xE0
+#define H_CONFER                0xE4
+#define H_PROD                  0xE8
+#define H_GET_PPP               0xEC
+#define H_SET_PPP               0xF0
+#define H_PURR                  0xF4
+#define H_PIC                   0xF8
+#define H_REG_CRQ               0xFC
+#define H_FREE_CRQ              0x100
+#define H_VIO_SIGNAL            0x104
+#define H_SEND_CRQ              0x108
+#define H_COPY_RDMA             0x110
+#define H_REGISTER_LOGICAL_LAN  0x114
+#define H_FREE_LOGICAL_LAN      0x118
+#define H_ADD_LOGICAL_LAN_BUFFER 0x11C
+#define H_SEND_LOGICAL_LAN      0x120
+#define H_BULK_REMOVE           0x124
+#define H_MULTICAST_CTRL        0x130
+#define H_SET_XDABR             0x134
+#define H_STUFF_TCE             0x138
+#define H_PUT_TCE_INDIRECT      0x13C
+#define H_CHANGE_LOGICAL_LAN_MAC 0x14C
+#define H_VTERM_PARTNER_INFO    0x150
+#define H_REGISTER_VTERM        0x154
+#define H_FREE_VTERM            0x158
+#define H_RESET_EVENTS          0x15C
+#define H_ALLOC_RESOURCE        0x160
+#define H_FREE_RESOURCE         0x164
+#define H_MODIFY_QP             0x168
+#define H_QUERY_QP              0x16C
+#define H_REREGISTER_PMR        0x170
+#define H_REGISTER_SMR          0x174
+#define H_QUERY_MR              0x178
+#define H_QUERY_MW              0x17C
+#define H_QUERY_HCA             0x180
+#define H_QUERY_PORT            0x184
+#define H_MODIFY_PORT           0x188
+#define H_DEFINE_AQP1           0x18C
+#define H_GET_TRACE_BUFFER      0x190
+#define H_DEFINE_AQP0           0x194
+#define H_RESIZE_MR             0x198
+#define H_ATTACH_MCQP           0x19C
+#define H_DETACH_MCQP           0x1A0
+#define H_CREATE_RPT            0x1A4
+#define H_REMOVE_RPT            0x1A8
+#define H_REGISTER_RPAGES       0x1AC
+#define H_DISABLE_AND_GETC      0x1B0
+#define H_ERROR_DATA            0x1B4
+#define H_GET_HCA_INFO          0x1B8
+#define H_GET_PERF_COUNT        0x1BC
+#define H_MANAGE_TRACE          0x1C0
+#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4
+#define H_QUERY_INT_STATE       0x1E4
+#define H_POLL_PENDING          0x1D8
+#define H_ILLAN_ATTRIBUTES      0x244
+#define H_MODIFY_HEA_QP         0x250
+#define H_QUERY_HEA_QP          0x254
+#define H_QUERY_HEA             0x258
+#define H_QUERY_HEA_PORT        0x25C
+#define H_MODIFY_HEA_PORT       0x260
+#define H_REG_BCMC              0x264
+#define H_DEREG_BCMC            0x268
+#define H_REGISTER_HEA_RPAGES   0x26C
+#define H_DISABLE_AND_GET_HEA   0x270
+#define H_GET_HEA_INFO          0x274
+#define H_ALLOC_HEA_RESOURCE    0x278
+#define H_ADD_CONN              0x284
+#define H_DEL_CONN              0x288
+#define H_JOIN                  0x298
+#define H_VASI_STATE            0x2A4
+#define H_ENABLE_CRQ            0x2B0
+#define H_GET_EM_PARMS          0x2B8
+#define H_SET_MPP               0x2D0
+#define H_GET_MPP               0x2D4
+#define MAX_HCALL_OPCODE        H_GET_MPP
+
+extern sPAPREnvironment *spapr;
+
+/*#define DEBUG_SPAPR_HCALLS*/
+
+#ifdef DEBUG_SPAPR_HCALLS
+#define hcall_dprintf(fmt, ...) \
+    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define hcall_dprintf(fmt, ...) \
+    do { } while (0)
+#endif
+
+typedef target_ulong (*spapr_hcall_fn)(CPUState *env, sPAPREnvironment *spapr,
+                                       target_ulong opcode,
+                                       target_ulong *args);
+
+void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn);
+target_ulong spapr_hypercall(CPUState *env, target_ulong opcode,
+                             target_ulong *args);
+
+#endif /* !defined (__HW_SPAPR_H__) */
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
new file mode 100644
index 0000000000..e3919d01c2
--- /dev/null
+++ b/hw/spapr_hcall.c
@@ -0,0 +1,41 @@
+#include "sysemu.h"
+#include "cpu.h"
+#include "qemu-char.h"
+#include "hw/spapr.h"
+
+spapr_hcall_fn hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
+
+void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
+{
+    spapr_hcall_fn old_fn;
+
+    assert(opcode <= MAX_HCALL_OPCODE);
+    assert((opcode & 0x3) == 0);
+
+    old_fn = hypercall_table[opcode / 4];
+
+    assert(!old_fn || (fn == old_fn));
+
+    hypercall_table[opcode / 4] = fn;
+}
+
+target_ulong spapr_hypercall(CPUState *env, target_ulong opcode,
+                             target_ulong *args)
+{
+    if (msr_pr) {
+        hcall_dprintf("Hypercall made with MSR[PR]=1\n");
+        return H_PRIVILEGE;
+    }
+
+    if ((opcode <= MAX_HCALL_OPCODE)
+        && ((opcode & 0x3) == 0)) {
+        spapr_hcall_fn fn = hypercall_table[opcode / 4];
+
+        if (fn) {
+            return fn(env, spapr, opcode, args);
+        }
+    }
+
+    hcall_dprintf("Unimplemented hcall 0x" TARGET_FMT_lx "\n", opcode);
+    return H_FUNCTION;
+}

From 4040ab72379f75fe171c03f93ceb75efb48c14a5 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:21 +1100
Subject: [PATCH 019/386] Implement the bus structure for PAPR virtual IO

This extends the "pseries" (PAPR) machine to include a virtual IO bus
supporting the PAPR defined hypercall based virtual IO mechanisms.

So far only one VIO device is provided, the vty / vterm, providing
a full console (polled only, for now).

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 Makefile.target |   5 +-
 hw/spapr.c      |  48 +++++++----
 hw/spapr.h      |   3 +
 hw/spapr_vio.c  | 214 ++++++++++++++++++++++++++++++++++++++++++++++++
 hw/spapr_vio.h  |  50 +++++++++++
 hw/spapr_vty.c  | 150 +++++++++++++++++++++++++++++++++
 6 files changed, 450 insertions(+), 20 deletions(-)
 create mode 100644 hw/spapr_vio.c
 create mode 100644 hw/spapr_vio.h
 create mode 100644 hw/spapr_vty.c

diff --git a/Makefile.target b/Makefile.target
index ccf090ba4f..cf12691670 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -231,9 +231,10 @@ obj-ppc-y += ppc_prep.o
 obj-ppc-y += ppc_oldworld.o
 # NewWorld PowerMac
 obj-ppc-y += ppc_newworld.o
-# IBM pSeries (sPAPR)i
+# IBM pSeries (sPAPR)
 ifeq ($(CONFIG_FDT)$(TARGET_PPC64),yy)
-obj-ppc-y += spapr.o spapr_hcall.o
+obj-ppc-y += spapr.o spapr_hcall.o spapr_vio.o
+obj-ppc-y += spapr_vty.o
 endif
 # PowerPC 4xx boards
 obj-ppc-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
diff --git a/hw/spapr.c b/hw/spapr.c
index 410213afc8..c24c92b1a0 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -25,7 +25,6 @@
  *
  */
 #include "sysemu.h"
-#include "qemu-char.h"
 #include "hw.h"
 #include "elf.h"
 
@@ -34,6 +33,7 @@
 #include "hw/loader.h"
 
 #include "hw/spapr.h"
+#include "hw/spapr_vio.h"
 
 #include <libfdt.h>
 
@@ -60,6 +60,7 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
     uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
     int i;
     char *modelname;
+    int ret;
 
 #define _FDT(exp) \
     do { \
@@ -159,9 +160,30 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
 
     _FDT((fdt_end_node(fdt)));
 
+    /* vdevice */
+    _FDT((fdt_begin_node(fdt, "vdevice")));
+
+    _FDT((fdt_property_string(fdt, "device_type", "vdevice")));
+    _FDT((fdt_property_string(fdt, "compatible", "IBM,vdevice")));
+    _FDT((fdt_property_cell(fdt, "#address-cells", 0x1)));
+    _FDT((fdt_property_cell(fdt, "#size-cells", 0x0)));
+
+    _FDT((fdt_end_node(fdt)));
+
     _FDT((fdt_end_node(fdt))); /* close root node */
     _FDT((fdt_finish(fdt)));
 
+    /* re-expand to allow for further tweaks */
+    _FDT((fdt_open_into(fdt, fdt, FDT_MAX_SIZE)));
+
+    ret = spapr_populate_vdevice(spapr->vio_bus, fdt);
+    if (ret < 0) {
+        fprintf(stderr, "couldn't setup vio devices in fdt\n");
+        exit(1);
+    }
+
+    _FDT((fdt_pack(fdt)));
+
     *fdt_size = fdt_totalsize(fdt);
 
     return fdt;
@@ -177,21 +199,6 @@ static void emulate_spapr_hypercall(CPUState *env)
     env->gpr[3] = spapr_hypercall(env, env->gpr[3], &env->gpr[4]);
 }
 
-/* FIXME: hack until we implement the proper VIO console */
-static target_ulong h_put_term_char(CPUState *env, sPAPREnvironment *spapr,
-                                    target_ulong opcode, target_ulong *args)
-{
-    uint8_t buf[16];
-
-    stq_p(buf, args[2]);
-    stq_p(buf + 8, args[3]);
-
-    qemu_chr_write(serial_hds[0], buf, args[1]);
-
-    return 0;
-}
-
-
 /* pSeries LPAR / sPAPR hardware init */
 static void ppc_spapr_init(ram_addr_t ram_size,
                            const char *boot_device,
@@ -243,7 +250,13 @@ static void ppc_spapr_init(ram_addr_t ram_size,
     ram_offset = qemu_ram_alloc(NULL, "ppc_spapr.ram", ram_size);
     cpu_register_physical_memory(0, ram_size, ram_offset);
 
-    spapr_register_hypercall(H_PUT_TERM_CHAR, h_put_term_char);
+    spapr->vio_bus = spapr_vio_bus_init();
+
+    for (i = 0; i < MAX_SERIAL_PORTS; i++) {
+        if (serial_hds[i]) {
+            spapr_vty_create(spapr->vio_bus, i, serial_hds[i]);
+        }
+    }
 
     if (kernel_filename) {
         uint64_t lowaddr = 0;
@@ -276,7 +289,6 @@ static void ppc_spapr_init(ram_addr_t ram_size,
             initrd_base = 0;
             initrd_size = 0;
         }
-
     } else {
         fprintf(stderr, "pSeries machine needs -kernel for now");
         exit(1);
diff --git a/hw/spapr.h b/hw/spapr.h
index 685944b0f4..06cca15b94 100644
--- a/hw/spapr.h
+++ b/hw/spapr.h
@@ -1,7 +1,10 @@
 #if !defined(__HW_SPAPR_H__)
 #define __HW_SPAPR_H__
 
+struct VIOsPAPRBus;
+
 typedef struct sPAPREnvironment {
+    struct VIOsPAPRBus *vio_bus;
 } sPAPREnvironment;
 
 #define H_SUCCESS         0
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
new file mode 100644
index 0000000000..10acb4c308
--- /dev/null
+++ b/hw/spapr_vio.c
@@ -0,0 +1,214 @@
+/*
+ * QEMU sPAPR VIO code
+ *
+ * Copyright (c) 2010 David Gibson, IBM Corporation <dwg@au1.ibm.com>
+ * Based on the s390 virtio bus code:
+ * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw.h"
+#include "sysemu.h"
+#include "boards.h"
+#include "monitor.h"
+#include "loader.h"
+#include "elf.h"
+#include "hw/sysbus.h"
+#include "kvm.h"
+#include "device_tree.h"
+
+#include "hw/spapr.h"
+#include "hw/spapr_vio.h"
+
+#ifdef CONFIG_FDT
+#include <libfdt.h>
+#endif /* CONFIG_FDT */
+
+/* #define DEBUG_SPAPR */
+
+#ifdef DEBUG_SPAPR
+#define dprintf(fmt, ...) \
+    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define dprintf(fmt, ...) \
+    do { } while (0)
+#endif
+
+static struct BusInfo spapr_vio_bus_info = {
+    .name       = "spapr-vio",
+    .size       = sizeof(VIOsPAPRBus),
+};
+
+VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
+{
+    DeviceState *qdev;
+    VIOsPAPRDevice *dev = NULL;
+
+    QLIST_FOREACH(qdev, &bus->bus.children, sibling) {
+        dev = (VIOsPAPRDevice *)qdev;
+        if (dev->reg == reg) {
+            break;
+        }
+    }
+
+    return dev;
+}
+
+#ifdef CONFIG_FDT
+static int vio_make_devnode(VIOsPAPRDevice *dev,
+                            void *fdt)
+{
+    VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)dev->qdev.info;
+    int vdevice_off, node_off;
+    int ret;
+
+    vdevice_off = fdt_path_offset(fdt, "/vdevice");
+    if (vdevice_off < 0) {
+        return vdevice_off;
+    }
+
+    node_off = fdt_add_subnode(fdt, vdevice_off, dev->qdev.id);
+    if (node_off < 0) {
+        return node_off;
+    }
+
+    ret = fdt_setprop_cell(fdt, node_off, "reg", dev->reg);
+    if (ret < 0) {
+        return ret;
+    }
+
+    if (info->dt_type) {
+        ret = fdt_setprop_string(fdt, node_off, "device_type",
+                                 info->dt_type);
+        if (ret < 0) {
+            return ret;
+        }
+    }
+
+    if (info->dt_compatible) {
+        ret = fdt_setprop_string(fdt, node_off, "compatible",
+                                 info->dt_compatible);
+        if (ret < 0) {
+            return ret;
+        }
+    }
+
+    if (info->devnode) {
+        ret = (info->devnode)(dev, fdt, node_off);
+        if (ret < 0) {
+            return ret;
+        }
+    }
+
+    return node_off;
+}
+#endif /* CONFIG_FDT */
+
+static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo)
+{
+    VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
+    VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
+    char *id;
+
+    if (asprintf(&id, "%s@%x", info->dt_name, dev->reg) < 0) {
+        return -1;
+    }
+
+    dev->qdev.id = id;
+
+    return info->init(dev);
+}
+
+void spapr_vio_bus_register_withprop(VIOsPAPRDeviceInfo *info)
+{
+    info->qdev.init = spapr_vio_busdev_init;
+    info->qdev.bus_info = &spapr_vio_bus_info;
+
+    assert(info->qdev.size >= sizeof(VIOsPAPRDevice));
+    qdev_register(&info->qdev);
+}
+
+VIOsPAPRBus *spapr_vio_bus_init(void)
+{
+    VIOsPAPRBus *bus;
+    BusState *qbus;
+    DeviceState *dev;
+    DeviceInfo *qinfo;
+
+    /* Create bridge device */
+    dev = qdev_create(NULL, "spapr-vio-bridge");
+    qdev_init_nofail(dev);
+
+    /* Create bus on bridge device */
+
+    qbus = qbus_create(&spapr_vio_bus_info, dev, "spapr-vio");
+    bus = DO_UPCAST(VIOsPAPRBus, bus, qbus);
+
+    for (qinfo = device_info_list; qinfo; qinfo = qinfo->next) {
+        VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
+
+        if (qinfo->bus_info != &spapr_vio_bus_info) {
+            continue;
+        }
+
+        if (info->hcalls) {
+            info->hcalls(bus);
+        }
+    }
+
+    return bus;
+}
+
+/* Represents sPAPR hcall VIO devices */
+
+static int spapr_vio_bridge_init(SysBusDevice *dev)
+{
+    /* nothing */
+    return 0;
+}
+
+static SysBusDeviceInfo spapr_vio_bridge_info = {
+    .init = spapr_vio_bridge_init,
+    .qdev.name  = "spapr-vio-bridge",
+    .qdev.size  = sizeof(SysBusDevice),
+    .qdev.no_user = 1,
+};
+
+static void spapr_vio_register_devices(void)
+{
+    sysbus_register_withprop(&spapr_vio_bridge_info);
+}
+
+device_init(spapr_vio_register_devices)
+
+#ifdef CONFIG_FDT
+int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt)
+{
+    DeviceState *qdev;
+    int ret = 0;
+
+    QLIST_FOREACH(qdev, &bus->bus.children, sibling) {
+        VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
+
+        ret = vio_make_devnode(dev, fdt);
+
+        if (ret < 0) {
+            return ret;
+        }
+    }
+
+    return 0;
+}
+#endif /* CONFIG_FDT */
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
new file mode 100644
index 0000000000..b164ad326c
--- /dev/null
+++ b/hw/spapr_vio.h
@@ -0,0 +1,50 @@
+#ifndef _HW_SPAPR_VIO_H
+#define _HW_SPAPR_VIO_H
+/*
+ * QEMU sPAPR VIO bus definitions
+ *
+ * Copyright (c) 2010 David Gibson, IBM Corporation <david@gibson.dropbear.id.au>
+ * Based on the s390 virtio bus definitions:
+ * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+typedef struct VIOsPAPRDevice {
+    DeviceState qdev;
+    uint32_t reg;
+} VIOsPAPRDevice;
+
+typedef struct VIOsPAPRBus {
+    BusState bus;
+} VIOsPAPRBus;
+
+typedef struct {
+    DeviceInfo qdev;
+    const char *dt_name, *dt_type, *dt_compatible;
+    int (*init)(VIOsPAPRDevice *dev);
+    void (*hcalls)(VIOsPAPRBus *bus);
+    int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off);
+} VIOsPAPRDeviceInfo;
+
+extern VIOsPAPRBus *spapr_vio_bus_init(void);
+extern VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg);
+extern void spapr_vio_bus_register_withprop(VIOsPAPRDeviceInfo *info);
+extern int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt);
+
+void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len);
+void spapr_vty_create(VIOsPAPRBus *bus,
+                      uint32_t reg, CharDriverState *chardev);
+
+#endif /* _HW_SPAPR_VIO_H */
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
new file mode 100644
index 0000000000..b4da6a83fb
--- /dev/null
+++ b/hw/spapr_vty.c
@@ -0,0 +1,150 @@
+#include "qdev.h"
+#include "qemu-char.h"
+#include "hw/spapr.h"
+#include "hw/spapr_vio.h"
+
+#define VTERM_BUFSIZE   16
+
+typedef struct VIOsPAPRVTYDevice {
+    VIOsPAPRDevice sdev;
+    CharDriverState *chardev;
+    uint32_t in, out;
+    uint8_t buf[VTERM_BUFSIZE];
+} VIOsPAPRVTYDevice;
+
+static int vty_can_receive(void *opaque)
+{
+    VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)opaque;
+
+    return (dev->in - dev->out) < VTERM_BUFSIZE;
+}
+
+static void vty_receive(void *opaque, const uint8_t *buf, int size)
+{
+    VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)opaque;
+    int i;
+
+    for (i = 0; i < size; i++) {
+        assert((dev->in - dev->out) < VTERM_BUFSIZE);
+        dev->buf[dev->in++ % VTERM_BUFSIZE] = buf[i];
+    }
+}
+
+static int vty_getchars(VIOsPAPRDevice *sdev, uint8_t *buf, int max)
+{
+    VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)sdev;
+    int n = 0;
+
+    while ((n < max) && (dev->out != dev->in)) {
+        buf[n++] = dev->buf[dev->out++ % VTERM_BUFSIZE];
+    }
+
+    return n;
+}
+
+void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len)
+{
+    VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)sdev;
+
+    /* FIXME: should check the qemu_chr_write() return value */
+    qemu_chr_write(dev->chardev, buf, len);
+}
+
+static int spapr_vty_init(VIOsPAPRDevice *sdev)
+{
+    VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)sdev;
+
+    qemu_chr_add_handlers(dev->chardev, vty_can_receive,
+                          vty_receive, NULL, dev);
+
+    return 0;
+}
+
+static target_ulong h_put_term_char(CPUState *env, sPAPREnvironment *spapr,
+                                    target_ulong opcode, target_ulong *args)
+{
+    target_ulong reg = args[0];
+    target_ulong len = args[1];
+    target_ulong char0_7 = args[2];
+    target_ulong char8_15 = args[3];
+    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    uint8_t buf[16];
+
+    if (!sdev) {
+        return H_PARAMETER;
+    }
+
+    if (len > 16) {
+        return H_PARAMETER;
+    }
+
+    *((uint64_t *)buf) = cpu_to_be64(char0_7);
+    *((uint64_t *)buf + 1) = cpu_to_be64(char8_15);
+
+    vty_putchars(sdev, buf, len);
+
+    return H_SUCCESS;
+}
+
+static target_ulong h_get_term_char(CPUState *env, sPAPREnvironment *spapr,
+                                    target_ulong opcode, target_ulong *args)
+{
+    target_ulong reg = args[0];
+    target_ulong *len = args + 0;
+    target_ulong *char0_7 = args + 1;
+    target_ulong *char8_15 = args + 2;
+    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    uint8_t buf[16];
+
+    if (!sdev) {
+        return H_PARAMETER;
+    }
+
+    *len = vty_getchars(sdev, buf, sizeof(buf));
+    if (*len < 16) {
+        memset(buf + *len, 0, 16 - *len);
+    }
+
+    *char0_7 = be64_to_cpu(*((uint64_t *)buf));
+    *char8_15 = be64_to_cpu(*((uint64_t *)buf + 1));
+
+    return H_SUCCESS;
+}
+
+void spapr_vty_create(VIOsPAPRBus *bus,
+                      uint32_t reg, CharDriverState *chardev)
+{
+    DeviceState *dev;
+
+    dev = qdev_create(&bus->bus, "spapr-vty");
+    qdev_prop_set_uint32(dev, "reg", reg);
+    qdev_prop_set_chr(dev, "chardev", chardev);
+    qdev_init_nofail(dev);
+}
+
+static void vty_hcalls(VIOsPAPRBus *bus)
+{
+    spapr_register_hypercall(H_PUT_TERM_CHAR, h_put_term_char);
+    spapr_register_hypercall(H_GET_TERM_CHAR, h_get_term_char);
+}
+
+static VIOsPAPRDeviceInfo spapr_vty = {
+    .init = spapr_vty_init,
+    .dt_name = "vty",
+    .dt_type = "serial",
+    .dt_compatible = "hvterm1",
+    .hcalls = vty_hcalls,
+    .qdev.name = "spapr-vty",
+    .qdev.size = sizeof(VIOsPAPRVTYDevice),
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT32("reg", VIOsPAPRDevice, reg, 0),
+        DEFINE_PROP_CHR("chardev", VIOsPAPRVTYDevice, chardev),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+};
+
+static void spapr_vty_register(void)
+{
+    spapr_vio_bus_register_withprop(&spapr_vty);
+}
+device_init(spapr_vty_register);

From f43e35255cffb6ac6230dd09d308f7909f823f96 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:22 +1100
Subject: [PATCH 020/386] Virtual hash page table handling on pSeries machine

On pSeries logical partitions, excepting the old POWER4-style full system
partitions, the guest does not have direct access to the hardware page
table.  Instead, the pagetable exists in hypervisor memory, and the guest
must manipulate it with hypercalls.

However, our current pSeries emulation more closely resembles the old
style where the guest must set up and handle the pagetables itself.  This
patch converts it to act like a modern partition.

This involves two things: first, the hash translation path is modified to
permit the has table to be stored externally to the emulated machine's
RAM.  The pSeries machine init code configures the CPUs to use this mode.

Secondly, we emulate the PAPR hypercalls for manipulating the external
hashed page table.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/spapr.c          |  35 +++++-
 hw/spapr_hcall.c    | 254 ++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/cpu.h    |   2 +
 target-ppc/helper.c |  36 +++++--
 4 files changed, 315 insertions(+), 12 deletions(-)

diff --git a/hw/spapr.c b/hw/spapr.c
index c24c92b1a0..57140d231d 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -52,12 +52,15 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
                               sPAPREnvironment *spapr,
                               target_phys_addr_t initrd_base,
                               target_phys_addr_t initrd_size,
-                              const char *kernel_cmdline)
+                              const char *kernel_cmdline,
+                              long hash_shift)
 {
     void *fdt;
     uint64_t mem_reg_property[] = { 0, cpu_to_be64(ramsize) };
     uint32_t start_prop = cpu_to_be32(initrd_base);
     uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
+    uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)};
+    char hypertas_prop[] = "hcall-pft\0hcall-term";
     int i;
     char *modelname;
     int ret;
@@ -145,6 +148,8 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
          * full emu, for kvm we should copy it from the host */
         _FDT((fdt_property_cell(fdt, "clock-frequency", 1000000000)));
         _FDT((fdt_property_cell(fdt, "ibm,slb-size", env->slb_nr)));
+        _FDT((fdt_property(fdt, "ibm,pft-size",
+                           pft_size_prop, sizeof(pft_size_prop))));
         _FDT((fdt_property_string(fdt, "status", "okay")));
         _FDT((fdt_property(fdt, "64-bit", NULL, 0)));
 
@@ -160,6 +165,14 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
 
     _FDT((fdt_end_node(fdt)));
 
+    /* RTAS */
+    _FDT((fdt_begin_node(fdt, "rtas")));
+
+    _FDT((fdt_property(fdt, "ibm,hypertas-functions", hypertas_prop,
+                       sizeof(hypertas_prop))));
+
+    _FDT((fdt_end_node(fdt)));
+
     /* vdevice */
     _FDT((fdt_begin_node(fdt, "vdevice")));
 
@@ -208,12 +221,13 @@ static void ppc_spapr_init(ram_addr_t ram_size,
                            const char *cpu_model)
 {
     CPUState *envs[MAX_CPUS];
-    void *fdt;
+    void *fdt, *htab;
     int i;
     ram_addr_t ram_offset;
     target_phys_addr_t fdt_addr;
     uint32_t kernel_base, initrd_base;
-    long kernel_size, initrd_size;
+    long kernel_size, initrd_size, htab_size;
+    long pteg_shift = 17;
     int fdt_size;
 
     spapr = qemu_malloc(sizeof(*spapr));
@@ -250,6 +264,18 @@ static void ppc_spapr_init(ram_addr_t ram_size,
     ram_offset = qemu_ram_alloc(NULL, "ppc_spapr.ram", ram_size);
     cpu_register_physical_memory(0, ram_size, ram_offset);
 
+    /* allocate hash page table.  For now we always make this 16mb,
+     * later we should probably make it scale to the size of guest
+     * RAM */
+    htab_size = 1ULL << (pteg_shift + 7);
+    htab = qemu_mallocz(htab_size);
+
+    for (i = 0; i < smp_cpus; i++) {
+        envs[i]->external_htab = htab;
+        envs[i]->htab_base = -1;
+        envs[i]->htab_mask = htab_size - 1;
+    }
+
     spapr->vio_bus = spapr_vio_bus_init();
 
     for (i = 0; i < MAX_SERIAL_PORTS; i++) {
@@ -296,7 +322,8 @@ static void ppc_spapr_init(ram_addr_t ram_size,
 
     /* Prepare the device tree */
     fdt = spapr_create_fdt(&fdt_size, ram_size, cpu_model, envs, spapr,
-                           initrd_base, initrd_size, kernel_cmdline);
+                           initrd_base, initrd_size, kernel_cmdline,
+                           pteg_shift + 7);
     assert(fdt != NULL);
 
     cpu_physical_memory_write(fdt_addr, fdt, fdt_size);
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index e3919d01c2..0ba17172da 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -1,8 +1,253 @@
 #include "sysemu.h"
 #include "cpu.h"
 #include "qemu-char.h"
+#include "sysemu.h"
+#include "qemu-char.h"
+#include "exec-all.h"
 #include "hw/spapr.h"
 
+#define HPTES_PER_GROUP 8
+
+#define HPTE_V_SSIZE_SHIFT      62
+#define HPTE_V_AVPN_SHIFT       7
+#define HPTE_V_AVPN             0x3fffffffffffff80ULL
+#define HPTE_V_AVPN_VAL(x)      (((x) & HPTE_V_AVPN) >> HPTE_V_AVPN_SHIFT)
+#define HPTE_V_COMPARE(x, y)    (!(((x) ^ (y)) & 0xffffffffffffff80UL))
+#define HPTE_V_BOLTED           0x0000000000000010ULL
+#define HPTE_V_LOCK             0x0000000000000008ULL
+#define HPTE_V_LARGE            0x0000000000000004ULL
+#define HPTE_V_SECONDARY        0x0000000000000002ULL
+#define HPTE_V_VALID            0x0000000000000001ULL
+
+#define HPTE_R_PP0              0x8000000000000000ULL
+#define HPTE_R_TS               0x4000000000000000ULL
+#define HPTE_R_KEY_HI           0x3000000000000000ULL
+#define HPTE_R_RPN_SHIFT        12
+#define HPTE_R_RPN              0x3ffffffffffff000ULL
+#define HPTE_R_FLAGS            0x00000000000003ffULL
+#define HPTE_R_PP               0x0000000000000003ULL
+#define HPTE_R_N                0x0000000000000004ULL
+#define HPTE_R_G                0x0000000000000008ULL
+#define HPTE_R_M                0x0000000000000010ULL
+#define HPTE_R_I                0x0000000000000020ULL
+#define HPTE_R_W                0x0000000000000040ULL
+#define HPTE_R_WIMG             0x0000000000000078ULL
+#define HPTE_R_C                0x0000000000000080ULL
+#define HPTE_R_R                0x0000000000000100ULL
+#define HPTE_R_KEY_LO           0x0000000000000e00ULL
+
+#define HPTE_V_1TB_SEG          0x4000000000000000ULL
+#define HPTE_V_VRMA_MASK        0x4001ffffff000000ULL
+
+#define HPTE_V_HVLOCK           0x40ULL
+
+static inline int lock_hpte(void *hpte, target_ulong bits)
+{
+    uint64_t pteh;
+
+    pteh = ldq_p(hpte);
+
+    /* We're protected by qemu's global lock here */
+    if (pteh & bits) {
+        return 0;
+    }
+    stq_p(hpte, pteh | HPTE_V_HVLOCK);
+    return 1;
+}
+
+static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r,
+                                     target_ulong pte_index)
+{
+    target_ulong rb, va_low;
+
+    rb = (v & ~0x7fULL) << 16; /* AVA field */
+    va_low = pte_index >> 3;
+    if (v & HPTE_V_SECONDARY) {
+        va_low = ~va_low;
+    }
+    /* xor vsid from AVA */
+    if (!(v & HPTE_V_1TB_SEG)) {
+        va_low ^= v >> 12;
+    } else {
+        va_low ^= v >> 24;
+    }
+    va_low &= 0x7ff;
+    if (v & HPTE_V_LARGE) {
+        rb |= 1;                         /* L field */
+#if 0 /* Disable that P7 specific bit for now */
+        if (r & 0xff000) {
+            /* non-16MB large page, must be 64k */
+            /* (masks depend on page size) */
+            rb |= 0x1000;                /* page encoding in LP field */
+            rb |= (va_low & 0x7f) << 16; /* 7b of VA in AVA/LP field */
+            rb |= (va_low & 0xfe);       /* AVAL field */
+        }
+#endif
+    } else {
+        /* 4kB page */
+        rb |= (va_low & 0x7ff) << 12;   /* remaining 11b of AVA */
+    }
+    rb |= (v >> 54) & 0x300;            /* B field */
+    return rb;
+}
+
+static target_ulong h_enter(CPUState *env, sPAPREnvironment *spapr,
+                            target_ulong opcode, target_ulong *args)
+{
+    target_ulong flags = args[0];
+    target_ulong pte_index = args[1];
+    target_ulong pteh = args[2];
+    target_ulong ptel = args[3];
+    target_ulong porder;
+    target_ulong i, pa;
+    uint8_t *hpte;
+
+    /* only handle 4k and 16M pages for now */
+    porder = 12;
+    if (pteh & HPTE_V_LARGE) {
+#if 0 /* We don't support 64k pages yet */
+        if ((ptel & 0xf000) == 0x1000) {
+            /* 64k page */
+            porder = 16;
+        } else
+#endif
+        if ((ptel & 0xff000) == 0) {
+            /* 16M page */
+            porder = 24;
+            /* lowest AVA bit must be 0 for 16M pages */
+            if (pteh & 0x80) {
+                return H_PARAMETER;
+            }
+        } else {
+            return H_PARAMETER;
+        }
+    }
+
+    pa = ptel & HPTE_R_RPN;
+    /* FIXME: bounds check the pa? */
+
+    /* Check WIMG */
+    if ((ptel & HPTE_R_WIMG) != HPTE_R_M) {
+        return H_PARAMETER;
+    }
+    pteh &= ~0x60ULL;
+
+    if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {
+        return H_PARAMETER;
+    }
+    if (likely((flags & H_EXACT) == 0)) {
+        pte_index &= ~7ULL;
+        hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
+        for (i = 0; ; ++i) {
+            if (i == 8) {
+                return H_PTEG_FULL;
+            }
+            if (((ldq_p(hpte) & HPTE_V_VALID) == 0) &&
+                lock_hpte(hpte, HPTE_V_HVLOCK | HPTE_V_VALID)) {
+                break;
+            }
+            hpte += HASH_PTE_SIZE_64;
+        }
+    } else {
+        i = 0;
+        hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
+        if (!lock_hpte(hpte, HPTE_V_HVLOCK | HPTE_V_VALID)) {
+            return H_PTEG_FULL;
+        }
+    }
+    stq_p(hpte + (HASH_PTE_SIZE_64/2), ptel);
+    /* eieio();  FIXME: need some sort of barrier for smp? */
+    stq_p(hpte, pteh);
+
+    assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));
+    args[0] = pte_index + i;
+    return H_SUCCESS;
+}
+
+static target_ulong h_remove(CPUState *env, sPAPREnvironment *spapr,
+                             target_ulong opcode, target_ulong *args)
+{
+    target_ulong flags = args[0];
+    target_ulong pte_index = args[1];
+    target_ulong avpn = args[2];
+    uint8_t *hpte;
+    target_ulong v, r, rb;
+
+    if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {
+        return H_PARAMETER;
+    }
+
+    hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
+    while (!lock_hpte(hpte, HPTE_V_HVLOCK)) {
+        /* We have no real concurrency in qemu soft-emulation, so we
+         * will never actually have a contested lock */
+        assert(0);
+    }
+
+    v = ldq_p(hpte);
+    r = ldq_p(hpte + (HASH_PTE_SIZE_64/2));
+
+    if ((v & HPTE_V_VALID) == 0 ||
+        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn) ||
+        ((flags & H_ANDCOND) && (v & avpn) != 0)) {
+        stq_p(hpte, v & ~HPTE_V_HVLOCK);
+        assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));
+        return H_NOT_FOUND;
+    }
+    args[0] = v & ~HPTE_V_HVLOCK;
+    args[1] = r;
+    stq_p(hpte, 0);
+    rb = compute_tlbie_rb(v, r, pte_index);
+    ppc_tlb_invalidate_one(env, rb);
+    assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));
+    return H_SUCCESS;
+}
+
+static target_ulong h_protect(CPUState *env, sPAPREnvironment *spapr,
+                              target_ulong opcode, target_ulong *args)
+{
+    target_ulong flags = args[0];
+    target_ulong pte_index = args[1];
+    target_ulong avpn = args[2];
+    uint8_t *hpte;
+    target_ulong v, r, rb;
+
+    if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {
+        return H_PARAMETER;
+    }
+
+    hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
+    while (!lock_hpte(hpte, HPTE_V_HVLOCK)) {
+        /* We have no real concurrency in qemu soft-emulation, so we
+         * will never actually have a contested lock */
+        assert(0);
+    }
+
+    v = ldq_p(hpte);
+    r = ldq_p(hpte + (HASH_PTE_SIZE_64/2));
+
+    if ((v & HPTE_V_VALID) == 0 ||
+        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) {
+        stq_p(hpte, v & ~HPTE_V_HVLOCK);
+        assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));
+        return H_NOT_FOUND;
+    }
+
+    r &= ~(HPTE_R_PP0 | HPTE_R_PP | HPTE_R_N |
+           HPTE_R_KEY_HI | HPTE_R_KEY_LO);
+    r |= (flags << 55) & HPTE_R_PP0;
+    r |= (flags << 48) & HPTE_R_KEY_HI;
+    r |= flags & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO);
+    rb = compute_tlbie_rb(v, r, pte_index);
+    stq_p(hpte, v & ~HPTE_V_VALID);
+    ppc_tlb_invalidate_one(env, rb);
+    stq_p(hpte + (HASH_PTE_SIZE_64/2), r);
+    /* Don't need a memory barrier, due to qemu's global lock */
+    stq_p(hpte, v & ~HPTE_V_HVLOCK);
+    assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));
+    return H_SUCCESS;
+}
+
 spapr_hcall_fn hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
 
 void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
@@ -39,3 +284,12 @@ target_ulong spapr_hypercall(CPUState *env, target_ulong opcode,
     hcall_dprintf("Unimplemented hcall 0x" TARGET_FMT_lx "\n", opcode);
     return H_FUNCTION;
 }
+
+static void hypercall_init(void)
+{
+    /* hcall-pft */
+    spapr_register_hypercall(H_ENTER, h_enter);
+    spapr_register_hypercall(H_REMOVE, h_remove);
+    spapr_register_hypercall(H_PROTECT, h_protect);
+}
+device_init(hypercall_init);
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 25d0658c47..b4c2555626 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -670,6 +670,8 @@ struct CPUPPCState {
     target_phys_addr_t htab_base;
     target_phys_addr_t htab_mask;
     target_ulong sr[32];
+    /* externally stored hash table */
+    uint8_t *external_htab;
     /* BATs */
     int nb_BATs;
     target_ulong DBAT[2][8];
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 278bee4f17..5e4030bb53 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -589,8 +589,13 @@ static inline int _find_pte(CPUState *env, mmu_ctx_t *ctx, int is_64b, int h,
     for (i = 0; i < 8; i++) {
 #if defined(TARGET_PPC64)
         if (is_64b) {
-            pte0 = ldq_phys(env->htab_base + pteg_off + (i * 16));
-            pte1 = ldq_phys(env->htab_base + pteg_off + (i * 16) + 8);
+            if (env->external_htab) {
+                pte0 = ldq_p(env->external_htab + pteg_off + (i * 16));
+                pte1 = ldq_p(env->external_htab + pteg_off + (i * 16) + 8);
+            } else {
+                pte0 = ldq_phys(env->htab_base + pteg_off + (i * 16));
+                pte1 = ldq_phys(env->htab_base + pteg_off + (i * 16) + 8);
+            }
 
             /* We have a TLB that saves 4K pages, so let's
              * split a huge page to 4k chunks */
@@ -606,8 +611,13 @@ static inline int _find_pte(CPUState *env, mmu_ctx_t *ctx, int is_64b, int h,
         } else
 #endif
         {
-            pte0 = ldl_phys(env->htab_base + pteg_off + (i * 8));
-            pte1 =  ldl_phys(env->htab_base + pteg_off + (i * 8) + 4);
+            if (env->external_htab) {
+                pte0 = ldl_p(env->external_htab + pteg_off + (i * 8));
+                pte1 = ldl_p(env->external_htab + pteg_off + (i * 8) + 4);
+            } else {
+                pte0 = ldl_phys(env->htab_base + pteg_off + (i * 8));
+                pte1 = ldl_phys(env->htab_base + pteg_off + (i * 8) + 4);
+            }
             r = pte32_check(ctx, pte0, pte1, h, rw, type);
             LOG_MMU("Load pte from " TARGET_FMT_lx " => " TARGET_FMT_lx " "
                     TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",
@@ -647,13 +657,23 @@ static inline int _find_pte(CPUState *env, mmu_ctx_t *ctx, int is_64b, int h,
         if (pte_update_flags(ctx, &pte1, ret, rw) == 1) {
 #if defined(TARGET_PPC64)
             if (is_64b) {
-                stq_phys_notdirty(env->htab_base + pteg_off + (good * 16) + 8,
-                                  pte1);
+                if (env->external_htab) {
+                    stq_p(env->external_htab + pteg_off + (good * 16) + 8,
+                          pte1);
+                } else {
+                    stq_phys_notdirty(env->htab_base + pteg_off +
+                                      (good * 16) + 8, pte1);
+                }
             } else
 #endif
             {
-                stl_phys_notdirty(env->htab_base + pteg_off + (good * 8) + 4,
-                                  pte1);
+                if (env->external_htab) {
+                    stl_p(env->external_htab + pteg_off + (good * 8) + 4,
+                          pte1);
+                } else {
+                    stl_phys_notdirty(env->htab_base + pteg_off +
+                                      (good * 8) + 4, pte1);
+                }
             }
         }
     }

From 39ac8455106af1ed669b8e10223420cf1ac5b190 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:23 +1100
Subject: [PATCH 021/386] Implement hcall based RTAS for pSeries machines

On pSeries machines, operating systems can instantiate "RTAS" (Run-Time
Abstraction Services), a runtime component of the firmware which implements
a number of low-level, infrequently used operations.  On logical partitions
under a hypervisor, many of the RTAS functions require hypervisor
privilege.  For simplicity, therefore, hypervisor systems typically
implement the in-partition RTAS as just a tiny wrapper around a hypercall
which actually implements the various RTAS functions.

This patch implements such a hypercall based RTAS for our emulated pSeries
machine.  A tiny in-partition "firmware" calls a new hypercall, which
looks up available RTAS services in a table.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 Makefile                        |   3 +-
 Makefile.target                 |   2 +-
 configure                       |   4 +-
 hw/spapr.c                      |  26 ++++++-
 hw/spapr.h                      |  32 ++++++++
 hw/spapr_hcall.c                |  44 +++++++++--
 hw/spapr_rtas.c                 | 131 ++++++++++++++++++++++++++++++++
 pc-bios/spapr-rtas.bin          | Bin 0 -> 20 bytes
 pc-bios/spapr-rtas/Makefile     |  24 ++++++
 pc-bios/spapr-rtas/spapr-rtas.S |  37 +++++++++
 10 files changed, 289 insertions(+), 14 deletions(-)
 create mode 100644 hw/spapr_rtas.c
 create mode 100755 pc-bios/spapr-rtas.bin
 create mode 100644 pc-bios/spapr-rtas/Makefile
 create mode 100644 pc-bios/spapr-rtas/spapr-rtas.S

diff --git a/Makefile b/Makefile
index 89e88b4a9e..e0b3fea6bc 100644
--- a/Makefile
+++ b/Makefile
@@ -213,7 +213,8 @@ pxe-ne2k_pci.bin pxe-pcnet.bin \
 pxe-rtl8139.bin pxe-virtio.bin \
 bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
 multiboot.bin linuxboot.bin \
-s390-zipl.rom
+s390-zipl.rom \
+spapr-rtas.bin
 else
 BLOBS=
 endif
diff --git a/Makefile.target b/Makefile.target
index cf12691670..a53d99fd52 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -233,7 +233,7 @@ obj-ppc-y += ppc_oldworld.o
 obj-ppc-y += ppc_newworld.o
 # IBM pSeries (sPAPR)
 ifeq ($(CONFIG_FDT)$(TARGET_PPC64),yy)
-obj-ppc-y += spapr.o spapr_hcall.o spapr_vio.o
+obj-ppc-y += spapr.o spapr_hcall.o spapr_rtas.o spapr_vio.o
 obj-ppc-y += spapr_vty.o
 endif
 # PowerPC 4xx boards
diff --git a/configure b/configure
index 5a5827f6db..7d8d890891 100755
--- a/configure
+++ b/configure
@@ -2461,7 +2461,9 @@ if test \( "$cpu" = "i386" -o "$cpu" = "x86_64" \) -a \
         "$softmmu" = yes ; then
   roms="optionrom"
 fi
-
+if test "$cpu" = "ppc64" ; then
+  roms="$roms spapr-rtas"
+fi
 
 echo "Install prefix    $prefix"
 echo "BIOS directory    `eval echo $datadir`"
diff --git a/hw/spapr.c b/hw/spapr.c
index 57140d231d..c07af19543 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -40,6 +40,7 @@
 #define KERNEL_LOAD_ADDR        0x00000000
 #define INITRD_LOAD_ADDR        0x02800000
 #define FDT_MAX_SIZE            0x10000
+#define RTAS_MAX_SIZE           0x10000
 
 #define TIMEBASE_FREQ           512000000ULL
 
@@ -53,6 +54,8 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
                               target_phys_addr_t initrd_base,
                               target_phys_addr_t initrd_size,
                               const char *kernel_cmdline,
+                              target_phys_addr_t rtas_addr,
+                              target_phys_addr_t rtas_size,
                               long hash_shift)
 {
     void *fdt;
@@ -195,6 +198,12 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
         exit(1);
     }
 
+    /* RTAS */
+    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);
+    if (ret < 0) {
+        fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
+    }
+
     _FDT((fdt_pack(fdt)));
 
     *fdt_size = fdt_totalsize(fdt);
@@ -224,11 +233,12 @@ static void ppc_spapr_init(ram_addr_t ram_size,
     void *fdt, *htab;
     int i;
     ram_addr_t ram_offset;
-    target_phys_addr_t fdt_addr;
+    target_phys_addr_t fdt_addr, rtas_addr;
     uint32_t kernel_base, initrd_base;
-    long kernel_size, initrd_size, htab_size;
+    long kernel_size, initrd_size, htab_size, rtas_size;
     long pteg_shift = 17;
     int fdt_size;
+    char *filename;
 
     spapr = qemu_malloc(sizeof(*spapr));
     cpu_ppc_hypercall = emulate_spapr_hypercall;
@@ -237,6 +247,8 @@ static void ppc_spapr_init(ram_addr_t ram_size,
      * 2GB, so that it can be processed with 32-bit code if
      * necessary */
     fdt_addr = MIN(ram_size, 0x80000000) - FDT_MAX_SIZE;
+    /* RTAS goes just below that */
+    rtas_addr = fdt_addr - RTAS_MAX_SIZE;
 
     /* init CPUs */
     if (cpu_model == NULL) {
@@ -276,6 +288,14 @@ static void ppc_spapr_init(ram_addr_t ram_size,
         envs[i]->htab_mask = htab_size - 1;
     }
 
+    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");
+    rtas_size = load_image_targphys(filename, rtas_addr, ram_size - rtas_addr);
+    if (rtas_size < 0) {
+        hw_error("qemu: could not load LPAR rtas '%s'\n", filename);
+        exit(1);
+    }
+    qemu_free(filename);
+
     spapr->vio_bus = spapr_vio_bus_init();
 
     for (i = 0; i < MAX_SERIAL_PORTS; i++) {
@@ -323,7 +343,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
     /* Prepare the device tree */
     fdt = spapr_create_fdt(&fdt_size, ram_size, cpu_model, envs, spapr,
                            initrd_base, initrd_size, kernel_cmdline,
-                           pteg_shift + 7);
+                           rtas_addr, rtas_size, pteg_shift + 7);
     assert(fdt != NULL);
 
     cpu_physical_memory_write(fdt_addr, fdt, fdt_size);
diff --git a/hw/spapr.h b/hw/spapr.h
index 06cca15b94..0dcb83a5ae 100644
--- a/hw/spapr.h
+++ b/hw/spapr.h
@@ -237,6 +237,18 @@ typedef struct sPAPREnvironment {
 #define H_GET_MPP               0x2D4
 #define MAX_HCALL_OPCODE        H_GET_MPP
 
+/* The hcalls above are standardized in PAPR and implemented by pHyp
+ * as well.
+ *
+ * We also need some hcalls which are specific to qemu / KVM-on-POWER.
+ * So far we just need one for H_RTAS, but in future we'll need more
+ * for extensions like virtio.  We put those into the 0xf000-0xfffc
+ * range which is reserved by PAPR for "platform-specific" hcalls.
+ */
+#define KVMPPC_HCALL_BASE       0xf000
+#define KVMPPC_H_RTAS           (KVMPPC_HCALL_BASE + 0x0)
+#define KVMPPC_HCALL_MAX        KVMPPC_H_RTAS
+
 extern sPAPREnvironment *spapr;
 
 /*#define DEBUG_SPAPR_HCALLS*/
@@ -257,4 +269,24 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn);
 target_ulong spapr_hypercall(CPUState *env, target_ulong opcode,
                              target_ulong *args);
 
+static inline uint32_t rtas_ld(target_ulong phys, int n)
+{
+    return ldl_phys(phys + 4*n);
+}
+
+static inline void rtas_st(target_ulong phys, int n, uint32_t val)
+{
+    stl_phys(phys + 4*n, val);
+}
+
+typedef void (*spapr_rtas_fn)(sPAPREnvironment *spapr, uint32_t token,
+                              uint32_t nargs, target_ulong args,
+                              uint32_t nret, target_ulong rets);
+void spapr_rtas_register(const char *name, spapr_rtas_fn fn);
+target_ulong spapr_rtas_call(sPAPREnvironment *spapr,
+                             uint32_t token, uint32_t nargs, target_ulong args,
+                             uint32_t nret, target_ulong rets);
+int spapr_rtas_device_tree_setup(void *fdt, target_phys_addr_t rtas_addr,
+                                 target_phys_addr_t rtas_size);
+
 #endif /* !defined (__HW_SPAPR_H__) */
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index 0ba17172da..d8c721e472 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -248,20 +248,38 @@ static target_ulong h_protect(CPUState *env, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-spapr_hcall_fn hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
+static target_ulong h_rtas(CPUState *env, sPAPREnvironment *spapr,
+                           target_ulong opcode, target_ulong *args)
+{
+    target_ulong rtas_r3 = args[0];
+    uint32_t token = ldl_phys(rtas_r3);
+    uint32_t nargs = ldl_phys(rtas_r3 + 4);
+    uint32_t nret = ldl_phys(rtas_r3 + 8);
+
+    return spapr_rtas_call(spapr, token, nargs, rtas_r3 + 12,
+                           nret, rtas_r3 + 12 + 4*nargs);
+}
+
+spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
+spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCALL_BASE];
 
 void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
 {
-    spapr_hcall_fn old_fn;
+    spapr_hcall_fn *slot;
 
-    assert(opcode <= MAX_HCALL_OPCODE);
-    assert((opcode & 0x3) == 0);
+    if (opcode <= MAX_HCALL_OPCODE) {
+        assert((opcode & 0x3) == 0);
 
-    old_fn = hypercall_table[opcode / 4];
+        slot = &papr_hypercall_table[opcode / 4];
+    } else {
+        assert((opcode >= KVMPPC_HCALL_BASE) && (opcode <= KVMPPC_HCALL_MAX));
 
-    assert(!old_fn || (fn == old_fn));
 
-    hypercall_table[opcode / 4] = fn;
+        slot = &kvmppc_hypercall_table[opcode - KVMPPC_HCALL_BASE];
+    }
+
+    assert(!(*slot) || (fn == *slot));
+    *slot = fn;
 }
 
 target_ulong spapr_hypercall(CPUState *env, target_ulong opcode,
@@ -274,7 +292,14 @@ target_ulong spapr_hypercall(CPUState *env, target_ulong opcode,
 
     if ((opcode <= MAX_HCALL_OPCODE)
         && ((opcode & 0x3) == 0)) {
-        spapr_hcall_fn fn = hypercall_table[opcode / 4];
+        spapr_hcall_fn fn = papr_hypercall_table[opcode / 4];
+
+        if (fn) {
+            return fn(env, spapr, opcode, args);
+        }
+    } else if ((opcode >= KVMPPC_HCALL_BASE) &&
+               (opcode <= KVMPPC_HCALL_MAX)) {
+        spapr_hcall_fn fn = kvmppc_hypercall_table[opcode - KVMPPC_HCALL_BASE];
 
         if (fn) {
             return fn(env, spapr, opcode, args);
@@ -291,5 +316,8 @@ static void hypercall_init(void)
     spapr_register_hypercall(H_ENTER, h_enter);
     spapr_register_hypercall(H_REMOVE, h_remove);
     spapr_register_hypercall(H_PROTECT, h_protect);
+
+    /* qemu/KVM-PPC specific hcalls */
+    spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
 }
 device_init(hypercall_init);
diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c
new file mode 100644
index 0000000000..3f090f5518
--- /dev/null
+++ b/hw/spapr_rtas.c
@@ -0,0 +1,131 @@
+/*
+ * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
+ *
+ * Hypercall based emulated RTAS
+ *
+ * Copyright (c) 2010-2011 David Gibson, IBM Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+#include "cpu.h"
+#include "sysemu.h"
+#include "qemu-char.h"
+#include "hw/qdev.h"
+#include "device_tree.h"
+
+#include "hw/spapr.h"
+#include "hw/spapr_vio.h"
+
+#include <libfdt.h>
+
+#define TOKEN_BASE      0x2000
+#define TOKEN_MAX       0x100
+
+static struct rtas_call {
+    const char *name;
+    spapr_rtas_fn fn;
+} rtas_table[TOKEN_MAX];
+
+struct rtas_call *rtas_next = rtas_table;
+
+target_ulong spapr_rtas_call(sPAPREnvironment *spapr,
+                             uint32_t token, uint32_t nargs, target_ulong args,
+                             uint32_t nret, target_ulong rets)
+{
+    if ((token >= TOKEN_BASE)
+        && ((token - TOKEN_BASE) < TOKEN_MAX)) {
+        struct rtas_call *call = rtas_table + (token - TOKEN_BASE);
+
+        if (call->fn) {
+            call->fn(spapr, token, nargs, args, nret, rets);
+            return H_SUCCESS;
+        }
+    }
+
+    hcall_dprintf("Unknown RTAS token 0x%x\n", token);
+    rtas_st(rets, 0, -3);
+    return H_PARAMETER;
+}
+
+void spapr_rtas_register(const char *name, spapr_rtas_fn fn)
+{
+    assert(rtas_next < (rtas_table + TOKEN_MAX));
+
+    rtas_next->name = name;
+    rtas_next->fn = fn;
+
+    rtas_next++;
+}
+
+int spapr_rtas_device_tree_setup(void *fdt, target_phys_addr_t rtas_addr,
+                                 target_phys_addr_t rtas_size)
+{
+    int ret;
+    int i;
+
+    ret = fdt_add_mem_rsv(fdt, rtas_addr, rtas_size);
+    if (ret < 0) {
+        fprintf(stderr, "Couldn't add RTAS reserve entry: %s\n",
+                fdt_strerror(ret));
+        return ret;
+    }
+
+    ret = qemu_devtree_setprop_cell(fdt, "/rtas", "linux,rtas-base",
+                                    rtas_addr);
+    if (ret < 0) {
+        fprintf(stderr, "Couldn't add linux,rtas-base property: %s\n",
+                fdt_strerror(ret));
+        return ret;
+    }
+
+    ret = qemu_devtree_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
+                                    rtas_addr);
+    if (ret < 0) {
+        fprintf(stderr, "Couldn't add linux,rtas-entry property: %s\n",
+                fdt_strerror(ret));
+        return ret;
+    }
+
+    ret = qemu_devtree_setprop_cell(fdt, "/rtas", "rtas-size",
+                                    rtas_size);
+    if (ret < 0) {
+        fprintf(stderr, "Couldn't add rtas-size property: %s\n",
+                fdt_strerror(ret));
+        return ret;
+    }
+
+    for (i = 0; i < TOKEN_MAX; i++) {
+        struct rtas_call *call = &rtas_table[i];
+
+        if (!call->fn) {
+            continue;
+        }
+
+        ret = qemu_devtree_setprop_cell(fdt, "/rtas", call->name,
+                                        i + TOKEN_BASE);
+        if (ret < 0) {
+            fprintf(stderr, "Couldn't add rtas token for %s: %s\n",
+                    call->name, fdt_strerror(ret));
+            return ret;
+        }
+
+    }
+    return 0;
+}
diff --git a/pc-bios/spapr-rtas.bin b/pc-bios/spapr-rtas.bin
new file mode 100755
index 0000000000000000000000000000000000000000..fc24c8ed8b92a3a441aed6e2bd013b2ccece9229
GIT binary patch
literal 20
bcmb<Pk*=^wU|>i{{=neEz@X&Uz@PvCJTV0q

literal 0
HcmV?d00001

diff --git a/pc-bios/spapr-rtas/Makefile b/pc-bios/spapr-rtas/Makefile
new file mode 100644
index 0000000000..dc8b23e3ce
--- /dev/null
+++ b/pc-bios/spapr-rtas/Makefile
@@ -0,0 +1,24 @@
+all: build-all
+# Dummy command so that make thinks it has done something
+	@true
+
+include ../../config-host.mak
+include $(SRC_PATH)/rules.mak
+
+$(call set-vpath, $(SRC_PATH)/pc-bios/spapr-rtas)
+
+.PHONY : all clean build-all
+
+#CFLAGS += -I$(SRC_PATH)
+#QEMU_CFLAGS = $(CFLAGS)
+
+build-all: spapr-rtas.bin
+
+%.img: %.o
+	$(call quiet-command,$(CC) -nostdlib -o $@ $<,"  Building $(TARGET_DIR)$@")
+
+%.bin: %.img
+	$(call quiet-command,$(OBJCOPY) -O binary -j .text $< $@,"  Building $(TARGET_DIR)$@")
+
+clean:
+	rm -f *.o *.d *.img *.bin *~
diff --git a/pc-bios/spapr-rtas/spapr-rtas.S b/pc-bios/spapr-rtas/spapr-rtas.S
new file mode 100644
index 0000000000..903bec2150
--- /dev/null
+++ b/pc-bios/spapr-rtas/spapr-rtas.S
@@ -0,0 +1,37 @@
+/*
+ * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
+ *
+ * Trivial in-partition RTAS implementation, based on a hypercall
+ *
+ * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#define KVMPPC_HCALL_BASE       0xf000
+#define KVMPPC_H_RTAS           (KVMPPC_HCALL_BASE + 0x0)
+
+.globl	_start
+_start:
+	mr	4,3
+	lis	3,KVMPPC_H_RTAS@h
+	ori	3,3,KVMPPC_H_RTAS@l
+	sc	1
+	blr

From 821303f59b63ab832f0921f070db55e95bb21858 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:24 +1100
Subject: [PATCH 022/386] Implement assorted pSeries hcalls and RTAS methods

This patch adds several small utility hypercalls and RTAS methods to
the pSeries platform emulation.  Specifically:

* 'display-character' rtas call

This just prints a character to the console, it's occasionally used
for early debug of the OS.  The support includes a hack to make this
RTAS call respond on the normal token value present on real hardware,
since some early debugging tools just assume this value without
checking the device tree.

* 'get-time-of-day' rtas call

This one just takes the host real time, converts to the PAPR described
format and returns it to the guest.

* 'power-off' rtas call

This one shuts down the emulated system.

* H_DABR hypercall

On pSeries, the DABR debug register is usually a hypervisor resource
and virtualized through this hypercall.  If the hypercall is not
present, Linux will under some circumstances attempt to manipulate the
DABR directly which will fail on this emulated machine.

This stub implementation is enough to stop that behaviour, although it
doesn't actually implement the requested DABR operations as yet.

Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/spapr.c       |  2 +-
 hw/spapr_hcall.c | 10 +++++++
 hw/spapr_rtas.c  | 69 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/hw/spapr.c b/hw/spapr.c
index c07af19543..6c64de82de 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -63,7 +63,7 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
     uint32_t start_prop = cpu_to_be32(initrd_base);
     uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
     uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)};
-    char hypertas_prop[] = "hcall-pft\0hcall-term";
+    char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr";
     int i;
     char *modelname;
     int ret;
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index d8c721e472..a47a97ba55 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -248,6 +248,13 @@ static target_ulong h_protect(CPUState *env, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
+static target_ulong h_set_dabr(CPUState *env, sPAPREnvironment *spapr,
+                               target_ulong opcode, target_ulong *args)
+{
+    /* FIXME: actually implement this */
+    return H_HARDWARE;
+}
+
 static target_ulong h_rtas(CPUState *env, sPAPREnvironment *spapr,
                            target_ulong opcode, target_ulong *args)
 {
@@ -317,6 +324,9 @@ static void hypercall_init(void)
     spapr_register_hypercall(H_REMOVE, h_remove);
     spapr_register_hypercall(H_PROTECT, h_protect);
 
+    /* hcall-dabr */
+    spapr_register_hypercall(H_SET_DABR, h_set_dabr);
+
     /* qemu/KVM-PPC specific hcalls */
     spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
 }
diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c
index 3f090f5518..72268537a8 100644
--- a/hw/spapr_rtas.c
+++ b/hw/spapr_rtas.c
@@ -38,6 +38,58 @@
 #define TOKEN_BASE      0x2000
 #define TOKEN_MAX       0x100
 
+static void rtas_display_character(sPAPREnvironment *spapr,
+                                   uint32_t token, uint32_t nargs,
+                                   target_ulong args,
+                                   uint32_t nret, target_ulong rets)
+{
+    uint8_t c = rtas_ld(args, 0);
+    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, 0);
+
+    if (!sdev) {
+        rtas_st(rets, 0, -1);
+    } else {
+        vty_putchars(sdev, &c, sizeof(c));
+        rtas_st(rets, 0, 0);
+    }
+}
+
+static void rtas_get_time_of_day(sPAPREnvironment *spapr,
+                                 uint32_t token, uint32_t nargs,
+                                 target_ulong args,
+                                 uint32_t nret, target_ulong rets)
+{
+    struct tm tm;
+
+    if (nret != 8) {
+        rtas_st(rets, 0, -3);
+        return;
+    }
+
+    qemu_get_timedate(&tm, 0);
+
+    rtas_st(rets, 0, 0); /* Success */
+    rtas_st(rets, 1, tm.tm_year + 1900);
+    rtas_st(rets, 2, tm.tm_mon + 1);
+    rtas_st(rets, 3, tm.tm_mday);
+    rtas_st(rets, 4, tm.tm_hour);
+    rtas_st(rets, 5, tm.tm_min);
+    rtas_st(rets, 6, tm.tm_sec);
+    rtas_st(rets, 7, 0); /* we don't do nanoseconds */
+}
+
+static void rtas_power_off(sPAPREnvironment *spapr,
+                           uint32_t token, uint32_t nargs, target_ulong args,
+                           uint32_t nret, target_ulong rets)
+{
+    if (nargs != 2 || nret != 1) {
+        rtas_st(rets, 0, -3);
+        return;
+    }
+    qemu_system_shutdown_request();
+    rtas_st(rets, 0, 0);
+}
+
 static struct rtas_call {
     const char *name;
     spapr_rtas_fn fn;
@@ -59,6 +111,15 @@ target_ulong spapr_rtas_call(sPAPREnvironment *spapr,
         }
     }
 
+    /* HACK: Some Linux early debug code uses RTAS display-character,
+     * but assumes the token value is 0xa (which it is on some real
+     * machines) without looking it up in the device tree.  This
+     * special case makes this work */
+    if (token == 0xa) {
+        rtas_display_character(spapr, 0xa, nargs, args, nret, rets);
+        return H_SUCCESS;
+    }
+
     hcall_dprintf("Unknown RTAS token 0x%x\n", token);
     rtas_st(rets, 0, -3);
     return H_PARAMETER;
@@ -129,3 +190,11 @@ int spapr_rtas_device_tree_setup(void *fdt, target_phys_addr_t rtas_addr,
     }
     return 0;
 }
+
+static void register_core_rtas(void)
+{
+    spapr_rtas_register("display-character", rtas_display_character);
+    spapr_rtas_register("get-time-of-day", rtas_get_time_of_day);
+    spapr_rtas_register("power-off", rtas_power_off);
+}
+device_init(register_core_rtas);

From b5cec4c5f294ca3af24e7edf4f37cc2de0ae0e03 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:25 +1100
Subject: [PATCH 023/386] Implement the PAPR (pSeries) virtualized interrupt
 controller (xics)

PAPR defines an interrupt control architecture which is logically divided
into ICS (Interrupt Control Presentation, each unit is responsible for
presenting interrupts to a particular "interrupt server", i.e. CPU) and
ICS (Interrupt Control Source, each unit responsible for one or more
hardware interrupts as numbered globally across the system).  All PAPR
virtual IO devices expect to deliver interrupts via this mechanism.  In
Linux, this interrupt controller system is handled by the "xics" driver.

On pSeries systems, access to the interrupt controller is virtualized via
hypercalls and RTAS methods.  However, the virtualized interface is very
similar to the underlying interrupt controller hardware, and similar PICs
exist un-virtualized in some other systems.

This patch implements both the ICP and ICS sides of the PAPR interrupt
controller.  For now, only the hypercall virtualized interface is provided,
however it would be relatively straightforward to graft an emulated
register interface onto the underlying interrupt logic if we want to add
a machine with a hardware ICS/ICP system in the future.

There are some limitations in this implementation: it is assumed for now
that only one instance of the ICS exists, although a full xics system can
have several, each responsible for a different group of hardware irqs.
ICP/ICS can handle both level-sensitve (LSI) and message signalled (MSI)
interrupt inputs.  For now, this implementation supports only MSI
interrupts, since that is used by PAPR virtual IO devices.

Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 Makefile.target |   2 +-
 hw/spapr.c      |  27 +++
 hw/spapr.h      |   2 +
 hw/xics.c       | 486 ++++++++++++++++++++++++++++++++++++++++++++++++
 hw/xics.h       |  39 ++++
 5 files changed, 555 insertions(+), 1 deletion(-)
 create mode 100644 hw/xics.c
 create mode 100644 hw/xics.h

diff --git a/Makefile.target b/Makefile.target
index a53d99fd52..c79542842f 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -234,7 +234,7 @@ obj-ppc-y += ppc_newworld.o
 # IBM pSeries (sPAPR)
 ifeq ($(CONFIG_FDT)$(TARGET_PPC64),yy)
 obj-ppc-y += spapr.o spapr_hcall.o spapr_rtas.o spapr_vio.o
-obj-ppc-y += spapr_vty.o
+obj-ppc-y += xics.o spapr_vty.o
 endif
 # PowerPC 4xx boards
 obj-ppc-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
diff --git a/hw/spapr.c b/hw/spapr.c
index 6c64de82de..b5aefd72c3 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -34,6 +34,7 @@
 
 #include "hw/spapr.h"
 #include "hw/spapr_vio.h"
+#include "hw/xics.h"
 
 #include <libfdt.h>
 
@@ -45,6 +46,7 @@
 #define TIMEBASE_FREQ           512000000ULL
 
 #define MAX_CPUS                32
+#define XICS_IRQS		1024
 
 sPAPREnvironment *spapr;
 
@@ -64,6 +66,7 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
     uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
     uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)};
     char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr";
+    uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
     int i;
     char *modelname;
     int ret;
@@ -125,6 +128,7 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
 
     for (i = 0; i < smp_cpus; i++) {
         CPUState *env = envs[i];
+        uint32_t gserver_prop[] = {cpu_to_be32(i), 0}; /* HACK! */
         char *nodename;
         uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
                            0xffffffff, 0xffffffff};
@@ -155,6 +159,9 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
                            pft_size_prop, sizeof(pft_size_prop))));
         _FDT((fdt_property_string(fdt, "status", "okay")));
         _FDT((fdt_property(fdt, "64-bit", NULL, 0)));
+        _FDT((fdt_property_cell(fdt, "ibm,ppc-interrupt-server#s", i)));
+        _FDT((fdt_property(fdt, "ibm,ppc-interrupt-gserver#s",
+                           gserver_prop, sizeof(gserver_prop))));
 
         if (envs[i]->mmu_model & POWERPC_MMU_1TSEG) {
             _FDT((fdt_property(fdt, "ibm,processor-segment-sizes",
@@ -176,6 +183,20 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
 
     _FDT((fdt_end_node(fdt)));
 
+    /* interrupt controller */
+    _FDT((fdt_begin_node(fdt, "interrupt-controller@0")));
+
+    _FDT((fdt_property_string(fdt, "device_type",
+                              "PowerPC-External-Interrupt-Presentation")));
+    _FDT((fdt_property_string(fdt, "compatible", "IBM,ppc-xicp")));
+    _FDT((fdt_property_cell(fdt, "reg", 0)));
+    _FDT((fdt_property(fdt, "interrupt-controller", NULL, 0)));
+    _FDT((fdt_property(fdt, "ibm,interrupt-server-ranges",
+                       interrupt_server_ranges_prop,
+                       sizeof(interrupt_server_ranges_prop))));
+
+    _FDT((fdt_end_node(fdt)));
+
     /* vdevice */
     _FDT((fdt_begin_node(fdt, "vdevice")));
 
@@ -183,6 +204,8 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
     _FDT((fdt_property_string(fdt, "compatible", "IBM,vdevice")));
     _FDT((fdt_property_cell(fdt, "#address-cells", 0x1)));
     _FDT((fdt_property_cell(fdt, "#size-cells", 0x0)));
+    _FDT((fdt_property_cell(fdt, "#interrupt-cells", 0x2)));
+    _FDT((fdt_property(fdt, "interrupt-controller", NULL, 0)));
 
     _FDT((fdt_end_node(fdt)));
 
@@ -296,6 +319,10 @@ static void ppc_spapr_init(ram_addr_t ram_size,
     }
     qemu_free(filename);
 
+    /* Set up Interrupt Controller */
+    spapr->icp = xics_system_init(smp_cpus, envs, XICS_IRQS);
+
+    /* Set up VIO bus */
     spapr->vio_bus = spapr_vio_bus_init();
 
     for (i = 0; i < MAX_SERIAL_PORTS; i++) {
diff --git a/hw/spapr.h b/hw/spapr.h
index 0dcb83a5ae..fae8e1351c 100644
--- a/hw/spapr.h
+++ b/hw/spapr.h
@@ -2,9 +2,11 @@
 #define __HW_SPAPR_H__
 
 struct VIOsPAPRBus;
+struct icp_state;
 
 typedef struct sPAPREnvironment {
     struct VIOsPAPRBus *vio_bus;
+    struct icp_state *icp;
 } sPAPREnvironment;
 
 #define H_SUCCESS         0
diff --git a/hw/xics.c b/hw/xics.c
new file mode 100644
index 0000000000..66047a6c57
--- /dev/null
+++ b/hw/xics.c
@@ -0,0 +1,486 @@
+/*
+ * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
+ *
+ * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics
+ *
+ * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "hw.h"
+#include "hw/spapr.h"
+#include "hw/xics.h"
+
+#include <pthread.h>
+
+/*
+ * ICP: Presentation layer
+ */
+
+struct icp_server_state {
+    uint32_t xirr;
+    uint8_t pending_priority;
+    uint8_t mfrr;
+    qemu_irq output;
+};
+
+#define XISR_MASK  0x00ffffff
+#define CPPR_MASK  0xff000000
+
+#define XISR(ss)   (((ss)->xirr) & XISR_MASK)
+#define CPPR(ss)   (((ss)->xirr) >> 24)
+
+struct ics_state;
+
+struct icp_state {
+    long nr_servers;
+    struct icp_server_state *ss;
+    struct ics_state *ics;
+};
+
+static void ics_reject(struct ics_state *ics, int nr);
+static void ics_resend(struct ics_state *ics);
+static void ics_eoi(struct ics_state *ics, int nr);
+
+static void icp_check_ipi(struct icp_state *icp, int server)
+{
+    struct icp_server_state *ss = icp->ss + server;
+
+    if (XISR(ss) && (ss->pending_priority <= ss->mfrr)) {
+        return;
+    }
+
+    if (XISR(ss)) {
+        ics_reject(icp->ics, XISR(ss));
+    }
+
+    ss->xirr = (ss->xirr & ~XISR_MASK) | XICS_IPI;
+    ss->pending_priority = ss->mfrr;
+    qemu_irq_raise(ss->output);
+}
+
+static void icp_resend(struct icp_state *icp, int server)
+{
+    struct icp_server_state *ss = icp->ss + server;
+
+    if (ss->mfrr < CPPR(ss)) {
+        icp_check_ipi(icp, server);
+    }
+    ics_resend(icp->ics);
+}
+
+static void icp_set_cppr(struct icp_state *icp, int server, uint8_t cppr)
+{
+    struct icp_server_state *ss = icp->ss + server;
+    uint8_t old_cppr;
+    uint32_t old_xisr;
+
+    old_cppr = CPPR(ss);
+    ss->xirr = (ss->xirr & ~CPPR_MASK) | (cppr << 24);
+
+    if (cppr < old_cppr) {
+        if (XISR(ss) && (cppr <= ss->pending_priority)) {
+            old_xisr = XISR(ss);
+            ss->xirr &= ~XISR_MASK; /* Clear XISR */
+            qemu_irq_lower(ss->output);
+            ics_reject(icp->ics, old_xisr);
+        }
+    } else {
+        if (!XISR(ss)) {
+            icp_resend(icp, server);
+        }
+    }
+}
+
+static void icp_set_mfrr(struct icp_state *icp, int nr, uint8_t mfrr)
+{
+    struct icp_server_state *ss = icp->ss + nr;
+
+    ss->mfrr = mfrr;
+    if (mfrr < CPPR(ss)) {
+        icp_check_ipi(icp, nr);
+    }
+}
+
+static uint32_t icp_accept(struct icp_server_state *ss)
+{
+    uint32_t xirr;
+
+    qemu_irq_lower(ss->output);
+    xirr = ss->xirr;
+    ss->xirr = ss->pending_priority << 24;
+    return xirr;
+}
+
+static void icp_eoi(struct icp_state *icp, int server, uint32_t xirr)
+{
+    struct icp_server_state *ss = icp->ss + server;
+
+    ics_eoi(icp->ics, xirr & XISR_MASK);
+    /* Send EOI -> ICS */
+    ss->xirr = (ss->xirr & ~CPPR_MASK) | (xirr & CPPR_MASK);
+    if (!XISR(ss)) {
+        icp_resend(icp, server);
+    }
+}
+
+static void icp_irq(struct icp_state *icp, int server, int nr, uint8_t priority)
+{
+    struct icp_server_state *ss = icp->ss + server;
+
+    if ((priority >= CPPR(ss))
+        || (XISR(ss) && (ss->pending_priority <= priority))) {
+        ics_reject(icp->ics, nr);
+    } else {
+        if (XISR(ss)) {
+            ics_reject(icp->ics, XISR(ss));
+        }
+        ss->xirr = (ss->xirr & ~XISR_MASK) | (nr & XISR_MASK);
+        ss->pending_priority = priority;
+        qemu_irq_raise(ss->output);
+    }
+}
+
+/*
+ * ICS: Source layer
+ */
+
+struct ics_irq_state {
+    int server;
+    uint8_t priority;
+    uint8_t saved_priority;
+    /* int pending:1; */
+    /* int presented:1; */
+    int rejected:1;
+    int masked_pending:1;
+};
+
+struct ics_state {
+    int nr_irqs;
+    int offset;
+    qemu_irq *qirqs;
+    struct ics_irq_state *irqs;
+    struct icp_state *icp;
+};
+
+static int ics_valid_irq(struct ics_state *ics, uint32_t nr)
+{
+    return (nr >= ics->offset)
+        && (nr < (ics->offset + ics->nr_irqs));
+}
+
+static void ics_set_irq_msi(void *opaque, int nr, int val)
+{
+    struct ics_state *ics = (struct ics_state *)opaque;
+    struct ics_irq_state *irq = ics->irqs + nr;
+
+    if (val) {
+        if (irq->priority == 0xff) {
+            irq->masked_pending = 1;
+            /* masked pending */ ;
+        } else  {
+            icp_irq(ics->icp, irq->server, nr + ics->offset, irq->priority);
+        }
+    }
+}
+
+static void ics_reject_msi(struct ics_state *ics, int nr)
+{
+    struct ics_irq_state *irq = ics->irqs + nr - ics->offset;
+
+    irq->rejected = 1;
+}
+
+static void ics_resend_msi(struct ics_state *ics)
+{
+    int i;
+
+    for (i = 0; i < ics->nr_irqs; i++) {
+        struct ics_irq_state *irq = ics->irqs + i;
+
+        /* FIXME: filter by server#? */
+        if (irq->rejected) {
+            irq->rejected = 0;
+            if (irq->priority != 0xff) {
+                icp_irq(ics->icp, irq->server, i + ics->offset, irq->priority);
+            }
+        }
+    }
+}
+
+static void ics_write_xive_msi(struct ics_state *ics, int nr, int server,
+                               uint8_t priority)
+{
+    struct ics_irq_state *irq = ics->irqs + nr;
+
+    irq->server = server;
+    irq->priority = priority;
+
+    if (!irq->masked_pending || (priority == 0xff)) {
+        return;
+    }
+
+    irq->masked_pending = 0;
+    icp_irq(ics->icp, server, nr + ics->offset, priority);
+}
+
+static void ics_reject(struct ics_state *ics, int nr)
+{
+    ics_reject_msi(ics, nr);
+}
+
+static void ics_resend(struct ics_state *ics)
+{
+    ics_resend_msi(ics);
+}
+
+static void ics_eoi(struct ics_state *ics, int nr)
+{
+}
+
+/*
+ * Exported functions
+ */
+
+qemu_irq xics_find_qirq(struct icp_state *icp, int irq)
+{
+    if ((irq < icp->ics->offset)
+        || (irq >= (icp->ics->offset + icp->ics->nr_irqs))) {
+        return NULL;
+    }
+
+    return icp->ics->qirqs[irq - icp->ics->offset];
+}
+
+static target_ulong h_cppr(CPUState *env, sPAPREnvironment *spapr,
+                           target_ulong opcode, target_ulong *args)
+{
+    target_ulong cppr = args[0];
+
+    icp_set_cppr(spapr->icp, env->cpu_index, cppr);
+    return H_SUCCESS;
+}
+
+static target_ulong h_ipi(CPUState *env, sPAPREnvironment *spapr,
+                          target_ulong opcode, target_ulong *args)
+{
+    target_ulong server = args[0];
+    target_ulong mfrr = args[1];
+
+    if (server >= spapr->icp->nr_servers) {
+        return H_PARAMETER;
+    }
+
+    icp_set_mfrr(spapr->icp, server, mfrr);
+    return H_SUCCESS;
+
+}
+
+static target_ulong h_xirr(CPUState *env, sPAPREnvironment *spapr,
+                           target_ulong opcode, target_ulong *args)
+{
+    uint32_t xirr = icp_accept(spapr->icp->ss + env->cpu_index);
+
+    args[0] = xirr;
+    return H_SUCCESS;
+}
+
+static target_ulong h_eoi(CPUState *env, sPAPREnvironment *spapr,
+                          target_ulong opcode, target_ulong *args)
+{
+    target_ulong xirr = args[0];
+
+    icp_eoi(spapr->icp, env->cpu_index, xirr);
+    return H_SUCCESS;
+}
+
+static void rtas_set_xive(sPAPREnvironment *spapr, uint32_t token,
+                          uint32_t nargs, target_ulong args,
+                          uint32_t nret, target_ulong rets)
+{
+    struct ics_state *ics = spapr->icp->ics;
+    uint32_t nr, server, priority;
+
+    if ((nargs != 3) || (nret != 1)) {
+        rtas_st(rets, 0, -3);
+        return;
+    }
+
+    nr = rtas_ld(args, 0);
+    server = rtas_ld(args, 1);
+    priority = rtas_ld(args, 2);
+
+    if (!ics_valid_irq(ics, nr) || (server >= ics->icp->nr_servers)
+        || (priority > 0xff)) {
+        rtas_st(rets, 0, -3);
+        return;
+    }
+
+    ics_write_xive_msi(ics, nr - ics->offset, server, priority);
+
+    rtas_st(rets, 0, 0); /* Success */
+}
+
+static void rtas_get_xive(sPAPREnvironment *spapr, uint32_t token,
+                          uint32_t nargs, target_ulong args,
+                          uint32_t nret, target_ulong rets)
+{
+    struct ics_state *ics = spapr->icp->ics;
+    uint32_t nr;
+
+    if ((nargs != 1) || (nret != 3)) {
+        rtas_st(rets, 0, -3);
+        return;
+    }
+
+    nr = rtas_ld(args, 0);
+
+    if (!ics_valid_irq(ics, nr)) {
+        rtas_st(rets, 0, -3);
+        return;
+    }
+
+    rtas_st(rets, 0, 0); /* Success */
+    rtas_st(rets, 1, ics->irqs[nr - ics->offset].server);
+    rtas_st(rets, 2, ics->irqs[nr - ics->offset].priority);
+}
+
+static void rtas_int_off(sPAPREnvironment *spapr, uint32_t token,
+                         uint32_t nargs, target_ulong args,
+                         uint32_t nret, target_ulong rets)
+{
+    struct ics_state *ics = spapr->icp->ics;
+    uint32_t nr;
+
+    if ((nargs != 1) || (nret != 1)) {
+        rtas_st(rets, 0, -3);
+        return;
+    }
+
+    nr = rtas_ld(args, 0);
+
+    if (!ics_valid_irq(ics, nr)) {
+        rtas_st(rets, 0, -3);
+        return;
+    }
+
+    /* This is a NOP for now, since the described PAPR semantics don't
+     * seem to gel with what Linux does */
+#if 0
+    struct ics_irq_state *irq = xics->irqs + (nr - xics->offset);
+
+    irq->saved_priority = irq->priority;
+    ics_write_xive_msi(xics, nr - xics->offset, irq->server, 0xff);
+#endif
+
+    rtas_st(rets, 0, 0); /* Success */
+}
+
+static void rtas_int_on(sPAPREnvironment *spapr, uint32_t token,
+                        uint32_t nargs, target_ulong args,
+                        uint32_t nret, target_ulong rets)
+{
+    struct ics_state *ics = spapr->icp->ics;
+    uint32_t nr;
+
+    if ((nargs != 1) || (nret != 1)) {
+        rtas_st(rets, 0, -3);
+        return;
+    }
+
+    nr = rtas_ld(args, 0);
+
+    if (!ics_valid_irq(ics, nr)) {
+        rtas_st(rets, 0, -3);
+        return;
+    }
+
+    /* This is a NOP for now, since the described PAPR semantics don't
+     * seem to gel with what Linux does */
+#if 0
+    struct ics_irq_state *irq = xics->irqs + (nr - xics->offset);
+
+    ics_write_xive_msi(xics, nr - xics->offset,
+                       irq->server, irq->saved_priority);
+#endif
+
+    rtas_st(rets, 0, 0); /* Success */
+}
+
+struct icp_state *xics_system_init(int nr_servers, CPUState *servers[],
+                                   int nr_irqs)
+{
+    int i;
+    struct icp_state *icp;
+    struct ics_state *ics;
+
+    icp = qemu_mallocz(sizeof(*icp));
+    icp->nr_servers = nr_servers;
+    icp->ss = qemu_mallocz(nr_servers * sizeof(struct icp_server_state));
+
+    for (i = 0; i < nr_servers; i++) {
+        servers[i]->cpu_index = i;
+
+        switch (PPC_INPUT(servers[i])) {
+        case PPC_FLAGS_INPUT_POWER7:
+            icp->ss[i].output = servers[i]->irq_inputs[POWER7_INPUT_INT];
+            break;
+
+        case PPC_FLAGS_INPUT_970:
+            icp->ss[i].output = servers[i]->irq_inputs[PPC970_INPUT_INT];
+            break;
+
+        default:
+            hw_error("XICS interrupt model does not support this CPU bus "
+                     "model\n");
+            exit(1);
+        }
+
+        icp->ss[i].mfrr = 0xff;
+    }
+
+    ics = qemu_mallocz(sizeof(*ics));
+    ics->nr_irqs = nr_irqs;
+    ics->offset = 16;
+    ics->irqs = qemu_mallocz(nr_irqs * sizeof(struct ics_irq_state));
+
+    icp->ics = ics;
+    ics->icp = icp;
+
+    for (i = 0; i < nr_irqs; i++) {
+        ics->irqs[i].priority = 0xff;
+        ics->irqs[i].saved_priority = 0xff;
+    }
+
+    ics->qirqs = qemu_allocate_irqs(ics_set_irq_msi, ics, nr_irqs);
+
+    spapr_register_hypercall(H_CPPR, h_cppr);
+    spapr_register_hypercall(H_IPI, h_ipi);
+    spapr_register_hypercall(H_XIRR, h_xirr);
+    spapr_register_hypercall(H_EOI, h_eoi);
+
+    spapr_rtas_register("ibm,set-xive", rtas_set_xive);
+    spapr_rtas_register("ibm,get-xive", rtas_get_xive);
+    spapr_rtas_register("ibm,int-off", rtas_int_off);
+    spapr_rtas_register("ibm,int-on", rtas_int_on);
+
+    return icp;
+}
diff --git a/hw/xics.h b/hw/xics.h
new file mode 100644
index 0000000000..096eeb346d
--- /dev/null
+++ b/hw/xics.h
@@ -0,0 +1,39 @@
+/*
+ * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
+ *
+ * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics
+ *
+ * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+#if !defined(__XICS_H__)
+#define __XICS_H__
+
+#define XICS_IPI        0x2
+
+struct icp_state;
+
+qemu_irq xics_find_qirq(struct icp_state *icp, int irq);
+
+struct icp_state *xics_system_init(int nr_servers, CPUState *servers[],
+                                   int nr_irqs);
+
+#endif /* __XICS_H__ */

From 00dc738d8a08fce0f0d327e081bb2bd7b6fba888 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:26 +1100
Subject: [PATCH 024/386] Add PAPR H_VIO_SIGNAL hypercall and infrastructure
 for VIO interrupts

This patch adds infrastructure to support interrupts from PAPR virtual IO
devices.  This includes correctly advertising those interrupts in the
device tree, and implementing the H_VIO_SIGNAL hypercall, used to
enable and disable individual device interrupts.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/spapr.c     |  2 +-
 hw/spapr_vio.c | 37 +++++++++++++++++++++++++++++++++++++
 hw/spapr_vio.h |  6 ++++++
 3 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/hw/spapr.c b/hw/spapr.c
index b5aefd72c3..200617bc7c 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -65,7 +65,7 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
     uint32_t start_prop = cpu_to_be32(initrd_base);
     uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
     uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)};
-    char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr";
+    char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt";
     uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
     int i;
     char *modelname;
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 10acb4c308..605079cda5 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -105,6 +105,16 @@ static int vio_make_devnode(VIOsPAPRDevice *dev,
         }
     }
 
+    if (dev->qirq) {
+        uint32_t ints_prop[] = {cpu_to_be32(dev->vio_irq_num), 0};
+
+        ret = fdt_setprop(fdt, node_off, "interrupts", ints_prop,
+                          sizeof(ints_prop));
+        if (ret < 0) {
+            return ret;
+        }
+    }
+
     if (info->devnode) {
         ret = (info->devnode)(dev, fdt, node_off);
         if (ret < 0) {
@@ -140,6 +150,30 @@ void spapr_vio_bus_register_withprop(VIOsPAPRDeviceInfo *info)
     qdev_register(&info->qdev);
 }
 
+static target_ulong h_vio_signal(CPUState *env, sPAPREnvironment *spapr,
+                                 target_ulong opcode,
+                                 target_ulong *args)
+{
+    target_ulong reg = args[0];
+    target_ulong mode = args[1];
+    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRDeviceInfo *info;
+
+    if (!dev) {
+        return H_PARAMETER;
+    }
+
+    info = (VIOsPAPRDeviceInfo *)dev->qdev.info;
+
+    if (mode & ~info->signal_mask) {
+        return H_PARAMETER;
+    }
+
+    dev->signal_state = mode;
+
+    return H_SUCCESS;
+}
+
 VIOsPAPRBus *spapr_vio_bus_init(void)
 {
     VIOsPAPRBus *bus;
@@ -156,6 +190,9 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
     qbus = qbus_create(&spapr_vio_bus_info, dev, "spapr-vio");
     bus = DO_UPCAST(VIOsPAPRBus, bus, qbus);
 
+    /* hcall-vio */
+    spapr_register_hypercall(H_VIO_SIGNAL, h_vio_signal);
+
     for (qinfo = device_info_list; qinfo; qinfo = qinfo->next) {
         VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
 
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index b164ad326c..8a000c6fe5 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -24,6 +24,9 @@
 typedef struct VIOsPAPRDevice {
     DeviceState qdev;
     uint32_t reg;
+    qemu_irq qirq;
+    uint32_t vio_irq_num;
+    target_ulong signal_state;
 } VIOsPAPRDevice;
 
 typedef struct VIOsPAPRBus {
@@ -33,6 +36,7 @@ typedef struct VIOsPAPRBus {
 typedef struct {
     DeviceInfo qdev;
     const char *dt_name, *dt_type, *dt_compatible;
+    target_ulong signal_mask;
     int (*init)(VIOsPAPRDevice *dev);
     void (*hcalls)(VIOsPAPRBus *bus);
     int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off);
@@ -43,6 +47,8 @@ extern VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg);
 extern void spapr_vio_bus_register_withprop(VIOsPAPRDeviceInfo *info);
 extern int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt);
 
+extern int spapr_vio_signal(VIOsPAPRDevice *dev, target_ulong mode);
+
 void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len);
 void spapr_vty_create(VIOsPAPRBus *bus,
                       uint32_t reg, CharDriverState *chardev);

From 0201e2da65b1828937c478fa1ac52e58522a32c1 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:27 +1100
Subject: [PATCH 025/386] Add (virtual) interrupt to PAPR virtual tty device

Now that we have implemented the PAPR "xics" virtualized interrupt
controller, we can add interrupts in PAPR VIO devices.  This patch adds
interrupt support to the PAPR virtual tty/console device.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/spapr.c     |  6 ++++--
 hw/spapr_vio.h |  3 ++-
 hw/spapr_vty.c | 11 ++++++++++-
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/hw/spapr.c b/hw/spapr.c
index 200617bc7c..859cf86011 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -262,6 +262,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
     long pteg_shift = 17;
     int fdt_size;
     char *filename;
+    int irq = 16;
 
     spapr = qemu_malloc(sizeof(*spapr));
     cpu_ppc_hypercall = emulate_spapr_hypercall;
@@ -325,9 +326,10 @@ static void ppc_spapr_init(ram_addr_t ram_size,
     /* Set up VIO bus */
     spapr->vio_bus = spapr_vio_bus_init();
 
-    for (i = 0; i < MAX_SERIAL_PORTS; i++) {
+    for (i = 0; i < MAX_SERIAL_PORTS; i++, irq++) {
         if (serial_hds[i]) {
-            spapr_vty_create(spapr->vio_bus, i, serial_hds[i]);
+            spapr_vty_create(spapr->vio_bus, i, serial_hds[i],
+                             xics_find_qirq(spapr->icp, irq), irq);
         }
     }
 
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index 8a000c6fe5..20139273d3 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -51,6 +51,7 @@ extern int spapr_vio_signal(VIOsPAPRDevice *dev, target_ulong mode);
 
 void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len);
 void spapr_vty_create(VIOsPAPRBus *bus,
-                      uint32_t reg, CharDriverState *chardev);
+                      uint32_t reg, CharDriverState *chardev,
+                      qemu_irq qirq, uint32_t vio_irq_num);
 
 #endif /* _HW_SPAPR_VIO_H */
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index b4da6a83fb..6fc0105eac 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -24,6 +24,10 @@ static void vty_receive(void *opaque, const uint8_t *buf, int size)
     VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)opaque;
     int i;
 
+    if ((dev->in == dev->out) && size) {
+        /* toggle line to simulate edge interrupt */
+        qemu_irq_pulse(dev->sdev.qirq);
+    }
     for (i = 0; i < size; i++) {
         assert((dev->in - dev->out) < VTERM_BUFSIZE);
         dev->buf[dev->in++ % VTERM_BUFSIZE] = buf[i];
@@ -112,14 +116,19 @@ static target_ulong h_get_term_char(CPUState *env, sPAPREnvironment *spapr,
 }
 
 void spapr_vty_create(VIOsPAPRBus *bus,
-                      uint32_t reg, CharDriverState *chardev)
+                      uint32_t reg, CharDriverState *chardev,
+                      qemu_irq qirq, uint32_t vio_irq_num)
 {
     DeviceState *dev;
+    VIOsPAPRDevice *sdev;
 
     dev = qdev_create(&bus->bus, "spapr-vty");
     qdev_prop_set_uint32(dev, "reg", reg);
     qdev_prop_set_chr(dev, "chardev", chardev);
     qdev_init_nofail(dev);
+    sdev = (VIOsPAPRDevice *)dev;
+    sdev->qirq = qirq;
+    sdev->vio_irq_num = vio_irq_num;
 }
 
 static void vty_hcalls(VIOsPAPRBus *bus)

From ee86dfeebb5c12372935374b32e796e5d2544c90 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:28 +1100
Subject: [PATCH 026/386] Implement TCE translation for sPAPR VIO

This patch implements the necessary infrastructure and hypercalls for
sPAPR's TCE (Translation Control Entry) IOMMU mechanism.  This is necessary
for all virtual IO devices which do DMA (i.e. nearly all of them).

Signed-off-by: Ben Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/spapr.c     |   3 +-
 hw/spapr_vio.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++++
 hw/spapr_vio.h |  32 +++++++
 3 files changed, 272 insertions(+), 1 deletion(-)

diff --git a/hw/spapr.c b/hw/spapr.c
index 859cf86011..f8749cc57d 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -65,7 +65,8 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
     uint32_t start_prop = cpu_to_be32(initrd_base);
     uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
     uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)};
-    char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt";
+    char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt"
+        "\0hcall-tce";
     uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
     int i;
     char *modelname;
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 605079cda5..39d77ee28b 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -37,6 +37,7 @@
 #endif /* CONFIG_FDT */
 
 /* #define DEBUG_SPAPR */
+/* #define DEBUG_TCE */
 
 #ifdef DEBUG_SPAPR
 #define dprintf(fmt, ...) \
@@ -115,6 +116,28 @@ static int vio_make_devnode(VIOsPAPRDevice *dev,
         }
     }
 
+    if (dev->rtce_window_size) {
+        uint32_t dma_prop[] = {cpu_to_be32(dev->reg),
+                               0, 0,
+                               0, cpu_to_be32(dev->rtce_window_size)};
+
+        ret = fdt_setprop_cell(fdt, node_off, "ibm,#dma-address-cells", 2);
+        if (ret < 0) {
+            return ret;
+        }
+
+        ret = fdt_setprop_cell(fdt, node_off, "ibm,#dma-size-cells", 2);
+        if (ret < 0) {
+            return ret;
+        }
+
+        ret = fdt_setprop(fdt, node_off, "ibm,my-dma-window", dma_prop,
+                          sizeof(dma_prop));
+        if (ret < 0) {
+            return ret;
+        }
+    }
+
     if (info->devnode) {
         ret = (info->devnode)(dev, fdt, node_off);
         if (ret < 0) {
@@ -126,6 +149,216 @@ static int vio_make_devnode(VIOsPAPRDevice *dev,
 }
 #endif /* CONFIG_FDT */
 
+/*
+ * RTCE handling
+ */
+
+static void rtce_init(VIOsPAPRDevice *dev)
+{
+    size_t size = (dev->rtce_window_size >> SPAPR_VIO_TCE_PAGE_SHIFT)
+        * sizeof(VIOsPAPR_RTCE);
+
+    if (size) {
+        dev->rtce_table = qemu_mallocz(size);
+    }
+}
+
+static target_ulong h_put_tce(CPUState *env, sPAPREnvironment *spapr,
+                              target_ulong opcode, target_ulong *args)
+{
+    target_ulong liobn = args[0];
+    target_ulong ioba = args[1];
+    target_ulong tce = args[2];
+    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, liobn);
+    VIOsPAPR_RTCE *rtce;
+
+    if (!dev) {
+        hcall_dprintf("spapr_vio_put_tce on non-existent LIOBN "
+                      TARGET_FMT_lx "\n", liobn);
+        return H_PARAMETER;
+    }
+
+    ioba &= ~(SPAPR_VIO_TCE_PAGE_SIZE - 1);
+
+#ifdef DEBUG_TCE
+    fprintf(stderr, "spapr_vio_put_tce on %s  ioba 0x" TARGET_FMT_lx
+            "  TCE 0x" TARGET_FMT_lx "\n", dev->qdev.id, ioba, tce);
+#endif
+
+    if (ioba >= dev->rtce_window_size) {
+        hcall_dprintf("spapr_vio_put_tce on out-of-boards IOBA 0x"
+                      TARGET_FMT_lx "\n", ioba);
+        return H_PARAMETER;
+    }
+
+    rtce = dev->rtce_table + (ioba >> SPAPR_VIO_TCE_PAGE_SHIFT);
+    rtce->tce = tce;
+
+    return H_SUCCESS;
+}
+
+int spapr_vio_check_tces(VIOsPAPRDevice *dev, target_ulong ioba,
+                         target_ulong len, enum VIOsPAPR_TCEAccess access)
+{
+    int start, end, i;
+
+    start = ioba >> SPAPR_VIO_TCE_PAGE_SHIFT;
+    end = (ioba + len - 1) >> SPAPR_VIO_TCE_PAGE_SHIFT;
+
+    for (i = start; i <= end; i++) {
+        if ((dev->rtce_table[i].tce & access) != access) {
+#ifdef DEBUG_TCE
+            fprintf(stderr, "FAIL on %d\n", i);
+#endif
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+int spapr_tce_dma_write(VIOsPAPRDevice *dev, uint64_t taddr, const void *buf,
+                        uint32_t size)
+{
+#ifdef DEBUG_TCE
+    fprintf(stderr, "spapr_tce_dma_write taddr=0x%llx size=0x%x\n",
+            (unsigned long long)taddr, size);
+#endif
+
+    while (size) {
+        uint64_t tce;
+        uint32_t lsize;
+        uint64_t txaddr;
+
+        /* Check if we are in bound */
+        if (taddr >= dev->rtce_window_size) {
+#ifdef DEBUG_TCE
+            fprintf(stderr, "spapr_tce_dma_write out of bounds\n");
+#endif
+            return H_DEST_PARM;
+        }
+        tce = dev->rtce_table[taddr >> SPAPR_VIO_TCE_PAGE_SHIFT].tce;
+
+        /* How much til end of page ? */
+        lsize = MIN(size, ((~taddr) & SPAPR_VIO_TCE_PAGE_MASK) + 1);
+
+        /* Check TCE */
+        if (!(tce & 2)) {
+            return H_DEST_PARM;
+        }
+
+        /* Translate */
+        txaddr = (tce & ~SPAPR_VIO_TCE_PAGE_MASK) |
+            (taddr & SPAPR_VIO_TCE_PAGE_MASK);
+
+#ifdef DEBUG_TCE
+        fprintf(stderr, " -> write to txaddr=0x%llx, size=0x%x\n",
+                (unsigned long long)txaddr, lsize);
+#endif
+
+        /* Do it */
+        cpu_physical_memory_write(txaddr, buf, lsize);
+        buf += lsize;
+        taddr += lsize;
+        size -= lsize;
+    }
+    return 0;
+}
+
+int spapr_tce_dma_zero(VIOsPAPRDevice *dev, uint64_t taddr, uint32_t size)
+{
+    /* FIXME: allocating a temp buffer is nasty, but just stepping
+     * through writing zeroes is awkward.  This will do for now. */
+    uint8_t zeroes[size];
+
+#ifdef DEBUG_TCE
+    fprintf(stderr, "spapr_tce_dma_zero taddr=0x%llx size=0x%x\n",
+            (unsigned long long)taddr, size);
+#endif
+
+    memset(zeroes, 0, size);
+    return spapr_tce_dma_write(dev, taddr, zeroes, size);
+}
+
+void stb_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint8_t val)
+{
+    spapr_tce_dma_write(dev, taddr, &val, sizeof(val));
+}
+
+void sth_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint16_t val)
+{
+    val = tswap16(val);
+    spapr_tce_dma_write(dev, taddr, &val, sizeof(val));
+}
+
+
+void stw_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint32_t val)
+{
+    val = tswap32(val);
+    spapr_tce_dma_write(dev, taddr, &val, sizeof(val));
+}
+
+void stq_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint64_t val)
+{
+    val = tswap64(val);
+    spapr_tce_dma_write(dev, taddr, &val, sizeof(val));
+}
+
+int spapr_tce_dma_read(VIOsPAPRDevice *dev, uint64_t taddr, void *buf,
+                       uint32_t size)
+{
+#ifdef DEBUG_TCE
+    fprintf(stderr, "spapr_tce_dma_write taddr=0x%llx size=0x%x\n",
+            (unsigned long long)taddr, size);
+#endif
+
+    while (size) {
+        uint64_t tce;
+        uint32_t lsize;
+        uint64_t txaddr;
+
+        /* Check if we are in bound */
+        if (taddr >= dev->rtce_window_size) {
+#ifdef DEBUG_TCE
+            fprintf(stderr, "spapr_tce_dma_read out of bounds\n");
+#endif
+            return H_DEST_PARM;
+        }
+        tce = dev->rtce_table[taddr >> SPAPR_VIO_TCE_PAGE_SHIFT].tce;
+
+        /* How much til end of page ? */
+        lsize = MIN(size, ((~taddr) & SPAPR_VIO_TCE_PAGE_MASK) + 1);
+
+        /* Check TCE */
+        if (!(tce & 1)) {
+            return H_DEST_PARM;
+        }
+
+        /* Translate */
+        txaddr = (tce & ~SPAPR_VIO_TCE_PAGE_MASK) |
+            (taddr & SPAPR_VIO_TCE_PAGE_MASK);
+
+#ifdef DEBUG_TCE
+        fprintf(stderr, " -> write to txaddr=0x%llx, size=0x%x\n",
+                (unsigned long long)txaddr, lsize);
+#endif
+        /* Do it */
+        cpu_physical_memory_read(txaddr, buf, lsize);
+        buf += lsize;
+        taddr += lsize;
+        size -= lsize;
+    }
+    return H_SUCCESS;
+}
+
+uint64_t ldq_tce(VIOsPAPRDevice *dev, uint64_t taddr)
+{
+    uint64_t val;
+
+    spapr_tce_dma_read(dev, taddr, &val, sizeof(val));
+    return tswap64(val);
+}
+
 static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo)
 {
     VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
@@ -138,6 +371,8 @@ static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo)
 
     dev->qdev.id = id;
 
+    rtce_init(dev);
+
     return info->init(dev);
 }
 
@@ -193,6 +428,9 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
     /* hcall-vio */
     spapr_register_hypercall(H_VIO_SIGNAL, h_vio_signal);
 
+    /* hcall-tce */
+    spapr_register_hypercall(H_PUT_TCE, h_put_tce);
+
     for (qinfo = device_info_list; qinfo; qinfo = qinfo->next) {
         VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
 
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index 20139273d3..9d864c20fe 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -21,12 +21,29 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#define SPAPR_VIO_TCE_PAGE_SHIFT   12
+#define SPAPR_VIO_TCE_PAGE_SIZE    (1ULL << SPAPR_VIO_TCE_PAGE_SHIFT)
+#define SPAPR_VIO_TCE_PAGE_MASK    (SPAPR_VIO_TCE_PAGE_SIZE - 1)
+
+enum VIOsPAPR_TCEAccess {
+    SPAPR_TCE_FAULT = 0,
+    SPAPR_TCE_RO = 1,
+    SPAPR_TCE_WO = 2,
+    SPAPR_TCE_RW = 3,
+};
+
+typedef struct VIOsPAPR_RTCE {
+    uint64_t tce;
+} VIOsPAPR_RTCE;
+
 typedef struct VIOsPAPRDevice {
     DeviceState qdev;
     uint32_t reg;
     qemu_irq qirq;
     uint32_t vio_irq_num;
     target_ulong signal_state;
+    uint32_t rtce_window_size;
+    VIOsPAPR_RTCE *rtce_table;
 } VIOsPAPRDevice;
 
 typedef struct VIOsPAPRBus {
@@ -49,6 +66,21 @@ extern int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt);
 
 extern int spapr_vio_signal(VIOsPAPRDevice *dev, target_ulong mode);
 
+int spapr_vio_check_tces(VIOsPAPRDevice *dev, target_ulong ioba,
+                         target_ulong len,
+                         enum VIOsPAPR_TCEAccess access);
+
+int spapr_tce_dma_read(VIOsPAPRDevice *dev, uint64_t taddr,
+                       void *buf, uint32_t size);
+int spapr_tce_dma_write(VIOsPAPRDevice *dev, uint64_t taddr,
+                        const void *buf, uint32_t size);
+int spapr_tce_dma_zero(VIOsPAPRDevice *dev, uint64_t taddr, uint32_t size);
+void stb_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint8_t val);
+void sth_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint16_t val);
+void stw_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint32_t val);
+void stq_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint64_t val);
+uint64_t ldq_tce(VIOsPAPRDevice *dev, uint64_t taddr);
+
 void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len);
 void spapr_vty_create(VIOsPAPRBus *bus,
                       uint32_t reg, CharDriverState *chardev,

From 8d90ad900507e373a7aa26daacd51e0474760425 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:29 +1100
Subject: [PATCH 027/386] Implement sPAPR Virtual LAN (ibmveth)

This patch implements the PAPR specified Inter Virtual Machine Logical
LAN; that is the virtual hardware used by the Linux ibmveth driver.

Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 Makefile.target |   2 +-
 hw/spapr.c      |  19 ++
 hw/spapr_llan.c | 521 ++++++++++++++++++++++++++++++++++++++++++++++++
 hw/spapr_vio.h  |   3 +
 4 files changed, 544 insertions(+), 1 deletion(-)
 create mode 100644 hw/spapr_llan.c

diff --git a/Makefile.target b/Makefile.target
index c79542842f..cd7bb41a95 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -234,7 +234,7 @@ obj-ppc-y += ppc_newworld.o
 # IBM pSeries (sPAPR)
 ifeq ($(CONFIG_FDT)$(TARGET_PPC64),yy)
 obj-ppc-y += spapr.o spapr_hcall.o spapr_rtas.o spapr_vio.o
-obj-ppc-y += xics.o spapr_vty.o
+obj-ppc-y += xics.o spapr_vty.o spapr_llan.o
 endif
 # PowerPC 4xx boards
 obj-ppc-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
diff --git a/hw/spapr.c b/hw/spapr.c
index f8749cc57d..c7306d91a4 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -27,6 +27,7 @@
 #include "sysemu.h"
 #include "hw.h"
 #include "elf.h"
+#include "net.h"
 
 #include "hw/boards.h"
 #include "hw/ppc.h"
@@ -334,6 +335,24 @@ static void ppc_spapr_init(ram_addr_t ram_size,
         }
     }
 
+    for (i = 0; i < nb_nics; i++, irq++) {
+        NICInfo *nd = &nd_table[i];
+
+        if (!nd->model) {
+            nd->model = qemu_strdup("ibmveth");
+        }
+
+        if (strcmp(nd->model, "ibmveth") == 0) {
+            spapr_vlan_create(spapr->vio_bus, 0x1000 + i, nd,
+                              xics_find_qirq(spapr->icp, irq), irq);
+        } else {
+            fprintf(stderr, "pSeries (sPAPR) platform does not support "
+                    "NIC model '%s' (only ibmveth is supported)\n",
+                    nd->model);
+            exit(1);
+        }
+    }
+
     if (kernel_filename) {
         uint64_t lowaddr = 0;
 
diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c
new file mode 100644
index 0000000000..1d83fd58fd
--- /dev/null
+++ b/hw/spapr_llan.c
@@ -0,0 +1,521 @@
+/*
+ * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
+ *
+ * PAPR Inter-VM Logical Lan, aka ibmveth
+ *
+ * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+#include "hw.h"
+#include "net.h"
+#include "hw/qdev.h"
+#include "hw/spapr.h"
+#include "hw/spapr_vio.h"
+
+#include <libfdt.h>
+
+#define ETH_ALEN        6
+#define MAX_PACKET_SIZE 65536
+
+/*#define DEBUG*/
+
+#ifdef DEBUG
+#define dprintf(fmt...) do { fprintf(stderr, fmt); } while (0)
+#else
+#define dprintf(fmt...)
+#endif
+
+/*
+ * Virtual LAN device
+ */
+
+typedef uint64_t vlan_bd_t;
+
+#define VLAN_BD_VALID        0x8000000000000000ULL
+#define VLAN_BD_TOGGLE       0x4000000000000000ULL
+#define VLAN_BD_NO_CSUM      0x0200000000000000ULL
+#define VLAN_BD_CSUM_GOOD    0x0100000000000000ULL
+#define VLAN_BD_LEN_MASK     0x00ffffff00000000ULL
+#define VLAN_BD_LEN(bd)      (((bd) & VLAN_BD_LEN_MASK) >> 32)
+#define VLAN_BD_ADDR_MASK    0x00000000ffffffffULL
+#define VLAN_BD_ADDR(bd)     ((bd) & VLAN_BD_ADDR_MASK)
+
+#define VLAN_VALID_BD(addr, len) (VLAN_BD_VALID | \
+                                  (((len) << 32) & VLAN_BD_LEN_MASK) |  \
+                                  (addr & VLAN_BD_ADDR_MASK))
+
+#define VLAN_RXQC_TOGGLE     0x80
+#define VLAN_RXQC_VALID      0x40
+#define VLAN_RXQC_NO_CSUM    0x02
+#define VLAN_RXQC_CSUM_GOOD  0x01
+
+#define VLAN_RQ_ALIGNMENT    16
+#define VLAN_RXQ_BD_OFF      0
+#define VLAN_FILTER_BD_OFF   8
+#define VLAN_RX_BDS_OFF      16
+#define VLAN_MAX_BUFS        ((SPAPR_VIO_TCE_PAGE_SIZE - VLAN_RX_BDS_OFF) / 8)
+
+typedef struct VIOsPAPRVLANDevice {
+    VIOsPAPRDevice sdev;
+    NICConf nicconf;
+    NICState *nic;
+    int isopen;
+    target_ulong buf_list;
+    int add_buf_ptr, use_buf_ptr, rx_bufs;
+    target_ulong rxq_ptr;
+} VIOsPAPRVLANDevice;
+
+static int spapr_vlan_can_receive(VLANClientState *nc)
+{
+    VIOsPAPRVLANDevice *dev = DO_UPCAST(NICState, nc, nc)->opaque;
+
+    return (dev->isopen && dev->rx_bufs > 0);
+}
+
+static ssize_t spapr_vlan_receive(VLANClientState *nc, const uint8_t *buf,
+                                  size_t size)
+{
+    VIOsPAPRDevice *sdev = DO_UPCAST(NICState, nc, nc)->opaque;
+    VIOsPAPRVLANDevice *dev = (VIOsPAPRVLANDevice *)sdev;
+    vlan_bd_t rxq_bd = ldq_tce(sdev, dev->buf_list + VLAN_RXQ_BD_OFF);
+    vlan_bd_t bd;
+    int buf_ptr = dev->use_buf_ptr;
+    uint64_t handle;
+    uint8_t control;
+
+    dprintf("spapr_vlan_receive() [%s] rx_bufs=%d\n", sdev->qdev.id,
+            dev->rx_bufs);
+
+    if (!dev->isopen) {
+        return -1;
+    }
+
+    if (!dev->rx_bufs) {
+        return -1;
+    }
+
+    do {
+        buf_ptr += 8;
+        if (buf_ptr >= SPAPR_VIO_TCE_PAGE_SIZE) {
+            buf_ptr = VLAN_RX_BDS_OFF;
+        }
+
+        bd = ldq_tce(sdev, dev->buf_list + buf_ptr);
+        dprintf("use_buf_ptr=%d bd=0x%016llx\n",
+                buf_ptr, (unsigned long long)bd);
+    } while ((!(bd & VLAN_BD_VALID) || (VLAN_BD_LEN(bd) < (size + 8)))
+             && (buf_ptr != dev->use_buf_ptr));
+
+    if (!(bd & VLAN_BD_VALID) || (VLAN_BD_LEN(bd) < (size + 8))) {
+        /* Failed to find a suitable buffer */
+        return -1;
+    }
+
+    /* Remove the buffer from the pool */
+    dev->rx_bufs--;
+    dev->use_buf_ptr = buf_ptr;
+    stq_tce(sdev, dev->buf_list + dev->use_buf_ptr, 0);
+
+    dprintf("Found buffer: ptr=%d num=%d\n", dev->use_buf_ptr, dev->rx_bufs);
+
+    /* Transfer the packet data */
+    if (spapr_tce_dma_write(sdev, VLAN_BD_ADDR(bd) + 8, buf, size) < 0) {
+        return -1;
+    }
+
+    dprintf("spapr_vlan_receive: DMA write completed\n");
+
+    /* Update the receive queue */
+    control = VLAN_RXQC_TOGGLE | VLAN_RXQC_VALID;
+    if (rxq_bd & VLAN_BD_TOGGLE) {
+        control ^= VLAN_RXQC_TOGGLE;
+    }
+
+    handle = ldq_tce(sdev, VLAN_BD_ADDR(bd));
+    stq_tce(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 8, handle);
+    stw_tce(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 4, size);
+    sth_tce(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 2, 8);
+    stb_tce(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr, control);
+
+    dprintf("wrote rxq entry (ptr=0x%llx): 0x%016llx 0x%016llx\n",
+            (unsigned long long)dev->rxq_ptr,
+            (unsigned long long)ldq_tce(sdev, VLAN_BD_ADDR(rxq_bd) +
+                                        dev->rxq_ptr),
+            (unsigned long long)ldq_tce(sdev, VLAN_BD_ADDR(rxq_bd) +
+                                        dev->rxq_ptr + 8));
+
+    dev->rxq_ptr += 16;
+    if (dev->rxq_ptr >= VLAN_BD_LEN(rxq_bd)) {
+        dev->rxq_ptr = 0;
+        stq_tce(sdev, dev->buf_list + VLAN_RXQ_BD_OFF, rxq_bd ^ VLAN_BD_TOGGLE);
+    }
+
+    if (sdev->signal_state & 1) {
+        qemu_irq_pulse(sdev->qirq);
+    }
+
+    return size;
+}
+
+static NetClientInfo net_spapr_vlan_info = {
+    .type = NET_CLIENT_TYPE_NIC,
+    .size = sizeof(NICState),
+    .can_receive = spapr_vlan_can_receive,
+    .receive = spapr_vlan_receive,
+};
+
+static int spapr_vlan_init(VIOsPAPRDevice *sdev)
+{
+    VIOsPAPRVLANDevice *dev = (VIOsPAPRVLANDevice *)sdev;
+    VIOsPAPRBus *bus;
+
+    bus = DO_UPCAST(VIOsPAPRBus, bus, sdev->qdev.parent_bus);
+
+    qemu_macaddr_default_if_unset(&dev->nicconf.macaddr);
+
+    dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf,
+                            sdev->qdev.info->name, sdev->qdev.id, dev);
+    qemu_format_nic_info_str(&dev->nic->nc, dev->nicconf.macaddr.a);
+
+    return 0;
+}
+
+void spapr_vlan_create(VIOsPAPRBus *bus, uint32_t reg, NICInfo *nd,
+                       qemu_irq qirq, uint32_t vio_irq_num)
+{
+    DeviceState *dev;
+    VIOsPAPRDevice *sdev;
+
+    dev = qdev_create(&bus->bus, "spapr-vlan");
+    qdev_prop_set_uint32(dev, "reg", reg);
+
+    qdev_set_nic_properties(dev, nd);
+
+    qdev_init_nofail(dev);
+    sdev = (VIOsPAPRDevice *)dev;
+    sdev->qirq = qirq;
+    sdev->vio_irq_num = vio_irq_num;
+}
+
+static int spapr_vlan_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
+{
+    VIOsPAPRVLANDevice *vdev = (VIOsPAPRVLANDevice *)dev;
+    uint8_t padded_mac[8] = {0, 0};
+    int ret;
+
+    /* Some old phyp versions give the mac address in an 8-byte
+     * property.  The kernel driver has an insane workaround for this;
+     * rather than doing the obvious thing and checking the property
+     * length, it checks whether the first byte has 0b10 in the low
+     * bits.  If a correct 6-byte property has a different first byte
+     * the kernel will get the wrong mac address, overrunning its
+     * buffer in the process (read only, thank goodness).
+     *
+     * Here we workaround the kernel workaround by always supplying an
+     * 8-byte property, with the mac address in the last six bytes */
+    memcpy(&padded_mac[2], &vdev->nicconf.macaddr, ETH_ALEN);
+    ret = fdt_setprop(fdt, node_off, "local-mac-address",
+                      padded_mac, sizeof(padded_mac));
+    if (ret < 0) {
+        return ret;
+    }
+
+    ret = fdt_setprop_cell(fdt, node_off, "ibm,mac-address-filters", 0);
+    if (ret < 0) {
+        return ret;
+    }
+
+    return 0;
+}
+
+static int check_bd(VIOsPAPRVLANDevice *dev, vlan_bd_t bd,
+                    target_ulong alignment)
+{
+    if ((VLAN_BD_ADDR(bd) % alignment)
+        || (VLAN_BD_LEN(bd) % alignment)) {
+        return -1;
+    }
+
+    if (spapr_vio_check_tces(&dev->sdev, VLAN_BD_ADDR(bd),
+                             VLAN_BD_LEN(bd), SPAPR_TCE_RW) != 0) {
+        return -1;
+    }
+
+    return 0;
+}
+
+static target_ulong h_register_logical_lan(CPUState *env,
+                                           sPAPREnvironment *spapr,
+                                           target_ulong opcode,
+                                           target_ulong *args)
+{
+    target_ulong reg = args[0];
+    target_ulong buf_list = args[1];
+    target_ulong rec_queue = args[2];
+    target_ulong filter_list = args[3];
+    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRVLANDevice *dev = (VIOsPAPRVLANDevice *)sdev;
+    vlan_bd_t filter_list_bd;
+#ifdef DEBUG
+    target_ulong mac_address = args[4];
+#endif
+
+    if (!dev) {
+        return H_PARAMETER;
+    }
+
+    if (dev->isopen) {
+        hcall_dprintf("H_REGISTER_LOGICAL_LAN called twice without "
+                      "H_FREE_LOGICAL_LAN\n");
+        return H_RESOURCE;
+    }
+
+    if (check_bd(dev, VLAN_VALID_BD(buf_list, SPAPR_VIO_TCE_PAGE_SIZE),
+                 SPAPR_VIO_TCE_PAGE_SIZE) < 0) {
+        hcall_dprintf("Bad buf_list 0x" TARGET_FMT_lx " for "
+                      "H_REGISTER_LOGICAL_LAN\n", buf_list);
+        return H_PARAMETER;
+    }
+
+    filter_list_bd = VLAN_VALID_BD(filter_list, SPAPR_VIO_TCE_PAGE_SIZE);
+    if (check_bd(dev, filter_list_bd, SPAPR_VIO_TCE_PAGE_SIZE) < 0) {
+        hcall_dprintf("Bad filter_list 0x" TARGET_FMT_lx " for "
+                      "H_REGISTER_LOGICAL_LAN\n", filter_list);
+        return H_PARAMETER;
+    }
+
+    if (!(rec_queue & VLAN_BD_VALID)
+        || (check_bd(dev, rec_queue, VLAN_RQ_ALIGNMENT) < 0)) {
+        hcall_dprintf("Bad receive queue for H_REGISTER_LOGICAL_LAN\n");
+        return H_PARAMETER;
+    }
+
+    dev->buf_list = buf_list;
+    sdev->signal_state = 0;
+
+    rec_queue &= ~VLAN_BD_TOGGLE;
+
+    /* Initialize the buffer list */
+    stq_tce(sdev, buf_list, rec_queue);
+    stq_tce(sdev, buf_list + 8, filter_list_bd);
+    spapr_tce_dma_zero(sdev, buf_list + VLAN_RX_BDS_OFF,
+                       SPAPR_VIO_TCE_PAGE_SIZE - VLAN_RX_BDS_OFF);
+    dev->add_buf_ptr = VLAN_RX_BDS_OFF - 8;
+    dev->use_buf_ptr = VLAN_RX_BDS_OFF - 8;
+    dev->rx_bufs = 0;
+    dev->rxq_ptr = 0;
+
+    /* Initialize the receive queue */
+    spapr_tce_dma_zero(sdev, VLAN_BD_ADDR(rec_queue), VLAN_BD_LEN(rec_queue));
+
+    dev->isopen = 1;
+    return H_SUCCESS;
+}
+
+
+static target_ulong h_free_logical_lan(CPUState *env, sPAPREnvironment *spapr,
+                                       target_ulong opcode, target_ulong *args)
+{
+    target_ulong reg = args[0];
+    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRVLANDevice *dev = (VIOsPAPRVLANDevice *)sdev;
+
+    if (!dev) {
+        return H_PARAMETER;
+    }
+
+    if (!dev->isopen) {
+        hcall_dprintf("H_FREE_LOGICAL_LAN called without "
+                      "H_REGISTER_LOGICAL_LAN\n");
+        return H_RESOURCE;
+    }
+
+    dev->buf_list = 0;
+    dev->rx_bufs = 0;
+    dev->isopen = 0;
+    return H_SUCCESS;
+}
+
+static target_ulong h_add_logical_lan_buffer(CPUState *env,
+                                             sPAPREnvironment *spapr,
+                                             target_ulong opcode,
+                                             target_ulong *args)
+{
+    target_ulong reg = args[0];
+    target_ulong buf = args[1];
+    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRVLANDevice *dev = (VIOsPAPRVLANDevice *)sdev;
+    vlan_bd_t bd;
+
+    dprintf("H_ADD_LOGICAL_LAN_BUFFER(0x" TARGET_FMT_lx
+            ", 0x" TARGET_FMT_lx ")\n", reg, buf);
+
+    if (!sdev) {
+        hcall_dprintf("Wrong device in h_add_logical_lan_buffer\n");
+        return H_PARAMETER;
+    }
+
+    if ((check_bd(dev, buf, 4) < 0)
+        || (VLAN_BD_LEN(buf) < 16)) {
+        hcall_dprintf("Bad buffer enqueued in h_add_logical_lan_buffer\n");
+        return H_PARAMETER;
+    }
+
+    if (!dev->isopen || dev->rx_bufs >= VLAN_MAX_BUFS) {
+        return H_RESOURCE;
+    }
+
+    do {
+        dev->add_buf_ptr += 8;
+        if (dev->add_buf_ptr >= SPAPR_VIO_TCE_PAGE_SIZE) {
+            dev->add_buf_ptr = VLAN_RX_BDS_OFF;
+        }
+
+        bd = ldq_tce(sdev, dev->buf_list + dev->add_buf_ptr);
+    } while (bd & VLAN_BD_VALID);
+
+    stq_tce(sdev, dev->buf_list + dev->add_buf_ptr, buf);
+
+    dev->rx_bufs++;
+
+    dprintf("h_add_logical_lan_buffer():  Added buf  ptr=%d  rx_bufs=%d"
+            " bd=0x%016llx\n", dev->add_buf_ptr, dev->rx_bufs,
+            (unsigned long long)buf);
+
+    return H_SUCCESS;
+}
+
+static target_ulong h_send_logical_lan(CPUState *env, sPAPREnvironment *spapr,
+                                       target_ulong opcode, target_ulong *args)
+{
+    target_ulong reg = args[0];
+    target_ulong *bufs = args + 1;
+    target_ulong continue_token = args[7];
+    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRVLANDevice *dev = (VIOsPAPRVLANDevice *)sdev;
+    unsigned total_len;
+    uint8_t *lbuf, *p;
+    int i, nbufs;
+    int ret;
+
+    dprintf("H_SEND_LOGICAL_LAN(0x" TARGET_FMT_lx ", <bufs>, 0x"
+            TARGET_FMT_lx ")\n", reg, continue_token);
+
+    if (!sdev) {
+        return H_PARAMETER;
+    }
+
+    dprintf("rxbufs = %d\n", dev->rx_bufs);
+
+    if (!dev->isopen) {
+        return H_DROPPED;
+    }
+
+    if (continue_token) {
+        return H_HARDWARE; /* FIXME actually handle this */
+    }
+
+    total_len = 0;
+    for (i = 0; i < 6; i++) {
+        dprintf("   buf desc: 0x" TARGET_FMT_lx "\n", bufs[i]);
+        if (!(bufs[i] & VLAN_BD_VALID)) {
+            break;
+        }
+        total_len += VLAN_BD_LEN(bufs[i]);
+    }
+
+    nbufs = i;
+    dprintf("h_send_logical_lan() %d buffers, total length 0x%x\n",
+            nbufs, total_len);
+
+    if (total_len == 0) {
+        return H_SUCCESS;
+    }
+
+    if (total_len > MAX_PACKET_SIZE) {
+        /* Don't let the guest force too large an allocation */
+        return H_RESOURCE;
+    }
+
+    lbuf = alloca(total_len);
+    p = lbuf;
+    for (i = 0; i < nbufs; i++) {
+        ret = spapr_tce_dma_read(sdev, VLAN_BD_ADDR(bufs[i]),
+                                 p, VLAN_BD_LEN(bufs[i]));
+        if (ret < 0) {
+            return ret;
+        }
+
+        p += VLAN_BD_LEN(bufs[i]);
+    }
+
+    qemu_send_packet(&dev->nic->nc, lbuf, total_len);
+
+    return H_SUCCESS;
+}
+
+static target_ulong h_multicast_ctrl(CPUState *env, sPAPREnvironment *spapr,
+                                     target_ulong opcode, target_ulong *args)
+{
+    target_ulong reg = args[0];
+    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+
+    if (!dev) {
+        return H_PARAMETER;
+    }
+
+    return H_SUCCESS;
+}
+
+static void vlan_hcalls(VIOsPAPRBus *bus)
+{
+    spapr_register_hypercall(H_REGISTER_LOGICAL_LAN, h_register_logical_lan);
+    spapr_register_hypercall(H_FREE_LOGICAL_LAN, h_free_logical_lan);
+    spapr_register_hypercall(H_SEND_LOGICAL_LAN, h_send_logical_lan);
+    spapr_register_hypercall(H_ADD_LOGICAL_LAN_BUFFER,
+                             h_add_logical_lan_buffer);
+    spapr_register_hypercall(H_MULTICAST_CTRL, h_multicast_ctrl);
+}
+
+static VIOsPAPRDeviceInfo spapr_vlan = {
+    .init = spapr_vlan_init,
+    .devnode = spapr_vlan_devnode,
+    .dt_name = "l-lan",
+    .dt_type = "network",
+    .dt_compatible = "IBM,l-lan",
+    .signal_mask = 0x1,
+    .hcalls = vlan_hcalls,
+    .qdev.name = "spapr-vlan",
+    .qdev.size = sizeof(VIOsPAPRVLANDevice),
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT32("reg", VIOsPAPRDevice, reg, 0x1000),
+        DEFINE_PROP_UINT32("dma-window", VIOsPAPRDevice, rtce_window_size,
+                           0x10000000),
+        DEFINE_NIC_PROPERTIES(VIOsPAPRVLANDevice, nicconf),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+};
+
+static void spapr_vlan_register(void)
+{
+    spapr_vio_bus_register_withprop(&spapr_vlan);
+}
+device_init(spapr_vlan_register);
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index 9d864c20fe..4cfaf55bd8 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -86,4 +86,7 @@ void spapr_vty_create(VIOsPAPRBus *bus,
                       uint32_t reg, CharDriverState *chardev,
                       qemu_irq qirq, uint32_t vio_irq_num);
 
+void spapr_vlan_create(VIOsPAPRBus *bus, uint32_t reg, NICInfo *nd,
+                       qemu_irq qirq, uint32_t vio_irq_num);
+
 #endif /* _HW_SPAPR_VIO_H */

From b45d63b62f0c05eb54bba0fafaf29b9b3f4dd99a Mon Sep 17 00:00:00 2001
From: Ben Herrenschmidt <benh@kernel.crashing.org>
Date: Fri, 1 Apr 2011 15:15:30 +1100
Subject: [PATCH 028/386] Implement PAPR CRQ hypercalls

This patch implements the infrastructure and hypercalls necessary for the
PAPR specified CRQ (Command Request Queue) mechanism.  This general
request queueing system is used by many of the PAPR virtual IO devices,
including the virtual scsi adapter.

Signed-off-by: Ben Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/spapr.c           |   2 +-
 hw/spapr_vio.c       | 160 +++++++++++++++++++++++++++++++++++++++++++
 hw/spapr_vio.h       |  12 ++++
 target-ppc/kvm_ppc.h |  11 +++
 4 files changed, 184 insertions(+), 1 deletion(-)

diff --git a/hw/spapr.c b/hw/spapr.c
index c7306d91a4..b432a9dcee 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -67,7 +67,7 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
     uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
     uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)};
     char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt"
-        "\0hcall-tce";
+        "\0hcall-tce\0hcall-vio";
     uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
     int i;
     char *modelname;
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 39d77ee28b..8f14fcc794 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -28,6 +28,7 @@
 #include "hw/sysbus.h"
 #include "kvm.h"
 #include "device_tree.h"
+#include "kvm_ppc.h"
 
 #include "hw/spapr.h"
 #include "hw/spapr_vio.h"
@@ -359,6 +360,159 @@ uint64_t ldq_tce(VIOsPAPRDevice *dev, uint64_t taddr)
     return tswap64(val);
 }
 
+/*
+ * CRQ handling
+ */
+static target_ulong h_reg_crq(CPUState *env, sPAPREnvironment *spapr,
+                              target_ulong opcode, target_ulong *args)
+{
+    target_ulong reg = args[0];
+    target_ulong queue_addr = args[1];
+    target_ulong queue_len = args[2];
+    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+
+    if (!dev) {
+        hcall_dprintf("h_reg_crq on non-existent unit 0x"
+                      TARGET_FMT_lx "\n", reg);
+        return H_PARAMETER;
+    }
+
+    /* We can't grok a queue size bigger than 256M for now */
+    if (queue_len < 0x1000 || queue_len > 0x10000000) {
+        hcall_dprintf("h_reg_crq, queue size too small or too big (0x%llx)\n",
+                      (unsigned long long)queue_len);
+        return H_PARAMETER;
+    }
+
+    /* Check queue alignment */
+    if (queue_addr & 0xfff) {
+        hcall_dprintf("h_reg_crq, queue not aligned (0x%llx)\n",
+                      (unsigned long long)queue_addr);
+        return H_PARAMETER;
+    }
+
+    /* Check if device supports CRQs */
+    if (!dev->crq.SendFunc) {
+        return H_NOT_FOUND;
+    }
+
+
+    /* Already a queue ? */
+    if (dev->crq.qsize) {
+        return H_RESOURCE;
+    }
+    dev->crq.qladdr = queue_addr;
+    dev->crq.qsize = queue_len;
+    dev->crq.qnext = 0;
+
+    dprintf("CRQ for dev 0x" TARGET_FMT_lx " registered at 0x"
+            TARGET_FMT_lx "/0x" TARGET_FMT_lx "\n",
+            reg, queue_addr, queue_len);
+    return H_SUCCESS;
+}
+
+static target_ulong h_free_crq(CPUState *env, sPAPREnvironment *spapr,
+                               target_ulong opcode, target_ulong *args)
+{
+    target_ulong reg = args[0];
+    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+
+    if (!dev) {
+        hcall_dprintf("h_free_crq on non-existent unit 0x"
+                      TARGET_FMT_lx "\n", reg);
+        return H_PARAMETER;
+    }
+
+    dev->crq.qladdr = 0;
+    dev->crq.qsize = 0;
+    dev->crq.qnext = 0;
+
+    dprintf("CRQ for dev 0x" TARGET_FMT_lx " freed\n", reg);
+
+    return H_SUCCESS;
+}
+
+static target_ulong h_send_crq(CPUState *env, sPAPREnvironment *spapr,
+                               target_ulong opcode, target_ulong *args)
+{
+    target_ulong reg = args[0];
+    target_ulong msg_hi = args[1];
+    target_ulong msg_lo = args[2];
+    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    uint64_t crq_mangle[2];
+
+    if (!dev) {
+        hcall_dprintf("h_send_crq on non-existent unit 0x"
+                      TARGET_FMT_lx "\n", reg);
+        return H_PARAMETER;
+    }
+    crq_mangle[0] = cpu_to_be64(msg_hi);
+    crq_mangle[1] = cpu_to_be64(msg_lo);
+
+    if (dev->crq.SendFunc) {
+        return dev->crq.SendFunc(dev, (uint8_t *)crq_mangle);
+    }
+
+    return H_HARDWARE;
+}
+
+static target_ulong h_enable_crq(CPUState *env, sPAPREnvironment *spapr,
+                                 target_ulong opcode, target_ulong *args)
+{
+    target_ulong reg = args[0];
+    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+
+    if (!dev) {
+        hcall_dprintf("h_enable_crq on non-existent unit 0x"
+                      TARGET_FMT_lx "\n", reg);
+        return H_PARAMETER;
+    }
+
+    return 0;
+}
+
+/* Returns negative error, 0 success, or positive: queue full */
+int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq)
+{
+    int rc;
+    uint8_t byte;
+
+    if (!dev->crq.qsize) {
+        fprintf(stderr, "spapr_vio_send_creq on uninitialized queue\n");
+        return -1;
+    }
+
+    /* Maybe do a fast path for KVM just writing to the pages */
+    rc = spapr_tce_dma_read(dev, dev->crq.qladdr + dev->crq.qnext, &byte, 1);
+    if (rc) {
+        return rc;
+    }
+    if (byte != 0) {
+        return 1;
+    }
+
+    rc = spapr_tce_dma_write(dev, dev->crq.qladdr + dev->crq.qnext + 8,
+                             &crq[8], 8);
+    if (rc) {
+        return rc;
+    }
+
+    kvmppc_eieio();
+
+    rc = spapr_tce_dma_write(dev, dev->crq.qladdr + dev->crq.qnext, crq, 8);
+    if (rc) {
+        return rc;
+    }
+
+    dev->crq.qnext = (dev->crq.qnext + 16) % dev->crq.qsize;
+
+    if (dev->signal_state & 1) {
+        qemu_irq_pulse(dev->qirq);
+    }
+
+    return 0;
+}
+
 static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo)
 {
     VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
@@ -431,6 +585,12 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
     /* hcall-tce */
     spapr_register_hypercall(H_PUT_TCE, h_put_tce);
 
+    /* hcall-crq */
+    spapr_register_hypercall(H_REG_CRQ, h_reg_crq);
+    spapr_register_hypercall(H_FREE_CRQ, h_free_crq);
+    spapr_register_hypercall(H_SEND_CRQ, h_send_crq);
+    spapr_register_hypercall(H_ENABLE_CRQ, h_enable_crq);
+
     for (qinfo = device_info_list; qinfo; qinfo = qinfo->next) {
         VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
 
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index 4cfaf55bd8..ba16795c37 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -32,10 +32,19 @@ enum VIOsPAPR_TCEAccess {
     SPAPR_TCE_RW = 3,
 };
 
+struct VIOsPAPRDevice;
+
 typedef struct VIOsPAPR_RTCE {
     uint64_t tce;
 } VIOsPAPR_RTCE;
 
+typedef struct VIOsPAPR_CRQ {
+    uint64_t qladdr;
+    uint32_t qsize;
+    uint32_t qnext;
+    int(*SendFunc)(struct VIOsPAPRDevice *vdev, uint8_t *crq);
+} VIOsPAPR_CRQ;
+
 typedef struct VIOsPAPRDevice {
     DeviceState qdev;
     uint32_t reg;
@@ -44,6 +53,7 @@ typedef struct VIOsPAPRDevice {
     target_ulong signal_state;
     uint32_t rtce_window_size;
     VIOsPAPR_RTCE *rtce_table;
+    VIOsPAPR_CRQ crq;
 } VIOsPAPRDevice;
 
 typedef struct VIOsPAPRBus {
@@ -81,6 +91,8 @@ void stw_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint32_t val);
 void stq_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint64_t val);
 uint64_t ldq_tce(VIOsPAPRDevice *dev, uint64_t taddr);
 
+int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq);
+
 void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len);
 void spapr_vty_create(VIOsPAPRBus *bus,
                       uint32_t reg, CharDriverState *chardev,
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 911b19e378..5afb308477 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -18,6 +18,17 @@ uint32_t kvmppc_get_tbfreq(void);
 int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len);
 int kvmppc_set_interrupt(CPUState *env, int irq, int level);
 
+#ifndef CONFIG_KVM
+#define kvmppc_eieio() do { } while (0)
+#else
+#define kvmppc_eieio() \
+    do {                                          \
+        if (kvm_enabled()) {                          \
+            asm volatile("eieio" : : : "memory"); \
+        } \
+    } while (0)
+#endif
+
 #ifndef KVM_INTERRUPT_SET
 #define KVM_INTERRUPT_SET -1
 #endif

From 6e270446d0e107b5227d8c51d2f85546f8811e99 Mon Sep 17 00:00:00 2001
From: Ben Herrenschmidt <benh@kernel.crashing.org>
Date: Fri, 1 Apr 2011 15:15:31 +1100
Subject: [PATCH 029/386] Implement PAPR virtual SCSI interface (ibmvscsi)

This patch implements the infrastructure and hypercalls necessary for
the PAPR specified Virtual SCSI interface.  This is the normal method
for providing (virtual) disks to PAPR partitions.

Signed-off-by: Ben Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 Makefile.target  |   2 +-
 hw/ppc-viosrp.h  | 216 +++++++++++
 hw/spapr.c       |   8 +
 hw/spapr_vio.h   |   3 +
 hw/spapr_vscsi.c | 988 +++++++++++++++++++++++++++++++++++++++++++++++
 hw/srp.h         | 240 ++++++++++++
 6 files changed, 1456 insertions(+), 1 deletion(-)
 create mode 100644 hw/ppc-viosrp.h
 create mode 100644 hw/spapr_vscsi.c
 create mode 100644 hw/srp.h

diff --git a/Makefile.target b/Makefile.target
index cd7bb41a95..565e1fbd04 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -234,7 +234,7 @@ obj-ppc-y += ppc_newworld.o
 # IBM pSeries (sPAPR)
 ifeq ($(CONFIG_FDT)$(TARGET_PPC64),yy)
 obj-ppc-y += spapr.o spapr_hcall.o spapr_rtas.o spapr_vio.o
-obj-ppc-y += xics.o spapr_vty.o spapr_llan.o
+obj-ppc-y += xics.o spapr_vty.o spapr_llan.o spapr_vscsi.o
 endif
 # PowerPC 4xx boards
 obj-ppc-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
diff --git a/hw/ppc-viosrp.h b/hw/ppc-viosrp.h
new file mode 100644
index 0000000000..d8e365db1e
--- /dev/null
+++ b/hw/ppc-viosrp.h
@@ -0,0 +1,216 @@
+/*****************************************************************************/
+/* srp.h -- SCSI RDMA Protocol definitions                                   */
+/*                                                                           */
+/* Written By: Colin Devilbis, IBM Corporation                               */
+/*                                                                           */
+/* Copyright (C) 2003 IBM Corporation                                        */
+/*                                                                           */
+/* 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         */
+/* (at your option) any later version.                                       */
+/*                                                                           */
+/* This program is distributed in the hope that it will be useful,           */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of            */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
+/* GNU General Public License for more details.                              */
+/*                                                                           */
+/* You should have received a copy of the GNU General Public License         */
+/* along with this program; if not, write to the Free Software               */
+/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+/*                                                                           */
+/*                                                                           */
+/* This file contains structures and definitions for IBM RPA (RS/6000        */
+/* platform architecture) implementation of the SRP (SCSI RDMA Protocol)     */
+/* standard.  SRP is used on IBM iSeries and pSeries platforms to send SCSI  */
+/* commands between logical partitions.                                      */
+/*                                                                           */
+/* SRP Information Units (IUs) are sent on a "Command/Response Queue" (CRQ)  */
+/* between partitions.  The definitions in this file are architected,        */
+/* and cannot be changed without breaking compatibility with other versions  */
+/* of Linux and other operating systems (AIX, OS/400) that talk this protocol*/
+/* between logical partitions                                                */
+/*****************************************************************************/
+#ifndef PPC_VIOSRP_H
+#define PPC_VIOSRP_H
+
+#define SRP_VERSION "16.a"
+#define SRP_MAX_IU_LEN    256
+#define SRP_MAX_LOC_LEN 32
+
+union srp_iu {
+    struct srp_login_req login_req;
+    struct srp_login_rsp login_rsp;
+    struct srp_login_rej login_rej;
+    struct srp_i_logout i_logout;
+    struct srp_t_logout t_logout;
+    struct srp_tsk_mgmt tsk_mgmt;
+    struct srp_cmd cmd;
+    struct srp_rsp rsp;
+    uint8_t reserved[SRP_MAX_IU_LEN];
+};
+
+enum viosrp_crq_formats {
+    VIOSRP_SRP_FORMAT = 0x01,
+    VIOSRP_MAD_FORMAT = 0x02,
+    VIOSRP_OS400_FORMAT = 0x03,
+    VIOSRP_AIX_FORMAT = 0x04,
+    VIOSRP_LINUX_FORMAT = 0x06,
+    VIOSRP_INLINE_FORMAT = 0x07
+};
+
+enum viosrp_crq_status {
+    VIOSRP_OK = 0x0,
+    VIOSRP_NONRECOVERABLE_ERR = 0x1,
+    VIOSRP_VIOLATES_MAX_XFER = 0x2,
+    VIOSRP_PARTNER_PANIC = 0x3,
+    VIOSRP_DEVICE_BUSY = 0x8,
+    VIOSRP_ADAPTER_FAIL = 0x10,
+    VIOSRP_OK2 = 0x99,
+};
+
+struct viosrp_crq {
+    uint8_t valid;        /* used by RPA */
+    uint8_t format;        /* SCSI vs out-of-band */
+    uint8_t reserved;
+    uint8_t status;        /* non-scsi failure? (e.g. DMA failure) */
+    uint16_t timeout;        /* in seconds */
+    uint16_t IU_length;        /* in bytes */
+    uint64_t IU_data_ptr;    /* the TCE for transferring data */
+};
+
+/* MADs are Management requests above and beyond the IUs defined in the SRP
+ * standard.
+ */
+enum viosrp_mad_types {
+    VIOSRP_EMPTY_IU_TYPE = 0x01,
+    VIOSRP_ERROR_LOG_TYPE = 0x02,
+    VIOSRP_ADAPTER_INFO_TYPE = 0x03,
+    VIOSRP_HOST_CONFIG_TYPE = 0x04,
+    VIOSRP_CAPABILITIES_TYPE = 0x05,
+    VIOSRP_ENABLE_FAST_FAIL = 0x08,
+};
+
+enum viosrp_mad_status {
+    VIOSRP_MAD_SUCCESS = 0x00,
+    VIOSRP_MAD_NOT_SUPPORTED = 0xF1,
+    VIOSRP_MAD_FAILED = 0xF7,
+};
+
+enum viosrp_capability_type {
+    MIGRATION_CAPABILITIES = 0x01,
+    RESERVATION_CAPABILITIES = 0x02,
+};
+
+enum viosrp_capability_support {
+    SERVER_DOES_NOT_SUPPORTS_CAP = 0x0,
+    SERVER_SUPPORTS_CAP = 0x01,
+    SERVER_CAP_DATA = 0x02,
+};
+
+enum viosrp_reserve_type {
+    CLIENT_RESERVE_SCSI_2 = 0x01,
+};
+
+enum viosrp_capability_flag {
+    CLIENT_MIGRATED = 0x01,
+    CLIENT_RECONNECT = 0x02,
+    CAP_LIST_SUPPORTED = 0x04,
+    CAP_LIST_DATA = 0x08,
+};
+
+/*
+ * Common MAD header
+ */
+struct mad_common {
+    uint32_t type;
+    uint16_t status;
+    uint16_t length;
+    uint64_t tag;
+};
+
+/*
+ * All SRP (and MAD) requests normally flow from the
+ * client to the server.  There is no way for the server to send
+ * an asynchronous message back to the client.  The Empty IU is used
+ * to hang out a meaningless request to the server so that it can respond
+ * asynchrouously with something like a SCSI AER
+ */
+struct viosrp_empty_iu {
+    struct mad_common common;
+    uint64_t buffer;
+    uint32_t port;
+};
+
+struct viosrp_error_log {
+    struct mad_common common;
+    uint64_t buffer;
+};
+
+struct viosrp_adapter_info {
+    struct mad_common common;
+    uint64_t buffer;
+};
+
+struct viosrp_host_config {
+    struct mad_common common;
+    uint64_t buffer;
+};
+
+struct viosrp_fast_fail {
+    struct mad_common common;
+};
+
+struct viosrp_capabilities {
+    struct mad_common common;
+    uint64_t buffer;
+};
+
+struct mad_capability_common {
+    uint32_t cap_type;
+    uint16_t length;
+    uint16_t server_support;
+};
+
+struct mad_reserve_cap {
+    struct mad_capability_common common;
+    uint32_t type;
+};
+
+struct mad_migration_cap {
+    struct mad_capability_common common;
+    uint32_t ecl;
+};
+
+struct capabilities {
+    uint32_t flags;
+    char name[SRP_MAX_LOC_LEN];
+    char loc[SRP_MAX_LOC_LEN];
+    struct mad_migration_cap migration;
+    struct mad_reserve_cap reserve;
+};
+
+union mad_iu {
+    struct viosrp_empty_iu empty_iu;
+    struct viosrp_error_log error_log;
+    struct viosrp_adapter_info adapter_info;
+    struct viosrp_host_config host_config;
+    struct viosrp_fast_fail fast_fail;
+    struct viosrp_capabilities capabilities;
+};
+
+union viosrp_iu {
+    union srp_iu srp;
+    union mad_iu mad;
+};
+
+struct mad_adapter_info_data {
+    char srp_version[8];
+    char partition_name[96];
+    uint32_t partition_number;
+    uint32_t mad_version;
+    uint32_t os_type;
+    uint32_t port_max_txu[8];    /* per-port maximum transfer */
+};
+
+#endif
diff --git a/hw/spapr.c b/hw/spapr.c
index b432a9dcee..3bffaabe86 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -28,6 +28,7 @@
 #include "hw.h"
 #include "elf.h"
 #include "net.h"
+#include "blockdev.h"
 
 #include "hw/boards.h"
 #include "hw/ppc.h"
@@ -353,6 +354,12 @@ static void ppc_spapr_init(ram_addr_t ram_size,
         }
     }
 
+    for (i = 0; i <= drive_get_max_bus(IF_SCSI); i++) {
+        spapr_vscsi_create(spapr->vio_bus, 0x2000 + i,
+                           xics_find_qirq(spapr->icp, irq), irq);
+        irq++;
+    }
+
     if (kernel_filename) {
         uint64_t lowaddr = 0;
 
@@ -411,6 +418,7 @@ static QEMUMachine spapr_machine = {
     .max_cpus = MAX_CPUS,
     .no_vga = 1,
     .no_parallel = 1,
+    .use_scsi = 1,
 };
 
 static void spapr_machine_init(void)
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index ba16795c37..b7d0daab07 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -101,4 +101,7 @@ void spapr_vty_create(VIOsPAPRBus *bus,
 void spapr_vlan_create(VIOsPAPRBus *bus, uint32_t reg, NICInfo *nd,
                        qemu_irq qirq, uint32_t vio_irq_num);
 
+void spapr_vscsi_create(VIOsPAPRBus *bus, uint32_t reg,
+                        qemu_irq qirq, uint32_t vio_irq_num);
+
 #endif /* _HW_SPAPR_VIO_H */
diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
new file mode 100644
index 0000000000..e142dae624
--- /dev/null
+++ b/hw/spapr_vscsi.c
@@ -0,0 +1,988 @@
+/*
+ * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
+ *
+ * PAPR Virtual SCSI, aka ibmvscsi
+ *
+ * Copyright (c) 2010,2011 Benjamin Herrenschmidt, IBM Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * TODO:
+ *
+ *  - Cleanups :-)
+ *  - Sort out better how to assign devices to VSCSI instances
+ *  - Fix residual counts
+ *  - Add indirect descriptors support
+ *  - Maybe do autosense (PAPR seems to mandate it, linux doesn't care)
+ */
+#include "hw.h"
+#include "scsi.h"
+#include "scsi-defs.h"
+#include "net.h" /* Remove that when we can */
+#include "srp.h"
+#include "hw/qdev.h"
+#include "hw/spapr.h"
+#include "hw/spapr_vio.h"
+#include "hw/ppc-viosrp.h"
+
+#include <libfdt.h>
+
+/*#define DEBUG_VSCSI*/
+
+#ifdef DEBUG_VSCSI
+#define dprintf(fmt, ...) \
+    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define dprintf(fmt, ...) \
+    do { } while (0)
+#endif
+
+/*
+ * Virtual SCSI device
+ */
+
+/* Random numbers */
+#define VSCSI_MAX_SECTORS       4096
+#define VSCSI_REQ_LIMIT         24
+
+#define SCSI_SENSE_BUF_SIZE     96
+#define SRP_RSP_SENSE_DATA_LEN  18
+
+typedef union vscsi_crq {
+    struct viosrp_crq s;
+    uint8_t raw[16];
+} vscsi_crq;
+
+typedef struct vscsi_req {
+    vscsi_crq               crq;
+    union viosrp_iu         iu;
+
+    /* SCSI request tracking */
+    SCSIDevice              *sdev;
+    uint32_t                qtag; /* qemu tag != srp tag */
+    int                     lun;
+    int                     active;
+    long                    data_len;
+    int                     writing;
+    int                     sensing;
+    int                     senselen;
+    uint8_t                 sense[SCSI_SENSE_BUF_SIZE];
+
+    /* RDMA related bits */
+    uint8_t                 dma_fmt;
+    struct srp_direct_buf   ext_desc;
+    struct srp_direct_buf   *cur_desc;
+    struct srp_indirect_buf *ind_desc;
+    int                     local_desc;
+    int                     total_desc;
+} vscsi_req;
+
+
+typedef struct {
+    VIOsPAPRDevice vdev;
+    SCSIBus bus;
+    vscsi_req reqs[VSCSI_REQ_LIMIT];
+} VSCSIState;
+
+/* XXX Debug only */
+static VSCSIState *dbg_vscsi_state;
+
+
+static struct vscsi_req *vscsi_get_req(VSCSIState *s)
+{
+    vscsi_req *req;
+    int i;
+
+    for (i = 0; i < VSCSI_REQ_LIMIT; i++) {
+        req = &s->reqs[i];
+        if (!req->active) {
+            memset(req, 0, sizeof(*req));
+            req->qtag = i;
+            req->active = 1;
+            return req;
+        }
+    }
+    return NULL;
+}
+
+static void vscsi_put_req(VSCSIState *s, vscsi_req *req)
+{
+    req->active = 0;
+}
+
+static vscsi_req *vscsi_find_req(VSCSIState *s, uint32_t tag)
+{
+    if (tag >= VSCSI_REQ_LIMIT || !s->reqs[tag].active) {
+        return NULL;
+    }
+    return &s->reqs[tag];
+}
+
+static void vscsi_decode_id_lun(uint64_t srp_lun, int *id, int *lun)
+{
+    /* XXX Figure that one out properly ! This is crackpot */
+    *id = (srp_lun >> 56) & 0x7f;
+    *lun = (srp_lun >> 48) & 0xff;
+}
+
+static int vscsi_send_iu(VSCSIState *s, vscsi_req *req,
+                         uint64_t length, uint8_t format)
+{
+    long rc, rc1;
+
+    /* First copy the SRP */
+    rc = spapr_tce_dma_write(&s->vdev, req->crq.s.IU_data_ptr,
+                             &req->iu, length);
+    if (rc) {
+        fprintf(stderr, "vscsi_send_iu: DMA write failure !\n");
+    }
+
+    req->crq.s.valid = 0x80;
+    req->crq.s.format = format;
+    req->crq.s.reserved = 0x00;
+    req->crq.s.timeout = cpu_to_be16(0x0000);
+    req->crq.s.IU_length = cpu_to_be16(length);
+    req->crq.s.IU_data_ptr = req->iu.srp.rsp.tag; /* right byte order */
+
+    if (rc == 0) {
+        req->crq.s.status = 0x99; /* Just needs to be non-zero */
+    } else {
+        req->crq.s.status = 0x00;
+    }
+
+    rc1 = spapr_vio_send_crq(&s->vdev, req->crq.raw);
+    if (rc1) {
+        fprintf(stderr, "vscsi_send_iu: Error sending response\n");
+        return rc1;
+    }
+
+    return rc;
+}
+
+static void vscsi_makeup_sense(VSCSIState *s, vscsi_req *req,
+                               uint8_t key, uint8_t asc, uint8_t ascq)
+{
+    req->senselen = SRP_RSP_SENSE_DATA_LEN;
+
+    /* Valid bit and 'current errors' */
+    req->sense[0] = (0x1 << 7 | 0x70);
+    /* Sense key */
+    req->sense[2] = key;
+    /* Additional sense length */
+    req->sense[7] = 0xa; /* 10 bytes */
+    /* Additional sense code */
+    req->sense[12] = asc;
+    req->sense[13] = ascq;
+}
+
+static int vscsi_send_rsp(VSCSIState *s, vscsi_req *req,
+                          uint8_t status, int32_t res_in, int32_t res_out)
+{
+    union viosrp_iu *iu = &req->iu;
+    uint64_t tag = iu->srp.rsp.tag;
+    int total_len = sizeof(iu->srp.rsp);
+
+    dprintf("VSCSI: Sending resp status: 0x%x, "
+            "res_in: %d, res_out: %d\n", status, res_in, res_out);
+
+    memset(iu, 0, sizeof(struct srp_rsp));
+    iu->srp.rsp.opcode = SRP_RSP;
+    iu->srp.rsp.req_lim_delta = cpu_to_be32(1);
+    iu->srp.rsp.tag = tag;
+
+    /* Handle residuals */
+    if (res_in < 0) {
+        iu->srp.rsp.flags |= SRP_RSP_FLAG_DIUNDER;
+        res_in = -res_in;
+    } else if (res_in) {
+        iu->srp.rsp.flags |= SRP_RSP_FLAG_DIOVER;
+    }
+    if (res_out < 0) {
+        iu->srp.rsp.flags |= SRP_RSP_FLAG_DOUNDER;
+        res_out = -res_out;
+    } else if (res_out) {
+        iu->srp.rsp.flags |= SRP_RSP_FLAG_DOOVER;
+    }
+    iu->srp.rsp.data_in_res_cnt = cpu_to_be32(res_in);
+    iu->srp.rsp.data_out_res_cnt = cpu_to_be32(res_out);
+
+    /* We don't do response data */
+    /* iu->srp.rsp.flags &= ~SRP_RSP_FLAG_RSPVALID; */
+    iu->srp.rsp.resp_data_len = cpu_to_be32(0);
+
+    /* Handle success vs. failure */
+    iu->srp.rsp.status = status;
+    if (status) {
+        iu->srp.rsp.sol_not = (iu->srp.cmd.sol_not & 0x04) >> 2;
+        if (req->senselen) {
+            req->iu.srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID;
+            req->iu.srp.rsp.sense_data_len = cpu_to_be32(req->senselen);
+            memcpy(req->iu.srp.rsp.data, req->sense, req->senselen);
+            total_len += req->senselen;
+        }
+    } else {
+        iu->srp.rsp.sol_not = (iu->srp.cmd.sol_not & 0x02) >> 1;
+    }
+
+    vscsi_send_iu(s, req, total_len, VIOSRP_SRP_FORMAT);
+    return 0;
+}
+
+static inline void vscsi_swap_desc(struct srp_direct_buf *desc)
+{
+    desc->va = be64_to_cpu(desc->va);
+    desc->len = be32_to_cpu(desc->len);
+}
+
+static int vscsi_srp_direct_data(VSCSIState *s, vscsi_req *req,
+                                 uint8_t *buf, uint32_t len)
+{
+    struct srp_direct_buf *md = req->cur_desc;
+    uint32_t llen;
+    int rc;
+
+    dprintf("VSCSI: direct segment 0x%x bytes, va=0x%llx desc len=0x%x\n",
+            len, (unsigned long long)md->va, md->len);
+
+    llen = MIN(len, md->len);
+    if (llen) {
+        if (req->writing) { /* writing = to device = reading from memory */
+            rc = spapr_tce_dma_read(&s->vdev, md->va, buf, llen);
+        } else {
+            rc = spapr_tce_dma_write(&s->vdev, md->va, buf, llen);
+        }
+    }
+    md->len -= llen;
+    md->va += llen;
+
+    if (rc) {
+        return -1;
+    }
+    return llen;
+}
+
+static int vscsi_srp_indirect_data(VSCSIState *s, vscsi_req *req,
+                                   uint8_t *buf, uint32_t len)
+{
+    struct srp_direct_buf *td = &req->ind_desc->table_desc;
+    struct srp_direct_buf *md = req->cur_desc;
+    int rc = 0;
+    uint32_t llen, total = 0;
+
+    dprintf("VSCSI: indirect segment 0x%x bytes, td va=0x%llx len=0x%x\n",
+            len, (unsigned long long)td->va, td->len);
+
+    /* While we have data ... */
+    while (len) {
+        /* If we have a descriptor but it's empty, go fetch a new one */
+        if (md && md->len == 0) {
+            /* More local available, use one */
+            if (req->local_desc) {
+                md = ++req->cur_desc;
+                --req->local_desc;
+                --req->total_desc;
+                td->va += sizeof(struct srp_direct_buf);
+            } else {
+                md = req->cur_desc = NULL;
+            }
+        }
+        /* No descriptor at hand, fetch one */
+        if (!md) {
+            if (!req->total_desc) {
+                dprintf("VSCSI:   Out of descriptors !\n");
+                break;
+            }
+            md = req->cur_desc = &req->ext_desc;
+            dprintf("VSCSI:   Reading desc from 0x%llx\n",
+                    (unsigned long long)td->va);
+            rc = spapr_tce_dma_read(&s->vdev, td->va, md,
+                                    sizeof(struct srp_direct_buf));
+            if (rc) {
+                dprintf("VSCSI: tce_dma_read -> %d reading ext_desc\n", rc);
+                break;
+            }
+            vscsi_swap_desc(md);
+            td->va += sizeof(struct srp_direct_buf);
+            --req->total_desc;
+        }
+        dprintf("VSCSI:   [desc va=0x%llx,len=0x%x] remaining=0x%x\n",
+                (unsigned long long)md->va, md->len, len);
+
+        /* Perform transfer */
+        llen = MIN(len, md->len);
+        if (req->writing) { /* writing = to device = reading from memory */
+            rc = spapr_tce_dma_read(&s->vdev, md->va, buf, llen);
+        } else {
+            rc = spapr_tce_dma_write(&s->vdev, md->va, buf, llen);
+        }
+        if (rc) {
+            dprintf("VSCSI: tce_dma_r/w(%d) -> %d\n", req->writing, rc);
+            break;
+        }
+        dprintf("VSCSI:     data: %02x %02x %02x %02x...\n",
+                buf[0], buf[1], buf[2], buf[3]);
+
+        len -= llen;
+        buf += llen;
+        total += llen;
+        md->va += llen;
+        md->len -= llen;
+    }
+    return rc ? -1 : total;
+}
+
+static int vscsi_srp_transfer_data(VSCSIState *s, vscsi_req *req,
+                                   int writing, uint8_t *buf, uint32_t len)
+{
+    int err = 0;
+
+    switch (req->dma_fmt) {
+    case SRP_NO_DATA_DESC:
+        dprintf("VSCSI: no data desc transfer, skipping 0x%x bytes\n", len);
+        break;
+    case SRP_DATA_DESC_DIRECT:
+        err = vscsi_srp_direct_data(s, req, buf, len);
+        break;
+    case SRP_DATA_DESC_INDIRECT:
+        err = vscsi_srp_indirect_data(s, req, buf, len);
+        break;
+    }
+    return err;
+}
+
+/* Bits from linux srp */
+static int data_out_desc_size(struct srp_cmd *cmd)
+{
+    int size = 0;
+    uint8_t fmt = cmd->buf_fmt >> 4;
+
+    switch (fmt) {
+    case SRP_NO_DATA_DESC:
+        break;
+    case SRP_DATA_DESC_DIRECT:
+        size = sizeof(struct srp_direct_buf);
+        break;
+    case SRP_DATA_DESC_INDIRECT:
+        size = sizeof(struct srp_indirect_buf) +
+            sizeof(struct srp_direct_buf)*cmd->data_out_desc_cnt;
+        break;
+    default:
+        break;
+    }
+    return size;
+}
+
+static int vscsi_preprocess_desc(vscsi_req *req)
+{
+    struct srp_cmd *cmd = &req->iu.srp.cmd;
+    int offset, i;
+
+    offset = cmd->add_cdb_len & ~3;
+
+    if (req->writing) {
+        req->dma_fmt = cmd->buf_fmt >> 4;
+    } else {
+        offset += data_out_desc_size(cmd);
+        req->dma_fmt = cmd->buf_fmt & ((1U << 4) - 1);
+    }
+
+    switch (req->dma_fmt) {
+    case SRP_NO_DATA_DESC:
+        break;
+    case SRP_DATA_DESC_DIRECT:
+        req->cur_desc = (struct srp_direct_buf *)(cmd->add_data + offset);
+        req->total_desc = req->local_desc = 1;
+        vscsi_swap_desc(req->cur_desc);
+        dprintf("VSCSI: using direct RDMA %s, 0x%x bytes MD: 0x%llx\n",
+                req->writing ? "write" : "read",
+                req->cur_desc->len, (unsigned long long)req->cur_desc->va);
+        break;
+    case SRP_DATA_DESC_INDIRECT:
+        req->ind_desc = (struct srp_indirect_buf *)(cmd->add_data + offset);
+        vscsi_swap_desc(&req->ind_desc->table_desc);
+        req->total_desc = req->ind_desc->table_desc.len /
+            sizeof(struct srp_direct_buf);
+        req->local_desc = req->writing ? cmd->data_out_desc_cnt :
+            cmd->data_in_desc_cnt;
+        for (i = 0; i < req->local_desc; i++) {
+            vscsi_swap_desc(&req->ind_desc->desc_list[i]);
+        }
+        req->cur_desc = req->local_desc ? &req->ind_desc->desc_list[0] : NULL;
+        dprintf("VSCSI: using indirect RDMA %s, 0x%x bytes %d descs "
+                "(%d local) VA: 0x%llx\n",
+                req->writing ? "read" : "write",
+                be32_to_cpu(req->ind_desc->len),
+                req->total_desc, req->local_desc,
+                (unsigned long long)req->ind_desc->table_desc.va);
+        break;
+    default:
+        fprintf(stderr,
+                "vscsi_preprocess_desc: Unknown format %x\n", req->dma_fmt);
+        return -1;
+    }
+
+    return 0;
+}
+
+static void vscsi_send_request_sense(VSCSIState *s, vscsi_req *req)
+{
+    SCSIDevice *sdev = req->sdev;
+    uint8_t *cdb = req->iu.srp.cmd.cdb;
+    int n;
+
+    cdb[0] = 3;
+    cdb[1] = 0;
+    cdb[2] = 0;
+    cdb[3] = 0;
+    cdb[4] = 96;
+    cdb[5] = 0;
+    req->sensing = 1;
+    n = sdev->info->send_command(sdev, req->qtag, cdb, req->lun);
+    dprintf("VSCSI: Queued request sense tag 0x%x\n", req->qtag);
+    if (n < 0) {
+        fprintf(stderr, "VSCSI: REQUEST_SENSE wants write data !?!?!?\n");
+        sdev->info->cancel_io(sdev, req->qtag);
+        vscsi_makeup_sense(s, req, HARDWARE_ERROR, 0, 0);
+        vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
+        vscsi_put_req(s, req);
+        return;
+    } else if (n == 0) {
+        return;
+    }
+    sdev->info->read_data(sdev, req->qtag);
+}
+
+/* Callback to indicate that the SCSI layer has completed a transfer.  */
+static void vscsi_command_complete(SCSIBus *bus, int reason, uint32_t tag,
+                                   uint32_t arg)
+{
+    VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, bus->qbus.parent);
+    vscsi_req *req = vscsi_find_req(s, tag);
+    SCSIDevice *sdev;
+    uint8_t *buf;
+    int32_t res_in = 0, res_out = 0;
+    int len, rc = 0;
+
+    dprintf("VSCSI: SCSI cmd complete, r=0x%x tag=0x%x arg=0x%x, req=%p\n",
+            reason, tag, arg, req);
+    if (req == NULL) {
+        fprintf(stderr, "VSCSI: Can't find request for tag 0x%x\n", tag);
+        return;
+    }
+    sdev = req->sdev;
+
+    if (req->sensing) {
+        if (reason == SCSI_REASON_DONE) {
+            dprintf("VSCSI: Sense done !\n");
+            vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
+            vscsi_put_req(s, req);
+        } else {
+            uint8_t *buf = sdev->info->get_buf(sdev, tag);
+
+            len = MIN(arg, SCSI_SENSE_BUF_SIZE);
+            dprintf("VSCSI: Sense data, %d bytes:\n", len);
+            dprintf("       %02x  %02x  %02x  %02x  %02x  %02x  %02x  %02x\n",
+                    buf[0], buf[1], buf[2], buf[3],
+                    buf[4], buf[5], buf[6], buf[7]);
+            dprintf("       %02x  %02x  %02x  %02x  %02x  %02x  %02x  %02x\n",
+                    buf[8], buf[9], buf[10], buf[11],
+                    buf[12], buf[13], buf[14], buf[15]);
+            memcpy(req->sense, buf, len);
+            req->senselen = len;
+            sdev->info->read_data(sdev, req->qtag);
+        }
+        return;
+    }
+
+    if (reason == SCSI_REASON_DONE) {
+        dprintf("VSCSI: Command complete err=%d\n", arg);
+        if (arg == 0) {
+            /* We handle overflows, not underflows for normal commands,
+             * but hopefully nobody cares
+             */
+            if (req->writing) {
+                res_out = req->data_len;
+            } else {
+                res_in = req->data_len;
+            }
+            vscsi_send_rsp(s, req, 0, res_in, res_out);
+        } else if (arg == CHECK_CONDITION) {
+            dprintf("VSCSI: Got CHECK_CONDITION, requesting sense...\n");
+            vscsi_send_request_sense(s, req);
+            return;
+        } else {
+            vscsi_send_rsp(s, req, arg, 0, 0);
+        }
+        vscsi_put_req(s, req);
+        return;
+    }
+
+    /* "arg" is how much we have read for reads and how much we want
+     * to write for writes (ie, how much is to be DMA'd)
+     */
+    if (arg) {
+        buf = sdev->info->get_buf(sdev, tag);
+        rc = vscsi_srp_transfer_data(s, req, req->writing, buf, arg);
+    }
+    if (rc < 0) {
+        fprintf(stderr, "VSCSI: RDMA error rc=%d!\n", rc);
+        sdev->info->cancel_io(sdev, req->qtag);
+        vscsi_makeup_sense(s, req, HARDWARE_ERROR, 0, 0);
+        vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
+        vscsi_put_req(s, req);
+        return;
+    }
+
+    /* Start next chunk */
+    req->data_len -= rc;
+    if (req->writing) {
+        sdev->info->write_data(sdev, req->qtag);
+    } else {
+        sdev->info->read_data(sdev, req->qtag);
+    }
+}
+
+static void vscsi_process_login(VSCSIState *s, vscsi_req *req)
+{
+    union viosrp_iu *iu = &req->iu;
+    struct srp_login_rsp *rsp = &iu->srp.login_rsp;
+    uint64_t tag = iu->srp.rsp.tag;
+
+    dprintf("VSCSI: Got login, sendin response !\n");
+
+    /* TODO handle case that requested size is wrong and
+     * buffer format is wrong
+     */
+    memset(iu, 0, sizeof(struct srp_login_rsp));
+    rsp->opcode = SRP_LOGIN_RSP;
+    /* Don't advertise quite as many request as we support to
+     * keep room for management stuff etc...
+     */
+    rsp->req_lim_delta = cpu_to_be32(VSCSI_REQ_LIMIT-2);
+    rsp->tag = tag;
+    rsp->max_it_iu_len = cpu_to_be32(sizeof(union srp_iu));
+    rsp->max_ti_iu_len = cpu_to_be32(sizeof(union srp_iu));
+    /* direct and indirect */
+    rsp->buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT);
+
+    vscsi_send_iu(s, req, sizeof(*rsp), VIOSRP_SRP_FORMAT);
+}
+
+static void vscsi_inquiry_no_target(VSCSIState *s, vscsi_req *req)
+{
+    uint8_t *cdb = req->iu.srp.cmd.cdb;
+    uint8_t resp_data[36];
+    int rc, len, alen;
+
+    /* We dont do EVPD. Also check that page_code is 0 */
+    if ((cdb[1] & 0x01) || (cdb[1] & 0x01) || cdb[2] != 0) {
+        /* Send INVALID FIELD IN CDB */
+        vscsi_makeup_sense(s, req, ILLEGAL_REQUEST, 0x24, 0);
+        vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
+        return;
+    }
+    alen = cdb[3];
+    alen = (alen << 8) | cdb[4];
+    len = MIN(alen, 36);
+
+    /* Fake up inquiry using PQ=3 */
+    memset(resp_data, 0, 36);
+    resp_data[0] = 0x7f;   /* Not capable of supporting a device here */
+    resp_data[2] = 0x06;   /* SPS-4 */
+    resp_data[3] = 0x02;   /* Resp data format */
+    resp_data[4] = 36 - 5; /* Additional length */
+    resp_data[7] = 0x10;   /* Sync transfers */
+    memcpy(&resp_data[16], "QEMU EMPTY      ", 16);
+    memcpy(&resp_data[8], "QEMU    ", 8);
+
+    req->writing = 0;
+    vscsi_preprocess_desc(req);
+    rc = vscsi_srp_transfer_data(s, req, 0, resp_data, len);
+    if (rc < 0) {
+        vscsi_makeup_sense(s, req, HARDWARE_ERROR, 0, 0);
+        vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
+    } else {
+        vscsi_send_rsp(s, req, 0, 36 - rc, 0);
+    }
+}
+
+static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req)
+{
+    union srp_iu *srp = &req->iu.srp;
+    SCSIDevice *sdev;
+    int n, id, lun;
+
+    vscsi_decode_id_lun(be64_to_cpu(srp->cmd.lun), &id, &lun);
+
+    /* Qemu vs. linux issue with LUNs to be sorted out ... */
+    sdev = (id < 8 && lun < 16) ? s->bus.devs[id] : NULL;
+    if (!sdev) {
+        dprintf("VSCSI: Command for id %d with no drive\n", id);
+        if (srp->cmd.cdb[0] == INQUIRY) {
+            vscsi_inquiry_no_target(s, req);
+        } else {
+            vscsi_makeup_sense(s, req, ILLEGAL_REQUEST, 0x24, 0x00);
+            vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
+        } return 1;
+    }
+
+    req->sdev = sdev;
+    req->lun = lun;
+    n = sdev->info->send_command(sdev, req->qtag, srp->cmd.cdb, lun);
+
+    dprintf("VSCSI: Queued command tag 0x%x CMD 0x%x ID %d LUN %d ret: %d\n",
+            req->qtag, srp->cmd.cdb[0], id, lun, n);
+
+    if (n) {
+        /* Transfer direction must be set before preprocessing the
+         * descriptors
+         */
+        req->writing = (n < 1);
+
+        /* Preprocess RDMA descriptors */
+        vscsi_preprocess_desc(req);
+    }
+
+    /* Get transfer direction and initiate transfer */
+    if (n > 0) {
+        req->data_len = n;
+        sdev->info->read_data(sdev, req->qtag);
+    } else if (n < 0) {
+        req->data_len = -n;
+        sdev->info->write_data(sdev, req->qtag);
+    }
+    /* Don't touch req here, it may have been recycled already */
+
+    return 0;
+}
+
+static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req)
+{
+    union viosrp_iu *iu = &req->iu;
+    int fn;
+
+    fprintf(stderr, "vscsi_process_tsk_mgmt %02x\n",
+            iu->srp.tsk_mgmt.tsk_mgmt_func);
+
+    switch (iu->srp.tsk_mgmt.tsk_mgmt_func) {
+#if 0 /* We really don't deal with these for now */
+    case SRP_TSK_ABORT_TASK:
+        fn = ABORT_TASK;
+        break;
+    case SRP_TSK_ABORT_TASK_SET:
+        fn = ABORT_TASK_SET;
+        break;
+    case SRP_TSK_CLEAR_TASK_SET:
+        fn = CLEAR_TASK_SET;
+        break;
+    case SRP_TSK_LUN_RESET:
+        fn = LOGICAL_UNIT_RESET;
+        break;
+    case SRP_TSK_CLEAR_ACA:
+        fn = CLEAR_ACA;
+        break;
+#endif
+    default:
+        fn = 0;
+    }
+    if (fn) {
+        /* XXX Send/Handle target task management */
+        ;
+    } else {
+        vscsi_makeup_sense(s, req, ILLEGAL_REQUEST, 0x20, 0);
+        vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
+    }
+    return !fn;
+}
+
+static int vscsi_handle_srp_req(VSCSIState *s, vscsi_req *req)
+{
+    union srp_iu *srp = &req->iu.srp;
+    int done = 1;
+    uint8_t opcode = srp->rsp.opcode;
+
+    switch (opcode) {
+    case SRP_LOGIN_REQ:
+        vscsi_process_login(s, req);
+        break;
+    case SRP_TSK_MGMT:
+        done = vscsi_process_tsk_mgmt(s, req);
+        break;
+    case SRP_CMD:
+        done = vscsi_queue_cmd(s, req);
+        break;
+    case SRP_LOGIN_RSP:
+    case SRP_I_LOGOUT:
+    case SRP_T_LOGOUT:
+    case SRP_RSP:
+    case SRP_CRED_REQ:
+    case SRP_CRED_RSP:
+    case SRP_AER_REQ:
+    case SRP_AER_RSP:
+        fprintf(stderr, "VSCSI: Unsupported opcode %02x\n", opcode);
+        break;
+    default:
+        fprintf(stderr, "VSCSI: Unknown type %02x\n", opcode);
+    }
+
+    return done;
+}
+
+static int vscsi_send_adapter_info(VSCSIState *s, vscsi_req *req)
+{
+    struct viosrp_adapter_info *sinfo;
+    struct mad_adapter_info_data info;
+    int rc;
+
+    sinfo = &req->iu.mad.adapter_info;
+
+#if 0 /* What for ? */
+    rc = spapr_tce_dma_read(&s->vdev, be64_to_cpu(sinfo->buffer),
+                            &info, be16_to_cpu(sinfo->common.length));
+    if (rc) {
+        fprintf(stderr, "vscsi_send_adapter_info: DMA read failure !\n");
+    }
+#endif
+    memset(&info, 0, sizeof(info));
+    strcpy(info.srp_version, SRP_VERSION);
+    strncpy(info.partition_name, "qemu", sizeof("qemu"));
+    info.partition_number = cpu_to_be32(0);
+    info.mad_version = cpu_to_be32(1);
+    info.os_type = cpu_to_be32(2);
+    info.port_max_txu[0] = cpu_to_be32(VSCSI_MAX_SECTORS << 9);
+
+    rc = spapr_tce_dma_write(&s->vdev, be64_to_cpu(sinfo->buffer),
+                             &info, be16_to_cpu(sinfo->common.length));
+    if (rc)  {
+        fprintf(stderr, "vscsi_send_adapter_info: DMA write failure !\n");
+    }
+
+    sinfo->common.status = rc ? cpu_to_be32(1) : 0;
+
+    return vscsi_send_iu(s, req, sizeof(*sinfo), VIOSRP_MAD_FORMAT);
+}
+
+static int vscsi_handle_mad_req(VSCSIState *s, vscsi_req *req)
+{
+    union mad_iu *mad = &req->iu.mad;
+
+    switch (be32_to_cpu(mad->empty_iu.common.type)) {
+    case VIOSRP_EMPTY_IU_TYPE:
+        fprintf(stderr, "Unsupported EMPTY MAD IU\n");
+        break;
+    case VIOSRP_ERROR_LOG_TYPE:
+        fprintf(stderr, "Unsupported ERROR LOG MAD IU\n");
+        mad->error_log.common.status = cpu_to_be16(1);
+        vscsi_send_iu(s, req, sizeof(mad->error_log), VIOSRP_MAD_FORMAT);
+        break;
+    case VIOSRP_ADAPTER_INFO_TYPE:
+        vscsi_send_adapter_info(s, req);
+        break;
+    case VIOSRP_HOST_CONFIG_TYPE:
+        mad->host_config.common.status = cpu_to_be16(1);
+        vscsi_send_iu(s, req, sizeof(mad->host_config), VIOSRP_MAD_FORMAT);
+        break;
+    default:
+        fprintf(stderr, "VSCSI: Unknown MAD type %02x\n",
+                be32_to_cpu(mad->empty_iu.common.type));
+    }
+
+    return 1;
+}
+
+static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq)
+{
+    vscsi_req *req;
+    int done;
+
+    req = vscsi_get_req(s);
+    if (req == NULL) {
+        fprintf(stderr, "VSCSI: Failed to get a request !\n");
+        return;
+    }
+
+    /* We only support a limited number of descriptors, we know
+     * the ibmvscsi driver uses up to 10 max, so it should fit
+     * in our 256 bytes IUs. If not we'll have to increase the size
+     * of the structure.
+     */
+    if (crq->s.IU_length > sizeof(union viosrp_iu)) {
+        fprintf(stderr, "VSCSI: SRP IU too long (%d bytes) !\n",
+                crq->s.IU_length);
+        return;
+    }
+
+    /* XXX Handle failure differently ? */
+    if (spapr_tce_dma_read(&s->vdev, crq->s.IU_data_ptr, &req->iu,
+                           crq->s.IU_length)) {
+        fprintf(stderr, "vscsi_got_payload: DMA read failure !\n");
+        qemu_free(req);
+    }
+    memcpy(&req->crq, crq, sizeof(vscsi_crq));
+
+    if (crq->s.format == VIOSRP_MAD_FORMAT) {
+        done = vscsi_handle_mad_req(s, req);
+    } else {
+        done = vscsi_handle_srp_req(s, req);
+    }
+
+    if (done) {
+        vscsi_put_req(s, req);
+    }
+}
+
+
+static int vscsi_do_crq(struct VIOsPAPRDevice *dev, uint8_t *crq_data)
+{
+    VSCSIState *s = DO_UPCAST(VSCSIState, vdev, dev);
+    vscsi_crq crq;
+
+    memcpy(crq.raw, crq_data, 16);
+    crq.s.timeout = be16_to_cpu(crq.s.timeout);
+    crq.s.IU_length = be16_to_cpu(crq.s.IU_length);
+    crq.s.IU_data_ptr = be64_to_cpu(crq.s.IU_data_ptr);
+
+    dprintf("VSCSI: do_crq %02x %02x ...\n", crq.raw[0], crq.raw[1]);
+
+    switch (crq.s.valid) {
+    case 0xc0: /* Init command/response */
+
+        /* Respond to initialization request */
+        if (crq.s.format == 0x01) {
+            memset(crq.raw, 0, 16);
+            crq.s.valid = 0xc0;
+            crq.s.format = 0x02;
+            spapr_vio_send_crq(dev, crq.raw);
+        }
+
+        /* Note that in hotplug cases, we might get a 0x02
+         * as a result of us emitting the init request
+         */
+
+        break;
+    case 0xff: /* Link event */
+
+        /* Not handled for now */
+
+        break;
+    case 0x80: /* Payloads */
+        switch (crq.s.format) {
+        case VIOSRP_SRP_FORMAT: /* AKA VSCSI request */
+        case VIOSRP_MAD_FORMAT: /* AKA VSCSI response */
+            vscsi_got_payload(s, &crq);
+            break;
+        case VIOSRP_OS400_FORMAT:
+        case VIOSRP_AIX_FORMAT:
+        case VIOSRP_LINUX_FORMAT:
+        case VIOSRP_INLINE_FORMAT:
+            fprintf(stderr, "vscsi_do_srq: Unsupported payload format %02x\n",
+                    crq.s.format);
+            break;
+        default:
+            fprintf(stderr, "vscsi_do_srq: Unknown payload format %02x\n",
+                    crq.s.format);
+        }
+        break;
+    default:
+        fprintf(stderr, "vscsi_do_crq: unknown CRQ %02x %02x ...\n",
+                crq.raw[0], crq.raw[1]);
+    };
+
+    return 0;
+}
+
+static int spapr_vscsi_init(VIOsPAPRDevice *dev)
+{
+    VSCSIState *s = DO_UPCAST(VSCSIState, vdev, dev);
+    int i;
+
+    dbg_vscsi_state = s;
+
+    /* Initialize qemu request tags */
+    memset(s->reqs, 0, sizeof(s->reqs));
+    for (i = 0; i < VSCSI_REQ_LIMIT; i++) {
+        s->reqs[i].qtag = i;
+    }
+
+    dev->crq.SendFunc = vscsi_do_crq;
+
+    scsi_bus_new(&s->bus, &dev->qdev, 1, VSCSI_REQ_LIMIT,
+                 vscsi_command_complete);
+    if (!dev->qdev.hotplugged) {
+        scsi_bus_legacy_handle_cmdline(&s->bus);
+    }
+
+    return 0;
+}
+
+void spapr_vscsi_create(VIOsPAPRBus *bus, uint32_t reg,
+                        qemu_irq qirq, uint32_t vio_irq_num)
+{
+    DeviceState *dev;
+    VIOsPAPRDevice *sdev;
+
+    dev = qdev_create(&bus->bus, "spapr-vscsi");
+    qdev_prop_set_uint32(dev, "reg", reg);
+
+    qdev_init_nofail(dev);
+
+    sdev = (VIOsPAPRDevice *)dev;
+    sdev->qirq = qirq;
+    sdev->vio_irq_num = vio_irq_num;
+}
+
+static int spapr_vscsi_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
+{
+    int ret;
+
+    ret = fdt_setprop_cell(fdt, node_off, "#address-cells", 2);
+    if (ret < 0) {
+        return ret;
+    }
+
+    ret = fdt_setprop_cell(fdt, node_off, "#size-cells", 0);
+    if (ret < 0) {
+        return ret;
+    }
+
+    return 0;
+}
+
+static VIOsPAPRDeviceInfo spapr_vscsi = {
+    .init = spapr_vscsi_init,
+    .devnode = spapr_vscsi_devnode,
+    .dt_name = "v-scsi",
+    .dt_type = "vscsi",
+    .dt_compatible = "IBM,v-scsi",
+    .signal_mask = 0x00000001,
+    .qdev.name = "spapr-vscsi",
+    .qdev.size = sizeof(VSCSIState),
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT32("reg", VIOsPAPRDevice, reg, 0x2000),
+        DEFINE_PROP_UINT32("dma-window", VIOsPAPRDevice,
+                           rtce_window_size, 0x10000000),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+};
+
+static void spapr_vscsi_register(void)
+{
+    spapr_vio_bus_register_withprop(&spapr_vscsi);
+}
+device_init(spapr_vscsi_register);
diff --git a/hw/srp.h b/hw/srp.h
new file mode 100644
index 0000000000..afcd135c8f
--- /dev/null
+++ b/hw/srp.h
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef SCSI_SRP_H
+#define SCSI_SRP_H
+
+/*
+ * Structures and constants for the SCSI RDMA Protocol (SRP) as
+ * defined by the INCITS T10 committee.  This file was written using
+ * draft Revision 16a of the SRP standard.
+ */
+
+enum {
+
+    SRP_LOGIN_REQ = 0x00,
+    SRP_TSK_MGMT  = 0x01,
+    SRP_CMD       = 0x02,
+    SRP_I_LOGOUT  = 0x03,
+    SRP_LOGIN_RSP = 0xc0,
+    SRP_RSP       = 0xc1,
+    SRP_LOGIN_REJ = 0xc2,
+    SRP_T_LOGOUT  = 0x80,
+    SRP_CRED_REQ  = 0x81,
+    SRP_AER_REQ   = 0x82,
+    SRP_CRED_RSP  = 0x41,
+    SRP_AER_RSP   = 0x42
+};
+
+enum {
+    SRP_BUF_FORMAT_DIRECT   = 1 << 1,
+    SRP_BUF_FORMAT_INDIRECT = 1 << 2
+};
+
+enum {
+    SRP_NO_DATA_DESC       = 0,
+    SRP_DATA_DESC_DIRECT   = 1,
+    SRP_DATA_DESC_INDIRECT = 2
+};
+
+enum {
+    SRP_TSK_ABORT_TASK     = 0x01,
+    SRP_TSK_ABORT_TASK_SET = 0x02,
+    SRP_TSK_CLEAR_TASK_SET = 0x04,
+    SRP_TSK_LUN_RESET      = 0x08,
+    SRP_TSK_CLEAR_ACA      = 0x40
+};
+
+enum srp_login_rej_reason {
+    SRP_LOGIN_REJ_UNABLE_ESTABLISH_CHANNEL   = 0x00010000,
+    SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES     = 0x00010001,
+    SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE = 0x00010002,
+    SRP_LOGIN_REJ_UNABLE_ASSOCIATE_CHANNEL   = 0x00010003,
+    SRP_LOGIN_REJ_UNSUPPORTED_DESCRIPTOR_FMT = 0x00010004,
+    SRP_LOGIN_REJ_MULTI_CHANNEL_UNSUPPORTED  = 0x00010005,
+    SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED      = 0x00010006
+};
+
+enum {
+    SRP_REV10_IB_IO_CLASS  = 0xff00,
+    SRP_REV16A_IB_IO_CLASS = 0x0100
+};
+
+struct srp_direct_buf {
+    uint64_t    va;
+    uint32_t    key;
+    uint32_t    len;
+};
+
+/*
+ * We need the packed attribute because the SRP spec puts the list of
+ * descriptors at an offset of 20, which is not aligned to the size of
+ * struct srp_direct_buf.  The whole structure must be packed to avoid
+ * having the 20-byte structure padded to 24 bytes on 64-bit architectures.
+ */
+struct srp_indirect_buf {
+    struct srp_direct_buf    table_desc;
+    uint32_t                 len;
+    struct srp_direct_buf    desc_list[0];
+} __attribute__((packed));
+
+enum {
+    SRP_MULTICHAN_SINGLE = 0,
+    SRP_MULTICHAN_MULTI  = 1
+};
+
+struct srp_login_req {
+    uint8_t    opcode;
+    uint8_t    reserved1[7];
+    uint64_t   tag;
+    uint32_t   req_it_iu_len;
+    uint8_t    reserved2[4];
+    uint16_t   req_buf_fmt;
+    uint8_t    req_flags;
+    uint8_t    reserved3[5];
+    uint8_t    initiator_port_id[16];
+    uint8_t    target_port_id[16];
+};
+
+/*
+ * The SRP spec defines the size of the LOGIN_RSP structure to be 52
+ * bytes, so it needs to be packed to avoid having it padded to 56
+ * bytes on 64-bit architectures.
+ */
+struct srp_login_rsp {
+    uint8_t    opcode;
+    uint8_t    reserved1[3];
+    uint32_t   req_lim_delta;
+    uint64_t   tag;
+    uint32_t   max_it_iu_len;
+    uint32_t   max_ti_iu_len;
+    uint16_t   buf_fmt;
+    uint8_t    rsp_flags;
+    uint8_t    reserved2[25];
+} __attribute__((packed));
+
+struct srp_login_rej {
+    uint8_t    opcode;
+    uint8_t    reserved1[3];
+    uint32_t   reason;
+    uint64_t   tag;
+    uint8_t    reserved2[8];
+    uint16_t   buf_fmt;
+    uint8_t    reserved3[6];
+};
+
+struct srp_i_logout {
+    uint8_t    opcode;
+    uint8_t    reserved[7];
+    uint64_t   tag;
+};
+
+struct srp_t_logout {
+    uint8_t    opcode;
+    uint8_t    sol_not;
+    uint8_t    reserved[2];
+    uint32_t   reason;
+    uint64_t   tag;
+};
+
+/*
+ * We need the packed attribute because the SRP spec only aligns the
+ * 8-byte LUN field to 4 bytes.
+ */
+struct srp_tsk_mgmt {
+    uint8_t    opcode;
+    uint8_t    sol_not;
+    uint8_t    reserved1[6];
+    uint64_t   tag;
+    uint8_t    reserved2[4];
+    uint64_t   lun __attribute__((packed));
+    uint8_t    reserved3[2];
+    uint8_t    tsk_mgmt_func;
+    uint8_t    reserved4;
+    uint64_t   task_tag;
+    uint8_t    reserved5[8];
+};
+
+/*
+ * We need the packed attribute because the SRP spec only aligns the
+ * 8-byte LUN field to 4 bytes.
+ */
+struct srp_cmd {
+    uint8_t    opcode;
+    uint8_t    sol_not;
+    uint8_t    reserved1[3];
+    uint8_t    buf_fmt;
+    uint8_t    data_out_desc_cnt;
+    uint8_t    data_in_desc_cnt;
+    uint64_t   tag;
+    uint8_t    reserved2[4];
+    uint64_t   lun __attribute__((packed));
+    uint8_t    reserved3;
+    uint8_t    task_attr;
+    uint8_t    reserved4;
+    uint8_t    add_cdb_len;
+    uint8_t    cdb[16];
+    uint8_t    add_data[0];
+};
+
+enum {
+    SRP_RSP_FLAG_RSPVALID = 1 << 0,
+    SRP_RSP_FLAG_SNSVALID = 1 << 1,
+    SRP_RSP_FLAG_DOOVER   = 1 << 2,
+    SRP_RSP_FLAG_DOUNDER  = 1 << 3,
+    SRP_RSP_FLAG_DIOVER   = 1 << 4,
+    SRP_RSP_FLAG_DIUNDER  = 1 << 5
+};
+
+/*
+ * The SRP spec defines the size of the RSP structure to be 36 bytes,
+ * so it needs to be packed to avoid having it padded to 40 bytes on
+ * 64-bit architectures.
+ */
+struct srp_rsp {
+    uint8_t    opcode;
+    uint8_t    sol_not;
+    uint8_t    reserved1[2];
+    uint32_t   req_lim_delta;
+    uint64_t   tag;
+    uint8_t    reserved2[2];
+    uint8_t    flags;
+    uint8_t    status;
+    uint32_t   data_out_res_cnt;
+    uint32_t   data_in_res_cnt;
+    uint32_t   sense_data_len;
+    uint32_t   resp_data_len;
+    uint8_t    data[0];
+} __attribute__((packed));
+
+#endif /* SCSI_SRP_H */

From 08942ac17922d923a7cc5cf9854e9cc4b150b942 Mon Sep 17 00:00:00 2001
From: Ben Herrenschmidt <benh@kernel.crashing.org>
Date: Fri, 1 Apr 2011 15:15:32 +1100
Subject: [PATCH 030/386] Add a PAPR TCE-bypass mechanism for the pSeries
 machine

Usually, PAPR virtual IO devices use a virtual IOMMU mechanism, TCEs,
to mediate all DMA transfers.  While this is necessary for some sorts of
operation, it can be complex to program and slow for others.

This patch implements a mechanism for bypassing TCE translation, treating
"IO" addresses as plain (guest) physical memory addresses.  This has two
main uses:
 * Simple, but 64-bit aware programs like firmwares can use the VIO devices
without the complexity of TCE setup.
 * The guest OS can optionally use the TCE bypass to improve performance in
suitable situations.

The mechanism used is a per-device flag which disables TCE translation.
The flag is toggled with some (hypervisor-implemented) RTAS methods.

Signed-off-by: Ben Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/spapr_vio.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/spapr_vio.h |  5 +++
 2 files changed, 87 insertions(+)

diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 8f14fcc794..481a804e73 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -226,6 +226,12 @@ int spapr_tce_dma_write(VIOsPAPRDevice *dev, uint64_t taddr, const void *buf,
             (unsigned long long)taddr, size);
 #endif
 
+    /* Check for bypass */
+    if (dev->flags & VIO_PAPR_FLAG_DMA_BYPASS) {
+        cpu_physical_memory_write(taddr, buf, size);
+        return 0;
+    }
+
     while (size) {
         uint64_t tce;
         uint32_t lsize;
@@ -313,6 +319,12 @@ int spapr_tce_dma_read(VIOsPAPRDevice *dev, uint64_t taddr, void *buf,
             (unsigned long long)taddr, size);
 #endif
 
+    /* Check for bypass */
+    if (dev->flags & VIO_PAPR_FLAG_DMA_BYPASS) {
+        cpu_physical_memory_read(taddr, buf, size);
+        return 0;
+    }
+
     while (size) {
         uint64_t tce;
         uint32_t lsize;
@@ -513,6 +525,72 @@ int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq)
     return 0;
 }
 
+/* "quiesce" handling */
+
+static void spapr_vio_quiesce_one(VIOsPAPRDevice *dev)
+{
+    dev->flags &= ~VIO_PAPR_FLAG_DMA_BYPASS;
+
+    if (dev->rtce_table) {
+        size_t size = (dev->rtce_window_size >> SPAPR_VIO_TCE_PAGE_SHIFT)
+            * sizeof(VIOsPAPR_RTCE);
+        memset(dev->rtce_table, 0, size);
+    }
+
+    dev->crq.qladdr = 0;
+    dev->crq.qsize = 0;
+    dev->crq.qnext = 0;
+}
+
+static void rtas_set_tce_bypass(sPAPREnvironment *spapr, uint32_t token,
+                                uint32_t nargs, target_ulong args,
+                                uint32_t nret, target_ulong rets)
+{
+    VIOsPAPRBus *bus = spapr->vio_bus;
+    VIOsPAPRDevice *dev;
+    uint32_t unit, enable;
+
+    if (nargs != 2) {
+        rtas_st(rets, 0, -3);
+        return;
+    }
+    unit = rtas_ld(args, 0);
+    enable = rtas_ld(args, 1);
+    dev = spapr_vio_find_by_reg(bus, unit);
+    if (!dev) {
+        rtas_st(rets, 0, -3);
+        return;
+    }
+    if (enable) {
+        dev->flags |= VIO_PAPR_FLAG_DMA_BYPASS;
+    } else {
+        dev->flags &= ~VIO_PAPR_FLAG_DMA_BYPASS;
+    }
+
+    rtas_st(rets, 0, 0);
+}
+
+static void rtas_quiesce(sPAPREnvironment *spapr, uint32_t token,
+                         uint32_t nargs, target_ulong args,
+                         uint32_t nret, target_ulong rets)
+{
+    VIOsPAPRBus *bus = spapr->vio_bus;
+    DeviceState *qdev;
+    VIOsPAPRDevice *dev = NULL;
+
+    if (nargs != 0) {
+        rtas_st(rets, 0, -3);
+        return;
+    }
+
+    QLIST_FOREACH(qdev, &bus->bus.children, sibling) {
+        dev = (VIOsPAPRDevice *)qdev;
+        spapr_vio_quiesce_one(dev);
+    }
+
+    rtas_st(rets, 0, 0);
+}
+
 static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo)
 {
     VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
@@ -591,6 +669,10 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
     spapr_register_hypercall(H_SEND_CRQ, h_send_crq);
     spapr_register_hypercall(H_ENABLE_CRQ, h_enable_crq);
 
+    /* RTAS calls */
+    spapr_rtas_register("ibm,set-tce-bypass", rtas_set_tce_bypass);
+    spapr_rtas_register("quiesce", rtas_quiesce);
+
     for (qinfo = device_info_list; qinfo; qinfo = qinfo->next) {
         VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
 
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index b7d0daab07..841b04351a 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -48,6 +48,8 @@ typedef struct VIOsPAPR_CRQ {
 typedef struct VIOsPAPRDevice {
     DeviceState qdev;
     uint32_t reg;
+    uint32_t flags;
+#define VIO_PAPR_FLAG_DMA_BYPASS        0x1
     qemu_irq qirq;
     uint32_t vio_irq_num;
     target_ulong signal_state;
@@ -104,4 +106,7 @@ void spapr_vlan_create(VIOsPAPRBus *bus, uint32_t reg, NICInfo *nd,
 void spapr_vscsi_create(VIOsPAPRBus *bus, uint32_t reg,
                         qemu_irq qirq, uint32_t vio_irq_num);
 
+int spapr_tce_set_bypass(uint32_t unit, uint32_t enable);
+void spapr_vio_quiesce(void);
+
 #endif /* _HW_SPAPR_VIO_H */

From ed120055c7f9b26b5707d3ceabbe5a3f06aaf937 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:33 +1100
Subject: [PATCH 031/386] Implement PAPR VPA functions for pSeries shared
 processor partitions

Shared-processor partitions are those where a CPU is time-sliced between
partitions, rather than being permanently dedicated to a single
partition.  qemu emulated partitions, since they are just scheduled with
the qemu user process, behave mostly like shared processor partitions.

In order to better support shared processor partitions (splpar), PAPR
defines the "VPA" (Virtual Processor Area), a shared memory communication
channel between the hypervisor and partitions.  There are also two
additional shared memory communication areas for specialized purposes
associated with the VPA.

A VPA is not essential for operating an splpar, though it can be necessary
for obtaining accurate performance measurements in the presence of
runtime partition switching.

Most importantly, however, the VPA is a prerequisite for PAPR's H_CEDE,
hypercall, which allows a partition OS to give up it's shared processor
timeslices to other partitions when idle.

This patch implements the VPA and H_CEDE hypercalls in qemu.  We don't
implement any of the more advanced statistics which can be communicated
through the VPA.  However, this is enough to make normal pSeries kernels
do an effective power-save idle on an emulated pSeries, significantly
reducing the host load of a qemu emulated pSeries running an idle guest OS.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/spapr.c       |   2 +-
 hw/spapr_hcall.c | 192 +++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/cpu.h |   7 ++
 3 files changed, 200 insertions(+), 1 deletion(-)

diff --git a/hw/spapr.c b/hw/spapr.c
index 3bffaabe86..876768631b 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -68,7 +68,7 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
     uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
     uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)};
     char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt"
-        "\0hcall-tce\0hcall-vio";
+        "\0hcall-tce\0hcall-vio\0hcall-splpar";
     uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
     int i;
     char *modelname;
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index a47a97ba55..f88e1d2083 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -4,6 +4,8 @@
 #include "sysemu.h"
 #include "qemu-char.h"
 #include "exec-all.h"
+#include "exec.h"
+#include "helper_regs.h"
 #include "hw/spapr.h"
 
 #define HPTES_PER_GROUP 8
@@ -255,6 +257,192 @@ static target_ulong h_set_dabr(CPUState *env, sPAPREnvironment *spapr,
     return H_HARDWARE;
 }
 
+#define FLAGS_REGISTER_VPA         0x0000200000000000ULL
+#define FLAGS_REGISTER_DTL         0x0000400000000000ULL
+#define FLAGS_REGISTER_SLBSHADOW   0x0000600000000000ULL
+#define FLAGS_DEREGISTER_VPA       0x0000a00000000000ULL
+#define FLAGS_DEREGISTER_DTL       0x0000c00000000000ULL
+#define FLAGS_DEREGISTER_SLBSHADOW 0x0000e00000000000ULL
+
+#define VPA_MIN_SIZE           640
+#define VPA_SIZE_OFFSET        0x4
+#define VPA_SHARED_PROC_OFFSET 0x9
+#define VPA_SHARED_PROC_VAL    0x2
+
+static target_ulong register_vpa(CPUState *env, target_ulong vpa)
+{
+    uint16_t size;
+    uint8_t tmp;
+
+    if (vpa == 0) {
+        hcall_dprintf("Can't cope with registering a VPA at logical 0\n");
+        return H_HARDWARE;
+    }
+
+    if (vpa % env->dcache_line_size) {
+        return H_PARAMETER;
+    }
+    /* FIXME: bounds check the address */
+
+    size = lduw_phys(vpa + 0x4);
+
+    if (size < VPA_MIN_SIZE) {
+        return H_PARAMETER;
+    }
+
+    /* VPA is not allowed to cross a page boundary */
+    if ((vpa / 4096) != ((vpa + size - 1) / 4096)) {
+        return H_PARAMETER;
+    }
+
+    env->vpa = vpa;
+
+    tmp = ldub_phys(env->vpa + VPA_SHARED_PROC_OFFSET);
+    tmp |= VPA_SHARED_PROC_VAL;
+    stb_phys(env->vpa + VPA_SHARED_PROC_OFFSET, tmp);
+
+    return H_SUCCESS;
+}
+
+static target_ulong deregister_vpa(CPUState *env, target_ulong vpa)
+{
+    if (env->slb_shadow) {
+        return H_RESOURCE;
+    }
+
+    if (env->dispatch_trace_log) {
+        return H_RESOURCE;
+    }
+
+    env->vpa = 0;
+    return H_SUCCESS;
+}
+
+static target_ulong register_slb_shadow(CPUState *env, target_ulong addr)
+{
+    uint32_t size;
+
+    if (addr == 0) {
+        hcall_dprintf("Can't cope with SLB shadow at logical 0\n");
+        return H_HARDWARE;
+    }
+
+    size = ldl_phys(addr + 0x4);
+    if (size < 0x8) {
+        return H_PARAMETER;
+    }
+
+    if ((addr / 4096) != ((addr + size - 1) / 4096)) {
+        return H_PARAMETER;
+    }
+
+    if (!env->vpa) {
+        return H_RESOURCE;
+    }
+
+    env->slb_shadow = addr;
+
+    return H_SUCCESS;
+}
+
+static target_ulong deregister_slb_shadow(CPUState *env, target_ulong addr)
+{
+    env->slb_shadow = 0;
+    return H_SUCCESS;
+}
+
+static target_ulong register_dtl(CPUState *env, target_ulong addr)
+{
+    uint32_t size;
+
+    if (addr == 0) {
+        hcall_dprintf("Can't cope with DTL at logical 0\n");
+        return H_HARDWARE;
+    }
+
+    size = ldl_phys(addr + 0x4);
+
+    if (size < 48) {
+        return H_PARAMETER;
+    }
+
+    if (!env->vpa) {
+        return H_RESOURCE;
+    }
+
+    env->dispatch_trace_log = addr;
+    env->dtl_size = size;
+
+    return H_SUCCESS;
+}
+
+static target_ulong deregister_dtl(CPUState *emv, target_ulong addr)
+{
+    env->dispatch_trace_log = 0;
+    env->dtl_size = 0;
+
+    return H_SUCCESS;
+}
+
+static target_ulong h_register_vpa(CPUState *env, sPAPREnvironment *spapr,
+                                   target_ulong opcode, target_ulong *args)
+{
+    target_ulong flags = args[0];
+    target_ulong procno = args[1];
+    target_ulong vpa = args[2];
+    target_ulong ret = H_PARAMETER;
+    CPUState *tenv;
+
+    for (tenv = first_cpu; tenv; tenv = tenv->next_cpu) {
+        if (tenv->cpu_index == procno) {
+            break;
+        }
+    }
+
+    if (!tenv) {
+        return H_PARAMETER;
+    }
+
+    switch (flags) {
+    case FLAGS_REGISTER_VPA:
+        ret = register_vpa(tenv, vpa);
+        break;
+
+    case FLAGS_DEREGISTER_VPA:
+        ret = deregister_vpa(tenv, vpa);
+        break;
+
+    case FLAGS_REGISTER_SLBSHADOW:
+        ret = register_slb_shadow(tenv, vpa);
+        break;
+
+    case FLAGS_DEREGISTER_SLBSHADOW:
+        ret = deregister_slb_shadow(tenv, vpa);
+        break;
+
+    case FLAGS_REGISTER_DTL:
+        ret = register_dtl(tenv, vpa);
+        break;
+
+    case FLAGS_DEREGISTER_DTL:
+        ret = deregister_dtl(tenv, vpa);
+        break;
+    }
+
+    return ret;
+}
+
+static target_ulong h_cede(CPUState *env, sPAPREnvironment *spapr,
+                           target_ulong opcode, target_ulong *args)
+{
+    env->msr |= (1ULL << MSR_EE);
+    hreg_compute_hflags(env);
+    if (!cpu_has_work(env)) {
+        env->halted = 1;
+    }
+    return H_SUCCESS;
+}
+
 static target_ulong h_rtas(CPUState *env, sPAPREnvironment *spapr,
                            target_ulong opcode, target_ulong *args)
 {
@@ -327,6 +515,10 @@ static void hypercall_init(void)
     /* hcall-dabr */
     spapr_register_hypercall(H_SET_DABR, h_set_dabr);
 
+    /* hcall-splpar */
+    spapr_register_hypercall(H_REGISTER_VPA, h_register_vpa);
+    spapr_register_hypercall(H_CEDE, h_cede);
+
     /* qemu/KVM-PPC specific hcalls */
     spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
 }
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index b4c2555626..04b12590fa 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -721,6 +721,13 @@ struct CPUPPCState {
     uint32_t flags;
     uint64_t insns_flags;
 
+#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
+    target_phys_addr_t vpa;
+    target_phys_addr_t slb_shadow;
+    target_phys_addr_t dispatch_trace_log;
+    uint32_t dtl_size;
+#endif /* TARGET_PPC64 */
+
     int error_code;
     uint32_t pending_interrupts;
 #if !defined(CONFIG_USER_ONLY)

From a9f8ad8f2acdb2398da5d32a5efc19cb0196d79f Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 1 Apr 2011 15:15:34 +1100
Subject: [PATCH 032/386] Add SLOF-based partition firmware for pSeries
 machine, allowing more boot options

Currently, the emulated pSeries machine requires the use of the
-kernel parameter in order to explicitly load a guest kernel.  This
means booting from the virtual disk, cdrom or network is not possible.

This patch addresses this limitation by inserting a within-partition
firmware image (derived from the "SLOF" free Open Firmware project).
If -kernel is not specified, qemu will now load the SLOF image, which
has access to the qemu boot device list through the device tree, and
can boot from any of the usual virtual devices.

In order to support the new firmware, an extension to the emulated
machine/hypervisor is necessary.  Unlike Linux, which expects
multi-CPU entry to be handled kexec() style, the SLOF firmware expects
only one CPU to be active at entry, and to use a hypervisor RTAS
method to enable the other CPUs one by one.

This patch also implements this 'start-cpu' method, so that SLOF can
start the secondary CPUs and marshal them into the kexec() holding
pattern ready for entry into the guest OS.  Linux should, and in the
future might directly use the start-cpu method to enable initially
disabled CPUs, but for now it does require kexec() entry.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 .gitmodules      |   3 ++
 Makefile         |   2 +-
 hw/spapr.c       |  35 ++++++++++++++++++---
 hw/spapr_rtas.c  |  78 +++++++++++++++++++++++++++++++++++++++++++++++
 pc-bios/README   |   5 +++
 pc-bios/slof.bin | Bin 0 -> 579072 bytes
 roms/SLOF        |   1 +
 7 files changed, 119 insertions(+), 5 deletions(-)
 create mode 100644 pc-bios/slof.bin
 create mode 160000 roms/SLOF

diff --git a/.gitmodules b/.gitmodules
index 5217ce7d1c..44fdd1a02d 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,3 +4,6 @@
 [submodule "roms/seabios"]
 	path = roms/seabios
 	url = git://git.qemu.org/seabios.git/
+[submodule "roms/SLOF"]
+	path = roms/SLOF
+	url = git://git.qemu.org/SLOF.git
diff --git a/Makefile b/Makefile
index e0b3fea6bc..989622b388 100644
--- a/Makefile
+++ b/Makefile
@@ -214,7 +214,7 @@ pxe-rtl8139.bin pxe-virtio.bin \
 bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
 multiboot.bin linuxboot.bin \
 s390-zipl.rom \
-spapr-rtas.bin
+spapr-rtas.bin slof.bin
 else
 BLOBS=
 endif
diff --git a/hw/spapr.c b/hw/spapr.c
index 876768631b..1152a25b2e 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -44,6 +44,10 @@
 #define INITRD_LOAD_ADDR        0x02800000
 #define FDT_MAX_SIZE            0x10000
 #define RTAS_MAX_SIZE           0x10000
+#define FW_MAX_SIZE             0x400000
+#define FW_FILE_NAME            "slof.bin"
+
+#define MIN_RAM_SLOF		512UL
 
 #define TIMEBASE_FREQ           512000000ULL
 
@@ -57,6 +61,7 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
                               sPAPREnvironment *spapr,
                               target_phys_addr_t initrd_base,
                               target_phys_addr_t initrd_size,
+                              const char *boot_device,
                               const char *kernel_cmdline,
                               target_phys_addr_t rtas_addr,
                               target_phys_addr_t rtas_size,
@@ -105,6 +110,7 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
                        &start_prop, sizeof(start_prop))));
     _FDT((fdt_property(fdt, "linux,initrd-end",
                        &end_prop, sizeof(end_prop))));
+    _FDT((fdt_property_string(fdt, "qemu,boot-device", boot_device)));
 
     _FDT((fdt_end_node(fdt)));
 
@@ -261,7 +267,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
     ram_addr_t ram_offset;
     target_phys_addr_t fdt_addr, rtas_addr;
     uint32_t kernel_base, initrd_base;
-    long kernel_size, initrd_size, htab_size, rtas_size;
+    long kernel_size, initrd_size, htab_size, rtas_size, fw_size;
     long pteg_shift = 17;
     int fdt_size;
     char *filename;
@@ -392,13 +398,33 @@ static void ppc_spapr_init(ram_addr_t ram_size,
             initrd_size = 0;
         }
     } else {
-        fprintf(stderr, "pSeries machine needs -kernel for now");
-        exit(1);
+        if (ram_size < (MIN_RAM_SLOF << 20)) {
+            fprintf(stderr, "qemu: pSeries SLOF firmware requires >= "
+                    "%ldM guest RAM\n", MIN_RAM_SLOF);
+            exit(1);
+        }
+        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "slof.bin");
+        fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
+        if (fw_size < 0) {
+            hw_error("qemu: could not load LPAR rtas '%s'\n", filename);
+            exit(1);
+        }
+        qemu_free(filename);
+        kernel_base = 0x100;
+        initrd_base = 0;
+        initrd_size = 0;
+
+        /* SLOF will startup the secondary CPUs using RTAS,
+           rather than expecting a kexec() style entry */
+        for (i = 0; i < smp_cpus; i++) {
+            envs[i]->halted = 1;
+        }
     }
 
     /* Prepare the device tree */
     fdt = spapr_create_fdt(&fdt_size, ram_size, cpu_model, envs, spapr,
-                           initrd_base, initrd_size, kernel_cmdline,
+                           initrd_base, initrd_size,
+                           boot_device, kernel_cmdline,
                            rtas_addr, rtas_size, pteg_shift + 7);
     assert(fdt != NULL);
 
@@ -409,6 +435,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
     envs[0]->gpr[3] = fdt_addr;
     envs[0]->gpr[5] = 0;
     envs[0]->hreset_vector = kernel_base;
+    envs[0]->halted = 0;
 }
 
 static QEMUMachine spapr_machine = {
diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c
index 72268537a8..16b65422b6 100644
--- a/hw/spapr_rtas.c
+++ b/hw/spapr_rtas.c
@@ -90,6 +90,81 @@ static void rtas_power_off(sPAPREnvironment *spapr,
     rtas_st(rets, 0, 0);
 }
 
+static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr,
+                                         uint32_t token, uint32_t nargs,
+                                         target_ulong args,
+                                         uint32_t nret, target_ulong rets)
+{
+    target_ulong id;
+    CPUState *env;
+
+    if (nargs != 1 || nret != 2) {
+        rtas_st(rets, 0, -3);
+        return;
+    }
+
+    id = rtas_ld(args, 0);
+    for (env = first_cpu; env; env = env->next_cpu) {
+        if (env->cpu_index != id) {
+            continue;
+        }
+
+        if (env->halted) {
+            rtas_st(rets, 1, 0);
+        } else {
+            rtas_st(rets, 1, 2);
+        }
+
+        rtas_st(rets, 0, 0);
+        return;
+    }
+
+    /* Didn't find a matching cpu */
+    rtas_st(rets, 0, -3);
+}
+
+static void rtas_start_cpu(sPAPREnvironment *spapr,
+                           uint32_t token, uint32_t nargs,
+                           target_ulong args,
+                           uint32_t nret, target_ulong rets)
+{
+    target_ulong id, start, r3;
+    CPUState *env;
+
+    if (nargs != 3 || nret != 1) {
+        rtas_st(rets, 0, -3);
+        return;
+    }
+
+    id = rtas_ld(args, 0);
+    start = rtas_ld(args, 1);
+    r3 = rtas_ld(args, 2);
+
+    for (env = first_cpu; env; env = env->next_cpu) {
+        if (env->cpu_index != id) {
+            continue;
+        }
+
+        if (!env->halted) {
+            rtas_st(rets, 0, -1);
+            return;
+        }
+
+        env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
+        env->nip = start;
+        env->gpr[3] = r3;
+        env->halted = 0;
+
+        qemu_cpu_kick(env);
+
+        rtas_st(rets, 0, 0);
+        return;
+    }
+
+    /* Didn't find a matching cpu */
+    rtas_st(rets, 0, -3);
+}
+
 static struct rtas_call {
     const char *name;
     spapr_rtas_fn fn;
@@ -196,5 +271,8 @@ static void register_core_rtas(void)
     spapr_rtas_register("display-character", rtas_display_character);
     spapr_rtas_register("get-time-of-day", rtas_get_time_of_day);
     spapr_rtas_register("power-off", rtas_power_off);
+    spapr_rtas_register("query-cpu-stopped-state",
+                        rtas_query_cpu_stopped_state);
+    spapr_rtas_register("start-cpu", rtas_start_cpu);
 }
 device_init(register_core_rtas);
diff --git a/pc-bios/README b/pc-bios/README
index 3fc09449fa..646a31a313 100644
--- a/pc-bios/README
+++ b/pc-bios/README
@@ -13,6 +13,11 @@
   The included image for PowerPC (for 32 and 64 bit PPC CPUs), Sparc32
   and Sparc64 are built from OpenBIOS SVN revision 1018.
 
+- SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware
+  implementation for certain IBM POWER hardware.  The sources are at
+  https://github.com/dgibson/SLOF, and the image currently in qemu is
+  built from git tag qemu-slof-20110323.
+
 - The PXE roms come from Rom-o-Matic gPXE 0.9.9 with BANNER_TIMEOUT=0
 
   e1000 8086:100E
diff --git a/pc-bios/slof.bin b/pc-bios/slof.bin
new file mode 100644
index 0000000000000000000000000000000000000000..22c4c7f5c448e3002aefecf3438f5d080586d666
GIT binary patch
literal 579072
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

literal 0
HcmV?d00001

diff --git a/roms/SLOF b/roms/SLOF
new file mode 160000
index 0000000000..d1d6b53b71
--- /dev/null
+++ b/roms/SLOF
@@ -0,0 +1 @@
+Subproject commit d1d6b53b713a2b7c2c25685268fa932d28a4b4c0

From d818bfc5c34c59e9c6d03b3b9983bb5435967292 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Fri, 1 Apr 2011 20:04:24 +0200
Subject: [PATCH 033/386] pc-bios/spapr-rtas.bin: remove executable flag

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 pc-bios/spapr-rtas.bin | Bin
 1 file changed, 0 insertions(+), 0 deletions(-)
 mode change 100755 => 100644 pc-bios/spapr-rtas.bin

diff --git a/pc-bios/spapr-rtas.bin b/pc-bios/spapr-rtas.bin
old mode 100755
new mode 100644

From 09cec717bfaaaabd4c2789e480626ce70fdab204 Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Wed, 16 Feb 2011 21:15:40 +0100
Subject: [PATCH 034/386] ui/sdl: Load optional QEMU icon

Load an optional QEMU icon file. If there is no icon file named
qemu.bmp in QEMU's default search path, QEMU will run with
the usual system default icon.

A matching icon file  will be loaded and used by X Windows managers
or MS Windows while a QEMU instance is running.

SDL requires icon files in 32x32x4 bmp format.

Cc: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 ui/sdl.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/ui/sdl.c b/ui/sdl.c
index c5bb0a3705..dc5c3a1bc2 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -812,6 +812,7 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
     uint8_t data = 0;
     DisplayAllocator *da;
     const SDL_VideoInfo *vi;
+    char *filename;
 
 #if defined(__APPLE__)
     /* always use generic keymaps */
@@ -844,6 +845,18 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
     vi = SDL_GetVideoInfo();
     host_format = *(vi->vfmt);
 
+    /* Load a 32x32x4 image. White pixels are transparent. */
+    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "qemu-icon.bmp");
+    if (filename) {
+        SDL_Surface *image = SDL_LoadBMP(filename);
+        if (image) {
+            uint32_t colorkey = SDL_MapRGB(image->format, 255, 255, 255);
+            SDL_SetColorKey(image, SDL_SRCCOLORKEY, colorkey);
+            SDL_WM_SetIcon(image, NULL);
+        }
+        qemu_free(filename);
+    }
+
     dcl = qemu_mallocz(sizeof(DisplayChangeListener));
     dcl->dpy_update = sdl_update;
     dcl->dpy_resize = sdl_resize;

From 59df4c11560fb5da9071b5ab5c4607055fbe927a Mon Sep 17 00:00:00 2001
From: Wen Congyang <wency@cn.fujitsu.com>
Date: Mon, 28 Feb 2011 10:22:33 +0800
Subject: [PATCH 035/386] fix build errors when we enable acpi_piix4 debug
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

I enable acpi_piix4 debug, and got the following build errors:
# make
  CC    libhw64/acpi_piix4.o
cc1: warnings being treated as errors
/home/wency/source/qemu/hw/acpi_piix4.c: In function ‘pm_ioport_write’:
/home/wency/source/qemu/hw/acpi_piix4.c:193: error: format ‘%04x’ expects type ‘unsigned int’, but argument 2 has type ‘uint64_t’
/home/wency/source/qemu/hw/acpi_piix4.c:193: error: format ‘%04x’ expects type ‘unsigned int’, but argument 3 has type ‘uint64_t’
/home/wency/source/qemu/hw/acpi_piix4.c: In function ‘pm_ioport_read’:
/home/wency/source/qemu/hw/acpi_piix4.c:219: error: format ‘%04x’ expects type ‘unsigned int’, but argument 2 has type ‘uint64_t’
make[1]: *** [acpi_piix4.o] Error 1
make: *** [subdir-libhw64] Error 2

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/acpi_piix4.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 0b2bc97cf1..74044ddd9b 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -190,7 +190,8 @@ static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width,
     default:
         break;
     }
-    PIIX4_DPRINTF("PM writew port=0x%04x val=0x%04x\n", addr, val);
+    PIIX4_DPRINTF("PM writew port=0x%04x val=0x%04x\n", (unsigned int)addr,
+                  (unsigned int)val);
 }
 
 static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width,
@@ -216,7 +217,7 @@ static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width,
         val = 0;
         break;
     }
-    PIIX4_DPRINTF("PM readw port=0x%04x val=0x%04x\n", addr, val);
+    PIIX4_DPRINTF("PM readw port=0x%04x val=0x%04x\n", (unsigned int)addr, val);
     *data = val;
 }
 

From 508240c0daecdd62ab46727f37145f2dbb029ff7 Mon Sep 17 00:00:00 2001
From: Bernhard Kohl <bernhard.kohl@nsn.com>
Date: Mon, 6 Sep 2010 04:42:54 +0000
Subject: [PATCH 036/386] lsi53c895a: add support for ABORT messages

If these messages are not handled correctly the guest driver may hang.

Always mandatory:
- ABORT
- BUS DEVICE RESET

Mandatory if tagged queuing is implemented (which disks usually do):
- ABORT TAG
- CLEAR QUEUE

Signed-off-by: Bernhard Kohl <bernhard.kohl@nsn.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/lsi53c895a.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 84a49928dc..e4b51a8eaf 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -853,6 +853,18 @@ static void lsi_do_msgout(LSIState *s)
 {
     uint8_t msg;
     int len;
+    uint32_t current_tag;
+    SCSIDevice *current_dev;
+    lsi_request *p, *p_next;
+    int id;
+
+    if (s->current) {
+        current_tag = s->current->tag;
+    } else {
+        current_tag = s->select_tag;
+    }
+    id = (current_tag >> 8) & 0xf;
+    current_dev = s->bus.devs[id];
 
     DPRINTF("MSG out len=%d\n", s->dbc);
     while (s->dbc) {
@@ -898,6 +910,51 @@ static void lsi_do_msgout(LSIState *s)
             BADF("ORDERED queue not implemented\n");
             s->select_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID;
             break;
+        case 0x0d:
+            /* The ABORT TAG message clears the current I/O process only. */
+            DPRINTF("MSG: ABORT TAG tag=0x%x\n", current_tag);
+            current_dev->info->cancel_io(current_dev, current_tag);
+            lsi_disconnect(s);
+            break;
+        case 0x06:
+        case 0x0e:
+        case 0x0c:
+            /* The ABORT message clears all I/O processes for the selecting
+               initiator on the specified logical unit of the target. */
+            if (msg == 0x06) {
+                DPRINTF("MSG: ABORT tag=0x%x\n", current_tag);
+            }
+            /* The CLEAR QUEUE message clears all I/O processes for all
+               initiators on the specified logical unit of the target. */
+            if (msg == 0x0e) {
+                DPRINTF("MSG: CLEAR QUEUE tag=0x%x\n", current_tag);
+            }
+            /* The BUS DEVICE RESET message clears all I/O processes for all
+               initiators on all logical units of the target. */
+            if (msg == 0x0c) {
+                DPRINTF("MSG: BUS DEVICE RESET tag=0x%x\n", current_tag);
+            }
+
+            /* clear the current I/O process */
+            current_dev->info->cancel_io(current_dev, current_tag);
+
+            /* As the current implemented devices scsi_disk and scsi_generic
+               only support one LUN, we don't need to keep track of LUNs.
+               Clearing I/O processes for other initiators could be possible
+               for scsi_generic by sending a SG_SCSI_RESET to the /dev/sgX
+               device, but this is currently not implemented (and seems not
+               to be really necessary). So let's simply clear all queued
+               commands for the current device: */
+            id = current_tag & 0x0000ff00;
+            QTAILQ_FOREACH_SAFE(p, &s->queue, next, p_next) {
+                if ((p->tag & 0x0000ff00) == id) {
+                    current_dev->info->cancel_io(current_dev, p->tag);
+                    QTAILQ_REMOVE(&s->queue, p, next);
+                }
+            }
+
+            lsi_disconnect(s);
+            break;
         default:
             if ((msg & 0x80) == 0) {
                 goto bad;

From 8cffde7329734c17ee2eeec84944abbf4a0f23f3 Mon Sep 17 00:00:00 2001
From: Michael Tokarev <mjt@tls.msk.ru>
Date: Thu, 10 Mar 2011 17:03:41 +0300
Subject: [PATCH 037/386] get rid of private bitmap functions in
 block/sheepdog.c, use generic ones

qemu now has generic bitmap functions,
so don't redefine them in sheepdog.c,
use common header instead.  A small cleanup.

Here's only one function which is actually
used in sheepdog and gets replaced with
a generic one (simplified):

- static inline int test_bit(int nr, const volatile unsigned long *addr)
+ static inline int test_bit(int nr, const unsigned long *addr)
 {
-  return ((1UL << (nr % BITS_PER_LONG))
            & ((unsigned long*)addr)[nr / BITS_PER_LONG])) != 0;
+  return 1UL & (addr[nr / BITS_PER_LONG] >> (nr & (BITS_PER_LONG-1)));
 }

The body is equivalent, but the argument is not: there's
"volatile" in there.  Why it is used for - I'm not sure.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Acked-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 block/sheepdog.c | 15 +--------------
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/block/sheepdog.c b/block/sheepdog.c
index a54e0dee31..98946d72b7 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -13,6 +13,7 @@
 #include "qemu-error.h"
 #include "qemu_socket.h"
 #include "block_int.h"
+#include "bitops.h"
 
 #define SD_PROTO_VER 0x01
 
@@ -1829,20 +1830,6 @@ static int sd_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
     return 0;
 }
 
-#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
-#define BITS_PER_BYTE        8
-#define BITS_TO_LONGS(nr)    DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
-#define DECLARE_BITMAP(name,bits)               \
-    unsigned long name[BITS_TO_LONGS(bits)]
-
-#define BITS_PER_LONG (BITS_PER_BYTE * sizeof(long))
-
-static inline int test_bit(unsigned int nr, const unsigned long *addr)
-{
-    return ((1UL << (nr % BITS_PER_LONG)) &
-            (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0;
-}
-
 static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
 {
     BDRVSheepdogState *s = bs->opaque;

From ee7495d3a9304942ad75f07713b565db25352411 Mon Sep 17 00:00:00 2001
From: Leszek Grzegorek <leszek.grzegorek@gmail.com>
Date: Mon, 14 Mar 2011 10:30:08 +0100
Subject: [PATCH 038/386] vnc: added missing name->keysym pairs for Polish
 national characters

There are no { name, keysym } values in name2keysym[] array for Polish
national characters so "-k pl" option has no effect.

Signed-off-by: Leszek Grzegorek <leszek.grzegorek@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 ui/vnc_keysym.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/ui/vnc_keysym.h b/ui/vnc_keysym.h
index 55cb87edec..df33cfe53c 100644
--- a/ui/vnc_keysym.h
+++ b/ui/vnc_keysym.h
@@ -202,6 +202,24 @@ static const name2keysym_t name2keysym[]={
 { "ydiaeresis",           0x0ff},
 {"EuroSign", 0x20ac},  /* XK_EuroSign */
 
+/* latin 2 - Polish national characters */
+{ "eogonek",              0x1ea},
+{ "Eogonek",              0x1ca},
+{ "aogonek",              0x1b1},
+{ "Aogonek",              0x1a1},
+{ "sacute",               0x1b6},
+{ "Sacute",               0x1a6},
+{ "lstroke",              0x1b3},
+{ "Lstroke",              0x1a3},
+{ "zabovedot",            0x1bf},
+{ "Zabovedot",            0x1af},
+{ "zacute",               0x1bc},
+{ "Zacute",               0x1ac},
+{ "cacute",               0x1e6},
+{ "Cacute",               0x1c6},
+{ "nacute",               0x1f1},
+{ "Nacute",               0x1d1},
+
     /* modifiers */
 {"ISO_Level3_Shift", 0xfe03}, /* XK_ISO_Level3_Shift */
 {"Control_L", 0xffe3}, /* XK_Control_L */

From ac60cc18711a9786af9844d7e3d002276fbd85f3 Mon Sep 17 00:00:00 2001
From: Tristan Gingold <gingold@adacore.com>
Date: Tue, 15 Mar 2011 14:20:54 +0100
Subject: [PATCH 039/386] Fix net_check_clients warnings: make it per vlan.

Signed-off-by: Tristan Gingold <gingold@adacore.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 net.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net.c b/net.c
index ddcca9752d..b2dfaa8085 100644
--- a/net.c
+++ b/net.c
@@ -1305,9 +1305,10 @@ void net_check_clients(void)
 {
     VLANState *vlan;
     VLANClientState *vc;
-    int has_nic = 0, has_host_dev = 0;
 
     QTAILQ_FOREACH(vlan, &vlans, next) {
+        int has_nic = 0, has_host_dev = 0;
+
         QTAILQ_FOREACH(vc, &vlan->clients, next) {
             switch (vc->info->type) {
             case NET_CLIENT_TYPE_NIC:

From 8e18cde30b06d2e7411bf38091c4e30602f85cdd Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Tue, 15 Mar 2011 16:26:51 +0000
Subject: [PATCH 040/386] target-arm: Fix VLD of single element to all lanes

Fix several bugs in VLD of single element to all lanes:

The "single element to all lanes" form of VLD1 differs from those for
VLD2, VLD3 and VLD4 in that bit 5 indicates whether the loaded element
should be written to one or two Dregs (rather than being a register
stride). Handle this by special-casing VLD1 rather than trying to
have one loop which deals with both VLD1 and 2/3/4.

Handle VLD4.32 with 16 byte alignment specified, rather than UNDEFfing.

UNDEF for the invalid size and alignment combinations.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 84 +++++++++++++++++++++++++++++-------------
 1 file changed, 59 insertions(+), 25 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index f69912f20c..1dfd4823f5 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -2648,6 +2648,28 @@ static void gen_neon_dup_high16(TCGv var)
     tcg_temp_free_i32(tmp);
 }
 
+static TCGv gen_load_and_replicate(DisasContext *s, TCGv addr, int size)
+{
+    /* Load a single Neon element and replicate into a 32 bit TCG reg */
+    TCGv tmp;
+    switch (size) {
+    case 0:
+        tmp = gen_ld8u(addr, IS_USER(s));
+        gen_neon_dup_u8(tmp, 0);
+        break;
+    case 1:
+        tmp = gen_ld16u(addr, IS_USER(s));
+        gen_neon_dup_low16(tmp);
+        break;
+    case 2:
+        tmp = gen_ld32(addr, IS_USER(s));
+        break;
+    default: /* Avoid compiler warnings.  */
+        abort();
+    }
+    return tmp;
+}
+
 /* Disassemble a VFP instruction.  Returns nonzero if an error occured
    (ie. an undefined instruction).  */
 static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
@@ -3890,36 +3912,48 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
         size = (insn >> 10) & 3;
         if (size == 3) {
             /* Load single element to all lanes.  */
-            if (!load)
+            int a = (insn >> 4) & 1;
+            if (!load) {
                 return 1;
+            }
             size = (insn >> 6) & 3;
             nregs = ((insn >> 8) & 3) + 1;
-            stride = (insn & (1 << 5)) ? 2 : 1;
-            load_reg_var(s, addr, rn);
-            for (reg = 0; reg < nregs; reg++) {
-                switch (size) {
-                case 0:
-                    tmp = gen_ld8u(addr, IS_USER(s));
-                    gen_neon_dup_u8(tmp, 0);
-                    break;
-                case 1:
-                    tmp = gen_ld16u(addr, IS_USER(s));
-                    gen_neon_dup_low16(tmp);
-                    break;
-                case 2:
-                    tmp = gen_ld32(addr, IS_USER(s));
-                    break;
-                case 3:
+
+            if (size == 3) {
+                if (nregs != 4 || a == 0) {
                     return 1;
-                default: /* Avoid compiler warnings.  */
-                    abort();
                 }
-                tcg_gen_addi_i32(addr, addr, 1 << size);
-                tmp2 = tcg_temp_new_i32();
-                tcg_gen_mov_i32(tmp2, tmp);
-                neon_store_reg(rd, 0, tmp2);
-                neon_store_reg(rd, 1, tmp);
-                rd += stride;
+                /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
+                size = 2;
+            }
+            if (nregs == 1 && a == 1 && size == 0) {
+                return 1;
+            }
+            if (nregs == 3 && a == 1) {
+                return 1;
+            }
+            load_reg_var(s, addr, rn);
+            if (nregs == 1) {
+                /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
+                tmp = gen_load_and_replicate(s, addr, size);
+                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
+                tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
+                if (insn & (1 << 5)) {
+                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
+                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
+                }
+                tcg_temp_free_i32(tmp);
+            } else {
+                /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
+                stride = (insn & (1 << 5)) ? 2 : 1;
+                for (reg = 0; reg < nregs; reg++) {
+                    tmp = gen_load_and_replicate(s, addr, size);
+                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
+                    tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
+                    tcg_temp_free_i32(tmp);
+                    tcg_gen_addi_i32(addr, addr, 1 << size);
+                    rd += stride;
+                }
             }
             stride = (1 << size) * nregs;
         } else {

From e318a60b94b152c1e80125861a8917ae177d845e Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Tue, 15 Mar 2011 16:26:52 +0000
Subject: [PATCH 041/386] target-arm: Don't leak TCG temp for UNDEFs in Neon
 load/store space

Move the allocation and freeing of the TCG temp used for the address for
Neon load/store instructions so that we don't allocate the temporary
until we've done enough decoding to know that the instruction is not
an UNDEF pattern; this avoids leaking the TCG temp in these cases.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 1dfd4823f5..39512bc62f 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3810,7 +3810,6 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
     rn = (insn >> 16) & 0xf;
     rm = insn & 0xf;
     load = (insn & (1 << 21)) != 0;
-    addr = tcg_temp_new_i32();
     if ((insn & (1 << 23)) == 0) {
         /* Load store all elements.  */
         op = (insn >> 8) & 0xf;
@@ -3822,6 +3821,7 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
         spacing = neon_ls_element_type[op].spacing;
         if (size == 3 && (interleave | spacing) != 1)
             return 1;
+        addr = tcg_temp_new_i32();
         load_reg_var(s, addr, rn);
         stride = (1 << size) * interleave;
         for (reg = 0; reg < nregs; reg++) {
@@ -3907,6 +3907,7 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
             }
             rd += spacing;
         }
+        tcg_temp_free_i32(addr);
         stride = nregs * 8;
     } else {
         size = (insn >> 10) & 3;
@@ -3932,6 +3933,7 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
             if (nregs == 3 && a == 1) {
                 return 1;
             }
+            addr = tcg_temp_new_i32();
             load_reg_var(s, addr, rn);
             if (nregs == 1) {
                 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
@@ -3955,6 +3957,7 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
                     rd += stride;
                 }
             }
+            tcg_temp_free_i32(addr);
             stride = (1 << size) * nregs;
         } else {
             /* Single element.  */
@@ -3976,6 +3979,7 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 abort();
             }
             nregs = ((insn >> 8) & 3) + 1;
+            addr = tcg_temp_new_i32();
             load_reg_var(s, addr, rn);
             for (reg = 0; reg < nregs; reg++) {
                 if (load) {
@@ -4017,10 +4021,10 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 rd += stride;
                 tcg_gen_addi_i32(addr, addr, 1 << size);
             }
+            tcg_temp_free_i32(addr);
             stride = nregs * (1 << size);
         }
     }
-    tcg_temp_free_i32(addr);
     if (rm != 15) {
         TCGv base;
 

From 366c9332450caace5843c17806ba4879bf2d005c Mon Sep 17 00:00:00 2001
From: Michael Brown <mcb30@ipxe.org>
Date: Tue, 15 Mar 2011 10:47:22 -0600
Subject: [PATCH 042/386] pcnet: Fix sign extension: make ipxe work with >2G
 RAM

The problem is with definitions in hw/pcnet.c such as:

  #define CSR_CRDA(S)      ((S)->csr[28] | ((S)->csr[29] << 16))

"(S)->csr[29]" is a uint16_t, but "(S)->csr[29] << 16" gets promoted to
int, so the overall CSR_CRDA(s) is a (signed) int rather than a uint32_t.

This then gets assigned to a uint64_t using

  target_phys_addr_t crda = CSR_CRDA(s);

so when (S)->csr[29] has the high bit set, we end up with
crda=0xffffffffxxxxxxxx.

From: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/pcnet.c | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/hw/pcnet.c b/hw/pcnet.c
index 82ccbbd2c3..cf16fd4d01 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -113,23 +113,23 @@ struct qemu_ether_header {
 #define CSR_XMTRL(S)     ((S)->csr[78])
 #define CSR_MISSC(S)     ((S)->csr[112])
 
-#define CSR_IADR(S)      ((S)->csr[ 1] | ((S)->csr[ 2] << 16))
-#define CSR_CRBA(S)      ((S)->csr[18] | ((S)->csr[19] << 16))
-#define CSR_CXBA(S)      ((S)->csr[20] | ((S)->csr[21] << 16))
-#define CSR_NRBA(S)      ((S)->csr[22] | ((S)->csr[23] << 16))
-#define CSR_BADR(S)      ((S)->csr[24] | ((S)->csr[25] << 16))
-#define CSR_NRDA(S)      ((S)->csr[26] | ((S)->csr[27] << 16))
-#define CSR_CRDA(S)      ((S)->csr[28] | ((S)->csr[29] << 16))
-#define CSR_BADX(S)      ((S)->csr[30] | ((S)->csr[31] << 16))
-#define CSR_NXDA(S)      ((S)->csr[32] | ((S)->csr[33] << 16))
-#define CSR_CXDA(S)      ((S)->csr[34] | ((S)->csr[35] << 16))
-#define CSR_NNRD(S)      ((S)->csr[36] | ((S)->csr[37] << 16))
-#define CSR_NNXD(S)      ((S)->csr[38] | ((S)->csr[39] << 16))
-#define CSR_PXDA(S)      ((S)->csr[60] | ((S)->csr[61] << 16))
-#define CSR_NXBA(S)      ((S)->csr[64] | ((S)->csr[65] << 16))
+#define CSR_IADR(S)      ((S)->csr[ 1] | ((uint32_t)(S)->csr[ 2] << 16))
+#define CSR_CRBA(S)      ((S)->csr[18] | ((uint32_t)(S)->csr[19] << 16))
+#define CSR_CXBA(S)      ((S)->csr[20] | ((uint32_t)(S)->csr[21] << 16))
+#define CSR_NRBA(S)      ((S)->csr[22] | ((uint32_t)(S)->csr[23] << 16))
+#define CSR_BADR(S)      ((S)->csr[24] | ((uint32_t)(S)->csr[25] << 16))
+#define CSR_NRDA(S)      ((S)->csr[26] | ((uint32_t)(S)->csr[27] << 16))
+#define CSR_CRDA(S)      ((S)->csr[28] | ((uint32_t)(S)->csr[29] << 16))
+#define CSR_BADX(S)      ((S)->csr[30] | ((uint32_t)(S)->csr[31] << 16))
+#define CSR_NXDA(S)      ((S)->csr[32] | ((uint32_t)(S)->csr[33] << 16))
+#define CSR_CXDA(S)      ((S)->csr[34] | ((uint32_t)(S)->csr[35] << 16))
+#define CSR_NNRD(S)      ((S)->csr[36] | ((uint32_t)(S)->csr[37] << 16))
+#define CSR_NNXD(S)      ((S)->csr[38] | ((uint32_t)(S)->csr[39] << 16))
+#define CSR_PXDA(S)      ((S)->csr[60] | ((uint32_t)(S)->csr[61] << 16))
+#define CSR_NXBA(S)      ((S)->csr[64] | ((uint32_t)(S)->csr[65] << 16))
 
 #define PHYSADDR(S,A) \
-  (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(s)->csr[2])<<16))
+  (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(S)->csr[2])<<16))
 
 struct pcnet_initblk16 {
     uint16_t mode;

From e6b3c8ca0222f6633516c0461a713e7bddc4f076 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Tue, 22 Mar 2011 18:21:58 +0000
Subject: [PATCH 043/386] hw/versatilepb, realview: Fix condition for
 instantiation of onboard NIC

Correct the condition determining whether we instantiate the onboard
NIC or a PCI card NIC on VersatilePB and Realview boards. This was broken
in two ways:
 (1) if the user asked for two default NICs ("-net nic -net nic") we would
crash trying to strcmp() a NULL pointer
 (2) if the user asked for two NICs explicitly of the same model as the
onboard NIC (eg "-net nic,model=smc91c111 -net nic,model=smc91c111")
we would try to instantiate two onboard NICs at the same address.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/realview.c    | 4 ++--
 hw/versatilepb.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/realview.c b/hw/realview.c
index a67861ec3c..96fb9da241 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -288,8 +288,8 @@ static void realview_init(ram_addr_t ram_size,
     for(n = 0; n < nb_nics; n++) {
         nd = &nd_table[n];
 
-        if ((!nd->model && !done_nic)
-            || strcmp(nd->model, is_pb ? "lan9118" : "smc91c111") == 0) {
+        if (!done_nic && (!nd->model ||
+                    strcmp(nd->model, is_pb ? "lan9118" : "smc91c111") == 0)) {
             if (is_pb) {
                 lan9118_init(nd, 0x4e000000, pic[28]);
             } else {
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index 9f1bfcf941..46b6a3f383 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -223,7 +223,7 @@ static void versatile_init(ram_addr_t ram_size,
     for(n = 0; n < nb_nics; n++) {
         nd = &nd_table[n];
 
-        if ((!nd->model && !done_smc) || strcmp(nd->model, "smc91c111") == 0) {
+        if (!done_smc && (!nd->model || strcmp(nd->model, "smc91c111") == 0)) {
             smc91c111_init(nd, 0x10010000, sic[25]);
             done_smc = 1;
         } else {

From f68b9d672b90dedc79aeb9b44607f484dbe46a6b Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Tue, 22 Mar 2011 18:39:40 +0000
Subject: [PATCH 044/386] net: Improve the warnings for dubious command line
 option combinations

Improve the warnings we give if the user specified a combination of -net
options which don't make much sense:
 * Don't warn about anything if the config is the implicit default
   "-net user -net nic" rather than one specified by the user (this will
   only kick in for boards with no NIC or if CONFIG_SLIRP is not set)
 * Diagnose the case where the user asked for NICs which the board
   didn't instantiate (for example where the user asked for two NICs
   but the board only supports one)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 net.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/net.c b/net.c
index b2dfaa8085..8d6a555374 100644
--- a/net.c
+++ b/net.c
@@ -1305,6 +1305,22 @@ void net_check_clients(void)
 {
     VLANState *vlan;
     VLANClientState *vc;
+    int seen_nics = 0;
+
+    /* Don't warn about the default network setup that you get if
+     * no command line -net options are specified. There are two
+     * cases that we would otherwise complain about:
+     * (1) board doesn't support a NIC but the implicit "-net nic"
+     * requested one; we'd otherwise complain about more NICs being
+     * specified than we support, and also that the vlan set up by
+     * the implicit "-net user" didn't have any NICs connected to it
+     * (2) CONFIG_SLIRP not set: we'd otherwise complain about the
+     * implicit "-net nic" setting up a nic that wasn't connected to
+     * anything.
+     */
+    if (default_net) {
+        return;
+    }
 
     QTAILQ_FOREACH(vlan, &vlans, next) {
         int has_nic = 0, has_host_dev = 0;
@@ -1312,6 +1328,7 @@ void net_check_clients(void)
         QTAILQ_FOREACH(vc, &vlan->clients, next) {
             switch (vc->info->type) {
             case NET_CLIENT_TYPE_NIC:
+                seen_nics++;
                 has_nic = 1;
                 break;
             case NET_CLIENT_TYPE_SLIRP:
@@ -1331,12 +1348,26 @@ void net_check_clients(void)
                     vlan->id);
     }
     QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
+        if (vc->info->type == NET_CLIENT_TYPE_NIC) {
+            seen_nics++;
+        }
         if (!vc->peer) {
             fprintf(stderr, "Warning: %s %s has no peer\n",
                     vc->info->type == NET_CLIENT_TYPE_NIC ? "nic" : "netdev",
                     vc->name);
         }
     }
+    if (seen_nics != nb_nics) {
+        /* Number of NICs requested by user on command line doesn't match
+         * the number the model actually registered with us.
+         * This will generally only happen for models of embedded boards
+         * with no PCI bus or similar. PCI based machines can instantiate
+         * all requested NICs as PCI devices but usually embedded boards
+         * only have a single NIC.
+         */
+        fprintf(stderr, "Warning: more nics requested than this machine "
+                "supports; some have been ignored\n");
+    }
 }
 
 static int net_init_client(QemuOpts *opts, void *dummy)

From f20600f213d4cae223660b4ca2eddf139f5e681e Mon Sep 17 00:00:00 2001
From: Alon Levy <alevy@redhat.com>
Date: Wed, 16 Mar 2011 17:30:21 +0200
Subject: [PATCH 045/386] trace: move trace objects from Makefile to
 Makefile.objs

---
 Makefile      | 32 --------------------------------
 Makefile.objs | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/Makefile b/Makefile
index 989622b388..1e3f51a881 100644
--- a/Makefile
+++ b/Makefile
@@ -112,38 +112,6 @@ ui/vnc.o: QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
 
 bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS)
 
-ifeq ($(TRACE_BACKEND),dtrace)
-trace.h: trace.h-timestamp trace-dtrace.h
-else
-trace.h: trace.h-timestamp
-endif
-trace.h-timestamp: $(SRC_PATH)/trace-events config-host.mak
-	$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -h < $< > $@,"  GEN   trace.h")
-	@cmp -s $@ trace.h || cp $@ trace.h
-
-trace.c: trace.c-timestamp
-trace.c-timestamp: $(SRC_PATH)/trace-events config-host.mak
-	$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -c < $< > $@,"  GEN   trace.c")
-	@cmp -s $@ trace.c || cp $@ trace.c
-
-trace.o: trace.c $(GENERATED_HEADERS)
-
-trace-dtrace.h: trace-dtrace.dtrace
-	$(call quiet-command,dtrace -o $@ -h -s $<, "  GEN   trace-dtrace.h")
-
-# Normal practice is to name DTrace probe file with a '.d' extension
-# but that gets picked up by QEMU's Makefile as an external dependancy
-# rule file. So we use '.dtrace' instead
-trace-dtrace.dtrace: trace-dtrace.dtrace-timestamp
-trace-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events config-host.mak
-	$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -d < $< > $@,"  GEN   trace-dtrace.dtrace")
-	@cmp -s $@ trace-dtrace.dtrace || cp $@ trace-dtrace.dtrace
-
-trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS)
-	$(call quiet-command,dtrace -o $@ -G -s $<, "  GEN trace-dtrace.o")
-
-simpletrace.o: simpletrace.c $(GENERATED_HEADERS)
-
 version.o: $(SRC_PATH)/version.rc config-host.mak
 	$(call quiet-command,$(WINDRES) -I. -o $@ $<,"  RC    $(TARGET_DIR)$@")
 
diff --git a/Makefile.objs b/Makefile.objs
index 42301fdf0c..d906a8e5d7 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -309,6 +309,38 @@ libdis-$(CONFIG_SPARC_DIS) += sparc-dis.o
 ######################################################################
 # trace
 
+ifeq ($(TRACE_BACKEND),dtrace)
+trace.h: trace.h-timestamp trace-dtrace.h
+else
+trace.h: trace.h-timestamp
+endif
+trace.h-timestamp: $(SRC_PATH)/trace-events config-host.mak
+	$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -h < $< > $@,"  GEN   trace.h")
+	@cmp -s $@ trace.h || cp $@ trace.h
+
+trace.c: trace.c-timestamp
+trace.c-timestamp: $(SRC_PATH)/trace-events config-host.mak
+	$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -c < $< > $@,"  GEN   trace.c")
+	@cmp -s $@ trace.c || cp $@ trace.c
+
+trace.o: trace.c $(GENERATED_HEADERS)
+
+trace-dtrace.h: trace-dtrace.dtrace
+	$(call quiet-command,dtrace -o $@ -h -s $<, "  GEN   trace-dtrace.h")
+
+# Normal practice is to name DTrace probe file with a '.d' extension
+# but that gets picked up by QEMU's Makefile as an external dependancy
+# rule file. So we use '.dtrace' instead
+trace-dtrace.dtrace: trace-dtrace.dtrace-timestamp
+trace-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events config-host.mak
+	$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -d < $< > $@,"  GEN   trace-dtrace.dtrace")
+	@cmp -s $@ trace-dtrace.dtrace || cp $@ trace-dtrace.dtrace
+
+trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS)
+	$(call quiet-command,dtrace -o $@ -G -s $<, "  GEN trace-dtrace.o")
+
+simpletrace.o: simpletrace.c $(GENERATED_HEADERS)
+
 ifeq ($(TRACE_BACKEND),dtrace)
 trace-obj-y = trace-dtrace.o
 else

From 65097429ae1929c0c2da5577f6510a1eac82bd7a Mon Sep 17 00:00:00 2001
From: Alon Levy <alevy@redhat.com>
Date: Tue, 15 Mar 2011 00:18:02 +0200
Subject: [PATCH 046/386] qemu-thread.h: include inttypes.h

qemu-thread.h relies on uint64_t being defined, but doesn't include
inttypes.h explicitly. This makes it easier to use it from vscclient (part
of libcacard).
---
 qemu-thread.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/qemu-thread.h b/qemu-thread.h
index edc7ab6858..0a73d50524 100644
--- a/qemu-thread.h
+++ b/qemu-thread.h
@@ -1,6 +1,8 @@
 #ifndef __QEMU_THREAD_H
 #define __QEMU_THREAD_H 1
 
+#include <inttypes.h>
+
 typedef struct QemuMutex QemuMutex;
 typedef struct QemuCond QemuCond;
 typedef struct QemuThread QemuThread;

From 367071447ec5b0dabc5452384bbeb62371838112 Mon Sep 17 00:00:00 2001
From: Alon Levy <alevy@redhat.com>
Date: Sun, 17 Oct 2010 11:40:07 +0200
Subject: [PATCH 047/386] usb-ccid: add CCID bus

A CCID device is a smart card reader. It is a USB device, defined at [1].
This patch introduces the usb-ccid device that is a ccid bus. Next patches will
introduce two card types to use it, a passthru card and an emulated card.

 [1] http://www.usb.org/developers/devclass_docs/DWG_Smart-Card_CCID_Rev110.

Signed-off-by: Alon Levy <alevy@redhat.com>

---

changes from v20->v21: (Jes Sorenson review)
 * cosmetic changes - fix multi line comments.
 * reorder fields in USBCCIDState
 * add reference to COPYING
 * add --enable-smartcard and --disable-smartcard here (moved
 from last patch)

changes from v19->v20:
 * checkpatch.pl

changes from v18->v19:
 * merged: ccid.h: add copyright, fix define and remove non C89 comments
 * add qdev.desc

changes from v15->v16:

Behavioral changes:
 * fix abort on client answer after card remove
 * enable migration
 * remove side affect code from asserts
 * return consistent self-powered state
 * mask out reserved bits in ccid_set_parameters
 * add missing abRFU in SetParameters (no affect on linux guest)

whitefixes / comments / consts defines:
 * remove stale comment
 * remove ccid_print_pending_answers if no DEBUG_CCID
 * replace printf's with DPRINTF, remove DEBUG_CCID, add verbosity defines
 * use error_report
 * update copyright (most of the code is not original)
 * reword known bug comment
 * add missing closing quote in comment
 * add missing whitespace on one line
 * s/CCID_SetParameter/CCID_SetParameters/
 * add comments
 * use define for max packet size

Comment for "return consistent self-powered state":

the Configuration Descriptor bmAttributes claims we are self powered,
but we were returning not self powered to USB_REQ_GET_STATUS control message.

In practice, this message is not sent by a linux 2.6.35.10-74.fc14.x86_64
guest (not tested on other guests), unless you issue lsusb -v as root (for
example).
---
 Makefile.objs |    1 +
 configure     |   11 +
 hw/ccid.h     |   59 ++
 hw/usb-ccid.c | 1419 +++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 1490 insertions(+)
 create mode 100644 hw/ccid.h
 create mode 100644 hw/usb-ccid.c

diff --git a/Makefile.objs b/Makefile.objs
index d906a8e5d7..7fdfc487fb 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -200,6 +200,7 @@ hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
 hw-obj-$(CONFIG_HPET) += hpet.o
 hw-obj-$(CONFIG_APPLESMC) += applesmc.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/configure b/configure
index 7d8d890891..01ee94d009 100755
--- a/configure
+++ b/configure
@@ -175,6 +175,7 @@ trace_backend="nop"
 trace_file="trace"
 spice=""
 rbd=""
+smartcard=""
 
 # parse CC options first
 for opt do
@@ -724,6 +725,10 @@ for opt do
   ;;
   --enable-rbd) rbd="yes"
   ;;
+  --disable-smartcard) smartcard="no"
+  ;;
+  --enable-smartcard) smartcard="yes"
+  ;;
   *) echo "ERROR: unknown option $opt"; show_help="yes"
   ;;
   esac
@@ -921,6 +926,8 @@ echo "                           Default:trace-<pid>"
 echo "  --disable-spice          disable spice"
 echo "  --enable-spice           enable spice"
 echo "  --enable-rbd             enable building the rados block device (rbd)"
+echo "  --disable-smartcard      disable smartcard support"
+echo "  --enable-smartcard       enable smartcard support"
 echo ""
 echo "NOTE: The object files are built at the place where configure is launched"
 exit 1
@@ -2824,6 +2831,10 @@ if test "$spice" = "yes" ; then
   echo "CONFIG_SPICE=y" >> $config_host_mak
 fi
 
+if test "$smartcard" = "yes" ; then
+  echo "CONFIG_SMARTCARD=y" >> $config_host_mak
+fi
+
 # XXX: suppress that
 if [ "$bsd" = "yes" ] ; then
   echo "CONFIG_BSD=y" >> $config_host_mak
diff --git a/hw/ccid.h b/hw/ccid.h
new file mode 100644
index 0000000000..dbfc13c4f5
--- /dev/null
+++ b/hw/ccid.h
@@ -0,0 +1,59 @@
+/*
+ * CCID Passthru Card Device emulation
+ *
+ * Copyright (c) 2011 Red Hat.
+ * Written by Alon Levy.
+ *
+ * This code is licenced under the GNU LGPL, version 2 or later.
+ */
+
+#ifndef CCID_H
+#define CCID_H
+
+#include "qdev.h"
+
+typedef struct CCIDCardState CCIDCardState;
+typedef struct CCIDCardInfo CCIDCardInfo;
+
+/*
+ * state of the CCID Card device (i.e. hw/ccid-card-*.c)
+ */
+struct CCIDCardState {
+    DeviceState qdev;
+    uint32_t    slot; /* For future use with multiple slot reader. */
+};
+
+/*
+ * callbacks to be used by the CCID device (hw/usb-ccid.c) to call
+ * into the smartcard device (hw/ccid-card-*.c)
+ */
+struct CCIDCardInfo {
+    DeviceInfo qdev;
+    void (*print)(Monitor *mon, CCIDCardState *card, int indent);
+    const uint8_t *(*get_atr)(CCIDCardState *card, uint32_t *len);
+    void (*apdu_from_guest)(CCIDCardState *card,
+                            const uint8_t *apdu,
+                            uint32_t len);
+    int (*exitfn)(CCIDCardState *card);
+    int (*initfn)(CCIDCardState *card);
+};
+
+/*
+ * API for smartcard calling the CCID device (used by hw/ccid-card-*.c)
+ */
+void ccid_card_send_apdu_to_guest(CCIDCardState *card,
+                                  uint8_t *apdu,
+                                  uint32_t len);
+void ccid_card_card_removed(CCIDCardState *card);
+void ccid_card_card_inserted(CCIDCardState *card);
+void ccid_card_card_error(CCIDCardState *card, uint64_t error);
+void ccid_card_qdev_register(CCIDCardInfo *card);
+
+/*
+ * support guest visible insertion/removal of ccid devices based on actual
+ * devices connected/removed. Called by card implementation (passthru, local)
+ */
+int ccid_card_ccid_attach(CCIDCardState *card);
+void ccid_card_ccid_detach(CCIDCardState *card);
+
+#endif /* CCID_H */
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
new file mode 100644
index 0000000000..723b2e325f
--- /dev/null
+++ b/hw/usb-ccid.c
@@ -0,0 +1,1419 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc.
+ *
+ * CCID Device emulation
+ *
+ * Written by Alon Levy, with contributions from Robert Relyea.
+ *
+ * Based on usb-serial.c, see it's copyright and attributions below.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ * ------- (original copyright & attribution for usb-serial.c below) --------
+ * Copyright (c) 2006 CodeSourcery.
+ * Copyright (c) 2008 Samuel Thibault <samuel.thibault@ens-lyon.org>
+ * Written by Paul Brook, reused for FTDI by Samuel Thibault,
+ */
+
+/*
+ * References:
+ *
+ * CCID Specification Revision 1.1 April 22nd 2005
+ *  "Universal Serial Bus, Device Class: Smart Card"
+ *  Specification for Integrated Circuit(s) Cards Interface Devices
+ *
+ * Endianess note: from the spec (1.3)
+ *  "Fields that are larger than a byte are stored in little endian"
+ *
+ * KNOWN BUGS
+ * 1. remove/insert can sometimes result in removed state instead of inserted.
+ * This is a result of the following:
+ *  symptom: dmesg shows ERMOTEIO (-121), pcscd shows -99. This can happen
+ *  when a short packet is sent, as seen in uhci-usb.c, resulting from a urb
+ *  from the guest requesting SPD and us returning a smaller packet.
+ *  Not sure which messages trigger this.
+ */
+
+#include "qemu-common.h"
+#include "qemu-error.h"
+#include "usb.h"
+#include "monitor.h"
+
+#include "hw/ccid.h"
+
+#define DPRINTF(s, lvl, fmt, ...) \
+do { \
+    if (lvl <= s->debug) { \
+        printf("usb-ccid: " fmt , ## __VA_ARGS__); \
+    } \
+} while (0)
+
+#define D_WARN 1
+#define D_INFO 2
+#define D_MORE_INFO 3
+#define D_VERBOSE 4
+
+#define CCID_DEV_NAME "usb-ccid"
+
+/*
+ * The two options for variable sized buffers:
+ * make them constant size, for large enough constant,
+ * or handle the migration complexity - VMState doesn't handle this case.
+ * sizes are expected never to be exceeded, unless guest misbehaves.
+ */
+#define BULK_OUT_DATA_SIZE 65536
+#define PENDING_ANSWERS_NUM 128
+
+#define BULK_IN_BUF_SIZE 384
+#define BULK_IN_PENDING_NUM 8
+
+#define InterfaceOutClass \
+    ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)<<8)
+
+#define InterfaceInClass  \
+    ((USB_DIR_IN  | USB_TYPE_CLASS | USB_RECIP_INTERFACE)<<8)
+
+#define CCID_MAX_PACKET_SIZE                64
+
+#define CCID_CONTROL_ABORT                  0x1
+#define CCID_CONTROL_GET_CLOCK_FREQUENCIES  0x2
+#define CCID_CONTROL_GET_DATA_RATES         0x3
+
+#define CCID_PRODUCT_DESCRIPTION        "QEMU USB CCID"
+#define CCID_VENDOR_DESCRIPTION         "QEMU " QEMU_VERSION
+#define CCID_INTERFACE_NAME             "CCID Interface"
+#define CCID_SERIAL_NUMBER_STRING       "1"
+/*
+ * Using Gemplus Vendor and Product id
+ * Effect on various drivers:
+ *  usbccid.sys (winxp, others untested) is a class driver so it doesn't care.
+ *  linux has a number of class drivers, but openct filters based on
+ *   vendor/product (/etc/openct.conf under fedora), hence Gemplus.
+ */
+#define CCID_VENDOR_ID                  0x08e6
+#define CCID_PRODUCT_ID                 0x4433
+#define CCID_DEVICE_VERSION             0x0000
+
+/*
+ * BULK_OUT messages from PC to Reader
+ * Defined in CCID Rev 1.1 6.1 (page 26)
+ */
+#define CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOn              0x62
+#define CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOff             0x63
+#define CCID_MESSAGE_TYPE_PC_to_RDR_GetSlotStatus           0x65
+#define CCID_MESSAGE_TYPE_PC_to_RDR_XfrBlock                0x6f
+#define CCID_MESSAGE_TYPE_PC_to_RDR_GetParameters           0x6c
+#define CCID_MESSAGE_TYPE_PC_to_RDR_ResetParameters         0x6d
+#define CCID_MESSAGE_TYPE_PC_to_RDR_SetParameters           0x61
+#define CCID_MESSAGE_TYPE_PC_to_RDR_Escape                  0x6b
+#define CCID_MESSAGE_TYPE_PC_to_RDR_IccClock                0x6e
+#define CCID_MESSAGE_TYPE_PC_to_RDR_T0APDU                  0x6a
+#define CCID_MESSAGE_TYPE_PC_to_RDR_Secure                  0x69
+#define CCID_MESSAGE_TYPE_PC_to_RDR_Mechanical              0x71
+#define CCID_MESSAGE_TYPE_PC_to_RDR_Abort                   0x72
+#define CCID_MESSAGE_TYPE_PC_to_RDR_SetDataRateAndClockFrequency 0x73
+
+/*
+ * BULK_IN messages from Reader to PC
+ * Defined in CCID Rev 1.1 6.2 (page 48)
+ */
+#define CCID_MESSAGE_TYPE_RDR_to_PC_DataBlock               0x80
+#define CCID_MESSAGE_TYPE_RDR_to_PC_SlotStatus              0x81
+#define CCID_MESSAGE_TYPE_RDR_to_PC_Parameters              0x82
+#define CCID_MESSAGE_TYPE_RDR_to_PC_Escape                  0x83
+#define CCID_MESSAGE_TYPE_RDR_to_PC_DataRateAndClockFrequency 0x84
+
+/*
+ * INTERRUPT_IN messages from Reader to PC
+ * Defined in CCID Rev 1.1 6.3 (page 56)
+ */
+#define CCID_MESSAGE_TYPE_RDR_to_PC_NotifySlotChange        0x50
+#define CCID_MESSAGE_TYPE_RDR_to_PC_HardwareError           0x51
+
+/*
+ * Endpoints for CCID - addresses are up to us to decide.
+ * To support slot insertion and removal we must have an interrupt in ep
+ * in addition we need a bulk in and bulk out ep
+ * 5.2, page 20
+ */
+#define CCID_INT_IN_EP       1
+#define CCID_BULK_IN_EP      2
+#define CCID_BULK_OUT_EP     3
+
+/* bmSlotICCState masks */
+#define SLOT_0_STATE_MASK    1
+#define SLOT_0_CHANGED_MASK  2
+
+/* Status codes that go in bStatus (see 6.2.6) */
+enum {
+    ICC_STATUS_PRESENT_ACTIVE = 0,
+    ICC_STATUS_PRESENT_INACTIVE,
+    ICC_STATUS_NOT_PRESENT
+};
+
+enum {
+    COMMAND_STATUS_NO_ERROR = 0,
+    COMMAND_STATUS_FAILED,
+    COMMAND_STATUS_TIME_EXTENSION_REQUIRED
+};
+
+/* Error codes that go in bError (see 6.2.6) */
+enum {
+    ERROR_CMD_NOT_SUPPORTED = 0,
+    ERROR_CMD_ABORTED       = -1,
+    ERROR_ICC_MUTE          = -2,
+    ERROR_XFR_PARITY_ERROR  = -3,
+    ERROR_XFR_OVERRUN       = -4,
+    ERROR_HW_ERROR          = -5,
+};
+
+/* 6.2.6 RDR_to_PC_SlotStatus definitions */
+enum {
+    CLOCK_STATUS_RUNNING = 0,
+    /*
+     * 0 - Clock Running, 1 - Clock stopped in State L, 2 - H,
+     * 3 - unkonwn state. rest are RFU
+     */
+};
+
+typedef struct __attribute__ ((__packed__)) CCID_Header {
+    uint8_t     bMessageType;
+    uint32_t    dwLength;
+    uint8_t     bSlot;
+    uint8_t     bSeq;
+} CCID_Header;
+
+typedef struct __attribute__ ((__packed__)) CCID_BULK_IN {
+    CCID_Header hdr;
+    uint8_t     bStatus;        /* Only used in BULK_IN */
+    uint8_t     bError;         /* Only used in BULK_IN */
+} CCID_BULK_IN;
+
+typedef struct __attribute__ ((__packed__)) CCID_SlotStatus {
+    CCID_BULK_IN b;
+    uint8_t     bClockStatus;
+} CCID_SlotStatus;
+
+typedef struct __attribute__ ((__packed__)) CCID_Parameter {
+    CCID_BULK_IN b;
+    uint8_t     bProtocolNum;
+    uint8_t     abProtocolDataStructure[0];
+} CCID_Parameter;
+
+typedef struct __attribute__ ((__packed__)) CCID_DataBlock {
+    CCID_BULK_IN b;
+    uint8_t      bChainParameter;
+    uint8_t      abData[0];
+} CCID_DataBlock;
+
+/* 6.1.4 PC_to_RDR_XfrBlock */
+typedef struct __attribute__ ((__packed__)) CCID_XferBlock {
+    CCID_Header  hdr;
+    uint8_t      bBWI; /* Block Waiting Timeout */
+    uint16_t     wLevelParameter; /* XXX currently unused */
+    uint8_t      abData[0];
+} CCID_XferBlock;
+
+typedef struct __attribute__ ((__packed__)) CCID_IccPowerOn {
+    CCID_Header hdr;
+    uint8_t     bPowerSelect;
+    uint16_t    abRFU;
+} CCID_IccPowerOn;
+
+typedef struct __attribute__ ((__packed__)) CCID_IccPowerOff {
+    CCID_Header hdr;
+    uint16_t    abRFU;
+} CCID_IccPowerOff;
+
+typedef struct __attribute__ ((__packed__)) CCID_SetParameters {
+    CCID_Header hdr;
+    uint8_t     bProtocolNum;
+    uint16_t   abRFU;
+    uint8_t    abProtocolDataStructure[0];
+} CCID_SetParameters;
+
+typedef struct CCID_Notify_Slot_Change {
+    uint8_t     bMessageType; /* CCID_MESSAGE_TYPE_RDR_to_PC_NotifySlotChange */
+    uint8_t     bmSlotICCState;
+} CCID_Notify_Slot_Change;
+
+/* used for DataBlock response to XferBlock */
+typedef struct Answer {
+    uint8_t slot;
+    uint8_t seq;
+} Answer;
+
+/* pending BULK_IN messages */
+typedef struct BulkIn {
+    uint8_t  data[BULK_IN_BUF_SIZE];
+    uint32_t len;
+    uint32_t pos;
+} BulkIn;
+
+enum {
+    MIGRATION_NONE,
+    MIGRATION_MIGRATED,
+};
+
+typedef struct CCIDBus CCIDBus;
+typedef struct USBCCIDState USBCCIDState;
+
+#define MAX_PROTOCOL_SIZE   7
+
+/*
+ * powered - defaults to true, changed by PowerOn/PowerOff messages
+ */
+struct USBCCIDState {
+    USBDevice dev;
+    CCIDBus *bus;
+    CCIDCardState *card;
+    CCIDCardInfo *cardinfo; /* caching the info pointer */
+    BulkIn bulk_in_pending[BULK_IN_PENDING_NUM]; /* circular */
+    uint32_t bulk_in_pending_start;
+    uint32_t bulk_in_pending_end; /* first free */
+    uint32_t bulk_in_pending_num;
+    BulkIn *current_bulk_in;
+    uint8_t  bulk_out_data[BULK_OUT_DATA_SIZE];
+    uint32_t bulk_out_pos;
+    uint64_t last_answer_error;
+    Answer pending_answers[PENDING_ANSWERS_NUM];
+    uint32_t pending_answers_start;
+    uint32_t pending_answers_end;
+    uint32_t pending_answers_num;
+    uint8_t  bError;
+    uint8_t  bmCommandStatus;
+    uint8_t  bProtocolNum;
+    uint8_t  abProtocolDataStructure[MAX_PROTOCOL_SIZE];
+    uint32_t ulProtocolDataStructureSize;
+    uint32_t state_vmstate;
+    uint32_t migration_target_ip;
+    uint16_t migration_target_port;
+    uint8_t  migration_state;
+    uint8_t  bmSlotICCState;
+    uint8_t  powered;
+    uint8_t  notify_slot_change;
+    uint8_t  debug;
+};
+
+/*
+ * CCID Spec chapter 4: CCID uses a standard device descriptor per Chapter 9,
+ * "USB Device Framework", section 9.6.1, in the Universal Serial Bus
+ * Specification.
+ *
+ * This device implemented based on the spec and with an Athena Smart Card
+ * Reader as reference:
+ *   0dc3:1004 Athena Smartcard Solutions, Inc.
+ */
+
+static const uint8_t qemu_ccid_dev_descriptor[] = {
+        0x12,       /*  u8 bLength; */
+        USB_DT_DEVICE, /*  u8 bDescriptorType; Device */
+        0x10, 0x01, /*  u16 bcdUSB; v1.1 */
+
+        0x00,       /*  u8  bDeviceClass; */
+        0x00,       /*  u8  bDeviceSubClass; */
+        0x00,       /*  u8  bDeviceProtocol; [ low/full speeds only ] */
+        0x40,       /*  u8  bMaxPacketSize0; 8 Bytes (valid: 8,16,32,64) */
+
+        /* Vendor and product id are arbitrary.  */
+                    /*  u16 idVendor  */
+        CCID_VENDOR_ID & 0xff, CCID_VENDOR_ID >> 8,
+                    /*  u16 idProduct */
+        CCID_PRODUCT_ID & 0xff, CCID_PRODUCT_ID >> 8,
+                    /*  u16 bcdDevice */
+        CCID_DEVICE_VERSION & 0xff, CCID_DEVICE_VERSION >> 8,
+        0x01,       /*  u8  iManufacturer; */
+        0x02,       /*  u8  iProduct; */
+        0x03,       /*  u8  iSerialNumber; */
+        0x01,       /*  u8  bNumConfigurations; */
+};
+
+static const uint8_t qemu_ccid_config_descriptor[] = {
+
+        /* one configuration */
+        0x09,       /* u8  bLength; */
+        USB_DT_CONFIG, /* u8  bDescriptorType; Configuration */
+        0x5d, 0x00, /* u16 wTotalLength; 9+9+54+7+7+7 */
+        0x01,       /* u8  bNumInterfaces; (1) */
+        0x01,       /* u8  bConfigurationValue; */
+        0x00,       /* u8  iConfiguration; */
+        0xe0,       /* u8  bmAttributes;
+                                 Bit 7: must be set,
+                                     6: Self-powered,
+                                     5: Remote wakeup,
+                                     4..0: resvd */
+        100/2,      /* u8  MaxPower; 50 == 100mA */
+
+        /* one interface */
+        0x09,       /* u8  if_bLength; */
+        USB_DT_INTERFACE, /* u8  if_bDescriptorType; Interface */
+        0x00,       /* u8  if_bInterfaceNumber; */
+        0x00,       /* u8  if_bAlternateSetting; */
+        0x03,       /* u8  if_bNumEndpoints; */
+        0x0b,       /* u8  if_bInterfaceClass; Smart Card Device Class */
+        0x00,       /* u8  if_bInterfaceSubClass; Subclass code */
+        0x00,       /* u8  if_bInterfaceProtocol; Protocol code */
+        0x04,       /* u8  if_iInterface; Index of string descriptor */
+
+        /* Smart Card Device Class Descriptor */
+        0x36,       /* u8  bLength; */
+        0x21,       /* u8  bDescriptorType; Functional */
+        0x10, 0x01, /* u16 bcdCCID; CCID Specification Release Number. */
+        0x00,       /*
+                     * u8  bMaxSlotIndex; The index of the highest available
+                     * slot on this device. All slots are consecutive starting
+                     * at 00h.
+                     */
+        0x07,       /* u8  bVoltageSupport; 01h - 5.0v, 02h - 3.0, 03 - 1.8 */
+
+        0x03, 0x00, /* u32 dwProtocols; RRRR PPPP. RRRR = 0000h.*/
+        0x00, 0x00, /* PPPP: 0001h = Protocol T=0, 0002h = Protocol T=1 */
+                    /* u32 dwDefaultClock; in kHZ (0x0fa0 is 4 MHz) */
+        0xa0, 0x0f, 0x00, 0x00,
+                    /* u32 dwMaximumClock; */
+        0x00, 0x00, 0x01, 0x00,
+        0x00,       /* u8 bNumClockSupported;                 *
+                     *    0 means just the default and max.   */
+                    /* u32 dwDataRate ;bps. 9600 == 00002580h */
+        0x80, 0x25, 0x00, 0x00,
+                    /* u32 dwMaxDataRate ; 11520 bps == 0001C200h */
+        0x00, 0xC2, 0x01, 0x00,
+        0x00,       /* u8  bNumDataRatesSupported; 00 means all rates between
+                     *     default and max */
+                    /* u32 dwMaxIFSD;                                  *
+                     *     maximum IFSD supported by CCID for protocol *
+                     *     T=1 (Maximum seen from various cards)       */
+        0xfe, 0x00, 0x00, 0x00,
+                    /* u32 dwSyncProtocols; 1 - 2-wire, 2 - 3-wire, 4 - I2C */
+        0x00, 0x00, 0x00, 0x00,
+                    /* u32 dwMechanical;  0 - no special characteristics. */
+        0x00, 0x00, 0x00, 0x00,
+                    /*
+                     * u32 dwFeatures;
+                     * 0 - No special characteristics
+                     * + 2 Automatic parameter configuration based on ATR data
+                     * + 4 Automatic activation of ICC on inserting
+                     * + 8 Automatic ICC voltage selection
+                     * + 10 Automatic ICC clock frequency change
+                     * + 20 Automatic baud rate change
+                     * + 40 Automatic parameters negotiation made by the CCID
+                     * + 80 automatic PPS made by the CCID
+                     * 100 CCID can set ICC in clock stop mode
+                     * 200 NAD value other then 00 accepted (T=1 protocol)
+                     * + 400 Automatic IFSD exchange as first exchange (T=1)
+                     * One of the following only:
+                     * + 10000 TPDU level exchanges with CCID
+                     * 20000 Short APDU level exchange with CCID
+                     * 40000 Short and Extended APDU level exchange with CCID
+                     *
+                     * + 100000 USB Wake up signaling supported on card
+                     * insertion and removal. Must set bit 5 in bmAttributes
+                     * in Configuration descriptor if 100000 is set.
+                     */
+        0xfe, 0x04, 0x11, 0x00,
+                    /*
+                     * u32 dwMaxCCIDMessageLength; For extended APDU in
+                     * [261 + 10 , 65544 + 10]. Otherwise the minimum is
+                     * wMaxPacketSize of the Bulk-OUT endpoint
+                     */
+        0x12, 0x00, 0x01, 0x00,
+        0xFF,       /*
+                     * u8  bClassGetResponse; Significant only for CCID that
+                     * offers an APDU level for exchanges. Indicates the
+                     * default class value used by the CCID when it sends a
+                     * Get Response command to perform the transportation of
+                     * an APDU by T=0 protocol
+                     * FFh indicates that the CCID echos the class of the APDU.
+                     */
+        0xFF,       /*
+                     * u8  bClassEnvelope; EAPDU only. Envelope command for
+                     * T=0
+                     */
+        0x00, 0x00, /*
+                     * u16 wLcdLayout; XXYY Number of lines (XX) and chars per
+                     * line for LCD display used for PIN entry. 0000 - no LCD
+                     */
+        0x01,       /*
+                     * u8  bPINSupport; 01h PIN Verification,
+                     *                  02h PIN Modification
+                     */
+        0x01,       /* u8  bMaxCCIDBusySlots; */
+
+        /* Interrupt-IN endpoint */
+        0x07,       /* u8  ep_bLength; */
+                    /* u8  ep_bDescriptorType; Endpoint */
+        USB_DT_ENDPOINT,
+                    /* u8  ep_bEndpointAddress; IN Endpoint 1 */
+        0x80 | CCID_INT_IN_EP,
+        0x03,       /* u8  ep_bmAttributes; Interrupt */
+                    /* u16 ep_wMaxPacketSize; */
+        CCID_MAX_PACKET_SIZE & 0xff, (CCID_MAX_PACKET_SIZE >> 8),
+        0xff,       /* u8  ep_bInterval; */
+
+        /* Bulk-In endpoint */
+        0x07,       /* u8  ep_bLength; */
+                    /* u8  ep_bDescriptorType; Endpoint */
+        USB_DT_ENDPOINT,
+                    /* u8  ep_bEndpointAddress; IN Endpoint 2 */
+        0x80 | CCID_BULK_IN_EP,
+        0x02,       /* u8  ep_bmAttributes; Bulk */
+        0x40, 0x00, /* u16 ep_wMaxPacketSize; */
+        0x00,       /* u8  ep_bInterval; */
+
+        /* Bulk-Out endpoint */
+        0x07,       /* u8  ep_bLength; */
+                    /* u8  ep_bDescriptorType; Endpoint */
+        USB_DT_ENDPOINT,
+                    /* u8  ep_bEndpointAddress; OUT Endpoint 3 */
+        CCID_BULK_OUT_EP,
+        0x02,       /* u8  ep_bmAttributes; Bulk */
+        0x40, 0x00, /* u16 ep_wMaxPacketSize; */
+        0x00,       /* u8  ep_bInterval; */
+
+};
+
+static bool ccid_has_pending_answers(USBCCIDState *s)
+{
+    return s->pending_answers_num > 0;
+}
+
+static void ccid_clear_pending_answers(USBCCIDState *s)
+{
+    s->pending_answers_num = 0;
+    s->pending_answers_start = 0;
+    s->pending_answers_end = 0;
+}
+
+static void ccid_print_pending_answers(USBCCIDState *s)
+{
+    Answer *answer;
+    int i, count;
+
+    DPRINTF(s, D_VERBOSE, "usb-ccid: pending answers:");
+    if (!ccid_has_pending_answers(s)) {
+        DPRINTF(s, D_VERBOSE, " empty\n");
+        return;
+    }
+    for (i = s->pending_answers_start, count = s->pending_answers_num ;
+         count > 0; count--, i++) {
+        answer = &s->pending_answers[i % PENDING_ANSWERS_NUM];
+        if (count == 1) {
+            DPRINTF(s, D_VERBOSE, "%d:%d\n", answer->slot, answer->seq);
+        } else {
+            DPRINTF(s, D_VERBOSE, "%d:%d,", answer->slot, answer->seq);
+        }
+    }
+}
+
+static void ccid_add_pending_answer(USBCCIDState *s, CCID_Header *hdr)
+{
+    Answer *answer;
+
+    assert(s->pending_answers_num < PENDING_ANSWERS_NUM);
+    s->pending_answers_num++;
+    answer =
+        &s->pending_answers[(s->pending_answers_end++) % PENDING_ANSWERS_NUM];
+    answer->slot = hdr->bSlot;
+    answer->seq = hdr->bSeq;
+    ccid_print_pending_answers(s);
+}
+
+static void ccid_remove_pending_answer(USBCCIDState *s,
+    uint8_t *slot, uint8_t *seq)
+{
+    Answer *answer;
+
+    assert(s->pending_answers_num > 0);
+    s->pending_answers_num--;
+    answer =
+        &s->pending_answers[(s->pending_answers_start++) % PENDING_ANSWERS_NUM];
+    *slot = answer->slot;
+    *seq = answer->seq;
+    ccid_print_pending_answers(s);
+}
+
+static void ccid_bulk_in_clear(USBCCIDState *s)
+{
+    s->bulk_in_pending_start = 0;
+    s->bulk_in_pending_end = 0;
+    s->bulk_in_pending_num = 0;
+}
+
+static void ccid_bulk_in_release(USBCCIDState *s)
+{
+    assert(s->current_bulk_in != NULL);
+    s->current_bulk_in->pos = 0;
+    s->current_bulk_in = NULL;
+}
+
+static void ccid_bulk_in_get(USBCCIDState *s)
+{
+    if (s->current_bulk_in != NULL || s->bulk_in_pending_num == 0) {
+        return;
+    }
+    assert(s->bulk_in_pending_num > 0);
+    s->bulk_in_pending_num--;
+    s->current_bulk_in =
+        &s->bulk_in_pending[(s->bulk_in_pending_start++) % BULK_IN_PENDING_NUM];
+}
+
+static void *ccid_reserve_recv_buf(USBCCIDState *s, uint16_t len)
+{
+    BulkIn *bulk_in;
+
+    DPRINTF(s, D_VERBOSE, "%s: QUEUE: reserve %d bytes\n", __func__, len);
+
+    /* look for an existing element */
+    if (len > BULK_IN_BUF_SIZE) {
+        DPRINTF(s, D_WARN, "usb-ccid.c: %s: len larger then max (%d>%d). "
+                           "discarding message.\n",
+                           __func__, len, BULK_IN_BUF_SIZE);
+        return NULL;
+    }
+    if (s->bulk_in_pending_num >= BULK_IN_PENDING_NUM) {
+        DPRINTF(s, D_WARN, "usb-ccid.c: %s: No free bulk_in buffers. "
+                           "discarding message.\n", __func__);
+        return NULL;
+    }
+    bulk_in =
+        &s->bulk_in_pending[(s->bulk_in_pending_end++) % BULK_IN_PENDING_NUM];
+    s->bulk_in_pending_num++;
+    bulk_in->len = len;
+    return bulk_in->data;
+}
+
+static void ccid_reset(USBCCIDState *s)
+{
+    ccid_bulk_in_clear(s);
+    ccid_clear_pending_answers(s);
+}
+
+static void ccid_detach(USBCCIDState *s)
+{
+    ccid_reset(s);
+}
+
+static void ccid_handle_reset(USBDevice *dev)
+{
+    USBCCIDState *s = DO_UPCAST(USBCCIDState, dev, dev);
+
+    DPRINTF(s, 1, "Reset\n");
+
+    ccid_reset(s);
+}
+
+static int ccid_handle_control(USBDevice *dev, int request, int value,
+                                  int index, int length, uint8_t *data)
+{
+    USBCCIDState *s = DO_UPCAST(USBCCIDState, dev, dev);
+    int ret = 0;
+
+    DPRINTF(s, 1, "got control %x, value %x\n", request, value);
+    switch (request) {
+    case DeviceRequest | USB_REQ_GET_STATUS:
+        data[0] = (1 << USB_DEVICE_SELF_POWERED) |
+            (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
+        data[1] = 0x00;
+        ret = 2;
+        break;
+    case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
+        if (value == USB_DEVICE_REMOTE_WAKEUP) {
+            dev->remote_wakeup = 0;
+        } else {
+            goto fail;
+        }
+        ret = 0;
+        break;
+    case DeviceOutRequest | USB_REQ_SET_FEATURE:
+        if (value == USB_DEVICE_REMOTE_WAKEUP) {
+            dev->remote_wakeup = 1;
+        } else {
+            goto fail;
+        }
+        ret = 0;
+        break;
+    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
+        dev->addr = value;
+        ret = 0;
+        break;
+    case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
+        switch (value >> 8) {
+        case USB_DT_DEVICE:
+            memcpy(data, qemu_ccid_dev_descriptor,
+                   sizeof(qemu_ccid_dev_descriptor));
+            ret = sizeof(qemu_ccid_dev_descriptor);
+            break;
+        case USB_DT_CONFIG:
+            memcpy(data, qemu_ccid_config_descriptor,
+                   sizeof(qemu_ccid_config_descriptor));
+            ret = sizeof(qemu_ccid_config_descriptor);
+            break;
+        case USB_DT_STRING:
+            switch (value & 0xff) {
+            case 0:
+                /* language ids */
+                data[0] = 4;
+                data[1] = 3;
+                data[2] = 0x09;
+                data[3] = 0x04;
+                ret = 4;
+                break;
+            case 1:
+                /* vendor description */
+                ret = set_usb_string(data, CCID_VENDOR_DESCRIPTION);
+                break;
+            case 2:
+                /* product description */
+                ret = set_usb_string(data, CCID_PRODUCT_DESCRIPTION);
+                break;
+            case 3:
+                /* serial number */
+                ret = set_usb_string(data, CCID_SERIAL_NUMBER_STRING);
+                break;
+            case 4:
+                /* interface name */
+                ret = set_usb_string(data, CCID_INTERFACE_NAME);
+                break;
+            default:
+                goto fail;
+            }
+            break;
+        default:
+            goto fail;
+        }
+        break;
+    case DeviceRequest | USB_REQ_GET_CONFIGURATION:
+        data[0] = 1;
+        ret = 1;
+        break;
+    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
+        /* Only one configuration - we just ignore the request */
+        ret = 0;
+        break;
+    case DeviceRequest | USB_REQ_GET_INTERFACE:
+        data[0] = 0;
+        ret = 1;
+        break;
+    case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
+        ret = 0;
+        break;
+    case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
+        ret = 0;
+        break;
+
+        /* Class specific requests.  */
+    case InterfaceOutClass | CCID_CONTROL_ABORT:
+        DPRINTF(s, 1, "ccid_control abort UNIMPLEMENTED\n");
+        ret = USB_RET_STALL;
+        break;
+    case InterfaceInClass | CCID_CONTROL_GET_CLOCK_FREQUENCIES:
+        DPRINTF(s, 1, "ccid_control get clock frequencies UNIMPLEMENTED\n");
+        ret = USB_RET_STALL;
+        break;
+    case InterfaceInClass | CCID_CONTROL_GET_DATA_RATES:
+        DPRINTF(s, 1, "ccid_control get data rates UNIMPLEMENTED\n");
+        ret = USB_RET_STALL;
+        break;
+    default:
+fail:
+        DPRINTF(s, 1, "got unsupported/bogus control %x, value %x\n",
+                request, value);
+        ret = USB_RET_STALL;
+        break;
+    }
+    return ret;
+}
+
+static bool ccid_card_inserted(USBCCIDState *s)
+{
+    return s->bmSlotICCState & SLOT_0_STATE_MASK;
+}
+
+static uint8_t ccid_card_status(USBCCIDState *s)
+{
+    return ccid_card_inserted(s)
+            ? (s->powered ?
+                ICC_STATUS_PRESENT_ACTIVE
+              : ICC_STATUS_PRESENT_INACTIVE
+              )
+            : ICC_STATUS_NOT_PRESENT;
+}
+
+static uint8_t ccid_calc_status(USBCCIDState *s)
+{
+    /*
+     * page 55, 6.2.6, calculation of bStatus from bmICCStatus and
+     * bmCommandStatus
+     */
+    uint8_t ret = ccid_card_status(s) | (s->bmCommandStatus << 6);
+    DPRINTF(s, D_VERBOSE, "status = %d\n", ret);
+    return ret;
+}
+
+static void ccid_reset_error_status(USBCCIDState *s)
+{
+    s->bError = ERROR_CMD_NOT_SUPPORTED;
+    s->bmCommandStatus = COMMAND_STATUS_NO_ERROR;
+}
+
+static void ccid_write_slot_status(USBCCIDState *s, CCID_Header *recv)
+{
+    CCID_SlotStatus *h = ccid_reserve_recv_buf(s, sizeof(CCID_SlotStatus));
+    if (h == NULL) {
+        return;
+    }
+    h->b.hdr.bMessageType = CCID_MESSAGE_TYPE_RDR_to_PC_SlotStatus;
+    h->b.hdr.dwLength = 0;
+    h->b.hdr.bSlot = recv->bSlot;
+    h->b.hdr.bSeq = recv->bSeq;
+    h->b.bStatus = ccid_calc_status(s);
+    h->b.bError = s->bError;
+    h->bClockStatus = CLOCK_STATUS_RUNNING;
+    ccid_reset_error_status(s);
+}
+
+static void ccid_write_parameters(USBCCIDState *s, CCID_Header *recv)
+{
+    CCID_Parameter *h;
+    uint32_t len = s->ulProtocolDataStructureSize;
+
+    h = ccid_reserve_recv_buf(s, sizeof(CCID_Parameter) + len);
+    if (h == NULL) {
+        return;
+    }
+    h->b.hdr.bMessageType = CCID_MESSAGE_TYPE_RDR_to_PC_Parameters;
+    h->b.hdr.dwLength = 0;
+    h->b.hdr.bSlot = recv->bSlot;
+    h->b.hdr.bSeq = recv->bSeq;
+    h->b.bStatus = ccid_calc_status(s);
+    h->b.bError = s->bError;
+    h->bProtocolNum = s->bProtocolNum;
+    memcpy(h->abProtocolDataStructure, s->abProtocolDataStructure, len);
+    ccid_reset_error_status(s);
+}
+
+static void ccid_write_data_block(USBCCIDState *s, uint8_t slot, uint8_t seq,
+                                  const uint8_t *data, uint32_t len)
+{
+    CCID_DataBlock *p = ccid_reserve_recv_buf(s, sizeof(*p) + len);
+
+    if (p == NULL) {
+        return;
+    }
+    p->b.hdr.bMessageType = CCID_MESSAGE_TYPE_RDR_to_PC_DataBlock;
+    p->b.hdr.dwLength = cpu_to_le32(len);
+    p->b.hdr.bSlot = slot;
+    p->b.hdr.bSeq = seq;
+    p->b.bStatus = ccid_calc_status(s);
+    p->b.bError = s->bError;
+    if (p->b.bError) {
+        DPRINTF(s, D_VERBOSE, "error %d", p->b.bError);
+    }
+    memcpy(p->abData, data, len);
+    ccid_reset_error_status(s);
+}
+
+static void ccid_write_data_block_answer(USBCCIDState *s,
+    const uint8_t *data, uint32_t len)
+{
+    uint8_t seq;
+    uint8_t slot;
+
+    if (!ccid_has_pending_answers(s)) {
+        abort();
+    }
+    ccid_remove_pending_answer(s, &slot, &seq);
+    ccid_write_data_block(s, slot, seq, data, len);
+}
+
+static void ccid_write_data_block_atr(USBCCIDState *s, CCID_Header *recv)
+{
+    const uint8_t *atr = NULL;
+    uint32_t len = 0;
+
+    if (s->card) {
+        atr = s->cardinfo->get_atr(s->card, &len);
+    }
+    ccid_write_data_block(s, recv->bSlot, recv->bSeq, atr, len);
+}
+
+static void ccid_set_parameters(USBCCIDState *s, CCID_Header *recv)
+{
+    CCID_SetParameters *ph = (CCID_SetParameters *) recv;
+    uint32_t len = 0;
+    if ((ph->bProtocolNum & 3) == 0) {
+        len = 5;
+    }
+    if ((ph->bProtocolNum & 3) == 1) {
+        len = 7;
+    }
+    if (len == 0) {
+        s->bmCommandStatus = COMMAND_STATUS_FAILED;
+        s->bError = 7; /* Protocol invalid or not supported */
+        return;
+    }
+    s->bProtocolNum = ph->bProtocolNum;
+    memcpy(s->abProtocolDataStructure, ph->abProtocolDataStructure, len);
+    s->ulProtocolDataStructureSize = len;
+    DPRINTF(s, 1, "%s: using len %d\n", __func__, len);
+}
+
+/*
+ * must be 5 bytes for T=0, 7 bytes for T=1
+ * See page 52
+ */
+static const uint8_t abDefaultProtocolDataStructure[7] = {
+    0x77, 0x00, 0x00, 0x00, 0x00, 0xfe /*IFSC*/, 0x00 /*NAD*/ };
+
+static void ccid_reset_parameters(USBCCIDState *s)
+{
+   uint32_t len = sizeof(abDefaultProtocolDataStructure);
+
+   s->bProtocolNum = 1; /* T=1 */
+   s->ulProtocolDataStructureSize = len;
+   memcpy(s->abProtocolDataStructure, abDefaultProtocolDataStructure, len);
+}
+
+static void ccid_report_error_failed(USBCCIDState *s, uint8_t error)
+{
+    s->bmCommandStatus = COMMAND_STATUS_FAILED;
+    s->bError = error;
+}
+
+/* NOTE: only a single slot is supported (SLOT_0) */
+static void ccid_on_slot_change(USBCCIDState *s, bool full)
+{
+    /* RDR_to_PC_NotifySlotChange, 6.3.1 page 56 */
+    uint8_t current = s->bmSlotICCState;
+    if (full) {
+        s->bmSlotICCState |= SLOT_0_STATE_MASK;
+    } else {
+        s->bmSlotICCState &= ~SLOT_0_STATE_MASK;
+    }
+    if (current != s->bmSlotICCState) {
+        s->bmSlotICCState |= SLOT_0_CHANGED_MASK;
+    }
+    s->notify_slot_change = true;
+}
+
+static void ccid_write_data_block_error(
+    USBCCIDState *s, uint8_t slot, uint8_t seq)
+{
+    ccid_write_data_block(s, slot, seq, NULL, 0);
+}
+
+static void ccid_on_apdu_from_guest(USBCCIDState *s, CCID_XferBlock *recv)
+{
+    uint32_t len;
+
+    if (ccid_card_status(s) != ICC_STATUS_PRESENT_ACTIVE) {
+        DPRINTF(s, 1,
+                "usb-ccid: not sending apdu to client, no card connected\n");
+        ccid_write_data_block_error(s, recv->hdr.bSlot, recv->hdr.bSeq);
+        return;
+    }
+    len = le32_to_cpu(recv->hdr.dwLength);
+    DPRINTF(s, 1, "%s: seq %d, len %d\n", __func__,
+                recv->hdr.bSeq, len);
+    ccid_add_pending_answer(s, (CCID_Header *)recv);
+    if (s->card) {
+        s->cardinfo->apdu_from_guest(s->card, recv->abData, len);
+    } else {
+        DPRINTF(s, D_WARN, "warning: discarded apdu\n");
+    }
+}
+
+/*
+ * Handle a single USB_TOKEN_OUT, return value returned to guest.
+ * Return value:
+ *  0             - all ok
+ *  USB_RET_STALL - failed to handle packet
+ */
+static int ccid_handle_bulk_out(USBCCIDState *s, USBPacket *p)
+{
+    CCID_Header *ccid_header;
+
+    if (p->len + s->bulk_out_pos > BULK_OUT_DATA_SIZE) {
+        return USB_RET_STALL;
+    }
+    ccid_header = (CCID_Header *)s->bulk_out_data;
+    memcpy(s->bulk_out_data + s->bulk_out_pos, p->data, p->len);
+    s->bulk_out_pos += p->len;
+    if (p->len == CCID_MAX_PACKET_SIZE) {
+        DPRINTF(s, D_VERBOSE,
+            "usb-ccid: bulk_in: expecting more packets (%d/%d)\n",
+            p->len, ccid_header->dwLength);
+        return 0;
+    }
+    if (s->bulk_out_pos < 10) {
+        DPRINTF(s, 1,
+                "%s: bad USB_TOKEN_OUT length, should be at least 10 bytes\n",
+                __func__);
+    } else {
+        DPRINTF(s, D_MORE_INFO, "%s %x\n", __func__, ccid_header->bMessageType);
+        switch (ccid_header->bMessageType) {
+        case CCID_MESSAGE_TYPE_PC_to_RDR_GetSlotStatus:
+            ccid_write_slot_status(s, ccid_header);
+            break;
+        case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOn:
+            DPRINTF(s, 1, "PowerOn: %d\n",
+                ((CCID_IccPowerOn *)(ccid_header))->bPowerSelect);
+            s->powered = true;
+            if (!ccid_card_inserted(s)) {
+                ccid_report_error_failed(s, ERROR_ICC_MUTE);
+            }
+            /* atr is written regardless of error. */
+            ccid_write_data_block_atr(s, ccid_header);
+            break;
+        case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOff:
+            DPRINTF(s, 1, "PowerOff\n");
+            ccid_reset_error_status(s);
+            s->powered = false;
+            ccid_write_slot_status(s, ccid_header);
+            break;
+        case CCID_MESSAGE_TYPE_PC_to_RDR_XfrBlock:
+            ccid_on_apdu_from_guest(s, (CCID_XferBlock *)s->bulk_out_data);
+            break;
+        case CCID_MESSAGE_TYPE_PC_to_RDR_SetParameters:
+            ccid_reset_error_status(s);
+            ccid_set_parameters(s, ccid_header);
+            ccid_write_parameters(s, ccid_header);
+            break;
+        case CCID_MESSAGE_TYPE_PC_to_RDR_ResetParameters:
+            ccid_reset_error_status(s);
+            ccid_reset_parameters(s);
+            ccid_write_parameters(s, ccid_header);
+            break;
+        case CCID_MESSAGE_TYPE_PC_to_RDR_GetParameters:
+            ccid_reset_error_status(s);
+            ccid_write_parameters(s, ccid_header);
+            break;
+        default:
+            DPRINTF(s, 1,
+                "handle_data: ERROR: unhandled message type %Xh\n",
+                ccid_header->bMessageType);
+            /*
+             * The caller is expecting the device to respond, tell it we
+             * don't support the operation.
+             */
+            ccid_report_error_failed(s, ERROR_CMD_NOT_SUPPORTED);
+            ccid_write_slot_status(s, ccid_header);
+            break;
+        }
+    }
+    s->bulk_out_pos = 0;
+    return 0;
+}
+
+static int ccid_bulk_in_copy_to_guest(USBCCIDState *s, uint8_t *data, int len)
+{
+    int ret = 0;
+
+    assert(len > 0);
+    ccid_bulk_in_get(s);
+    if (s->current_bulk_in != NULL) {
+        ret = MIN(s->current_bulk_in->len - s->current_bulk_in->pos, len);
+        memcpy(data, s->current_bulk_in->data + s->current_bulk_in->pos, ret);
+        s->current_bulk_in->pos += ret;
+        if (s->current_bulk_in->pos == s->current_bulk_in->len) {
+            ccid_bulk_in_release(s);
+        }
+    } else {
+        /* return when device has no data - usb 2.0 spec Table 8-4 */
+        ret = USB_RET_NAK;
+    }
+    if (ret > 0) {
+        DPRINTF(s, D_MORE_INFO,
+                "%s: %d/%d req/act to guest (BULK_IN)\n", __func__, len, ret);
+    }
+    if (ret != USB_RET_NAK && ret < len) {
+        DPRINTF(s, 1,
+            "%s: returning short (EREMOTEIO) %d < %d\n", __func__, ret, len);
+    }
+    return ret;
+}
+
+static int ccid_handle_data(USBDevice *dev, USBPacket *p)
+{
+    USBCCIDState *s = DO_UPCAST(USBCCIDState, dev, dev);
+    int ret = 0;
+    uint8_t *data = p->data;
+    int len = p->len;
+
+    switch (p->pid) {
+    case USB_TOKEN_OUT:
+        ret = ccid_handle_bulk_out(s, p);
+        break;
+
+    case USB_TOKEN_IN:
+        switch (p->devep & 0xf) {
+        case CCID_BULK_IN_EP:
+            if (!len) {
+                ret = USB_RET_NAK;
+            } else {
+                ret = ccid_bulk_in_copy_to_guest(s, data, len);
+            }
+            break;
+        case CCID_INT_IN_EP:
+            if (s->notify_slot_change) {
+                /* page 56, RDR_to_PC_NotifySlotChange */
+                data[0] = CCID_MESSAGE_TYPE_RDR_to_PC_NotifySlotChange;
+                data[1] = s->bmSlotICCState;
+                ret = 2;
+                s->notify_slot_change = false;
+                s->bmSlotICCState &= ~SLOT_0_CHANGED_MASK;
+                DPRINTF(s, D_INFO,
+                        "handle_data: int_in: notify_slot_change %X, "
+                        "requested len %d\n",
+                        s->bmSlotICCState, len);
+            }
+            break;
+        default:
+            DPRINTF(s, 1, "Bad endpoint\n");
+            break;
+        }
+        break;
+    default:
+        DPRINTF(s, 1, "Bad token\n");
+        ret = USB_RET_STALL;
+        break;
+    }
+
+    return ret;
+}
+
+static void ccid_handle_destroy(USBDevice *dev)
+{
+    USBCCIDState *s = DO_UPCAST(USBCCIDState, dev, dev);
+
+    ccid_bulk_in_clear(s);
+}
+
+static void ccid_flush_pending_answers(USBCCIDState *s)
+{
+    while (ccid_has_pending_answers(s)) {
+        ccid_write_data_block_answer(s, NULL, 0);
+    }
+}
+
+static Answer *ccid_peek_next_answer(USBCCIDState *s)
+{
+    return s->pending_answers_num == 0
+        ? NULL
+        : &s->pending_answers[s->pending_answers_start % PENDING_ANSWERS_NUM];
+}
+
+static void ccid_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
+{
+    CCIDCardState *card = DO_UPCAST(CCIDCardState, qdev, qdev);
+    CCIDCardInfo *info = DO_UPCAST(CCIDCardInfo, qdev, qdev->info);
+
+    if (info->print) {
+        info->print(mon, card, indent);
+    }
+}
+
+struct CCIDBus {
+    BusState qbus;
+};
+
+static struct BusInfo ccid_bus_info = {
+    .name = "ccid-bus",
+    .size = sizeof(CCIDBus),
+    .print_dev = ccid_bus_dev_print,
+    .props = (Property[]) {
+        DEFINE_PROP_UINT32("slot", struct CCIDCardState, slot, 0),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
+static CCIDBus *ccid_bus_new(DeviceState *dev)
+{
+    CCIDBus *bus;
+
+    bus = FROM_QBUS(CCIDBus, qbus_create(&ccid_bus_info, dev, NULL));
+    bus->qbus.allow_hotplug = 1;
+
+    return bus;
+}
+
+void ccid_card_send_apdu_to_guest(CCIDCardState *card,
+                                  uint8_t *apdu, uint32_t len)
+{
+    USBCCIDState *s = DO_UPCAST(USBCCIDState, dev.qdev,
+                                card->qdev.parent_bus->parent);
+    Answer *answer;
+
+    if (!ccid_has_pending_answers(s)) {
+        DPRINTF(s, 1, "CCID ERROR: got an APDU without pending answers\n");
+        return;
+    }
+    s->bmCommandStatus = COMMAND_STATUS_NO_ERROR;
+    answer = ccid_peek_next_answer(s);
+    if (answer == NULL) {
+        abort();
+    }
+    DPRINTF(s, 1, "APDU returned to guest %d (answer seq %d, slot %d)\n",
+        len, answer->seq, answer->slot);
+    ccid_write_data_block_answer(s, apdu, len);
+}
+
+void ccid_card_card_removed(CCIDCardState *card)
+{
+    USBCCIDState *s =
+        DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent);
+
+    ccid_on_slot_change(s, false);
+    ccid_flush_pending_answers(s);
+    ccid_reset(s);
+}
+
+int ccid_card_ccid_attach(CCIDCardState *card)
+{
+    USBCCIDState *s =
+        DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent);
+
+    DPRINTF(s, 1, "CCID Attach\n");
+    if (s->migration_state == MIGRATION_MIGRATED) {
+        s->migration_state = MIGRATION_NONE;
+    }
+    return 0;
+}
+
+void ccid_card_ccid_detach(CCIDCardState *card)
+{
+    USBCCIDState *s =
+        DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent);
+
+    DPRINTF(s, 1, "CCID Detach\n");
+    if (ccid_card_inserted(s)) {
+        ccid_on_slot_change(s, false);
+    }
+    ccid_detach(s);
+}
+
+void ccid_card_card_error(CCIDCardState *card, uint64_t error)
+{
+    USBCCIDState *s =
+        DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent);
+
+    s->bmCommandStatus = COMMAND_STATUS_FAILED;
+    s->last_answer_error = error;
+    DPRINTF(s, 1, "VSC_Error: %lX\n", s->last_answer_error);
+    /* TODO: these error's should be more verbose and propogated to the guest.*/
+    /*
+     * We flush all pending answers on CardRemove message in ccid-card-passthru,
+     * so check that first to not trigger abort
+     */
+    if (ccid_has_pending_answers(s)) {
+        ccid_write_data_block_answer(s, NULL, 0);
+    }
+}
+
+void ccid_card_card_inserted(CCIDCardState *card)
+{
+    USBCCIDState *s =
+        DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent);
+
+    s->bmCommandStatus = COMMAND_STATUS_NO_ERROR;
+    ccid_flush_pending_answers(s);
+    ccid_on_slot_change(s, true);
+}
+
+static int ccid_card_exit(DeviceState *qdev)
+{
+    int ret = 0;
+    CCIDCardState *card = DO_UPCAST(CCIDCardState, qdev, qdev);
+    CCIDCardInfo *info = DO_UPCAST(CCIDCardInfo, qdev, qdev->info);
+    USBCCIDState *s =
+        DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent);
+
+    if (ccid_card_inserted(s)) {
+        ccid_card_card_removed(card);
+    }
+    if (info->exitfn) {
+        ret = info->exitfn(card);
+    }
+    s->card = NULL;
+    s->cardinfo = NULL;
+    return ret;
+}
+
+static int ccid_card_init(DeviceState *qdev, DeviceInfo *base)
+{
+    CCIDCardState *card = DO_UPCAST(CCIDCardState, qdev, qdev);
+    CCIDCardInfo *info = DO_UPCAST(CCIDCardInfo, qdev, base);
+    USBCCIDState *s =
+        DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent);
+    int ret = 0;
+
+    if (card->slot != 0) {
+        error_report("Warning: usb-ccid supports one slot, can't add %d",
+                card->slot);
+        return -1;
+    }
+    if (s->card != NULL) {
+        error_report("Warning: usb-ccid card already full, not adding\n");
+        return -1;
+    }
+    ret = info->initfn ? info->initfn(card) : ret;
+    if (ret == 0) {
+        s->card = card;
+        s->cardinfo = info;
+    }
+    return ret;
+}
+
+void ccid_card_qdev_register(CCIDCardInfo *card)
+{
+    card->qdev.bus_info = &ccid_bus_info;
+    card->qdev.init = ccid_card_init;
+    card->qdev.exit = ccid_card_exit;
+    qdev_register(&card->qdev);
+}
+
+static int ccid_initfn(USBDevice *dev)
+{
+    USBCCIDState *s = DO_UPCAST(USBCCIDState, dev, dev);
+
+    s->bus = ccid_bus_new(&dev->qdev);
+    s->card = NULL;
+    s->cardinfo = NULL;
+    s->migration_state = MIGRATION_NONE;
+    s->migration_target_ip = 0;
+    s->migration_target_port = 0;
+    s->dev.speed = USB_SPEED_FULL;
+    s->notify_slot_change = false;
+    s->powered = true;
+    s->pending_answers_num = 0;
+    s->last_answer_error = 0;
+    s->bulk_in_pending_start = 0;
+    s->bulk_in_pending_end = 0;
+    s->current_bulk_in = NULL;
+    ccid_reset_error_status(s);
+    s->bulk_out_pos = 0;
+    ccid_reset_parameters(s);
+    ccid_reset(s);
+    return 0;
+}
+
+static int ccid_post_load(void *opaque, int version_id)
+{
+    USBCCIDState *s = opaque;
+
+    /*
+     * This must be done after usb_device_attach, which sets state to ATTACHED,
+     * while it must be DEFAULT in order to accept packets (like it is after
+     * reset, but reset will reset our addr and call our reset handler which
+     * may change state, and we don't want to do that when migrating).
+     */
+    s->dev.state = s->state_vmstate;
+    return 0;
+}
+
+static void ccid_pre_save(void *opaque)
+{
+    USBCCIDState *s = opaque;
+
+    s->state_vmstate = s->dev.state;
+    if (s->dev.attached) {
+        /*
+         * Migrating an open device, ignore reconnection CHR_EVENT to avoid an
+         * erronous detach.
+         */
+        s->migration_state = MIGRATION_MIGRATED;
+    }
+}
+
+static VMStateDescription bulk_in_vmstate = {
+    .name = "CCID BulkIn state",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_BUFFER(data, BulkIn),
+        VMSTATE_UINT32(len, BulkIn),
+        VMSTATE_UINT32(pos, BulkIn),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static VMStateDescription answer_vmstate = {
+    .name = "CCID Answer state",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT8(slot, Answer),
+        VMSTATE_UINT8(seq, Answer),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static VMStateDescription usb_device_vmstate = {
+    .name = "usb_device",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT8(addr, USBDevice),
+        VMSTATE_BUFFER(setup_buf, USBDevice),
+        VMSTATE_BUFFER(data_buf, USBDevice),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static VMStateDescription ccid_vmstate = {
+    .name = CCID_DEV_NAME,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .post_load = ccid_post_load,
+    .pre_save = ccid_pre_save,
+    .fields = (VMStateField[]) {
+        VMSTATE_STRUCT(dev, USBCCIDState, 1, usb_device_vmstate, USBDevice),
+        VMSTATE_UINT8(debug, USBCCIDState),
+        VMSTATE_BUFFER(bulk_out_data, USBCCIDState),
+        VMSTATE_UINT32(bulk_out_pos, USBCCIDState),
+        VMSTATE_UINT8(bmSlotICCState, USBCCIDState),
+        VMSTATE_UINT8(powered, USBCCIDState),
+        VMSTATE_UINT8(notify_slot_change, USBCCIDState),
+        VMSTATE_UINT64(last_answer_error, USBCCIDState),
+        VMSTATE_UINT8(bError, USBCCIDState),
+        VMSTATE_UINT8(bmCommandStatus, USBCCIDState),
+        VMSTATE_UINT8(bProtocolNum, USBCCIDState),
+        VMSTATE_BUFFER(abProtocolDataStructure, USBCCIDState),
+        VMSTATE_UINT32(ulProtocolDataStructureSize, USBCCIDState),
+        VMSTATE_STRUCT_ARRAY(bulk_in_pending, USBCCIDState,
+                       BULK_IN_PENDING_NUM, 1, bulk_in_vmstate, BulkIn),
+        VMSTATE_UINT32(bulk_in_pending_start, USBCCIDState),
+        VMSTATE_UINT32(bulk_in_pending_end, USBCCIDState),
+        VMSTATE_STRUCT_ARRAY(pending_answers, USBCCIDState,
+                        PENDING_ANSWERS_NUM, 1, answer_vmstate, Answer),
+        VMSTATE_UINT32(pending_answers_num, USBCCIDState),
+        VMSTATE_UINT8(migration_state, USBCCIDState),
+        VMSTATE_UINT32(state_vmstate, USBCCIDState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static struct USBDeviceInfo ccid_info = {
+    .product_desc   = "QEMU USB CCID",
+    .qdev.name      = CCID_DEV_NAME,
+    .qdev.desc      = "CCID Rev 1.1 smartcard reader",
+    .qdev.size      = sizeof(USBCCIDState),
+    .init           = ccid_initfn,
+    .handle_packet  = usb_generic_handle_packet,
+    .handle_reset   = ccid_handle_reset,
+    .handle_control = ccid_handle_control,
+    .handle_data    = ccid_handle_data,
+    .handle_destroy = ccid_handle_destroy,
+    .usbdevice_name = "ccid",
+    .qdev.props     = (Property[]) {
+        DEFINE_PROP_UINT8("debug", USBCCIDState, debug, 0),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+    .qdev.vmsd      = &ccid_vmstate,
+};
+
+static void ccid_register_devices(void)
+{
+    usb_qdev_register(&ccid_info);
+}
+device_init(ccid_register_devices)

From 0c16524709f38bb529f68c0921e72207606c57b1 Mon Sep 17 00:00:00 2001
From: Alon Levy <alevy@redhat.com>
Date: Wed, 2 Feb 2011 21:48:04 +0200
Subject: [PATCH 048/386] introduce libcacard/vscard_common.h

---

Signed-off-by: Alon Levy <alevy@redhat.com>

v20->v21 changes: (Jes Sorensen review)
 * license set to 2+
 * long comment fixes, remove empty line at eof.
 * add reference to COPYING

v19->v20 changes:
 * checkpatch.pl

v15->v16 changes:

Protocol change:
 * VSCMsgInit capabilities and magic
 * removed ReaderResponse, will use Error instead with code==VSC_SUCCESS.
 * adaded Flush and FlushComplete, remove Reconnect.
 * define VSCARD_MAGIC
 * added error code VSC_SUCCESS.

Fixes:
 * update VSCMsgInit comment
 * fix message type enum
 * remove underscore from wrapping define
 * update copyright
 * updated comments.
 * Header comment updated
 * remove C++ style comment
 * fix comment for VSCMsgError
 * give names to enums in typedefs
---
 libcacard/vscard_common.h | 178 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 178 insertions(+)
 create mode 100644 libcacard/vscard_common.h

diff --git a/libcacard/vscard_common.h b/libcacard/vscard_common.h
new file mode 100644
index 0000000000..bebd52db17
--- /dev/null
+++ b/libcacard/vscard_common.h
@@ -0,0 +1,178 @@
+/* Virtual Smart Card protocol definition
+ *
+ * This protocol is between a host using virtual smart card readers,
+ * and a client providing the smart cards, perhaps by emulating them or by
+ * access to real cards.
+ *
+ * Definitions for this protocol:
+ *  Host   - user of the card
+ *  Client - owner of the card
+ *
+ * The current implementation passes the raw APDU's from 7816 and additionally
+ * contains messages to setup and teardown readers, handle insertion and
+ * removal of cards, negotiate the protocol via capabilities and provide
+ * for error responses.
+ *
+ * Copyright (c) 2011 Red Hat.
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef VSCARD_COMMON_H
+#define VSCARD_COMMON_H
+
+#include <stdint.h>
+
+#define VERSION_MAJOR_BITS 11
+#define VERSION_MIDDLE_BITS 11
+#define VERSION_MINOR_BITS 10
+
+#define MAKE_VERSION(major, middle, minor) \
+     ((major  << (VERSION_MINOR_BITS + VERSION_MIDDLE_BITS)) \
+      | (middle <<  VERSION_MINOR_BITS) \
+      | (minor))
+
+/*
+ * IMPORTANT NOTE on VERSION
+ *
+ * The version below MUST be changed whenever a change in this file is made.
+ *
+ * The last digit, the minor, is for bug fix changes only.
+ *
+ * The middle digit is for backward / forward compatible changes, updates
+ * to the existing messages, addition of fields.
+ *
+ * The major digit is for a breaking change of protocol, presumably
+ * something that cannot be accomodated with the existing protocol.
+ */
+
+#define VSCARD_VERSION MAKE_VERSION(0, 0, 2)
+
+typedef enum VSCMsgType {
+    VSC_Init = 1,
+    VSC_Error,
+    VSC_ReaderAdd,
+    VSC_ReaderRemove,
+    VSC_ATR,
+    VSC_CardRemove,
+    VSC_APDU,
+    VSC_Flush,
+    VSC_FlushComplete
+} VSCMsgType;
+
+typedef enum VSCErrorCode {
+    VSC_SUCCESS = 0,
+    VSC_GENERAL_ERROR = 1,
+    VSC_CANNOT_ADD_MORE_READERS,
+    VSC_CARD_ALREAY_INSERTED,
+} VSCErrorCode;
+
+#define VSCARD_UNDEFINED_READER_ID  0xffffffff
+#define VSCARD_MINIMAL_READER_ID    0
+
+#define VSCARD_MAGIC (*(uint32_t *)"VSCD")
+
+/*
+ * Header
+ * Each message starts with the header.
+ * type - message type
+ * reader_id - used by messages that are reader specific
+ * length - length of payload (not including header, i.e. zero for
+ *  messages containing empty payloads)
+ */
+typedef struct VSCMsgHeader {
+    uint32_t   type;
+    uint32_t   reader_id;
+    uint32_t   length;
+    uint8_t    data[0];
+} VSCMsgHeader;
+
+/*
+ * VSCMsgInit               Client <-> Host
+ * Client sends it on connection, with its own capabilities.
+ * Host replies with VSCMsgInit filling in its capabilities.
+ *
+ * It is not meant to be used for negotiation, i.e. sending more then
+ * once from any side, but could be used for that in the future.
+ */
+typedef struct VSCMsgInit {
+    uint32_t   magic;
+    uint32_t   version;
+    uint32_t   capabilities[1]; /* receiver must check length,
+                                   array may grow in the future*/
+} VSCMsgInit;
+
+/*
+ * VSCMsgError              Client <-> Host
+ * This message is a response to any of:
+ *  Reader Add
+ *  Reader Remove
+ *  Card Remove
+ * If the operation was successful then VSC_SUCCESS
+ * is returned, other wise a specific error code.
+ */
+typedef struct VSCMsgError {
+    uint32_t   code;
+} VSCMsgError;
+
+/*
+ * VSCMsgReaderAdd          Client -> Host
+ * Host replies with allocated reader id in VSCMsgError with code==SUCCESS.
+ *
+ * name - name of the reader on client side, UTF-8 encoded. Only used
+ *  for client presentation (may be translated to the device presented to the
+ *  guest), protocol wise only reader_id is important.
+ */
+typedef struct VSCMsgReaderAdd {
+    uint8_t    name[0];
+} VSCMsgReaderAdd;
+
+/*
+ * VSCMsgReaderRemove       Client -> Host
+ * The client's reader has been removed.
+ */
+typedef struct VSCMsgReaderRemove {
+} VSCMsgReaderRemove;
+
+/*
+ * VSCMsgATR                Client -> Host
+ * Answer to reset. Sent for card insertion or card reset. The reset/insertion
+ * happens on the client side, they do not require any action from the host.
+ */
+typedef struct VSCMsgATR {
+    uint8_t     atr[0];
+} VSCMsgATR;
+
+/*
+ * VSCMsgCardRemove         Client -> Host
+ * The client card has been removed.
+ */
+typedef struct VSCMsgCardRemove {
+} VSCMsgCardRemove;
+
+/*
+ * VSCMsgAPDU               Client <-> Host
+ * Main reason of existance. Transfer a single APDU in either direction.
+ */
+typedef struct VSCMsgAPDU {
+    uint8_t    data[0];
+} VSCMsgAPDU;
+
+/*
+ * VSCMsgFlush               Host -> Client
+ * Request client to send a FlushComplete message when it is done
+ * servicing all outstanding APDUs
+ */
+typedef struct VSCMsgFlush {
+} VSCMsgFlush;
+
+/*
+ * VSCMsgFlush               Client -> Host
+ * Client response to Flush after all APDUs have been processed and
+ * responses sent.
+ */
+typedef struct VSCMsgFlushComplete {
+} VSCMsgFlushComplete;
+
+#endif /* VSCARD_COMMON_H */

From edbb21363fbfe40e050f583df921484cbc31c79d Mon Sep 17 00:00:00 2001
From: Alon Levy <alevy@redhat.com>
Date: Sun, 17 Oct 2010 13:10:32 +0200
Subject: [PATCH 049/386] ccid: add passthru card device

The passthru ccid card is a device sitting on the usb-ccid bus and
using a chardevice to communicate with a remote device using the
VSCard protocol defined in libcacard/vscard_common.h

Usage docs available in following patch in docs/ccid.txt

Signed-off-by: Alon Levy <alevy@redhat.com>

---

Changes from v23->v24:
 * fixed double license line in header.

Changes from v20->v21: (Jes Sorensen review)
 * add reference to COPYING in header
 * long comment reformatting

Changes from v19->v20:
 * checkpatch.pl

Changes from v18->v19:
 * add qdev.desc
 * remove .qdev.unplug (no hot unplug support for ccid bus)

Changes from v16->v17:
 * fix wrong cast when receiving VSC_Error
 * ccid-card-passthru: force chardev user wakeup by sending Init
   see lengthy comment below.

Changes from v15->v16:

Behavioral changes:
 * return correct size
 * return error instead of assert if client sent too large ATR
 * don't assert if client sent too large a size, but add asserts for indices to buffer
 * reset vscard_in indices on chardev disconnect
 * handle init from client
 * error if no chardev supplied
 * use ntoh, hton
 * eradicate reader_id_t
 * remove Reconnect usage (removed from VSCARD protocol)
 * send VSC_SUCCESS on card insert/remove and reader add/remove

Style fixes:
 * width of line fix
 * update copyright
 * remove old TODO's
 * update file header comment
 * use macros for debug levels
 * c++ style comment replacement
 * update copyright license
 * fix ATR size comment
 * fix whitespace in struct def
 * fix DPRINTF prefix
 * line width fix

ccid-card-passthru: force chardev user wakeup by sending Init

The problem: how to wakeup the user of the smartcard when the smartcard
device is initialized?

Long term solution: have a callback interface. This was done via
the deprecated so called chardev ioctl interface.

Short term solution: do a write. Specifically we write an Init message.
And we change the client to send it's own Init message regardless of
receiving this one. Additional Init messages will be regarded as
acceptable, the first one received after connection establishment is
the determining one wrt capabilities.
---
 Makefile.objs           |   2 +-
 hw/ccid-card-passthru.c | 340 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 341 insertions(+), 1 deletion(-)
 create mode 100644 hw/ccid-card-passthru.c

diff --git a/Makefile.objs b/Makefile.objs
index 7fdfc487fb..07063f1933 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -200,7 +200,7 @@ hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 hw-obj-$(CONFIG_DMA) += dma.o
 hw-obj-$(CONFIG_HPET) += hpet.o
 hw-obj-$(CONFIG_APPLESMC) += applesmc.o
-hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o
+hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
new file mode 100644
index 0000000000..8506fed4fc
--- /dev/null
+++ b/hw/ccid-card-passthru.c
@@ -0,0 +1,340 @@
+/*
+ * CCID Passthru Card Device emulation
+ *
+ * Copyright (c) 2011 Red Hat.
+ * Written by Alon Levy.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <arpa/inet.h>
+
+#include "qemu-char.h"
+#include "monitor.h"
+#include "hw/ccid.h"
+#include "libcacard/vscard_common.h"
+
+#define DPRINTF(card, lvl, fmt, ...)                    \
+do {                                                    \
+    if (lvl <= card->debug) {                           \
+        printf("ccid-card-passthru: " fmt , ## __VA_ARGS__);     \
+    }                                                   \
+} while (0)
+
+#define D_WARN 1
+#define D_INFO 2
+#define D_MORE_INFO 3
+#define D_VERBOSE 4
+
+/* TODO: do we still need this? */
+uint8_t DEFAULT_ATR[] = {
+/*
+ * From some example somewhere
+ * 0x3B, 0xB0, 0x18, 0x00, 0xD1, 0x81, 0x05, 0xB1, 0x40, 0x38, 0x1F, 0x03, 0x28
+ */
+
+/* From an Athena smart card */
+ 0x3B, 0xD5, 0x18, 0xFF, 0x80, 0x91, 0xFE, 0x1F, 0xC3, 0x80, 0x73, 0xC8, 0x21,
+ 0x13, 0x08
+};
+
+
+#define PASSTHRU_DEV_NAME "ccid-card-passthru"
+#define VSCARD_IN_SIZE 65536
+
+/* maximum size of ATR - from 7816-3 */
+#define MAX_ATR_SIZE        40
+
+typedef struct PassthruState PassthruState;
+
+struct PassthruState {
+    CCIDCardState base;
+    CharDriverState *cs;
+    uint8_t  vscard_in_data[VSCARD_IN_SIZE];
+    uint32_t vscard_in_pos;
+    uint32_t vscard_in_hdr;
+    uint8_t  atr[MAX_ATR_SIZE];
+    uint8_t  atr_length;
+    uint8_t  debug;
+};
+
+/*
+ * VSCard protocol over chardev
+ * This code should not depend on the card type.
+ */
+
+static void ccid_card_vscard_send_msg(PassthruState *s,
+        VSCMsgType type, uint32_t reader_id,
+        const uint8_t *payload, uint32_t length)
+{
+    VSCMsgHeader scr_msg_header;
+
+    scr_msg_header.type = htonl(type);
+    scr_msg_header.reader_id = htonl(reader_id);
+    scr_msg_header.length = htonl(length);
+    qemu_chr_write(s->cs, (uint8_t *)&scr_msg_header, sizeof(VSCMsgHeader));
+    qemu_chr_write(s->cs, payload, length);
+}
+
+static void ccid_card_vscard_send_apdu(PassthruState *s,
+    const uint8_t *apdu, uint32_t length)
+{
+    ccid_card_vscard_send_msg(
+        s, VSC_APDU, VSCARD_MINIMAL_READER_ID, apdu, length);
+}
+
+static void ccid_card_vscard_send_error(PassthruState *s,
+                    uint32_t reader_id, VSCErrorCode code)
+{
+    VSCMsgError msg = {.code = htonl(code)};
+
+    ccid_card_vscard_send_msg(
+        s, VSC_Error, reader_id, (uint8_t *)&msg, sizeof(msg));
+}
+
+static void ccid_card_vscard_send_init(PassthruState *s)
+{
+    VSCMsgInit msg = {
+        .version = htonl(VSCARD_VERSION),
+        .magic = VSCARD_MAGIC,
+        .capabilities = {0}
+    };
+
+    ccid_card_vscard_send_msg(s, VSC_Init, VSCARD_UNDEFINED_READER_ID,
+                         (uint8_t *)&msg, sizeof(msg));
+}
+
+static int ccid_card_vscard_can_read(void *opaque)
+{
+    PassthruState *card = opaque;
+
+    return VSCARD_IN_SIZE >= card->vscard_in_pos ?
+           VSCARD_IN_SIZE - card->vscard_in_pos : 0;
+}
+
+static void ccid_card_vscard_handle_init(
+    PassthruState *card, VSCMsgHeader *hdr, VSCMsgInit *init)
+{
+    uint32_t *capabilities;
+    int num_capabilities;
+    int i;
+
+    capabilities = init->capabilities;
+    num_capabilities =
+        1 + ((hdr->length - sizeof(VSCMsgInit)) / sizeof(uint32_t));
+    init->version = ntohl(init->version);
+    for (i = 0 ; i < num_capabilities; ++i) {
+        capabilities[i] = ntohl(capabilities[i]);
+    }
+    if (init->magic != VSCARD_MAGIC) {
+        error_report("wrong magic");
+        /* we can't disconnect the chardev */
+    }
+    if (init->version != VSCARD_VERSION) {
+        DPRINTF(card, D_WARN,
+            "got version %d, have %d", init->version, VSCARD_VERSION);
+    }
+    /* future handling of capabilities, none exist atm */
+    ccid_card_vscard_send_init(card);
+}
+
+static void ccid_card_vscard_handle_message(PassthruState *card,
+    VSCMsgHeader *scr_msg_header)
+{
+    uint8_t *data = (uint8_t *)&scr_msg_header[1];
+
+    switch (scr_msg_header->type) {
+    case VSC_ATR:
+        DPRINTF(card, D_INFO, "VSC_ATR %d\n", scr_msg_header->length);
+        if (scr_msg_header->length > MAX_ATR_SIZE) {
+            error_report("ATR size exceeds spec, ignoring");
+            ccid_card_vscard_send_error(card, scr_msg_header->reader_id,
+                                        VSC_GENERAL_ERROR);
+        }
+        memcpy(card->atr, data, scr_msg_header->length);
+        card->atr_length = scr_msg_header->length;
+        ccid_card_card_inserted(&card->base);
+        ccid_card_vscard_send_error(card, scr_msg_header->reader_id,
+                                    VSC_SUCCESS);
+        break;
+    case VSC_APDU:
+        ccid_card_send_apdu_to_guest(
+            &card->base, data, scr_msg_header->length);
+        break;
+    case VSC_CardRemove:
+        DPRINTF(card, D_INFO, "VSC_CardRemove\n");
+        ccid_card_card_removed(&card->base);
+        ccid_card_vscard_send_error(card,
+            scr_msg_header->reader_id, VSC_SUCCESS);
+        break;
+    case VSC_Init:
+        ccid_card_vscard_handle_init(
+            card, scr_msg_header, (VSCMsgInit *)data);
+        break;
+    case VSC_Error:
+        ccid_card_card_error(&card->base, *(uint32_t *)data);
+        break;
+    case VSC_ReaderAdd:
+        if (ccid_card_ccid_attach(&card->base) < 0) {
+            ccid_card_vscard_send_error(card, VSCARD_UNDEFINED_READER_ID,
+                                      VSC_CANNOT_ADD_MORE_READERS);
+        } else {
+            ccid_card_vscard_send_error(card, VSCARD_MINIMAL_READER_ID,
+                                        VSC_SUCCESS);
+        }
+        break;
+    case VSC_ReaderRemove:
+        ccid_card_ccid_detach(&card->base);
+        ccid_card_vscard_send_error(card,
+            scr_msg_header->reader_id, VSC_SUCCESS);
+        break;
+    default:
+        printf("usb-ccid: chardev: unexpected message of type %X\n",
+               scr_msg_header->type);
+        ccid_card_vscard_send_error(card, scr_msg_header->reader_id,
+            VSC_GENERAL_ERROR);
+    }
+}
+
+static void ccid_card_vscard_drop_connection(PassthruState *card)
+{
+    qemu_chr_close(card->cs);
+    card->vscard_in_pos = card->vscard_in_hdr = 0;
+}
+
+static void ccid_card_vscard_read(void *opaque, const uint8_t *buf, int size)
+{
+    PassthruState *card = opaque;
+    VSCMsgHeader *hdr;
+
+    if (card->vscard_in_pos + size > VSCARD_IN_SIZE) {
+        error_report(
+            "no room for data: pos %d +  size %d > %d. dropping connection.",
+            card->vscard_in_pos, size, VSCARD_IN_SIZE);
+        ccid_card_vscard_drop_connection(card);
+        return;
+    }
+    assert(card->vscard_in_pos < VSCARD_IN_SIZE);
+    assert(card->vscard_in_hdr < VSCARD_IN_SIZE);
+    memcpy(card->vscard_in_data + card->vscard_in_pos, buf, size);
+    card->vscard_in_pos += size;
+    hdr = (VSCMsgHeader *)(card->vscard_in_data + card->vscard_in_hdr);
+
+    while ((card->vscard_in_pos - card->vscard_in_hdr >= sizeof(VSCMsgHeader))
+         &&(card->vscard_in_pos - card->vscard_in_hdr >=
+                                  sizeof(VSCMsgHeader) + ntohl(hdr->length))) {
+        hdr->reader_id = ntohl(hdr->reader_id);
+        hdr->length = ntohl(hdr->length);
+        hdr->type = ntohl(hdr->type);
+        ccid_card_vscard_handle_message(card, hdr);
+        card->vscard_in_hdr += hdr->length + sizeof(VSCMsgHeader);
+        hdr = (VSCMsgHeader *)(card->vscard_in_data + card->vscard_in_hdr);
+    }
+    if (card->vscard_in_hdr == card->vscard_in_pos) {
+        card->vscard_in_pos = card->vscard_in_hdr = 0;
+    }
+}
+
+static void ccid_card_vscard_event(void *opaque, int event)
+{
+    PassthruState *card = opaque;
+
+    switch (event) {
+    case CHR_EVENT_BREAK:
+        card->vscard_in_pos = card->vscard_in_hdr = 0;
+        break;
+    case CHR_EVENT_FOCUS:
+        break;
+    case CHR_EVENT_OPENED:
+        DPRINTF(card, D_INFO, "%s: CHR_EVENT_OPENED\n", __func__);
+        break;
+    }
+}
+
+/* End VSCard handling */
+
+static void passthru_apdu_from_guest(
+    CCIDCardState *base, const uint8_t *apdu, uint32_t len)
+{
+    PassthruState *card = DO_UPCAST(PassthruState, base, base);
+
+    if (!card->cs) {
+        printf("ccid-passthru: no chardev, discarding apdu length %d\n", len);
+        return;
+    }
+    ccid_card_vscard_send_apdu(card, apdu, len);
+}
+
+static const uint8_t *passthru_get_atr(CCIDCardState *base, uint32_t *len)
+{
+    PassthruState *card = DO_UPCAST(PassthruState, base, base);
+
+    *len = card->atr_length;
+    return card->atr;
+}
+
+static int passthru_initfn(CCIDCardState *base)
+{
+    PassthruState *card = DO_UPCAST(PassthruState, base, base);
+
+    card->vscard_in_pos = 0;
+    card->vscard_in_hdr = 0;
+    if (card->cs) {
+        DPRINTF(card, D_INFO, "initing chardev\n");
+        qemu_chr_add_handlers(card->cs,
+            ccid_card_vscard_can_read,
+            ccid_card_vscard_read,
+            ccid_card_vscard_event, card);
+        ccid_card_vscard_send_init(card);
+    } else {
+        error_report("missing chardev");
+        return -1;
+    }
+    assert(sizeof(DEFAULT_ATR) <= MAX_ATR_SIZE);
+    memcpy(card->atr, DEFAULT_ATR, sizeof(DEFAULT_ATR));
+    card->atr_length = sizeof(DEFAULT_ATR);
+    return 0;
+}
+
+static int passthru_exitfn(CCIDCardState *base)
+{
+    return 0;
+}
+
+static VMStateDescription passthru_vmstate = {
+    .name = PASSTHRU_DEV_NAME,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_BUFFER(vscard_in_data, PassthruState),
+        VMSTATE_UINT32(vscard_in_pos, PassthruState),
+        VMSTATE_UINT32(vscard_in_hdr, PassthruState),
+        VMSTATE_BUFFER(atr, PassthruState),
+        VMSTATE_UINT8(atr_length, PassthruState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static CCIDCardInfo passthru_card_info = {
+    .qdev.name = PASSTHRU_DEV_NAME,
+    .qdev.desc = "passthrough smartcard",
+    .qdev.size = sizeof(PassthruState),
+    .qdev.vmsd = &passthru_vmstate,
+    .initfn = passthru_initfn,
+    .exitfn = passthru_exitfn,
+    .get_atr = passthru_get_atr,
+    .apdu_from_guest = passthru_apdu_from_guest,
+    .qdev.props     = (Property[]) {
+        DEFINE_PROP_CHR("chardev", PassthruState, cs),
+        DEFINE_PROP_UINT8("debug", PassthruState, debug, 0),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+};
+
+static void ccid_card_passthru_register_devices(void)
+{
+    ccid_card_qdev_register(&passthru_card_info);
+}
+
+device_init(ccid_card_passthru_register_devices)

From 111a38b018c86e6651750c5a548ad534f80b5bb5 Mon Sep 17 00:00:00 2001
From: Robert Relyea <rrelyea@redhat.com>
Date: Sun, 28 Nov 2010 16:36:38 +0200
Subject: [PATCH 050/386] libcacard: initial commit

libcacard emulates a Common Access Card (CAC) which is a standard
for smartcards. It is used by the emulated ccid card introduced in
a following patch. Docs are available in docs/libcacard.txt

Signed-off-by: Alon Levy <alevy@redhat.com>

---

changes from v24->v25:
 * Fix out of tree builds.
 * Fix build with linux-user targets.

changes from v23->v24: (Jes Sorensen review 2)
 * Makefile.target: use obj-$(CONFIG_*) +=
 * remove unrequired includes, include qemu-common before qemu-thread
  * required adding #define NO_NSPR_10_SUPPORT (harmless)

changes from v22->v23:
 * configure fixes: (reported by Stefan Hajnoczi)
  * test a = b, not a == b (second isn't portable)
  * quote $source_path in case it contains spaces
   - this doesn't really help since there are many other places
     that need similar fixes, not introduced by this patch.

changes from v21->v22:
 * fix configure to not link libcacard if nss not found
    (reported by Stefan Hajnoczi)
 * fix vscclient linkage with simpletrace backend
    (reported by Stefan Hajnoczi)
 * card_7816.c: add missing break in ERROR_DATA_NOT_FOUND
    (reported by William van de Velde)

changes from v20->v21: (Jes Sorensen review)
 * use qemu infrastructure: qemu-thread, qemu-common (qemu_malloc
  and qemu_free), error_report
 * assert instead of ASSERT
 * cosmetic fixes
 * use strpbrk and isspace
 * add --disable-nss --enable-nss here, instead of in the final patch.
 * split vscclient, passthru and docs to following patches.

changes from v19->v20:
 * checkpatch.pl

changes from v15->v16:

Build:
 * don't erase self with distclean
 * fix make clean after make distclean
 * Makefile: make vscclient link quiet

Behavioral:
 * vcard_emul_nss: load coolkey in more situations
 * vscclient:
  * use hton,ntoh
  * send init on connect, only start vevent thread on response
  * read payload after header check, before type switch
  * remove Reconnect
  * update for vscard_common changes, empty Flush implementation

Style/Whitespace:
 * fix wrong variable usage
 * remove unused variable
 * use only C style comments
  * add copyright header
  * fix tabulation

Signed-off-by: Alon Levy <alevy@redhat.com>

libcacard: fix out of tree builds
---
 Makefile                    |    6 +-
 Makefile.objs               |    5 +
 Makefile.target             |    6 +
 configure                   |   49 ++
 libcacard/Makefile          |   20 +
 libcacard/cac.c             |  403 ++++++++++++
 libcacard/cac.h             |   23 +
 libcacard/card_7816.c       |  763 +++++++++++++++++++++++
 libcacard/card_7816.h       |   62 ++
 libcacard/card_7816t.h      |  165 +++++
 libcacard/event.c           |  106 ++++
 libcacard/eventt.h          |   29 +
 libcacard/link_test.c       |   22 +
 libcacard/vcard.c           |  339 ++++++++++
 libcacard/vcard.h           |   86 +++
 libcacard/vcard_emul.h      |   65 ++
 libcacard/vcard_emul_nss.c  | 1157 +++++++++++++++++++++++++++++++++++
 libcacard/vcard_emul_type.c |   57 ++
 libcacard/vcard_emul_type.h |   32 +
 libcacard/vcardt.h          |   64 ++
 libcacard/vevent.h          |   27 +
 libcacard/vreader.c         |  513 ++++++++++++++++
 libcacard/vreader.h         |   55 ++
 libcacard/vreadert.h        |   24 +
 24 files changed, 4076 insertions(+), 2 deletions(-)
 create mode 100644 libcacard/Makefile
 create mode 100644 libcacard/cac.c
 create mode 100644 libcacard/cac.h
 create mode 100644 libcacard/card_7816.c
 create mode 100644 libcacard/card_7816.h
 create mode 100644 libcacard/card_7816t.h
 create mode 100644 libcacard/event.c
 create mode 100644 libcacard/eventt.h
 create mode 100644 libcacard/link_test.c
 create mode 100644 libcacard/vcard.c
 create mode 100644 libcacard/vcard.h
 create mode 100644 libcacard/vcard_emul.h
 create mode 100644 libcacard/vcard_emul_nss.c
 create mode 100644 libcacard/vcard_emul_type.c
 create mode 100644 libcacard/vcard_emul_type.h
 create mode 100644 libcacard/vcardt.h
 create mode 100644 libcacard/vevent.h
 create mode 100644 libcacard/vreader.c
 create mode 100644 libcacard/vreader.h
 create mode 100644 libcacard/vreadert.h

diff --git a/Makefile b/Makefile
index 1e3f51a881..fa93be5ed7 100644
--- a/Makefile
+++ b/Makefile
@@ -141,6 +141,8 @@ check-qlist: check-qlist.o qlist.o qint.o $(CHECK_PROG_DEPS)
 check-qfloat: check-qfloat.o qfloat.o $(CHECK_PROG_DEPS)
 check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o qjson.o json-streamer.o json-lexer.o json-parser.o $(CHECK_PROG_DEPS)
 
+QEMULIBS=libhw32 libhw64 libuser libdis libdis-user
+
 clean:
 # avoid old build problems by removing potentially incorrect old files
 	rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
@@ -152,7 +154,7 @@ clean:
 	rm -f trace-dtrace.dtrace trace-dtrace.dtrace-timestamp
 	rm -f trace-dtrace.h trace-dtrace.h-timestamp
 	$(MAKE) -C tests clean
-	for d in $(ALL_SUBDIRS) libhw32 libhw64 libuser libdis libdis-user; do \
+	for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard; do \
 	if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
 	rm -f $$d/qemu-options.def; \
         done
@@ -163,7 +165,7 @@ distclean: clean
 	rm -f roms/seabios/config.mak roms/vgabios/config.mak
 	rm -f qemu-doc.info qemu-doc.aux qemu-doc.cp qemu-doc.dvi qemu-doc.fn qemu-doc.info qemu-doc.ky qemu-doc.log qemu-doc.pdf qemu-doc.pg qemu-doc.toc qemu-doc.tp qemu-doc.vr
 	rm -f qemu-tech.info qemu-tech.aux qemu-tech.cp qemu-tech.dvi qemu-tech.fn qemu-tech.info qemu-tech.ky qemu-tech.log qemu-tech.pdf qemu-tech.pg qemu-tech.toc qemu-tech.tp qemu-tech.vr
-	for d in $(TARGET_DIRS) libhw32 libhw64 libuser libdis libdis-user; do \
+	for d in $(TARGET_DIRS) $(QEMULIBS); do \
 	rm -rf $$d || exit 1 ; \
         done
 
diff --git a/Makefile.objs b/Makefile.objs
index 07063f1933..8c425241fc 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -352,6 +352,11 @@ user-obj-y += qemu-timer-common.o
 endif
 endif
 
+######################################################################
+# smartcard
+
+libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o card_7816.o
+
 vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
 vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
diff --git a/Makefile.target b/Makefile.target
index 565e1fbd04..ace5608016 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -358,6 +358,12 @@ obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y))
 
 endif # CONFIG_SOFTMMU
 
+ifndef CONFIG_LINUX_USER
+# libcacard needs qemu-thread support, and besides is only needed by devices
+# so not requires with linux-user targets
+obj-$(CONFIG_SMARTCARD_NSS) += $(addprefix ../libcacard/, $(libcacard-y))
+endif # CONFIG_LINUX_USER
+
 obj-y += $(addprefix ../, $(trace-obj-y))
 obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o
 
diff --git a/configure b/configure
index 01ee94d009..2ef5c75054 100755
--- a/configure
+++ b/configure
@@ -176,6 +176,7 @@ trace_file="trace"
 spice=""
 rbd=""
 smartcard=""
+smartcard_nss=""
 
 # parse CC options first
 for opt do
@@ -729,6 +730,10 @@ for opt do
   ;;
   --enable-smartcard) smartcard="yes"
   ;;
+  --disable-smartcard-nss) smartcard_nss="no"
+  ;;
+  --enable-smartcard-nss) smartcard_nss="yes"
+  ;;
   *) echo "ERROR: unknown option $opt"; show_help="yes"
   ;;
   esac
@@ -928,6 +933,8 @@ echo "  --enable-spice           enable spice"
 echo "  --enable-rbd             enable building the rados block device (rbd)"
 echo "  --disable-smartcard      disable smartcard support"
 echo "  --enable-smartcard       enable smartcard support"
+echo "  --disable-smartcard-nss  disable smartcard nss support"
+echo "  --enable-smartcard-nss   enable smartcard nss support"
 echo ""
 echo "NOTE: The object files are built at the place where configure is launched"
 exit 1
@@ -2311,6 +2318,31 @@ EOF
   fi
 fi
 
+# check for libcacard for smartcard support
+if test "$smartcard" != "no" ; then
+    smartcard="yes"
+    smartcard_cflags=""
+    # TODO - what's the minimal nss version we support?
+    if test "$smartcard_nss" != "no"; then
+        if $pkg_config --atleast-version=3.12.8 nss >/dev/null 2>&1 ; then
+            smartcard_nss="yes"
+            smartcard_cflags="-I\$(SRC_PATH)/libcacard"
+            libcacard_libs=$($pkg_config --libs nss 2>/dev/null)
+            libcacard_cflags=$($pkg_config --cflags nss 2>/dev/null)
+            QEMU_CFLAGS="$QEMU_CFLAGS $smartcard_cflags $libcacard_cflags"
+            LIBS="$libcacard_libs $LIBS"
+        else
+            if test "$smartcard_nss" = "yes"; then
+                feature_not_found "nss"
+            fi
+            smartcard_nss="no"
+        fi
+    fi
+fi
+if test "$smartcard" = "no" ; then
+    smartcard_nss="no"
+fi
+
 ##########################################
 
 ##########################################
@@ -2549,6 +2581,7 @@ echo "Trace output file $trace_file-<pid>"
 echo "spice support     $spice"
 echo "rbd support       $rbd"
 echo "xfsctl support    $xfs"
+echo "nss used          $smartcard_nss"
 
 if test $sdl_too_old = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -2835,6 +2868,10 @@ if test "$smartcard" = "yes" ; then
   echo "CONFIG_SMARTCARD=y" >> $config_host_mak
 fi
 
+if test "$smartcard_nss" = "yes" ; then
+  echo "CONFIG_SMARTCARD_NSS=y" >> $config_host_mak
+fi
+
 # XXX: suppress that
 if [ "$bsd" = "yes" ] ; then
   echo "CONFIG_BSD=y" >> $config_host_mak
@@ -3183,6 +3220,11 @@ fi
 if test "$target_darwin_user" = "yes" ; then
   echo "CONFIG_DARWIN_USER=y" >> $config_target_mak
 fi
+if test "$smartcard_nss" = "yes" ; then
+  echo "subdir-$target: subdir-libcacard" >> $config_host_mak
+  echo "libcacard_libs=$libcacard_libs" >> $config_host_mak
+  echo "libcacard_cflags=$libcacard_cflags" >> $config_host_mak
+fi
 list=""
 if test ! -z "$gdb_xml_files" ; then
   for x in $gdb_xml_files; do
@@ -3396,6 +3438,13 @@ for hwlib in 32 64; do
   echo "QEMU_CFLAGS+=-DTARGET_PHYS_ADDR_BITS=$hwlib" > $d/config.mak
 done
 
+if [ "$source_path" != `pwd` ]; then
+    # out of tree build
+    mkdir -p libcacard
+    rm -f libcacard/Makefile
+    ln -s "$source_path/libcacard/Makefile" libcacard/Makefile
+fi
+
 d=libuser
 mkdir -p $d
 symlink $source_path/Makefile.user $d/Makefile
diff --git a/libcacard/Makefile b/libcacard/Makefile
new file mode 100644
index 0000000000..0211eacb64
--- /dev/null
+++ b/libcacard/Makefile
@@ -0,0 +1,20 @@
+-include ../config-host.mak
+-include $(SRC_PATH)/Makefile.objs
+-include $(SRC_PATH)/rules.mak
+
+$(call set-vpath, $(SRC_PATH):$(SRC_PATH)/libcacard)
+
+ifeq ($(CONFIG_WIN32),y)
+QEMU_THREAD=qemu-thread-win32.o
+else
+QEMU_THREAD=qemu-thread-posix.o
+endif
+
+
+QEMU_OBJS=$(addprefix ../, $(QEMU_THREAD) $(oslib-obj-y) $(trace-obj-y) qemu-malloc.o qemu-timer-common.o)
+
+QEMU_CFLAGS+=-I../
+
+clean:
+	rm -f *.o */*.o *.d */*.d *.a */*.a *~ */*~
+
diff --git a/libcacard/cac.c b/libcacard/cac.c
new file mode 100644
index 0000000000..f34f63ac78
--- /dev/null
+++ b/libcacard/cac.c
@@ -0,0 +1,403 @@
+/*
+ * implement the applets for the CAC card.
+ *
+ * This code is licensed under the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu-common.h"
+
+#include "cac.h"
+#include "vcard.h"
+#include "vcard_emul.h"
+#include "card_7816.h"
+
+#define CAC_GET_PROPERTIES  0x56
+#define CAC_GET_ACR         0x4c
+#define CAC_READ_BUFFER     0x52
+#define CAC_UPDATE_BUFFER   0x58
+#define CAC_SIGN_DECRYPT    0x42
+#define CAC_GET_CERTIFICATE 0x36
+
+/* private data for PKI applets */
+typedef struct CACPKIAppletDataStruct {
+    unsigned char *cert;
+    int cert_len;
+    unsigned char *cert_buffer;
+    int cert_buffer_len;
+    unsigned char *sign_buffer;
+    int sign_buffer_len;
+    VCardKey *key;
+} CACPKIAppletData;
+
+/*
+ * CAC applet private data
+ */
+struct VCardAppletPrivateStruct {
+    union {
+        CACPKIAppletData pki_data;
+        void *reserved;
+    } u;
+};
+
+/*
+ * handle all the APDU's that are common to all CAC applets
+ */
+static VCardStatus
+cac_common_process_apdu(VCard *card, VCardAPDU *apdu, VCardResponse **response)
+{
+    int ef;
+
+    switch (apdu->a_ins) {
+    case VCARD7816_INS_SELECT_FILE:
+        if (apdu->a_p1 != 0x02) {
+            /* let the 7816 code handle applet switches */
+            return VCARD_NEXT;
+        }
+        /* handle file id setting */
+        if (apdu->a_Lc != 2) {
+            *response = vcard_make_response(
+                VCARD7816_STATUS_ERROR_DATA_INVALID);
+            return VCARD_DONE;
+        }
+        /* CAC 1.0 only supports ef = 0 */
+        ef = apdu->a_body[0] | (apdu->a_body[1] << 8);
+        if (ef != 0) {
+            *response = vcard_make_response(
+                VCARD7816_STATUS_ERROR_FILE_NOT_FOUND);
+            return VCARD_DONE;
+        }
+        *response = vcard_make_response(VCARD7816_STATUS_SUCCESS);
+        return VCARD_DONE;
+    case VCARD7816_INS_GET_RESPONSE:
+    case VCARD7816_INS_VERIFY:
+        /* let the 7816 code handle these */
+        return VCARD_NEXT;
+    case CAC_GET_PROPERTIES:
+    case CAC_GET_ACR:
+        /* skip these for now, this will probably be needed */
+        *response = vcard_make_response(VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
+        return VCARD_DONE;
+    }
+    *response = vcard_make_response(
+        VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
+    return VCARD_DONE;
+}
+
+/*
+ *  reset the inter call state between applet selects
+ */
+static VCardStatus
+cac_applet_pki_reset(VCard *card, int channel)
+{
+    VCardAppletPrivate *applet_private = NULL;
+    CACPKIAppletData *pki_applet = NULL;
+    applet_private = vcard_get_current_applet_private(card, channel);
+    assert(applet_private);
+    pki_applet = &(applet_private->u.pki_data);
+
+    pki_applet->cert_buffer = NULL;
+    if (pki_applet->sign_buffer) {
+        qemu_free(pki_applet->sign_buffer);
+        pki_applet->sign_buffer = NULL;
+    }
+    pki_applet->cert_buffer_len = 0;
+    pki_applet->sign_buffer_len = 0;
+    return VCARD_DONE;
+}
+
+static VCardStatus
+cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu,
+                            VCardResponse **response)
+{
+    CACPKIAppletData *pki_applet = NULL;
+    VCardAppletPrivate *applet_private = NULL;
+    int size, next;
+    unsigned char *sign_buffer;
+    vcard_7816_status_t status;
+
+    applet_private = vcard_get_current_applet_private(card, apdu->a_channel);
+    assert(applet_private);
+    pki_applet = &(applet_private->u.pki_data);
+
+    switch (apdu->a_ins) {
+    case CAC_UPDATE_BUFFER:
+        *response = vcard_make_response(
+            VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED);
+        return VCARD_DONE;
+    case CAC_GET_CERTIFICATE:
+        if ((apdu->a_p2 != 0) || (apdu->a_p1 != 0)) {
+            *response = vcard_make_response(
+                             VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
+            break;
+        }
+        assert(pki_applet->cert != NULL);
+        size = apdu->a_Le;
+        if (pki_applet->cert_buffer == NULL) {
+            pki_applet->cert_buffer = pki_applet->cert;
+            pki_applet->cert_buffer_len = pki_applet->cert_len;
+        }
+        size = MIN(size, pki_applet->cert_buffer_len);
+        next = MIN(255, pki_applet->cert_buffer_len - size);
+        *response = vcard_response_new_bytes(
+                        card, pki_applet->cert_buffer, size,
+                        apdu->a_Le, next ?
+                        VCARD7816_SW1_WARNING_CHANGE :
+                        VCARD7816_SW1_SUCCESS,
+                        next);
+        pki_applet->cert_buffer += size;
+        pki_applet->cert_buffer_len -= size;
+        if ((*response == NULL) || (next == 0)) {
+            pki_applet->cert_buffer = NULL;
+        }
+        if (*response == NULL) {
+            *response = vcard_make_response(
+                            VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
+        }
+        return VCARD_DONE;
+    case CAC_SIGN_DECRYPT:
+        if (apdu->a_p2 != 0) {
+            *response = vcard_make_response(
+                             VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
+            break;
+        }
+        size = apdu->a_Lc;
+
+        sign_buffer = realloc(pki_applet->sign_buffer,
+                      pki_applet->sign_buffer_len+size);
+        if (sign_buffer == NULL) {
+            qemu_free(pki_applet->sign_buffer);
+            pki_applet->sign_buffer = NULL;
+            pki_applet->sign_buffer_len = 0;
+            *response = vcard_make_response(
+                            VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
+            return VCARD_DONE;
+        }
+        memcpy(sign_buffer+pki_applet->sign_buffer_len, apdu->a_body, size);
+        size += pki_applet->sign_buffer_len;
+        switch (apdu->a_p1) {
+        case  0x80:
+            /* p1 == 0x80 means we haven't yet sent the whole buffer, wait for
+             * the rest */
+            pki_applet->sign_buffer = sign_buffer;
+            pki_applet->sign_buffer_len = size;
+            *response = vcard_make_response(VCARD7816_STATUS_SUCCESS);
+            return VCARD_DONE;
+        case 0x00:
+            /* we now have the whole buffer, do the operation, result will be
+             * in the sign_buffer */
+            status = vcard_emul_rsa_op(card, pki_applet->key,
+                                       sign_buffer, size);
+            if (status != VCARD7816_STATUS_SUCCESS) {
+                *response = vcard_make_response(status);
+                break;
+            }
+            *response = vcard_response_new(card, sign_buffer, size, apdu->a_Le,
+                                                     VCARD7816_STATUS_SUCCESS);
+            if (*response == NULL) {
+                *response = vcard_make_response(
+                                VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
+            }
+            break;
+        default:
+           *response = vcard_make_response(
+                                VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
+            break;
+        }
+        qemu_free(sign_buffer);
+        pki_applet->sign_buffer = NULL;
+        pki_applet->sign_buffer_len = 0;
+        return VCARD_DONE;
+    case CAC_READ_BUFFER:
+        /* new CAC call, go ahead and use the old version for now */
+        /* TODO: implement */
+        *response = vcard_make_response(
+                                VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
+        return VCARD_DONE;
+    }
+    return cac_common_process_apdu(card, apdu, response);
+}
+
+
+static VCardStatus
+cac_applet_id_process_apdu(VCard *card, VCardAPDU *apdu,
+                           VCardResponse **response)
+{
+    switch (apdu->a_ins) {
+    case CAC_UPDATE_BUFFER:
+        *response = vcard_make_response(
+                        VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED);
+        return VCARD_DONE;
+    case CAC_READ_BUFFER:
+        /* new CAC call, go ahead and use the old version for now */
+        /* TODO: implement */
+        *response = vcard_make_response(
+                        VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
+        return VCARD_DONE;
+    }
+    return cac_common_process_apdu(card, apdu, response);
+}
+
+
+/*
+ * TODO: if we ever want to support general CAC middleware, we will need to
+ * implement the various containers.
+ */
+static VCardStatus
+cac_applet_container_process_apdu(VCard *card, VCardAPDU *apdu,
+                                  VCardResponse **response)
+{
+    switch (apdu->a_ins) {
+    case CAC_READ_BUFFER:
+    case CAC_UPDATE_BUFFER:
+        *response = vcard_make_response(
+                        VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
+        return VCARD_DONE;
+    default:
+        break;
+    }
+    return cac_common_process_apdu(card, apdu, response);
+}
+
+/*
+ * utilities for creating and destroying the private applet data
+ */
+static void
+cac_delete_pki_applet_private(VCardAppletPrivate *applet_private)
+{
+    CACPKIAppletData *pki_applet_data = NULL;
+    if (pki_applet_data == NULL) {
+        return;
+    }
+    pki_applet_data = &(applet_private->u.pki_data);
+    if (pki_applet_data->cert != NULL) {
+        qemu_free(pki_applet_data->cert);
+    }
+    if (pki_applet_data->sign_buffer != NULL) {
+        qemu_free(pki_applet_data->sign_buffer);
+    }
+    if (pki_applet_data->key != NULL) {
+        vcard_emul_delete_key(pki_applet_data->key);
+    }
+    qemu_free(applet_private);
+}
+
+static VCardAppletPrivate *
+cac_new_pki_applet_private(const unsigned char *cert,
+                           int cert_len, VCardKey *key)
+{
+    CACPKIAppletData *pki_applet_data = NULL;
+    VCardAppletPrivate *applet_private = NULL;
+    applet_private = (VCardAppletPrivate *)qemu_malloc(sizeof(VCardAppletPrivate));
+
+    pki_applet_data = &(applet_private->u.pki_data);
+    pki_applet_data->cert_buffer = NULL;
+    pki_applet_data->cert_buffer_len = 0;
+    pki_applet_data->sign_buffer = NULL;
+    pki_applet_data->sign_buffer_len = 0;
+    pki_applet_data->key = NULL;
+    pki_applet_data->cert = (unsigned char *)qemu_malloc(cert_len+1);
+    /*
+     * if we want to support compression, then we simply change the 0 to a 1
+     * and compress the cert data with libz
+     */
+    pki_applet_data->cert[0] = 0; /* not compressed */
+    memcpy(&pki_applet_data->cert[1], cert, cert_len);
+    pki_applet_data->cert_len = cert_len+1;
+
+    pki_applet_data->key = key;
+    return applet_private;
+}
+
+
+/*
+ * create a new cac applet which links to a given cert
+ */
+static VCardApplet *
+cac_new_pki_applet(int i, const unsigned char *cert,
+                   int cert_len, VCardKey *key)
+{
+    VCardAppletPrivate *applet_private = NULL;
+    VCardApplet *applet = NULL;
+    unsigned char pki_aid[] = { 0xa0, 0x00, 0x00, 0x00, 0x79, 0x01, 0x00 };
+    int pki_aid_len = sizeof(pki_aid);
+
+    pki_aid[pki_aid_len-1] = i;
+
+    applet_private = cac_new_pki_applet_private(cert, cert_len, key);
+    if (applet_private == NULL) {
+        goto failure;
+    }
+    applet = vcard_new_applet(cac_applet_pki_process_apdu, cac_applet_pki_reset,
+                              pki_aid, pki_aid_len);
+    if (applet == NULL) {
+        goto failure;
+    }
+    vcard_set_applet_private(applet, applet_private,
+                             cac_delete_pki_applet_private);
+    applet_private = NULL;
+
+    return applet;
+
+failure:
+    if (applet_private != NULL) {
+        cac_delete_pki_applet_private(applet_private);
+    }
+    return NULL;
+}
+
+
+static unsigned char cac_default_container_aid[] = {
+    0xa0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00 };
+static unsigned char cac_id_aid[] = {
+    0xa0, 0x00, 0x00, 0x00, 0x79, 0x03, 0x00 };
+/*
+ * Initialize the cac card. This is the only public function in this file. All
+ * the rest are connected through function pointers.
+ */
+VCardStatus
+cac_card_init(VReader *reader, VCard *card,
+              const char *params,
+              unsigned char * const *cert,
+              int cert_len[],
+              VCardKey *key[] /* adopt the keys*/,
+              int cert_count)
+{
+    int i;
+    VCardApplet *applet;
+
+    /* CAC Cards are VM Cards */
+    vcard_set_type(card, VCARD_VM);
+
+    /* create one PKI applet for each cert */
+    for (i = 0; i < cert_count; i++) {
+        applet = cac_new_pki_applet(i, cert[i], cert_len[i], key[i]);
+        if (applet == NULL) {
+            goto failure;
+        }
+        vcard_add_applet(card, applet);
+    }
+
+    /* create a default blank container applet */
+    applet = vcard_new_applet(cac_applet_container_process_apdu,
+                              NULL, cac_default_container_aid,
+                              sizeof(cac_default_container_aid));
+    if (applet == NULL) {
+        goto failure;
+    }
+    vcard_add_applet(card, applet);
+
+    /* create a default blank container applet */
+    applet = vcard_new_applet(cac_applet_id_process_apdu,
+                              NULL, cac_id_aid,
+                              sizeof(cac_id_aid));
+    if (applet == NULL) {
+        goto failure;
+    }
+    vcard_add_applet(card, applet);
+    return VCARD_DONE;
+
+failure:
+    return VCARD_FAIL;
+}
+
diff --git a/libcacard/cac.h b/libcacard/cac.h
new file mode 100644
index 0000000000..15a61be980
--- /dev/null
+++ b/libcacard/cac.h
@@ -0,0 +1,23 @@
+/*
+ * defines the entry point for the cac card. Only used by cac.c anc
+ * vcard_emul_type.c
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+#ifndef CAC_H
+#define CAC_H 1
+#include "vcard.h"
+#include "vreader.h"
+/*
+ * Initialize the cac card. This is the only public function in this file. All
+ * the rest are connected through function pointers.
+ */
+VCardStatus cac_card_init(VReader *reader, VCard *card, const char *params,
+              unsigned char * const *cert, int cert_len[],
+              VCardKey *key[] /* adopt the keys*/,
+              int cert_count);
+
+/* not yet implemented */
+VCardStatus cac_is_cac_card(VReader *reader);
+#endif
diff --git a/libcacard/card_7816.c b/libcacard/card_7816.c
new file mode 100644
index 0000000000..eeea849895
--- /dev/null
+++ b/libcacard/card_7816.c
@@ -0,0 +1,763 @@
+/*
+ * Implement the 7816 portion of the card spec
+ *
+ * This code is licensed under the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu-common.h"
+
+#include "vcard.h"
+#include "vcard_emul.h"
+#include "card_7816.h"
+
+/*
+ * set the status bytes based on the status word
+ */
+static void
+vcard_response_set_status(VCardResponse *response, vcard_7816_status_t status)
+{
+    unsigned char sw1, sw2;
+    response->b_status = status; /* make sure the status and swX representations
+                                  * are consistent */
+    sw1 = (status >> 8) & 0xff;
+    sw2 = status & 0xff;
+    response->b_sw1 = sw1;
+    response->b_sw2 = sw2;
+    response->b_data[response->b_len] = sw1;
+    response->b_data[response->b_len+1] = sw2;
+}
+
+/*
+ * set the status bytes in a response buffer
+ */
+static void
+vcard_response_set_status_bytes(VCardResponse *response,
+                               unsigned char sw1, unsigned char sw2)
+{
+    response->b_status = sw1 << 8 | sw2;
+    response->b_sw1 = sw1;
+    response->b_sw2 = sw2;
+    response->b_data[response->b_len] = sw1;
+    response->b_data[response->b_len+1] = sw2;
+}
+
+/*
+ * allocate a VCardResponse structure, plus space for the data buffer, and
+ * set up everything but the resonse bytes.
+ */
+VCardResponse *
+vcard_response_new_data(unsigned char *buf, int len)
+{
+    VCardResponse *new_response;
+
+    new_response = (VCardResponse *)qemu_malloc(sizeof(VCardResponse));
+    new_response->b_data = qemu_malloc(len + 2);
+    memcpy(new_response->b_data, buf, len);
+    new_response->b_total_len = len+2;
+    new_response->b_len = len;
+    new_response->b_type = VCARD_MALLOC;
+    return new_response;
+}
+
+static VCardResponse *
+vcard_init_buffer_response(VCard *card, unsigned char *buf, int len)
+{
+    VCardResponse *response;
+    VCardBufferResponse *buffer_response;
+
+    buffer_response = vcard_get_buffer_response(card);
+    if (buffer_response) {
+        vcard_set_buffer_response(card, NULL);
+        vcard_buffer_response_delete(buffer_response);
+    }
+    buffer_response = vcard_buffer_response_new(buf, len);
+    if (buffer_response == NULL) {
+        return NULL;
+    }
+    response = vcard_response_new_status_bytes(VCARD7816_SW1_RESPONSE_BYTES,
+                                               len > 255 ? 0 : len);
+    if (response == NULL) {
+        return NULL;
+    }
+    vcard_set_buffer_response(card, buffer_response);
+    return response;
+}
+
+/*
+ * general buffer to hold results from APDU calls
+ */
+VCardResponse *
+vcard_response_new(VCard *card, unsigned char *buf,
+                   int len, int Le, vcard_7816_status_t status)
+{
+    VCardResponse *new_response;
+
+    if (len > Le) {
+        return vcard_init_buffer_response(card, buf, len);
+    }
+    new_response = vcard_response_new_data(buf, len);
+    if (new_response == NULL) {
+        return NULL;
+    }
+    vcard_response_set_status(new_response, status);
+    return new_response;
+}
+
+/*
+ * general buffer to hold results from APDU calls
+ */
+VCardResponse *
+vcard_response_new_bytes(VCard *card, unsigned char *buf, int len, int Le,
+                         unsigned char sw1, unsigned char sw2)
+{
+    VCardResponse *new_response;
+
+    if (len > Le) {
+        return vcard_init_buffer_response(card, buf, len);
+    }
+    new_response = vcard_response_new_data(buf, len);
+    if (new_response == NULL) {
+        return NULL;
+    }
+    vcard_response_set_status_bytes(new_response, sw1, sw2);
+    return new_response;
+}
+
+/*
+ * get a new Reponse buffer that only has a status.
+ */
+static VCardResponse *
+vcard_response_new_status(vcard_7816_status_t status)
+{
+    VCardResponse *new_response;
+
+    new_response = (VCardResponse *)qemu_malloc(sizeof(VCardResponse));
+    new_response->b_data = &new_response->b_sw1;
+    new_response->b_len = 0;
+    new_response->b_total_len = 2;
+    new_response->b_type = VCARD_MALLOC_STRUCT;
+    vcard_response_set_status(new_response, status);
+    return new_response;
+}
+
+/*
+ * same as above, but specify the status as separate bytes
+ */
+VCardResponse *
+vcard_response_new_status_bytes(unsigned char sw1, unsigned char sw2)
+{
+    VCardResponse *new_response;
+
+    new_response = (VCardResponse *)qemu_malloc(sizeof(VCardResponse));
+    new_response->b_data = &new_response->b_sw1;
+    new_response->b_len = 0;
+    new_response->b_total_len = 2;
+    new_response->b_type = VCARD_MALLOC_STRUCT;
+    vcard_response_set_status_bytes(new_response, sw1, sw2);
+    return new_response;
+}
+
+
+/*
+ * free the response buffer. The Buffer has a type to handle the buffer
+ * allocated in other ways than through malloc.
+ */
+void
+vcard_response_delete(VCardResponse *response)
+{
+    if (response == NULL) {
+        return;
+    }
+    switch (response->b_type) {
+    case VCARD_MALLOC:
+        /* everything was malloc'ed */
+        if (response->b_data) {
+            qemu_free(response->b_data);
+        }
+        qemu_free(response);
+        break;
+    case VCARD_MALLOC_DATA:
+        /* only the data buffer was malloc'ed */
+        if (response->b_data) {
+            qemu_free(response->b_data);
+        }
+        break;
+    case VCARD_MALLOC_STRUCT:
+        /* only the structure was malloc'ed */
+        qemu_free(response);
+        break;
+    case VCARD_STATIC:
+        break;
+    }
+}
+
+/*
+ * decode the class bit and set our generic type field, channel, and
+ * secure messaging values.
+ */
+static vcard_7816_status_t
+vcard_apdu_set_class(VCardAPDU *apdu) {
+    apdu->a_channel = 0;
+    apdu->a_secure_messaging = 0;
+    apdu->a_type = apdu->a_cla & 0xf0;
+    apdu->a_gen_type = VCARD_7816_ISO;
+
+    /* parse the class  tables 8 & 9 of the 7816-4 Part 4 spec */
+    switch (apdu->a_type) {
+        /* we only support the basic types */
+    case 0x00:
+    case 0x80:
+    case 0x90:
+    case 0xa0:
+        apdu->a_channel = apdu->a_cla & 3;
+        apdu->a_secure_messaging = apdu->a_cla & 0xe;
+        break;
+    case 0xb0:
+    case 0xc0:
+        break;
+
+    case 0x10:
+    case 0x20:
+    case 0x30:
+    case 0x40:
+    case 0x50:
+    case 0x60:
+    case 0x70:
+        /* Reserved for future use */
+        apdu->a_gen_type = VCARD_7816_RFU;
+        break;
+    case 0xd0:
+    case 0xe0:
+    case 0xf0:
+    default:
+        apdu->a_gen_type =
+            (apdu->a_cla == 0xff) ? VCARD_7816_PTS : VCARD_7816_PROPIETARY;
+        break;
+    }
+    return VCARD7816_STATUS_SUCCESS;
+}
+
+/*
+ * set the Le and Lc fiels according to table 5 of the
+ * 7816-4 part 4 spec
+ */
+static vcard_7816_status_t
+vcard_apdu_set_length(VCardAPDU *apdu)
+{
+    int L, Le;
+
+    /* process according to table 5 of the 7816-4 Part 4 spec.
+     * variable names match the variables in the spec */
+    L = apdu->a_len-4; /* fixed APDU header */
+    apdu->a_Lc = 0;
+    apdu->a_Le = 0;
+    apdu->a_body = NULL;
+    switch (L) {
+    case 0:
+        /* 1 minimal apdu */
+        return VCARD7816_STATUS_SUCCESS;
+    case 1:
+        /* 2S only return values apdu */
+        /*   zero maps to 256 here */
+        apdu->a_Le = apdu->a_header->ah_Le ?
+                         apdu->a_header->ah_Le : 256;
+        return VCARD7816_STATUS_SUCCESS;
+    default:
+        /* if the ah_Le byte is zero and we have more than
+         * 1 byte in the header, then we must be using extended Le and Lc.
+         * process the extended now. */
+        if (apdu->a_header->ah_Le == 0) {
+            if (L < 3) {
+                /* coding error, need at least 3 bytes */
+                return VCARD7816_STATUS_ERROR_WRONG_LENGTH;
+            }
+            /* calculate the first extended value. Could be either Le or Lc */
+            Le = (apdu->a_header->ah_body[0] << 8)
+               || apdu->a_header->ah_body[1];
+            if (L == 3) {
+                /* 2E extended, return data only */
+                /*   zero maps to 65536 */
+                apdu->a_Le = Le ? Le : 65536;
+                return VCARD7816_STATUS_SUCCESS;
+            }
+            if (Le == 0) {
+                /* reserved for future use, probably for next time we need
+                 * to extend the lengths */
+                return VCARD7816_STATUS_ERROR_WRONG_LENGTH;
+            }
+            /* we know that the first extended value is Lc now */
+            apdu->a_Lc = Le;
+            apdu->a_body = &apdu->a_header->ah_body[2];
+            if (L == Le+3) {
+                /* 3E extended, only body parameters */
+                return VCARD7816_STATUS_SUCCESS;
+            }
+            if (L == Le+5) {
+                /* 4E extended, parameters and return data */
+                Le = (apdu->a_data[apdu->a_len-2] << 8)
+                   || apdu->a_data[apdu->a_len-1];
+                apdu->a_Le = Le ? Le : 65536;
+                return VCARD7816_STATUS_SUCCESS;
+            }
+            return VCARD7816_STATUS_ERROR_WRONG_LENGTH;
+        }
+        /* not extended */
+        apdu->a_Lc = apdu->a_header->ah_Le;
+        apdu->a_body = &apdu->a_header->ah_body[0];
+        if (L ==  apdu->a_Lc + 1) {
+            /* 3S only body parameters */
+            return VCARD7816_STATUS_SUCCESS;
+        }
+        if (L ==  apdu->a_Lc + 2) {
+            /* 4S parameters and return data */
+            Le = apdu->a_data[apdu->a_len-1];
+            apdu->a_Le = Le ?  Le : 256;
+            return VCARD7816_STATUS_SUCCESS;
+        }
+        break;
+    }
+    return VCARD7816_STATUS_ERROR_WRONG_LENGTH;
+}
+
+/*
+ * create a new APDU from a raw set of bytes. This will decode all the
+ * above fields. users of VCARDAPDU's can then depend on the already decoded
+ * values.
+ */
+VCardAPDU *
+vcard_apdu_new(unsigned char *raw_apdu, int len, vcard_7816_status_t *status)
+{
+    VCardAPDU *new_apdu;
+
+    *status = VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE;
+    if (len < 4) {
+        *status = VCARD7816_STATUS_ERROR_WRONG_LENGTH;
+        return NULL;
+    }
+
+    new_apdu = (VCardAPDU *)qemu_malloc(sizeof(VCardAPDU));
+    new_apdu->a_data = qemu_malloc(len);
+    memcpy(new_apdu->a_data, raw_apdu, len);
+    new_apdu->a_len = len;
+    *status = vcard_apdu_set_class(new_apdu);
+    if (*status != VCARD7816_STATUS_SUCCESS) {
+        qemu_free(new_apdu);
+        return NULL;
+    }
+    *status = vcard_apdu_set_length(new_apdu);
+    if (*status != VCARD7816_STATUS_SUCCESS) {
+        qemu_free(new_apdu);
+        new_apdu = NULL;
+    }
+    return new_apdu;
+}
+
+void
+vcard_apdu_delete(VCardAPDU *apdu)
+{
+    if (apdu == NULL) {
+        return;
+    }
+    if (apdu->a_data) {
+        qemu_free(apdu->a_data);
+    }
+    qemu_free(apdu);
+}
+
+
+/*
+ * declare response buffers for all the 7816 defined error codes
+ */
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_SUCCESS)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_RET_CORUPT)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_BUF_END_BEFORE_LE)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_INVALID_FILE_SELECTED)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_FCI_FORMAT_INVALID)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_CHANGE)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_WARNING_FILE_FILLED)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_EXC_ERROR)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_EXC_ERROR_CHANGE)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_WRONG_LENGTH)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_CLA_NOT_SUPPORTED)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_CHANNEL_NOT_SUPPORTED)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_SECURE_NOT_SUPPORTED)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED)
+VCARD_RESPONSE_NEW_STATIC_STATUS(
+                    VCARD7816_STATUS_ERROR_COMMAND_INCOMPATIBLE_WITH_FILE)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_SECURITY_NOT_SATISFIED)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_AUTHENTICATION_BLOCKED)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_DATA_INVALID)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_DATA_NO_EF)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_SM_OBJECT_MISSING)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_SM_OBJECT_INCORRECT)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_WRONG_PARAMETERS)
+VCARD_RESPONSE_NEW_STATIC_STATUS(
+                            VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_IN_DATA)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_FUNCTION_NOT_SUPPORTED)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_FILE_NOT_FOUND)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_RECORD_NOT_FOUND)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_NO_SPACE_FOR_FILE)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_LC_TLV_INCONSISTENT)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_P1_P2_INCORRECT)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_LC_P1_P2_INCONSISTENT)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_DATA_NOT_FOUND)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_2)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_INS_CODE_INVALID)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_CLA_INVALID)
+VCARD_RESPONSE_NEW_STATIC_STATUS(VCARD7816_STATUS_ERROR_GENERAL)
+
+/*
+ * return a single response code. This function cannot fail. It will always
+ * return a response.
+ */
+VCardResponse *
+vcard_make_response(vcard_7816_status_t status)
+{
+    VCardResponse *response = NULL;
+
+    switch (status) {
+    /* known 7816 response codes */
+    case VCARD7816_STATUS_SUCCESS:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_SUCCESS);
+    case VCARD7816_STATUS_WARNING:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_WARNING);
+    case VCARD7816_STATUS_WARNING_RET_CORUPT:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_WARNING_RET_CORUPT);
+    case VCARD7816_STATUS_WARNING_BUF_END_BEFORE_LE:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_WARNING_BUF_END_BEFORE_LE);
+    case VCARD7816_STATUS_WARNING_INVALID_FILE_SELECTED:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_WARNING_INVALID_FILE_SELECTED);
+    case VCARD7816_STATUS_WARNING_FCI_FORMAT_INVALID:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_WARNING_FCI_FORMAT_INVALID);
+    case VCARD7816_STATUS_WARNING_CHANGE:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_WARNING_CHANGE);
+    case VCARD7816_STATUS_WARNING_FILE_FILLED:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_WARNING_FILE_FILLED);
+    case VCARD7816_STATUS_EXC_ERROR:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_EXC_ERROR);
+    case VCARD7816_STATUS_EXC_ERROR_CHANGE:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_EXC_ERROR_CHANGE);
+    case VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
+    case VCARD7816_STATUS_ERROR_WRONG_LENGTH:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_WRONG_LENGTH);
+    case VCARD7816_STATUS_ERROR_CLA_NOT_SUPPORTED:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_CLA_NOT_SUPPORTED);
+    case VCARD7816_STATUS_ERROR_CHANNEL_NOT_SUPPORTED:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_CHANNEL_NOT_SUPPORTED);
+    case VCARD7816_STATUS_ERROR_SECURE_NOT_SUPPORTED:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_SECURE_NOT_SUPPORTED);
+    case VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
+    case VCARD7816_STATUS_ERROR_COMMAND_INCOMPATIBLE_WITH_FILE:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_COMMAND_INCOMPATIBLE_WITH_FILE);
+    case VCARD7816_STATUS_ERROR_SECURITY_NOT_SATISFIED:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_SECURITY_NOT_SATISFIED);
+    case VCARD7816_STATUS_ERROR_AUTHENTICATION_BLOCKED:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_AUTHENTICATION_BLOCKED);
+    case VCARD7816_STATUS_ERROR_DATA_INVALID:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_DATA_INVALID);
+    case VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED);
+    case VCARD7816_STATUS_ERROR_DATA_NO_EF:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_DATA_NO_EF);
+    case VCARD7816_STATUS_ERROR_SM_OBJECT_MISSING:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_SM_OBJECT_MISSING);
+    case VCARD7816_STATUS_ERROR_SM_OBJECT_INCORRECT:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_SM_OBJECT_INCORRECT);
+    case VCARD7816_STATUS_ERROR_WRONG_PARAMETERS:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_WRONG_PARAMETERS);
+    case VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_IN_DATA:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_IN_DATA);
+    case VCARD7816_STATUS_ERROR_FUNCTION_NOT_SUPPORTED:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_FUNCTION_NOT_SUPPORTED);
+    case VCARD7816_STATUS_ERROR_FILE_NOT_FOUND:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_FILE_NOT_FOUND);
+    case VCARD7816_STATUS_ERROR_RECORD_NOT_FOUND:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_RECORD_NOT_FOUND);
+    case VCARD7816_STATUS_ERROR_NO_SPACE_FOR_FILE:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_NO_SPACE_FOR_FILE);
+    case VCARD7816_STATUS_ERROR_LC_TLV_INCONSISTENT:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_LC_TLV_INCONSISTENT);
+    case VCARD7816_STATUS_ERROR_P1_P2_INCORRECT:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
+    case VCARD7816_STATUS_ERROR_LC_P1_P2_INCONSISTENT:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_LC_P1_P2_INCONSISTENT);
+    case VCARD7816_STATUS_ERROR_DATA_NOT_FOUND:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_DATA_NOT_FOUND);
+    case VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_2:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_2);
+    case VCARD7816_STATUS_ERROR_INS_CODE_INVALID:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_INS_CODE_INVALID);
+    case VCARD7816_STATUS_ERROR_CLA_INVALID:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_CLA_INVALID);
+    case VCARD7816_STATUS_ERROR_GENERAL:
+        return VCARD_RESPONSE_GET_STATIC(
+                    VCARD7816_STATUS_ERROR_GENERAL);
+    default:
+        /* we don't know this status code, create a response buffer to
+         * hold it */
+        response = vcard_response_new_status(status);
+        if (response == NULL) {
+            /* couldn't allocate the buffer, return memmory error */
+            return VCARD_RESPONSE_GET_STATIC(
+                        VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
+        }
+    }
+    assert(response);
+    return response;
+}
+
+/*
+ * Add File card support here if you need it.
+ */
+static VCardStatus
+vcard7816_file_system_process_apdu(VCard *card, VCardAPDU *apdu,
+                                   VCardResponse **response)
+{
+    /* TODO: if we want to support a virtual file system card, we do it here.
+     * It would probably be a pkcs #15 card type */
+    *response = vcard_make_response(
+                    VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
+    return VCARD_DONE;
+}
+
+/*
+ * VM card (including java cards)
+ */
+static VCardStatus
+vcard7816_vm_process_apdu(VCard *card, VCardAPDU *apdu,
+                          VCardResponse **response)
+{
+    int bytes_to_copy, next_byte_count, count;
+    VCardApplet *current_applet;
+    VCardBufferResponse *buffer_response;
+    vcard_7816_status_t status;
+
+    /* parse the class first */
+    if (apdu->a_gen_type !=  VCARD_7816_ISO) {
+        *response = vcard_make_response(
+                        VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
+        return VCARD_DONE;
+    }
+
+    /* use a switch so that if we need to support secure channel stuff later,
+     * we know where to put it */
+    switch (apdu->a_secure_messaging) {
+    case 0x0: /* no SM */
+        break;
+    case 0x4: /* proprietary SM */
+    case 0x8: /* header not authenticated */
+    case 0xc: /* header authenticated */
+    default:
+        /* for now, don't try to support secure channel stuff in the
+         * virtual card. */
+        *response = vcard_make_response(
+                        VCARD7816_STATUS_ERROR_SECURE_NOT_SUPPORTED);
+        return VCARD_DONE;
+    }
+
+    /* now parse the instruction */
+    switch (apdu->a_ins) {
+    case  VCARD7816_INS_MANAGE_CHANNEL: /* secure channel op */
+    case  VCARD7816_INS_EXTERNAL_AUTHENTICATE: /* secure channel op */
+    case  VCARD7816_INS_GET_CHALLENGE: /* secure channel op */
+    case  VCARD7816_INS_INTERNAL_AUTHENTICATE: /* secure channel op */
+    case  VCARD7816_INS_ERASE_BINARY: /* applet control op */
+    case  VCARD7816_INS_READ_BINARY: /* applet control op */
+    case  VCARD7816_INS_WRITE_BINARY: /* applet control op */
+    case  VCARD7816_INS_UPDATE_BINARY: /* applet control op */
+    case  VCARD7816_INS_READ_RECORD: /* file op */
+    case  VCARD7816_INS_WRITE_RECORD: /* file op */
+    case  VCARD7816_INS_UPDATE_RECORD: /* file op */
+    case  VCARD7816_INS_APPEND_RECORD: /* file op */
+    case  VCARD7816_INS_ENVELOPE:
+    case  VCARD7816_INS_PUT_DATA:
+        *response = vcard_make_response(
+                            VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
+        break;
+
+    case  VCARD7816_INS_SELECT_FILE:
+        if (apdu->a_p1 != 0x04) {
+            *response = vcard_make_response(
+                            VCARD7816_STATUS_ERROR_FUNCTION_NOT_SUPPORTED);
+            break;
+        }
+
+        /* side effect, deselect the current applet if no applet has been found
+         * */
+        current_applet = vcard_find_applet(card, apdu->a_body, apdu->a_Lc);
+        vcard_select_applet(card, apdu->a_channel, current_applet);
+        if (current_applet) {
+            unsigned char *aid;
+            int aid_len;
+            aid = vcard_applet_get_aid(current_applet, &aid_len);
+            *response = vcard_response_new(card, aid, aid_len, apdu->a_Le,
+                                          VCARD7816_STATUS_SUCCESS);
+        } else {
+            *response = vcard_make_response(
+                             VCARD7816_STATUS_ERROR_FILE_NOT_FOUND);
+        }
+        break;
+
+    case  VCARD7816_INS_VERIFY:
+        if ((apdu->a_p1 != 0x00) || (apdu->a_p2 != 0x00)) {
+            *response = vcard_make_response(
+                            VCARD7816_STATUS_ERROR_WRONG_PARAMETERS);
+        } else {
+            if (apdu->a_Lc == 0) {
+                /* handle pin count if possible */
+                count = vcard_emul_get_login_count(card);
+                if (count < 0) {
+                    *response = vcard_make_response(
+                                    VCARD7816_STATUS_ERROR_DATA_NOT_FOUND);
+                } else {
+                    if (count > 0xf) {
+                        count = 0xf;
+                    }
+                    *response = vcard_response_new_status_bytes(
+                                                VCARD7816_SW1_WARNING_CHANGE,
+                                                                0xc0 | count);
+                    if (*response == NULL) {
+                        *response = vcard_make_response(
+                                    VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
+                    }
+                }
+            } else {
+                    status = vcard_emul_login(card, apdu->a_body, apdu->a_Lc);
+                *response = vcard_make_response(status);
+            }
+        }
+        break;
+
+    case VCARD7816_INS_GET_RESPONSE:
+        buffer_response = vcard_get_buffer_response(card);
+        if (!buffer_response) {
+            *response = vcard_make_response(
+                            VCARD7816_STATUS_ERROR_DATA_NOT_FOUND);
+            /* handle error */
+            break;
+        }
+        bytes_to_copy = MIN(buffer_response->len, apdu->a_Le);
+        next_byte_count = MIN(256, buffer_response->len - bytes_to_copy);
+        *response = vcard_response_new_bytes(
+                        card, buffer_response->current, bytes_to_copy,
+                        apdu->a_Le,
+                        next_byte_count ?
+                        VCARD7816_SW1_RESPONSE_BYTES : VCARD7816_SW1_SUCCESS,
+                        next_byte_count);
+        buffer_response->current += bytes_to_copy;
+        buffer_response->len -= bytes_to_copy;
+        if (*response == NULL || (next_byte_count == 0)) {
+            vcard_set_buffer_response(card, NULL);
+            vcard_buffer_response_delete(buffer_response);
+        }
+        if (*response == NULL) {
+            *response =
+                vcard_make_response(VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
+        }
+        break;
+
+    case VCARD7816_INS_GET_DATA:
+        *response =
+            vcard_make_response(VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
+        break;
+
+    default:
+        *response =
+            vcard_make_response(VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
+        break;
+    }
+
+    /* response should have been set somewhere */
+    assert(*response != NULL);
+    return VCARD_DONE;
+}
+
+
+/*
+ * APDU processing starts here. This routes the card processing stuff to the
+ * right location.
+ */
+VCardStatus
+vcard_process_apdu(VCard *card, VCardAPDU *apdu, VCardResponse **response)
+{
+    VCardStatus status;
+    VCardBufferResponse *buffer_response;
+
+    /* first handle any PTS commands, which aren't really APDU's */
+    if (apdu->a_type == VCARD_7816_PTS) {
+        /* the PTS responses aren't really responses either */
+        *response = vcard_response_new_data(apdu->a_data, apdu->a_len);
+        /* PTS responses have no status bytes */
+        (*response)->b_total_len = (*response)->b_len;
+        return VCARD_DONE;
+    }
+    buffer_response = vcard_get_buffer_response(card);
+    if (buffer_response && apdu->a_ins != VCARD7816_INS_GET_RESPONSE) {
+        /* clear out buffer_response, return an error */
+        vcard_set_buffer_response(card, NULL);
+        vcard_buffer_response_delete(buffer_response);
+        *response = vcard_make_response(VCARD7816_STATUS_EXC_ERROR);
+        return VCARD_DONE;
+    }
+
+    status = vcard_process_applet_apdu(card, apdu, response);
+    if (status != VCARD_NEXT) {
+        return status;
+    }
+    switch (vcard_get_type(card)) {
+    case VCARD_FILE_SYSTEM:
+        return vcard7816_file_system_process_apdu(card, apdu, response);
+    case VCARD_VM:
+        return vcard7816_vm_process_apdu(card, apdu, response);
+    case VCARD_DIRECT:
+        /* if we are type direct, then the applet should handle everything */
+        assert("VCARD_DIRECT: applet failure");
+        break;
+    }
+    *response =
+        vcard_make_response(VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
+    return VCARD_DONE;
+}
diff --git a/libcacard/card_7816.h b/libcacard/card_7816.h
new file mode 100644
index 0000000000..2bb2a0d8aa
--- /dev/null
+++ b/libcacard/card_7816.h
@@ -0,0 +1,62 @@
+/*
+ * Implement the 7816 portion of the card spec
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+#ifndef CARD_7816_H
+#define CARD_7816_H  1
+
+#include "card_7816t.h"
+#include "vcardt.h"
+
+/*
+ * constructors for VCardResponse's
+ */
+/* response from a return buffer and a status */
+VCardResponse *vcard_response_new(VCard *card, unsigned char *buf, int len,
+                                  int Le, vcard_7816_status_t status);
+/* response from a return buffer and status bytes */
+VCardResponse *vcard_response_new_bytes(VCard *card, unsigned char *buf,
+                                        int len, int Le,
+                                        unsigned char sw1, unsigned char sw2);
+/* response from just status bytes */
+VCardResponse *vcard_response_new_status_bytes(unsigned char sw1,
+                                               unsigned char sw2);
+/* response from just status: NOTE this cannot fail, it will alwyas return a
+ * valid response, if it can't allocate memory, the response will be
+ * VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE */
+VCardResponse *vcard_make_response(vcard_7816_status_t status);
+
+/* create a raw response (status has already been encoded */
+VCardResponse *vcard_response_new_data(unsigned char *buf, int len);
+
+
+
+
+/*
+ * destructor for VCardResponse.
+ *  Can be called with a NULL response
+ */
+void vcard_response_delete(VCardResponse *response);
+
+/*
+ * constructor for VCardAPDU
+ */
+VCardAPDU *vcard_apdu_new(unsigned char *raw_apdu, int len,
+                          unsigned short *status);
+
+/*
+ * destructor for VCardAPDU
+ *  Can be called with a NULL apdu
+ */
+void vcard_apdu_delete(VCardAPDU *apdu);
+
+/*
+ * APDU processing starts here. This routes the card processing stuff to the
+ * right location. Always returns a valid response.
+ */
+VCardStatus vcard_process_apdu(VCard *card, VCardAPDU *apdu,
+                               VCardResponse **response);
+
+#endif
diff --git a/libcacard/card_7816t.h b/libcacard/card_7816t.h
new file mode 100644
index 0000000000..9333285d73
--- /dev/null
+++ b/libcacard/card_7816t.h
@@ -0,0 +1,165 @@
+/*
+ * Implement the 7816 portion of the card spec
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+#ifndef CARD_7816T_H
+#define CARD_7816T_H 1
+
+typedef unsigned short vcard_7816_status_t;
+
+struct VCardResponseStruct {
+    unsigned char *b_data;
+    vcard_7816_status_t b_status;
+    unsigned char b_sw1;
+    unsigned char b_sw2;
+    int b_len;
+    int b_total_len;
+    enum VCardResponseBufferType {
+        VCARD_MALLOC,
+        VCARD_MALLOC_DATA,
+        VCARD_MALLOC_STRUCT,
+        VCARD_STATIC
+    } b_type;
+};
+
+#define VCARD_RESPONSE_NEW_STATIC_STATUS(stat) \
+static const VCardResponse VCardResponse##stat = \
+        {(unsigned char *)&VCardResponse##stat.b_sw1, (stat), ((stat) >> 8), \
+         ((stat) & 0xff), 0, 2, VCARD_STATIC};
+
+#define VCARD_RESPONSE_NEW_STATIC_STATUS_BYTES(sw1, sw2) \
+static const VCardResponse VCARDResponse##sw1 = \
+        {(unsigned char *)&VCardResponse##name.b_sw1, ((sw1) << 8 | (sw2)), \
+         (sw1), (sw2), 0, 2, VCARD_STATIC};
+
+/* cast away the const, callers need may need to 'free' the
+ * result, and const implies that they don't */
+#define VCARD_RESPONSE_GET_STATIC(name) \
+        ((VCardResponse *)(&VCardResponse##name))
+
+typedef enum {
+    VCARD_7816_ISO,
+    VCARD_7816_RFU,
+    VCARD_7816_PTS,
+    VCARD_7816_PROPIETARY
+} VCardAPDUType;
+
+
+/*
+ * 7816 header. All APDU's have this header.
+ * They must be laid out in this order.
+ */
+struct VCardAPDUHeader {
+    unsigned char ah_cla;
+    unsigned char ah_ins;
+    unsigned char ah_p1;
+    unsigned char ah_p2;
+    unsigned char ah_Le;
+    unsigned char ah_body[1]; /* indefinate length */
+};
+
+/*
+ * 7816 APDU structure. The raw bytes are stored in the union and can be
+ * accessed directly through u.data (which is aliased as a_data).
+ *
+ * Names of the fields match the 7816 documentation.
+ */
+struct VCardAPDUStruct {
+    int a_len;                /* length of the whole buffer, including header */
+    int a_Lc;                 /* 7816 Lc (parameter length) value */
+    int a_Le;                 /* 7816 Le (expected result length) value */
+    unsigned char *a_body;    /* pointer to the parameter */
+    int a_channel;            /* decoded channel */
+    int a_secure_messaging;   /* decoded secure messaging type */
+    int a_type;               /* decoded type from cla (top nibble of class) */
+    VCardAPDUType a_gen_type; /* generic type (7816, PROPRIETARY, RFU, etc) */
+    union {
+        struct VCardAPDUHeader *header;
+        unsigned char   *data;
+    } u;
+/* give the subfields a unified look */
+#define a_header u.header
+#define a_data u.data
+#define a_cla a_header->ah_cla /* class */
+#define a_ins a_header->ah_ins /* instruction */
+#define a_p1 a_header->ah_p1   /* parameter 1 */
+#define a_p2 a_header->ah_p2   /* parameter 2 */
+};
+
+/* 7816 status codes */
+#define VCARD7816_STATUS_SUCCESS                              0x9000
+#define VCARD7816_STATUS_WARNING                              0x6200
+#define VCARD7816_STATUS_WARNING_RET_CORUPT                   0x6281
+#define VCARD7816_STATUS_WARNING_BUF_END_BEFORE_LE            0x6282
+#define VCARD7816_STATUS_WARNING_INVALID_FILE_SELECTED        0x6283
+#define VCARD7816_STATUS_WARNING_FCI_FORMAT_INVALID           0x6284
+#define VCARD7816_STATUS_WARNING_CHANGE                       0x6300
+#define VCARD7816_STATUS_WARNING_FILE_FILLED                  0x6381
+#define VCARD7816_STATUS_EXC_ERROR                            0x6400
+#define VCARD7816_STATUS_EXC_ERROR_CHANGE                     0x6500
+#define VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE             0x6581
+#define VCARD7816_STATUS_ERROR_WRONG_LENGTH                   0x6700
+#define VCARD7816_STATUS_ERROR_CLA_NOT_SUPPORTED              0x6800
+#define VCARD7816_STATUS_ERROR_CHANNEL_NOT_SUPPORTED          0x6881
+#define VCARD7816_STATUS_ERROR_SECURE_NOT_SUPPORTED           0x6882
+#define VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED          0x6900
+#define VCARD7816_STATUS_ERROR_COMMAND_INCOMPATIBLE_WITH_FILE 0x6981
+#define VCARD7816_STATUS_ERROR_SECURITY_NOT_SATISFIED         0x6982
+#define VCARD7816_STATUS_ERROR_AUTHENTICATION_BLOCKED         0x6983
+#define VCARD7816_STATUS_ERROR_DATA_INVALID                   0x6984
+#define VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED        0x6985
+#define VCARD7816_STATUS_ERROR_DATA_NO_EF                     0x6986
+#define VCARD7816_STATUS_ERROR_SM_OBJECT_MISSING              0x6987
+#define VCARD7816_STATUS_ERROR_SM_OBJECT_INCORRECT            0x6988
+#define VCARD7816_STATUS_ERROR_WRONG_PARAMETERS               0x6a00
+#define VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_IN_DATA       0x6a80
+#define VCARD7816_STATUS_ERROR_FUNCTION_NOT_SUPPORTED         0x6a81
+#define VCARD7816_STATUS_ERROR_FILE_NOT_FOUND                 0x6a82
+#define VCARD7816_STATUS_ERROR_RECORD_NOT_FOUND               0x6a83
+#define VCARD7816_STATUS_ERROR_NO_SPACE_FOR_FILE              0x6a84
+#define VCARD7816_STATUS_ERROR_LC_TLV_INCONSISTENT            0x6a85
+#define VCARD7816_STATUS_ERROR_P1_P2_INCORRECT                0x6a86
+#define VCARD7816_STATUS_ERROR_LC_P1_P2_INCONSISTENT          0x6a87
+#define VCARD7816_STATUS_ERROR_DATA_NOT_FOUND                 0x6a88
+#define VCARD7816_STATUS_ERROR_WRONG_PARAMETERS_2             0x6b00
+#define VCARD7816_STATUS_ERROR_INS_CODE_INVALID               0x6d00
+#define VCARD7816_STATUS_ERROR_CLA_INVALID                    0x6e00
+#define VCARD7816_STATUS_ERROR_GENERAL                        0x6f00
+/* 7816 sw1 codes */
+#define VCARD7816_SW1_SUCCESS               0x90
+#define VCARD7816_SW1_RESPONSE_BYTES        0x61
+#define VCARD7816_SW1_WARNING               0x62
+#define VCARD7816_SW1_WARNING_CHANGE        0x63
+#define VCARD7816_SW1_EXC_ERROR             0x64
+#define VCARD7816_SW1_EXC_ERROR_CHANGE      0x65
+#define VCARD7816_SW1_ERROR_WRONG_LENGTH    0x67
+#define VCARD7816_SW1_CLA_ERROR             0x68
+#define VCARD7816_SW1_COMMAND_ERROR         0x69
+#define VCARD7816_SW1_P1_P2_ERROR           0x6a
+#define VCARD7816_SW1_LE_ERROR              0x6c
+#define VCARD7816_SW1_INS_ERROR             0x6d
+#define VCARD7816_SW1_CLA_NOT_SUPPORTED     0x6e
+
+/* 7816 Instructions */
+#define VCARD7816_INS_MANAGE_CHANNEL        0x70
+#define VCARD7816_INS_EXTERNAL_AUTHENTICATE 0x82
+#define VCARD7816_INS_GET_CHALLENGE         0x84
+#define VCARD7816_INS_INTERNAL_AUTHENTICATE 0x88
+#define VCARD7816_INS_ERASE_BINARY          0x0e
+#define VCARD7816_INS_READ_BINARY           0xb0
+#define VCARD7816_INS_WRITE_BINARY          0xd0
+#define VCARD7816_INS_UPDATE_BINARY         0xd6
+#define VCARD7816_INS_READ_RECORD           0xb2
+#define VCARD7816_INS_WRITE_RECORD          0xd2
+#define VCARD7816_INS_UPDATE_RECORD         0xdc
+#define VCARD7816_INS_APPEND_RECORD         0xe2
+#define VCARD7816_INS_ENVELOPE              0xc2
+#define VCARD7816_INS_PUT_DATA              0xda
+#define VCARD7816_INS_GET_DATA              0xca
+#define VCARD7816_INS_SELECT_FILE           0xa4
+#define VCARD7816_INS_VERIFY                0x20
+#define VCARD7816_INS_GET_RESPONSE          0xc0
+
+#endif
diff --git a/libcacard/event.c b/libcacard/event.c
new file mode 100644
index 0000000000..bb2f9219f9
--- /dev/null
+++ b/libcacard/event.c
@@ -0,0 +1,106 @@
+/*
+ * event queue implementation.
+ *
+ * This code is licensed under the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu-common.h"
+#include "qemu-thread.h"
+
+#include "vcard.h"
+#include "vreader.h"
+#include "vevent.h"
+
+VEvent *
+vevent_new(VEventType type, VReader *reader, VCard *card)
+{
+    VEvent *new_vevent;
+
+    new_vevent = (VEvent *)qemu_malloc(sizeof(VEvent));
+    new_vevent->next = NULL;
+    new_vevent->type = type;
+    new_vevent->reader = vreader_reference(reader);
+    new_vevent->card = vcard_reference(card);
+
+    return new_vevent;
+}
+
+void
+vevent_delete(VEvent *vevent)
+{
+    if (vevent == NULL) {
+        return;
+    }
+    vreader_free(vevent->reader);
+    vcard_free(vevent->card);
+    qemu_free(vevent);
+}
+
+/*
+ * VEvent queue management
+ */
+
+static VEvent *vevent_queue_head;
+static VEvent *vevent_queue_tail;
+static QemuMutex vevent_queue_lock;
+static QemuCond vevent_queue_condition;
+
+void vevent_queue_init(void)
+{
+    qemu_mutex_init(&vevent_queue_lock);
+    qemu_cond_init(&vevent_queue_condition);
+    vevent_queue_head = vevent_queue_tail = NULL;
+}
+
+void
+vevent_queue_vevent(VEvent *vevent)
+{
+    vevent->next = NULL;
+    qemu_mutex_lock(&vevent_queue_lock);
+    if (vevent_queue_head) {
+        assert(vevent_queue_tail);
+        vevent_queue_tail->next = vevent;
+    } else {
+        vevent_queue_head = vevent;
+    }
+    vevent_queue_tail = vevent;
+    qemu_cond_signal(&vevent_queue_condition);
+    qemu_mutex_unlock(&vevent_queue_lock);
+}
+
+/* must have lock */
+static VEvent *
+vevent_dequeue_vevent(void)
+{
+    VEvent *vevent = NULL;
+    if (vevent_queue_head) {
+        vevent = vevent_queue_head;
+        vevent_queue_head = vevent->next;
+        vevent->next = NULL;
+    }
+    return vevent;
+}
+
+VEvent *vevent_wait_next_vevent(void)
+{
+    VEvent *vevent;
+
+    qemu_mutex_lock(&vevent_queue_lock);
+    while ((vevent = vevent_dequeue_vevent()) == NULL) {
+        qemu_cond_wait(&vevent_queue_condition, &vevent_queue_lock);
+    }
+    qemu_mutex_unlock(&vevent_queue_lock);
+    return vevent;
+}
+
+VEvent *vevent_get_next_vevent(void)
+{
+    VEvent *vevent;
+
+    qemu_mutex_lock(&vevent_queue_lock);
+    vevent = vevent_dequeue_vevent();
+    qemu_mutex_unlock(&vevent_queue_lock);
+    return vevent;
+}
+
diff --git a/libcacard/eventt.h b/libcacard/eventt.h
new file mode 100644
index 0000000000..0dc7bd468c
--- /dev/null
+++ b/libcacard/eventt.h
@@ -0,0 +1,29 @@
+/*
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef EVENTT_H
+#define EVENTT_H 1
+#include "vreadert.h"
+#include "vcardt.h"
+
+typedef struct VEventStruct VEvent;
+
+typedef enum {
+    VEVENT_READER_INSERT,
+    VEVENT_READER_REMOVE,
+    VEVENT_CARD_INSERT,
+    VEVENT_CARD_REMOVE,
+    VEVENT_LAST,
+} VEventType;
+
+struct VEventStruct {
+    VEvent *next;
+    VEventType type;
+    VReader *reader;
+    VCard *card;
+};
+#endif
+
+
diff --git a/libcacard/link_test.c b/libcacard/link_test.c
new file mode 100644
index 0000000000..6f67a23d95
--- /dev/null
+++ b/libcacard/link_test.c
@@ -0,0 +1,22 @@
+/*
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include <stdio.h>
+#include "vcard.h"
+
+VCardStatus cac_card_init(const char *flags, VCard *card,
+                const unsigned char *cert[],
+                int cert_len[], VCardKey *key[] /* adopt the keys*/,
+                int cert_count);
+/*
+ * this will crash... just test the linkage right now
+ */
+
+main(int argc, char **argv)
+{
+    VCard *card; /* no constructor yet */
+    cac_card_init("", card, NULL, 0, NULL, 0);
+}
+
diff --git a/libcacard/vcard.c b/libcacard/vcard.c
new file mode 100644
index 0000000000..29b4cce6e5
--- /dev/null
+++ b/libcacard/vcard.c
@@ -0,0 +1,339 @@
+/*
+ * implement the Java card standard.
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu-common.h"
+
+#include "vcard.h"
+#include "vcard_emul.h"
+#include "card_7816t.h"
+
+struct VCardAppletStruct {
+    VCardApplet   *next;
+    VCardProcessAPDU process_apdu;
+    VCardResetApplet reset_applet;
+    unsigned char *aid;
+    int aid_len;
+    void *applet_private;
+    VCardAppletPrivateFree applet_private_free;
+};
+
+struct VCardStruct {
+    int reference_count;
+    VCardApplet *applet_list;
+    VCardApplet *current_applet[MAX_CHANNEL];
+    VCardBufferResponse *vcard_buffer_response;
+    VCardType type;
+    VCardEmul *vcard_private;
+    VCardEmulFree vcard_private_free;
+    VCardGetAtr vcard_get_atr;
+};
+
+VCardBufferResponse *
+vcard_buffer_response_new(unsigned char *buffer, int size)
+{
+    VCardBufferResponse *new_buffer;
+
+    new_buffer = (VCardBufferResponse *)qemu_malloc(sizeof(VCardBufferResponse));
+    new_buffer->buffer = (unsigned char *)qemu_malloc(size);
+    memcpy(new_buffer->buffer, buffer, size);
+    new_buffer->buffer_len = size;
+    new_buffer->current = new_buffer->buffer;
+    new_buffer->len = size;
+    return new_buffer;
+}
+
+void
+vcard_buffer_response_delete(VCardBufferResponse *buffer_response)
+{
+    if (buffer_response == NULL) {
+        return;
+    }
+    if (buffer_response->buffer) {
+        qemu_free(buffer_response->buffer);
+    }
+    qemu_free(buffer_response);
+}
+
+
+/*
+ * clean up state after a reset
+ */
+void
+vcard_reset(VCard *card, VCardPower power)
+{
+    int i;
+    VCardApplet *applet = NULL;
+
+    if (card->type ==  VCARD_DIRECT) {
+        /* select the last applet */
+        VCardApplet *current_applet = NULL;
+        for (current_applet = card->applet_list; current_applet;
+                                       current_applet = current_applet->next) {
+            applet = current_applet;
+        }
+    }
+    for (i = 0; i < MAX_CHANNEL; i++) {
+        card->current_applet[i] = applet;
+    }
+    if (card->vcard_buffer_response) {
+        vcard_buffer_response_delete(card->vcard_buffer_response);
+        card->vcard_buffer_response = NULL;
+    }
+    vcard_emul_reset(card, power);
+    if (applet) {
+        applet->reset_applet(card, 0);
+    }
+}
+
+/* applet utilities */
+
+/*
+ * applet utilities
+ */
+/* constructor */
+VCardApplet *
+vcard_new_applet(VCardProcessAPDU applet_process_function,
+                 VCardResetApplet applet_reset_function,
+                 unsigned char *aid, int aid_len)
+{
+    VCardApplet *applet;
+
+    applet = (VCardApplet *)qemu_malloc(sizeof(VCardApplet));
+    applet->next = NULL;
+    applet->applet_private = NULL;
+    applet->applet_private_free = NULL;
+    applet->process_apdu = applet_process_function;
+    applet->reset_applet = applet_reset_function;
+
+    applet->aid = qemu_malloc(aid_len);
+    memcpy(applet->aid, aid, aid_len);
+    applet->aid_len = aid_len;
+    return applet;
+}
+
+/* destructor */
+void
+vcard_delete_applet(VCardApplet *applet)
+{
+    if (applet == NULL) {
+        return;
+    }
+    if (applet->applet_private_free) {
+        applet->applet_private_free(applet->applet_private);
+        applet->applet_private = NULL;
+    }
+    if (applet->aid) {
+        qemu_free(applet->aid);
+        applet->aid = NULL;
+    }
+    qemu_free(applet);
+}
+
+/* accessor */
+void
+vcard_set_applet_private(VCardApplet *applet, VCardAppletPrivate *private,
+                         VCardAppletPrivateFree private_free)
+{
+    if (applet->applet_private_free) {
+        applet->applet_private_free(applet->applet_private);
+    }
+    applet->applet_private = private;
+    applet->applet_private_free = private_free;
+}
+
+VCard *
+vcard_new(VCardEmul *private, VCardEmulFree private_free)
+{
+    VCard *new_card;
+    int i;
+
+    new_card = (VCard *)qemu_malloc(sizeof(VCard));
+    new_card->applet_list = NULL;
+    for (i = 0; i < MAX_CHANNEL; i++) {
+        new_card->current_applet[i] = NULL;
+    }
+    new_card->vcard_buffer_response = NULL;
+    new_card->type = VCARD_VM;
+    new_card->vcard_private = private;
+    new_card->vcard_private_free = private_free;
+    new_card->vcard_get_atr = NULL;
+    new_card->reference_count = 1;
+    return new_card;
+}
+
+VCard *
+vcard_reference(VCard *vcard)
+{
+    if (vcard == NULL) {
+        return NULL;
+    }
+    vcard->reference_count++;
+    return vcard;
+}
+
+void
+vcard_free(VCard *vcard)
+{
+    VCardApplet *current_applet = NULL;
+    VCardApplet *next_applet = NULL;
+
+    if (vcard == NULL) {
+        return;
+    }
+    vcard->reference_count--;
+    if (vcard->reference_count != 0) {
+        return;
+    }
+    if (vcard->vcard_private_free) {
+        (*vcard->vcard_private_free)(vcard->vcard_private);
+        vcard->vcard_private_free = 0;
+        vcard->vcard_private = 0;
+    }
+    for (current_applet = vcard->applet_list; current_applet;
+                                        current_applet = next_applet) {
+        next_applet = current_applet->next;
+        vcard_delete_applet(current_applet);
+    }
+    vcard_buffer_response_delete(vcard->vcard_buffer_response);
+    qemu_free(vcard);
+    return;
+}
+
+void
+vcard_get_atr(VCard *vcard, unsigned char *atr, int *atr_len)
+{
+    if (vcard->vcard_get_atr) {
+        (*vcard->vcard_get_atr)(vcard, atr, atr_len);
+        return;
+    }
+    vcard_emul_get_atr(vcard, atr, atr_len);
+}
+
+void
+vcard_set_atr_func(VCard *card, VCardGetAtr vcard_get_atr)
+{
+    card->vcard_get_atr = vcard_get_atr;
+}
+
+
+VCardStatus
+vcard_add_applet(VCard *card, VCardApplet *applet)
+{
+    applet->next = card->applet_list;
+    card->applet_list = applet;
+    /* if our card-type is direct, always call the applet */
+    if (card->type ==  VCARD_DIRECT) {
+        int i;
+
+        for (i = 0; i < MAX_CHANNEL; i++) {
+            card->current_applet[i] = applet;
+        }
+    }
+    return VCARD_DONE;
+}
+
+/*
+ * manage applets
+ */
+VCardApplet *
+vcard_find_applet(VCard *card, unsigned char *aid, int aid_len)
+{
+    VCardApplet *current_applet;
+
+    for (current_applet = card->applet_list; current_applet;
+                                        current_applet = current_applet->next) {
+        if (current_applet->aid_len != aid_len) {
+            continue;
+        }
+        if (memcmp(current_applet->aid, aid, aid_len) == 0) {
+            break;
+        }
+    }
+    return current_applet;
+}
+
+unsigned char *
+vcard_applet_get_aid(VCardApplet *applet, int *aid_len)
+{
+    if (applet == NULL) {
+        return NULL;
+    }
+    *aid_len = applet->aid_len;
+    return applet->aid;
+}
+
+
+void
+vcard_select_applet(VCard *card, int channel, VCardApplet *applet)
+{
+    assert(channel < MAX_CHANNEL);
+    card->current_applet[channel] = applet;
+    /* reset the applet */
+    if (applet && applet->reset_applet) {
+        applet->reset_applet(card, channel);
+    }
+}
+
+VCardAppletPrivate *
+vcard_get_current_applet_private(VCard *card, int channel)
+{
+    VCardApplet *applet = card->current_applet[channel];
+
+    if (applet == NULL) {
+        return NULL;
+    }
+    return applet->applet_private;
+}
+
+VCardStatus
+vcard_process_applet_apdu(VCard *card, VCardAPDU *apdu,
+                          VCardResponse **response)
+{
+    if (card->current_applet[apdu->a_channel]) {
+        return card->current_applet[apdu->a_channel]->process_apdu(
+                                                        card, apdu, response);
+    }
+    return VCARD_NEXT;
+}
+
+/*
+ * Accessor functions
+ */
+/* accessor functions for the response buffer */
+VCardBufferResponse *
+vcard_get_buffer_response(VCard *card)
+{
+    return card->vcard_buffer_response;
+}
+
+void
+vcard_set_buffer_response(VCard *card, VCardBufferResponse *buffer)
+{
+    card->vcard_buffer_response = buffer;
+}
+
+
+/* accessor functions for the type */
+VCardType
+vcard_get_type(VCard *card)
+{
+    return card->type;
+}
+
+void
+vcard_set_type(VCard *card, VCardType type)
+{
+    card->type = type;
+}
+
+/* accessor for private data */
+VCardEmul *
+vcard_get_private(VCard *vcard)
+{
+    return vcard->vcard_private;
+}
+
diff --git a/libcacard/vcard.h b/libcacard/vcard.h
new file mode 100644
index 0000000000..47dc70382b
--- /dev/null
+++ b/libcacard/vcard.h
@@ -0,0 +1,86 @@
+/*
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+#ifndef VCARD_H
+#define VCARD_H 1
+
+#include "vcardt.h"
+
+/*
+ * response buffer constructors and destructors.
+ *
+ * response buffers are used when we need to return more data than will fit in
+ * a normal APDU response (nominally 254 bytes).
+ */
+VCardBufferResponse *vcard_buffer_response_new(unsigned char *buffer, int size);
+void vcard_buffer_response_delete(VCardBufferResponse *buffer_response);
+
+
+/*
+ * clean up state on reset
+ */
+void vcard_reset(VCard *card, VCardPower power);
+
+/*
+ * applet utilities
+ */
+/*
+ * Constructor for a VCardApplet
+ */
+VCardApplet *vcard_new_applet(VCardProcessAPDU applet_process_function,
+                              VCardResetApplet applet_reset_function,
+                              unsigned char *aid, int aid_len);
+
+/*
+ * destructor for a VCardApplet
+ *  Can be called with a NULL applet
+ */
+void vcard_delete_applet(VCardApplet *applet);
+
+/* accessor - set the card type specific private data */
+void vcard_set_applet_private(VCardApplet *applet, VCardAppletPrivate *_private,
+                              VCardAppletPrivateFree private_free);
+
+/* set type of vcard */
+void vcard_set_type(VCard *card, VCardType type);
+
+/*
+ * utilities interacting with the current applet
+ */
+/* add a new applet to a card */
+VCardStatus vcard_add_applet(VCard *card, VCardApplet *applet);
+/* find the applet on the card with the given aid */
+VCardApplet *vcard_find_applet(VCard *card, unsigned char *aid, int aid_len);
+/* set the following applet to be current on the given channel */
+void vcard_select_applet(VCard *card, int channel, VCardApplet *applet);
+/* get the card type specific private data on the given channel */
+VCardAppletPrivate *vcard_get_current_applet_private(VCard *card, int channel);
+/* fetch the applet's id */
+unsigned char *vcard_applet_get_aid(VCardApplet *applet, int *aid_len);
+
+/* process the apdu for the current selected applet/file */
+VCardStatus vcard_process_applet_apdu(VCard *card, VCardAPDU *apdu,
+                                      VCardResponse **response);
+/*
+ * VCard utilities
+ */
+/* constructor */
+VCard *vcard_new(VCardEmul *_private, VCardEmulFree private_free);
+/* get a reference */
+VCard *vcard_reference(VCard *);
+/* destructor (reference counted) */
+void vcard_free(VCard *);
+/* get the atr from the card */
+void vcard_get_atr(VCard *card, unsigned char *atr, int *atr_len);
+void vcard_set_atr_func(VCard *card, VCardGetAtr vcard_get_atr);
+
+/* accessor functions for the response buffer */
+VCardBufferResponse *vcard_get_buffer_response(VCard *card);
+void vcard_set_buffer_response(VCard *card, VCardBufferResponse *buffer);
+/* accessor functions for the type */
+VCardType vcard_get_type(VCard *card);
+/* get the private data */
+VCardEmul *vcard_get_private(VCard *card);
+
+#endif
diff --git a/libcacard/vcard_emul.h b/libcacard/vcard_emul.h
new file mode 100644
index 0000000000..963563f86d
--- /dev/null
+++ b/libcacard/vcard_emul.h
@@ -0,0 +1,65 @@
+/*
+ * This is the actual card emulator.
+ *
+ * These functions can be implemented in different ways on different platforms
+ * using the underlying system primitives. For Linux it uses NSS, though direct
+ * to PKCS #11, openssl+pkcs11, or even gnu crypto libraries+pkcs #11 could be
+ * used. On Windows CAPI could be used.
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef VCARD_EMUL_H
+#define VCARD_EMUL_H 1
+
+#include "card_7816t.h"
+#include "vcard.h"
+#include "vcard_emul_type.h"
+
+/*
+ * types
+ */
+typedef enum {
+    VCARD_EMUL_OK = 0,
+    VCARD_EMUL_FAIL,
+    /* return values by vcard_emul_init */
+    VCARD_EMUL_INIT_ALREADY_INITED,
+} VCardEmulError;
+
+/* options are emul specific. call card_emul_parse_args to change a string
+ * To an options struct */
+typedef struct VCardEmulOptionsStruct VCardEmulOptions;
+
+/*
+ * Login functions
+ */
+/* return the number of login attempts still possible on the card. if unknown,
+ * return -1 */
+int vcard_emul_get_login_count(VCard *card);
+/* login into the card, return the 7816 status word (sw2 || sw1) */
+vcard_7816_status_t vcard_emul_login(VCard *card, unsigned char *pin,
+                                     int pin_len);
+
+/*
+ * key functions
+ */
+/* delete a key */
+void vcard_emul_delete_key(VCardKey *key);
+/* RSA sign/decrypt with the key, signature happens 'in place' */
+vcard_7816_status_t vcard_emul_rsa_op(VCard *card, VCardKey *key,
+                                  unsigned char *buffer, int buffer_size);
+
+void vcard_emul_reset(VCard *card, VCardPower power);
+void vcard_emul_get_atr(VCard *card, unsigned char *atr, int *atr_len);
+
+/* Re-insert of a card that has been removed by force removal */
+VCardEmulError vcard_emul_force_card_insert(VReader *vreader);
+/* Force a card removal even if the card is not physically removed */
+VCardEmulError vcard_emul_force_card_remove(VReader *vreader);
+
+VCardEmulOptions *vcard_emul_options(const char *args);
+VCardEmulError vcard_emul_init(const VCardEmulOptions *options);
+void vcard_emul_replay_insertion_events(void);
+void vcard_emul_usage(void);
+#endif
diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c
new file mode 100644
index 0000000000..71f2ba3ae5
--- /dev/null
+++ b/libcacard/vcard_emul_nss.c
@@ -0,0 +1,1157 @@
+/*
+ * This is the actual card emulator.
+ *
+ * These functions can be implemented in different ways on different platforms
+ * using the underlying system primitives. For Linux it uses NSS, though direct
+ * to PKCS #11, openssl+pkcs11, or even gnu crypto libraries+pkcs #11 could be
+ * used. On Windows CAPI could be used.
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+/*
+ * NSS headers
+ */
+
+/* avoid including prototypes.h that redefines uint32 */
+#define NO_NSPR_10_SUPPORT
+
+#include <nss.h>
+#include <pk11pub.h>
+#include <cert.h>
+#include <key.h>
+#include <secmod.h>
+#include <prthread.h>
+#include <secerr.h>
+
+#include "qemu-common.h"
+
+#include "vcard.h"
+#include "card_7816t.h"
+#include "vcard_emul.h"
+#include "vreader.h"
+#include "vevent.h"
+
+struct VCardKeyStruct {
+    CERTCertificate *cert;
+    PK11SlotInfo *slot;
+    SECKEYPrivateKey *key;
+};
+
+
+typedef struct VirtualReaderOptionsStruct VirtualReaderOptions;
+
+struct VReaderEmulStruct {
+    PK11SlotInfo *slot;
+    VCardEmulType default_type;
+    char *type_params;
+    PRBool present;
+    int     series;
+    VCard *saved_vcard;
+};
+
+/*
+ *  NSS Specific options
+ */
+struct VirtualReaderOptionsStruct {
+    char *name;
+    char *vname;
+    VCardEmulType card_type;
+    char *type_params;
+    char **cert_name;
+    int cert_count;
+};
+
+struct VCardEmulOptionsStruct {
+    void *nss_db;
+    VirtualReaderOptions *vreader;
+    int vreader_count;
+    VCardEmulType hw_card_type;
+    const char *hw_type_params;
+    PRBool use_hw;
+};
+
+static int nss_emul_init;
+
+/* if we have more that just the slot, define
+ * VCardEmulStruct here */
+
+/*
+ * allocate the set of arrays for certs, cert_len, key
+ */
+static PRBool
+vcard_emul_alloc_arrays(unsigned char ***certsp, int **cert_lenp,
+                        VCardKey ***keysp, int cert_count)
+{
+    *certsp = NULL;
+    *cert_lenp = NULL;
+    *keysp = NULL;
+    *certsp = (unsigned char **)qemu_malloc(sizeof(unsigned char *)*cert_count);
+    *cert_lenp = (int *)qemu_malloc(sizeof(int)*cert_count);
+    *keysp = (VCardKey **)qemu_malloc(sizeof(VCardKey *)*cert_count);
+    return PR_TRUE;
+}
+
+/*
+ * Emulator specific card information
+ */
+typedef struct CardEmulCardStruct CardEmulPrivate;
+
+static VCardEmul *
+vcard_emul_new_card(PK11SlotInfo *slot)
+{
+    PK11_ReferenceSlot(slot);
+    /* currently we don't need anything other than the slot */
+    return (VCardEmul *)slot;
+}
+
+static void
+vcard_emul_delete_card(VCardEmul *vcard_emul)
+{
+    PK11SlotInfo *slot = (PK11SlotInfo *)vcard_emul;
+    if (slot == NULL) {
+        return;
+    }
+    PK11_FreeSlot(slot);
+}
+
+static PK11SlotInfo *
+vcard_emul_card_get_slot(VCard *card)
+{
+    /* note, the card is holding the reference, no need to get another one */
+    return (PK11SlotInfo *)vcard_get_private(card);
+}
+
+
+/*
+ * key functions
+ */
+/* private constructure */
+static VCardKey *
+vcard_emul_make_key(PK11SlotInfo *slot, CERTCertificate *cert)
+{
+    VCardKey *key;
+
+    key = (VCardKey *)qemu_malloc(sizeof(VCardKey));
+    key->slot = PK11_ReferenceSlot(slot);
+    key->cert = CERT_DupCertificate(cert);
+    /* NOTE: if we aren't logged into the token, this could return NULL */
+    /* NOTE: the cert is a temp cert, not necessarily the cert in the token,
+     * use the DER version of this function */
+    key->key = PK11_FindKeyByDERCert(slot, cert, NULL);
+    return key;
+}
+
+/* destructor */
+void
+vcard_emul_delete_key(VCardKey *key)
+{
+    if (!nss_emul_init || (key == NULL)) {
+        return;
+    }
+    if (key->key) {
+        SECKEY_DestroyPrivateKey(key->key);
+        key->key = NULL;
+    }
+    if (key->cert) {
+        CERT_DestroyCertificate(key->cert);
+    }
+    if (key->slot) {
+        PK11_FreeSlot(key->slot);
+    }
+    return;
+}
+
+/*
+ * grab the nss key from a VCardKey. If it doesn't exist, try to look it up
+ */
+static SECKEYPrivateKey *
+vcard_emul_get_nss_key(VCardKey *key)
+{
+    if (key->key) {
+        return key->key;
+    }
+    /* NOTE: if we aren't logged into the token, this could return NULL */
+    key->key = PK11_FindPrivateKeyFromCert(key->slot, key->cert, NULL);
+    return key->key;
+}
+
+/*
+ * Map NSS errors to 7816 errors
+ */
+static vcard_7816_status_t
+vcard_emul_map_error(int error)
+{
+    switch (error) {
+    case SEC_ERROR_TOKEN_NOT_LOGGED_IN:
+        return VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED;
+    case SEC_ERROR_BAD_DATA:
+    case SEC_ERROR_OUTPUT_LEN:
+    case SEC_ERROR_INPUT_LEN:
+    case SEC_ERROR_INVALID_ARGS:
+    case SEC_ERROR_INVALID_ALGORITHM:
+    case SEC_ERROR_NO_KEY:
+    case SEC_ERROR_INVALID_KEY:
+    case SEC_ERROR_DECRYPTION_DISALLOWED:
+        return VCARD7816_STATUS_ERROR_DATA_INVALID;
+    case SEC_ERROR_NO_MEMORY:
+        return VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE;
+    }
+    return VCARD7816_STATUS_EXC_ERROR_CHANGE;
+}
+
+/* RSA sign/decrypt with the key, signature happens 'in place' */
+vcard_7816_status_t
+vcard_emul_rsa_op(VCard *card, VCardKey *key,
+                  unsigned char *buffer, int buffer_size)
+{
+    SECKEYPrivateKey *priv_key;
+    unsigned signature_len;
+    SECStatus rv;
+
+    if ((!nss_emul_init) || (key == NULL)) {
+        /* couldn't get the key, indicate that we aren't logged in */
+        return VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED;
+    }
+    priv_key = vcard_emul_get_nss_key(key);
+
+    /*
+     * this is only true of the rsa signature
+     */
+    signature_len = PK11_SignatureLen(priv_key);
+    if (buffer_size != signature_len) {
+        return  VCARD7816_STATUS_ERROR_DATA_INVALID;
+    }
+    rv = PK11_PrivDecryptRaw(priv_key, buffer, &signature_len, signature_len,
+                             buffer, buffer_size);
+    if (rv != SECSuccess) {
+        return vcard_emul_map_error(PORT_GetError());
+    }
+    assert(buffer_size == signature_len);
+    return VCARD7816_STATUS_SUCCESS;
+}
+
+/*
+ * Login functions
+ */
+/* return the number of login attempts still possible on the card. if unknown,
+ * return -1 */
+int
+vcard_emul_get_login_count(VCard *card)
+{
+    return -1;
+}
+
+/* login into the card, return the 7816 status word (sw2 || sw1) */
+vcard_7816_status_t
+vcard_emul_login(VCard *card, unsigned char *pin, int pin_len)
+{
+    PK11SlotInfo *slot;
+    unsigned char *pin_string = NULL;
+    int i;
+    SECStatus rv;
+
+    if (!nss_emul_init) {
+        return VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED;
+    }
+    slot = vcard_emul_card_get_slot(card);
+     /* We depend on the PKCS #11 module internal login state here because we
+      * create a separate process to handle each guest instance. If we needed
+      * to handle multiple guests from one process, then we would need to keep
+      * a lot of extra state in our card structure
+      * */
+    pin_string = qemu_malloc(pin_len+1);
+    memcpy(pin_string, pin, pin_len);
+    pin_string[pin_len] = 0;
+
+    /* handle CAC expanded pins correctly */
+    for (i = pin_len-1; i >= 0 && (pin_string[i] == 0xff); i--) {
+        pin_string[i] = 0;
+    }
+
+    rv = PK11_Authenticate(slot, PR_FALSE, pin_string);
+    memset(pin_string, 0, pin_len);  /* don't let the pin hang around in memory
+                                        to be snooped */
+    qemu_free(pin_string);
+    if (rv == SECSuccess) {
+        return VCARD7816_STATUS_SUCCESS;
+    }
+    /* map the error from port get error */
+    return VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED;
+}
+
+void
+vcard_emul_reset(VCard *card, VCardPower power)
+{
+    PK11SlotInfo *slot;
+
+    if (!nss_emul_init) {
+        return;
+    }
+
+    /*
+     * if we reset the card (either power on or power off), we lose our login
+     * state
+     */
+    /* TODO: we may also need to send insertion/removal events? */
+    slot = vcard_emul_card_get_slot(card);
+    PK11_Logout(slot); /* NOTE: ignoring SECStatus return value */
+    return;
+}
+
+
+static VReader *
+vcard_emul_find_vreader_from_slot(PK11SlotInfo *slot)
+{
+    VReaderList *reader_list = vreader_get_reader_list();
+    VReaderListEntry *current_entry = NULL;
+
+    if (reader_list == NULL) {
+        return NULL;
+    }
+    for (current_entry = vreader_list_get_first(reader_list); current_entry;
+                        current_entry = vreader_list_get_next(current_entry)) {
+        VReader *reader = vreader_list_get_reader(current_entry);
+        VReaderEmul *reader_emul = vreader_get_private(reader);
+        if (reader_emul->slot == slot) {
+            return reader;
+        }
+        vreader_free(reader);
+    }
+
+    return NULL;
+}
+
+/*
+ * create a new reader emul
+ */
+static VReaderEmul *
+vreader_emul_new(PK11SlotInfo *slot, VCardEmulType type, const char *params)
+{
+    VReaderEmul *new_reader_emul;
+
+    new_reader_emul = (VReaderEmul *)qemu_malloc(sizeof(VReaderEmul));
+
+    new_reader_emul->slot = PK11_ReferenceSlot(slot);
+    new_reader_emul->default_type = type;
+    new_reader_emul->type_params = strdup(params);
+    new_reader_emul->present = PR_FALSE;
+    new_reader_emul->series = 0;
+    new_reader_emul->saved_vcard = NULL;
+    return new_reader_emul;
+}
+
+static void
+vreader_emul_delete(VReaderEmul *vreader_emul)
+{
+    if (vreader_emul == NULL) {
+        return;
+    }
+    if (vreader_emul->slot) {
+        PK11_FreeSlot(vreader_emul->slot);
+    }
+    if (vreader_emul->type_params) {
+        qemu_free(vreader_emul->type_params);
+    }
+    qemu_free(vreader_emul);
+}
+
+/*
+ *  TODO: move this to emulater non-specific file
+ */
+static VCardEmulType
+vcard_emul_get_type(VReader *vreader)
+{
+    VReaderEmul *vreader_emul;
+
+    vreader_emul = vreader_get_private(vreader);
+    if (vreader_emul && vreader_emul->default_type != VCARD_EMUL_NONE) {
+        return vreader_emul->default_type;
+    }
+
+    return vcard_emul_type_select(vreader);
+}
+/*
+ *  TODO: move this to emulater non-specific file
+ */
+static const char *
+vcard_emul_get_type_params(VReader *vreader)
+{
+    VReaderEmul *vreader_emul;
+
+    vreader_emul = vreader_get_private(vreader);
+    if (vreader_emul && vreader_emul->type_params) {
+        return vreader_emul->type_params;
+    }
+
+    return "";
+}
+
+/* pull the slot out of the reader private data */
+static PK11SlotInfo *
+vcard_emul_reader_get_slot(VReader *vreader)
+{
+    VReaderEmul *vreader_emul = vreader_get_private(vreader);
+    if (vreader_emul == NULL) {
+        return NULL;
+    }
+    return vreader_emul->slot;
+}
+
+/*
+ *  Card ATR's map to physical cards. VCARD_ATR_PREFIX will set appropriate
+ *  historical bytes for any software emulated card. The remaining bytes can be
+ *  used to indicate the actual emulator
+ */
+static const unsigned char nss_atr[] = { VCARD_ATR_PREFIX(3), 'N', 'S', 'S' };
+
+void
+vcard_emul_get_atr(VCard *card, unsigned char *atr, int *atr_len)
+{
+    int len = MIN(sizeof(nss_atr), *atr_len);
+    assert(atr != NULL);
+
+    memcpy(atr, nss_atr, len);
+    *atr_len = len;
+    return;
+}
+
+/*
+ * create a new card from certs and keys
+ */
+static VCard *
+vcard_emul_make_card(VReader *reader,
+                     unsigned char * const *certs, int *cert_len,
+                     VCardKey *keys[], int cert_count)
+{
+    VCardEmul *vcard_emul;
+    VCard *vcard;
+    PK11SlotInfo *slot;
+    VCardEmulType type;
+    const char *params;
+
+    type = vcard_emul_get_type(reader);
+
+    /* ignore the inserted card */
+    if (type == VCARD_EMUL_NONE) {
+        return NULL;
+    }
+    slot = vcard_emul_reader_get_slot(reader);
+    if (slot == NULL) {
+        return NULL;
+    }
+
+    params = vcard_emul_get_type_params(reader);
+    /* params these can be NULL */
+
+    vcard_emul = vcard_emul_new_card(slot);
+    if (vcard_emul == NULL) {
+        return NULL;
+    }
+    vcard = vcard_new(vcard_emul, vcard_emul_delete_card);
+    if (vcard == NULL) {
+        vcard_emul_delete_card(vcard_emul);
+        return NULL;
+    }
+    vcard_init(reader, vcard, type, params, certs, cert_len, keys, cert_count);
+    return vcard;
+}
+
+
+/*
+ * 'clone' a physical card as a virtual card
+ */
+static VCard *
+vcard_emul_mirror_card(VReader *vreader)
+{
+    /*
+     * lookup certs using the C_FindObjects. The Stan Cert handle won't give
+     * us the real certs until we log in.
+     */
+    PK11GenericObject *firstObj, *thisObj;
+    int cert_count;
+    unsigned char **certs;
+    int *cert_len;
+    VCardKey **keys;
+    PK11SlotInfo *slot;
+    PRBool ret;
+
+    slot = vcard_emul_reader_get_slot(vreader);
+    if (slot == NULL) {
+        return NULL;
+    }
+
+    firstObj = PK11_FindGenericObjects(slot, CKO_CERTIFICATE);
+    if (firstObj == NULL) {
+        return NULL;
+    }
+
+    /* count the certs */
+    cert_count = 0;
+    for (thisObj = firstObj; thisObj;
+                             thisObj = PK11_GetNextGenericObject(thisObj)) {
+        cert_count++;
+    }
+
+    if (cert_count == 0) {
+        PK11_DestroyGenericObjects(firstObj);
+        return NULL;
+    }
+
+    /* allocate the arrays */
+    ret = vcard_emul_alloc_arrays(&certs, &cert_len, &keys, cert_count);
+    if (ret == PR_FALSE) {
+        return NULL;
+    }
+
+    /* fill in the arrays */
+    cert_count = 0;
+    for (thisObj = firstObj; thisObj;
+                             thisObj = PK11_GetNextGenericObject(thisObj)) {
+        SECItem derCert;
+        CERTCertificate *cert;
+        SECStatus rv;
+
+        rv = PK11_ReadRawAttribute(PK11_TypeGeneric, thisObj,
+                                   CKA_VALUE, &derCert);
+        if (rv != SECSuccess) {
+            continue;
+        }
+        /* create floating temp cert. This gives us a cert structure even if
+         * the token isn't logged in */
+        cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &derCert,
+                                       NULL, PR_FALSE, PR_TRUE);
+        SECITEM_FreeItem(&derCert, PR_FALSE);
+        if (cert == NULL) {
+            continue;
+        }
+
+        certs[cert_count] = cert->derCert.data;
+        cert_len[cert_count] = cert->derCert.len;
+        keys[cert_count] = vcard_emul_make_key(slot, cert);
+        cert_count++;
+        CERT_DestroyCertificate(cert); /* key obj still has a reference */
+    }
+
+    /* now create the card */
+    return vcard_emul_make_card(vreader, certs, cert_len, keys, cert_count);
+}
+
+static VCardEmulType default_card_type = VCARD_EMUL_NONE;
+static const char *default_type_params = "";
+
+/*
+ * This thread looks for card and reader insertions and puts events on the
+ * event queue
+ */
+static void
+vcard_emul_event_thread(void *arg)
+{
+    PK11SlotInfo *slot;
+    VReader *vreader;
+    VReaderEmul *vreader_emul;
+    VCard *vcard;
+    SECMODModule *module = (SECMODModule *)arg;
+
+    do {
+        slot = SECMOD_WaitForAnyTokenEvent(module, 0, 500);
+        if (slot == NULL) {
+            break;
+        }
+        vreader = vcard_emul_find_vreader_from_slot(slot);
+        if (vreader == NULL) {
+            /* new vreader */
+            vreader_emul = vreader_emul_new(slot, default_card_type,
+                                            default_type_params);
+            vreader = vreader_new(PK11_GetSlotName(slot), vreader_emul,
+                                  vreader_emul_delete);
+            PK11_FreeSlot(slot);
+            slot = NULL;
+            vreader_add_reader(vreader);
+            vreader_free(vreader);
+            continue;
+        }
+        /* card remove/insert */
+        vreader_emul = vreader_get_private(vreader);
+        if (PK11_IsPresent(slot)) {
+            int series = PK11_GetSlotSeries(slot);
+            if (series != vreader_emul->series) {
+                if (vreader_emul->present) {
+                    vreader_insert_card(vreader, NULL);
+                }
+                vcard = vcard_emul_mirror_card(vreader);
+                vreader_insert_card(vreader, vcard);
+                vcard_free(vcard);
+            }
+            vreader_emul->series = series;
+            vreader_emul->present = 1;
+            vreader_free(vreader);
+            PK11_FreeSlot(slot);
+            continue;
+        }
+        if (vreader_emul->present) {
+            vreader_insert_card(vreader, NULL);
+        }
+        vreader_emul->series = 0;
+        vreader_emul->present = 0;
+        PK11_FreeSlot(slot);
+        vreader_free(vreader);
+    } while (1);
+}
+
+/* if the card is inserted when we start up, make sure our state is correct */
+static void
+vcard_emul_init_series(VReader *vreader, VCard *vcard)
+{
+    VReaderEmul *vreader_emul = vreader_get_private(vreader);
+    PK11SlotInfo *slot = vreader_emul->slot;
+
+    vreader_emul->present = PK11_IsPresent(slot);
+    vreader_emul->series = PK11_GetSlotSeries(slot);
+    if (vreader_emul->present == 0) {
+        vreader_insert_card(vreader, NULL);
+    }
+}
+
+/*
+ * each module has a separate wait call, create a thread for each module that
+ * we are using.
+ */
+static void
+vcard_emul_new_event_thread(SECMODModule *module)
+{
+    PR_CreateThread(PR_SYSTEM_THREAD, vcard_emul_event_thread,
+                     module, PR_PRIORITY_HIGH, PR_GLOBAL_THREAD,
+                     PR_UNJOINABLE_THREAD, 0);
+}
+
+static const VCardEmulOptions default_options = {
+    .nss_db = NULL,
+    .vreader = NULL,
+    .vreader_count = 0,
+    .hw_card_type = VCARD_EMUL_CAC,
+    .hw_type_params = "",
+    .use_hw = PR_TRUE
+};
+
+
+/*
+ *  NSS needs the app to supply a password prompt. In our case the only time
+ *  the password is supplied is as part of the Login APDU. The actual password
+ *  is passed in the pw_arg in that case. In all other cases pw_arg should be
+ *  NULL.
+ */
+static char *
+vcard_emul_get_password(PK11SlotInfo *slot, PRBool retries, void *pw_arg)
+{
+    /* if it didn't work the first time, don't keep trying */
+    if (retries) {
+        return NULL;
+    }
+    /* we are looking up a password when we don't have one in hand */
+    if (pw_arg == NULL) {
+        return NULL;
+    }
+    /* TODO: we really should verify that were are using the right slot */
+    return PORT_Strdup(pw_arg);
+}
+
+/* Force a card removal even if the card is not physically removed */
+VCardEmulError
+vcard_emul_force_card_remove(VReader *vreader)
+{
+    if (!nss_emul_init || (vreader_card_is_present(vreader) != VREADER_OK)) {
+        return VCARD_EMUL_FAIL; /* card is already removed */
+    }
+
+    /* OK, remove it */
+    vreader_insert_card(vreader, NULL);
+    return VCARD_EMUL_OK;
+}
+
+/* Re-insert of a card that has been removed by force removal */
+VCardEmulError
+vcard_emul_force_card_insert(VReader *vreader)
+{
+    VReaderEmul *vreader_emul;
+    VCard *vcard;
+
+    if (!nss_emul_init || (vreader_card_is_present(vreader) == VREADER_OK)) {
+        return VCARD_EMUL_FAIL; /* card is already removed */
+    }
+    vreader_emul = vreader_get_private(vreader);
+
+    /* if it's a softcard, get the saved vcard from the reader emul structure */
+    if (vreader_emul->saved_vcard) {
+        vcard = vcard_reference(vreader_emul->saved_vcard);
+    } else {
+        /* it must be a physical card, rebuild it */
+        if (!PK11_IsPresent(vreader_emul->slot)) {
+            /* physical card has been removed, not way to reinsert it */
+            return VCARD_EMUL_FAIL;
+        }
+        vcard = vcard_emul_mirror_card(vreader);
+    }
+    vreader_insert_card(vreader, vcard);
+    vcard_free(vcard);
+
+    return VCARD_EMUL_OK;
+}
+
+
+static PRBool
+module_has_removable_hw_slots(SECMODModule *mod)
+{
+    int i;
+    PRBool ret = PR_FALSE;
+    SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
+
+    if (!moduleLock) {
+        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+        return ret;
+    }
+    SECMOD_GetReadLock(moduleLock);
+    for (i = 0; i < mod->slotCount; i++) {
+        PK11SlotInfo *slot = mod->slots[i];
+        if (PK11_IsRemovable(slot) && PK11_IsHW(slot)) {
+            ret = PR_TRUE;
+            break;
+        }
+    }
+    SECMOD_ReleaseReadLock(moduleLock);
+    return ret;
+}
+
+/* Previously we returned FAIL if no readers found. This makes
+ * no sense when using hardware, since there may be no readers connected
+ * at the time vcard_emul_init is called, but they will be properly
+ * recognized later. So Instead return FAIL only if no_hw==1 and no
+ * vcards can be created (indicates error with certificates provided
+ * or db), or if any other higher level error (NSS error, missing coolkey). */
+static int vcard_emul_init_called;
+
+VCardEmulError
+vcard_emul_init(const VCardEmulOptions *options)
+{
+    SECStatus rv;
+    PRBool ret, has_readers = PR_FALSE, need_coolkey_module;
+    VReader *vreader;
+    VReaderEmul *vreader_emul;
+    SECMODListLock *module_lock;
+    SECMODModuleList *module_list;
+    SECMODModuleList *mlp;
+    int i;
+
+    if (vcard_emul_init_called) {
+        return VCARD_EMUL_INIT_ALREADY_INITED;
+    }
+    vcard_emul_init_called = 1;
+    vreader_init();
+    vevent_queue_init();
+
+    if (options == NULL) {
+        options = &default_options;
+    }
+
+    /* first initialize NSS */
+    if (options->nss_db) {
+        rv = NSS_Init(options->nss_db);
+    } else {
+        rv = NSS_Init("sql:/etc/pki/nssdb");
+    }
+    if (rv != SECSuccess) {
+        return VCARD_EMUL_FAIL;
+    }
+    /* Set password callback function */
+    PK11_SetPasswordFunc(vcard_emul_get_password);
+
+    /* set up soft cards emulated by software certs rather than physical cards
+     * */
+    for (i = 0; i < options->vreader_count; i++) {
+        int j;
+        int cert_count;
+        unsigned char **certs;
+        int *cert_len;
+        VCardKey **keys;
+        PK11SlotInfo *slot;
+
+        slot = PK11_FindSlotByName(options->vreader[i].name);
+        if (slot == NULL) {
+            continue;
+        }
+        vreader_emul = vreader_emul_new(slot, options->vreader[i].card_type,
+                                        options->vreader[i].type_params);
+        vreader = vreader_new(options->vreader[i].vname, vreader_emul,
+                              vreader_emul_delete);
+        vreader_add_reader(vreader);
+        cert_count = options->vreader[i].cert_count;
+
+        ret = vcard_emul_alloc_arrays(&certs, &cert_len, &keys,
+                                      options->vreader[i].cert_count);
+        if (ret == PR_FALSE) {
+            continue;
+        }
+        cert_count = 0;
+        for (j = 0; j < options->vreader[i].cert_count; j++) {
+            /* we should have a better way of identifying certs than by
+             * nickname here */
+            CERTCertificate *cert = PK11_FindCertFromNickname(
+                                        options->vreader[i].cert_name[j],
+                                        NULL);
+            if (cert == NULL) {
+                continue;
+            }
+            certs[cert_count] = cert->derCert.data;
+            cert_len[cert_count] = cert->derCert.len;
+            keys[cert_count] = vcard_emul_make_key(slot, cert);
+            /* this is safe because the key is still holding a cert reference */
+            CERT_DestroyCertificate(cert);
+            cert_count++;
+        }
+        if (cert_count) {
+            VCard *vcard = vcard_emul_make_card(vreader, certs, cert_len,
+                                                keys, cert_count);
+            vreader_insert_card(vreader, vcard);
+            vcard_emul_init_series(vreader, vcard);
+            /* allow insertion and removal of soft cards */
+            vreader_emul->saved_vcard = vcard_reference(vcard);
+            vcard_free(vcard);
+            vreader_free(vreader);
+            has_readers = PR_TRUE;
+        }
+    }
+
+    /* if we aren't suppose to use hw, skip looking up hardware tokens */
+    if (!options->use_hw) {
+        nss_emul_init = has_readers;
+        return has_readers ? VCARD_EMUL_OK : VCARD_EMUL_FAIL;
+    }
+
+    /* make sure we have some PKCS #11 module loaded */
+    module_lock = SECMOD_GetDefaultModuleListLock();
+    module_list = SECMOD_GetDefaultModuleList();
+    need_coolkey_module = !has_readers;
+    SECMOD_GetReadLock(module_lock);
+    for (mlp = module_list; mlp; mlp = mlp->next) {
+        SECMODModule *module = mlp->module;
+        if (module_has_removable_hw_slots(module)) {
+            need_coolkey_module = PR_FALSE;
+            break;
+        }
+    }
+    SECMOD_ReleaseReadLock(module_lock);
+
+    if (need_coolkey_module) {
+        SECMODModule *module;
+        module = SECMOD_LoadUserModule(
+                    (char *)"library=libcoolkeypk11.so name=Coolkey",
+                    NULL, PR_FALSE);
+        if (module == NULL) {
+            return VCARD_EMUL_FAIL;
+        }
+        SECMOD_DestroyModule(module); /* free our reference, Module will still
+                                       * be on the list.
+                                       * until we destroy it */
+    }
+
+    /* now examine all the slots, finding which should be readers */
+    /* We should control this with options. For now we mirror out any
+     * removable hardware slot */
+    default_card_type = options->hw_card_type;
+    default_type_params = strdup(options->hw_type_params);
+
+    SECMOD_GetReadLock(module_lock);
+    for (mlp = module_list; mlp; mlp = mlp->next) {
+        SECMODModule *module = mlp->module;
+        PRBool has_emul_slots = PR_FALSE;
+
+        if (module == NULL) {
+                continue;
+        }
+
+        for (i = 0; i < module->slotCount; i++) {
+            PK11SlotInfo *slot = module->slots[i];
+
+            /* only map removable HW slots */
+            if (slot == NULL || !PK11_IsRemovable(slot) || !PK11_IsHW(slot)) {
+                continue;
+            }
+            vreader_emul = vreader_emul_new(slot, options->hw_card_type,
+                                            options->hw_type_params);
+            vreader = vreader_new(PK11_GetSlotName(slot), vreader_emul,
+                                  vreader_emul_delete);
+            vreader_add_reader(vreader);
+
+            has_readers = PR_TRUE;
+            has_emul_slots = PR_TRUE;
+
+            if (PK11_IsPresent(slot)) {
+                VCard *vcard;
+                vcard = vcard_emul_mirror_card(vreader);
+                vreader_insert_card(vreader, vcard);
+                vcard_emul_init_series(vreader, vcard);
+                vcard_free(vcard);
+            }
+        }
+        if (has_emul_slots) {
+            vcard_emul_new_event_thread(module);
+        }
+    }
+    SECMOD_ReleaseReadLock(module_lock);
+    nss_emul_init = has_readers;
+
+    return VCARD_EMUL_OK;
+}
+
+/* Recreate card insert events for all readers (user should
+ * deduce implied reader insert. perhaps do a reader insert as well?)
+ */
+void
+vcard_emul_replay_insertion_events(void)
+{
+    VReaderListEntry *current_entry;
+    VReaderListEntry *next_entry = NULL;
+    VReaderList *list = vreader_get_reader_list();
+
+    for (current_entry = vreader_list_get_first(list); current_entry;
+            current_entry = next_entry) {
+        VReader *vreader = vreader_list_get_reader(current_entry);
+        next_entry = vreader_list_get_next(current_entry);
+        vreader_queue_card_event(vreader);
+    }
+}
+
+/*
+ *  Silly little functions to help parsing our argument string
+ */
+static char *
+copy_string(const char *str, int str_len)
+{
+    char *new_str;
+
+    new_str = qemu_malloc(str_len+1);
+    memcpy(new_str, str, str_len);
+    new_str[str_len] = 0;
+    return new_str;
+}
+
+static int
+count_tokens(const char *str, char token, char token_end)
+{
+    int count = 0;
+
+    for (; *str; str++) {
+        if (*str == token) {
+            count++;
+        }
+        if (*str == token_end) {
+            break;
+        }
+    }
+    return count;
+}
+
+static const char *
+strip(const char *str)
+{
+    for (; *str && !isspace(*str); str++) {
+    }
+    return str;
+}
+
+static const char *
+find_blank(const char *str)
+{
+    for (; *str && isspace(*str); str++) {
+    }
+    return str;
+}
+
+
+/*
+ *  We really want to use some existing argument parsing library here. That
+ *  would give us a consistant look */
+static VCardEmulOptions options;
+#define READER_STEP 4
+
+VCardEmulOptions *
+vcard_emul_options(const char *args)
+{
+    int reader_count = 0;
+    VCardEmulOptions *opts;
+    char type_str[100];
+    int type_len;
+
+    /* Allow the future use of allocating the options structure on the fly */
+    memcpy(&options, &default_options, sizeof(options));
+    opts = &options;
+
+    do {
+        args = strip(args); /* strip off the leading spaces */
+        if (*args == ',') {
+            continue;
+        }
+        /* soft=(slot_name,virt_name,emul_type,emul_flags,cert_1, (no eol)
+         *       cert_2,cert_3...) */
+        if (strncmp(args, "soft=", 5) == 0) {
+            const char *name;
+            const char *vname;
+            const char *type_params;
+            VCardEmulType type;
+            int name_length, vname_length, type_params_length, count, i;
+            VirtualReaderOptions *vreaderOpt = NULL;
+
+            args = strip(args + 5);
+            if (*args != '(') {
+                continue;
+            }
+            name = args;
+            args = strpbrk(args + 1, ",)");
+            if (*args == 0) {
+                break;
+            }
+            if (*args == ')') {
+                args++;
+                continue;
+            }
+            args = strip(args+1);
+            name_length = args - name - 2;
+            vname = args;
+            args = strpbrk(args + 1, ",)");
+            if (*args == 0) {
+                break;
+            }
+            if (*args == ')') {
+                args++;
+                continue;
+            }
+            vname_length = args - name - 2;
+            args = strip(args+1);
+            type_len = strpbrk(args, ",)") - args;
+            assert(sizeof(type_str) > type_len);
+            strncpy(type_str, args, type_len);
+            type_str[type_len] = 0;
+            type = vcard_emul_type_from_string(type_str);
+            args = strpbrk(args, ",)");
+            if (*args == 0) {
+                break;
+            }
+            if (*args == ')') {
+                args++;
+                continue;
+            }
+            args = strip(args++);
+            type_params = args;
+            args = strpbrk(args + 1, ",)");
+            if (*args == 0) {
+                break;
+            }
+            if (*args == ')') {
+                args++;
+                continue;
+            }
+            type_params_length = args - name;
+            args = strip(args++);
+            if (*args == 0) {
+                break;
+            }
+
+            if (opts->vreader_count >= reader_count) {
+                reader_count += READER_STEP;
+                vreaderOpt = realloc(opts->vreader,
+                                reader_count * sizeof(*vreaderOpt));
+                if (vreaderOpt == NULL) {
+                    return opts; /* we're done */
+                }
+            }
+            opts->vreader = vreaderOpt;
+            vreaderOpt = &vreaderOpt[opts->vreader_count];
+            vreaderOpt->name = copy_string(name, name_length);
+            vreaderOpt->vname = copy_string(vname, vname_length);
+            vreaderOpt->card_type = type;
+            vreaderOpt->type_params =
+                copy_string(type_params, type_params_length);
+            count = count_tokens(args, ',', ')');
+            vreaderOpt->cert_count = count;
+            vreaderOpt->cert_name = (char **)qemu_malloc(count*sizeof(char *));
+            for (i = 0; i < count; i++) {
+                const char *cert = args + 1;
+                args = strpbrk(args + 1, ",)");
+                vreaderOpt->cert_name[i] = copy_string(cert, args - cert);
+            }
+            if (*args == ')') {
+                args++;
+            }
+            opts->vreader_count++;
+        /* use_hw= */
+        } else if (strncmp(args, "use_hw=", 7) == 0) {
+            args = strip(args+7);
+            if (*args == '0' || *args == 'N' || *args == 'n' || *args == 'F') {
+                opts->use_hw = PR_FALSE;
+            } else {
+                opts->use_hw = PR_TRUE;
+            }
+            args = find_blank(args);
+        /* hw_type= */
+        } else if (strncmp(args, "hw_type=", 8) == 0) {
+            args = strip(args+8);
+            opts->hw_card_type = vcard_emul_type_from_string(args);
+            args = find_blank(args);
+        /* hw_params= */
+        } else if (strncmp(args, "hw_params=", 10) == 0) {
+            const char *params;
+            args = strip(args+10);
+            params = args;
+            args = find_blank(args);
+            opts->hw_type_params = copy_string(params, args-params);
+        /* db="/data/base/path" */
+        } else if (strncmp(args, "db=", 3) == 0) {
+            const char *db;
+            args = strip(args+3);
+            if (*args != '"') {
+                continue;
+            }
+            args++;
+            db = args;
+            args = strpbrk(args, "\"\n");
+            opts->nss_db = copy_string(db, args-db);
+            if (*args != 0) {
+                args++;
+            }
+        } else {
+            args = find_blank(args);
+        }
+    } while (*args != 0);
+
+    return opts;
+}
+
+void
+vcard_emul_usage(void)
+{
+   fprintf(stderr,
+"emul args: comma separated list of the following arguments\n"
+" db={nss_database}               (default sql:/etc/pki/nssdb)\n"
+" use_hw=[yes|no]                 (default yes)\n"
+" hw_type={card_type_to_emulate}  (default CAC)\n"
+" hw_param={param_for_card}       (default \"\")\n"
+" soft=({slot_name},{vreader_name},{card_type_to_emulate},{params_for_card},\n"
+"       {cert1},{cert2},{cert3}    (default none)\n"
+"\n"
+"  {nss_database}          The location of the NSS cert & key database\n"
+"  {card_type_to_emulate}  What card interface to present to the guest\n"
+"  {param_for_card}        Card interface specific parameters\n"
+"  {slot_name}             NSS slot that contains the certs\n"
+"  {vreader_name}          Virutal reader name to present to the guest\n"
+"  {certN}                 Nickname of the certificate n on the virtual card\n"
+"\n"
+"These parameters come as a single string separated by blanks or newlines."
+"\n"
+"Unless use_hw is set to no, all tokens that look like removable hardware\n"
+"tokens will be presented to the guest using the emulator specified by\n"
+"hw_type, and parameters of hw_param.\n"
+"\n"
+"If more one or more soft= parameters are specified, these readers will be\n"
+"presented to the guest\n");
+}
diff --git a/libcacard/vcard_emul_type.c b/libcacard/vcard_emul_type.c
new file mode 100644
index 0000000000..59a1458201
--- /dev/null
+++ b/libcacard/vcard_emul_type.c
@@ -0,0 +1,57 @@
+/*
+ *  This file contains utility functions which abstract the different card
+ *  types.  The goal is that new card types can easily be added by simply
+ *  changing this file and vcard_emul_type.h. It is currently not a requirement
+ *  to dynamically add new card types.
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include <strings.h>
+#include "vcardt.h"
+#include "vcard_emul_type.h"
+#include "cac.h"
+
+VCardStatus vcard_init(VReader *vreader, VCard *vcard,
+                       VCardEmulType type, const char *params,
+                       unsigned char *const *cert, int cert_len[],
+                       VCardKey *key[], int cert_count)
+{
+    switch (type) {
+    case VCARD_EMUL_NONE:
+        break;
+    case VCARD_EMUL_CAC:
+        return cac_card_init(vreader, vcard, params,
+                             cert, cert_len, key,  cert_count);
+    /* add new ones here */
+    default:
+        break;
+    }
+    return VCARD_FAIL;
+}
+
+VCardEmulType vcard_emul_type_select(VReader *vreader)
+{
+#ifdef notdef
+    /* since there is only one emulator no need to call this function */
+    if (cac_is_cac_card(vreader) == VCARD_DONE) {
+        return VCARD_EMUL_CAC;
+    }
+#endif
+    /* return the default */
+    return VCARD_EMUL_CAC;
+}
+
+VCardEmulType vcard_emul_type_from_string(const char *type_string)
+{
+     if (strcasecmp(type_string, "CAC") == 0) {
+        return VCARD_EMUL_CAC;
+     }
+#ifdef USE_PASSTHRU
+     if (strcasecmp(type_string, "PASSTHRU") == 0) {
+        return VCARD_EMUL_PASSTHRU;
+     }
+#endif
+     return VCARD_EMUL_NONE;
+}
diff --git a/libcacard/vcard_emul_type.h b/libcacard/vcard_emul_type.h
new file mode 100644
index 0000000000..0242f40eb1
--- /dev/null
+++ b/libcacard/vcard_emul_type.h
@@ -0,0 +1,32 @@
+/*
+ *  This header file abstracts the different card types. The goal is new card
+ *  types can easily be added by simply changing this file and
+ *  vcard_emul_type.c. It is currently not a requirement to dynamically add new
+ *  card types.
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef VCARD_EMUL_TYPE_H
+#define VCARD_EMUL_TYPE_H 1
+#include "vcardt.h"
+#include "vreadert.h"
+
+/*
+ * types
+ */
+typedef enum {
+     VCARD_EMUL_NONE = 0,
+     VCARD_EMUL_CAC,
+     VCARD_EMUL_PASSTHRU
+} VCardEmulType;
+
+/* functions used by the rest of the emulator */
+VCardStatus vcard_init(VReader *vreader, VCard *vcard, VCardEmulType type,
+                       const char *params, unsigned char * const *cert,
+                       int cert_len[], VCardKey *key[], int cert_count);
+VCardEmulType vcard_emul_type_select(VReader *vreader);
+VCardEmulType vcard_emul_type_from_string(const char *type_string);
+
+#endif
diff --git a/libcacard/vcardt.h b/libcacard/vcardt.h
new file mode 100644
index 0000000000..538bdde3df
--- /dev/null
+++ b/libcacard/vcardt.h
@@ -0,0 +1,64 @@
+/*
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+#ifndef VCARDT_H
+#define VCARDT_H 1
+
+/*
+ * these should come from some common spice header file
+ */
+#include <assert.h>
+#ifndef MIN
+#define MIN(x, y) ((x) > (y) ? (y) : (x))
+#define MAX(x, y) ((x) > (y) ? (x) : (y))
+#endif
+
+typedef struct VCardStruct VCard;
+typedef struct VCardAPDUStruct VCardAPDU;
+typedef struct VCardResponseStruct VCardResponse;
+typedef struct VCardBufferResponseStruct VCardBufferResponse;
+typedef struct VCardAppletStruct VCardApplet;
+typedef struct VCardAppletPrivateStruct VCardAppletPrivate;
+typedef struct VCardKeyStruct VCardKey;  /* opaque */
+typedef struct VCardEmulStruct VCardEmul;
+
+#define MAX_CHANNEL 4
+
+/* create an ATR with appropriate historical bytes */
+#define VCARD_ATR_PREFIX(size) 0x3b, 0x66+(size), 0x00, 0xff, \
+                               'V', 'C', 'A', 'R', 'D', '_'
+
+
+typedef enum {
+    VCARD_DONE,
+    VCARD_NEXT,
+    VCARD_FAIL
+} VCardStatus;
+
+typedef enum {
+    VCARD_FILE_SYSTEM,
+    VCARD_VM,
+    VCARD_DIRECT
+} VCardType;
+
+typedef enum {
+    VCARD_POWER_ON,
+    VCARD_POWER_OFF
+} VCardPower;
+
+typedef VCardStatus (*VCardProcessAPDU)(VCard *card, VCardAPDU *apdu,
+                                        VCardResponse **response);
+typedef VCardStatus (*VCardResetApplet)(VCard *card, int channel);
+typedef void (*VCardAppletPrivateFree) (VCardAppletPrivate *);
+typedef void (*VCardEmulFree) (VCardEmul *);
+typedef void (*VCardGetAtr) (VCard *, unsigned char *atr, int *atr_len);
+
+struct VCardBufferResponseStruct {
+    unsigned char *buffer;
+    int buffer_len;
+    unsigned char *current;
+    int len;
+};
+
+#endif
diff --git a/libcacard/vevent.h b/libcacard/vevent.h
new file mode 100644
index 0000000000..38c3482c35
--- /dev/null
+++ b/libcacard/vevent.h
@@ -0,0 +1,27 @@
+/*
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+#ifndef EVENT_H
+#define EVENT_H 1
+#include "eventt.h"
+#include "vreadert.h"
+#include "vcardt.h"
+
+VEvent *vevent_new(VEventType type, VReader *reader, VCard *card);
+void vevent_delete(VEvent *);
+
+/*
+ * VEvent queueing services
+ */
+void vevent_queue_vevent(VEvent *);
+void vevent_queue_init(void);
+
+/*
+ *  VEvent dequeing services
+ */
+VEvent *vevent_wait_next_vevent(void);
+VEvent *vevent_get_next_vevent(void);
+
+
+#endif
diff --git a/libcacard/vreader.c b/libcacard/vreader.c
new file mode 100644
index 0000000000..4a0125b0e2
--- /dev/null
+++ b/libcacard/vreader.c
@@ -0,0 +1,513 @@
+/*
+ * emulate the reader
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu-common.h"
+#include "qemu-thread.h"
+
+#include "vcard.h"
+#include "vcard_emul.h"
+#include "card_7816.h"
+#include "vreader.h"
+#include "vevent.h"
+
+struct VReaderStruct {
+    int    reference_count;
+    VCard *card;
+    char *name;
+    vreader_id_t id;
+    QemuMutex lock;
+    VReaderEmul  *reader_private;
+    VReaderEmulFree reader_private_free;
+};
+
+/* manage locking */
+static inline void
+vreader_lock(VReader *reader)
+{
+    qemu_mutex_lock(&reader->lock);
+}
+
+static inline void
+vreader_unlock(VReader *reader)
+{
+    qemu_mutex_unlock(&reader->lock);
+}
+
+/*
+ * vreader constructor
+ */
+VReader *
+vreader_new(const char *name, VReaderEmul *private,
+            VReaderEmulFree private_free)
+{
+    VReader *reader;
+
+    reader = (VReader *)qemu_malloc(sizeof(VReader));
+    qemu_mutex_init(&reader->lock);
+    reader->reference_count = 1;
+    reader->name = name ? strdup(name) : NULL;
+    reader->card = NULL;
+    reader->id = (vreader_id_t)-1;
+    reader->reader_private = private;
+    reader->reader_private_free = private_free;
+    return reader;
+}
+
+/* get a reference */
+VReader*
+vreader_reference(VReader *reader)
+{
+    if (reader == NULL) {
+        return NULL;
+    }
+    vreader_lock(reader);
+    reader->reference_count++;
+    vreader_unlock(reader);
+    return reader;
+}
+
+/* free a reference */
+void
+vreader_free(VReader *reader)
+{
+    if (reader == NULL) {
+        return;
+    }
+    vreader_lock(reader);
+    if (reader->reference_count-- > 1) {
+        vreader_unlock(reader);
+        return;
+    }
+    vreader_unlock(reader);
+    if (reader->card) {
+        vcard_free(reader->card);
+    }
+    if (reader->name) {
+        qemu_free(reader->name);
+    }
+    if (reader->reader_private_free) {
+        reader->reader_private_free(reader->reader_private);
+    }
+    qemu_free(reader);
+    return;
+}
+
+static VCard *
+vreader_get_card(VReader *reader)
+{
+    VCard *card;
+
+    vreader_lock(reader);
+    card = vcard_reference(reader->card);
+    vreader_unlock(reader);
+    return card;
+}
+
+VReaderStatus
+vreader_card_is_present(VReader *reader)
+{
+    VCard *card = vreader_get_card(reader);
+
+    if (card == NULL) {
+        return VREADER_NO_CARD;
+    }
+    vcard_free(card);
+    return VREADER_OK;
+}
+
+vreader_id_t
+vreader_get_id(VReader *reader)
+{
+    if (reader == NULL) {
+        return (vreader_id_t)-1;
+    }
+    return reader->id;
+}
+
+VReaderStatus
+vreader_set_id(VReader *reader, vreader_id_t id)
+{
+    if (reader == NULL) {
+        return VREADER_NO_CARD;
+    }
+    reader->id = id;
+    return VREADER_OK;
+}
+
+const char *
+vreader_get_name(VReader *reader)
+{
+    if (reader == NULL) {
+        return NULL;
+    }
+    return reader->name;
+}
+
+VReaderEmul *
+vreader_get_private(VReader *reader)
+{
+    return reader->reader_private;
+}
+
+static VReaderStatus
+vreader_reset(VReader *reader, VCardPower power, unsigned char *atr, int *len)
+{
+    VCard *card = vreader_get_card(reader);
+
+    if (card == NULL) {
+        return VREADER_NO_CARD;
+    }
+    /*
+     * clean up our state
+     */
+    vcard_reset(card, power);
+    if (atr) {
+        vcard_get_atr(card, atr, len);
+    }
+    vcard_free(card); /* free our reference */
+    return VREADER_OK;
+}
+
+VReaderStatus
+vreader_power_on(VReader *reader, unsigned char *atr, int *len)
+{
+    return vreader_reset(reader, VCARD_POWER_ON, atr, len);
+}
+
+VReaderStatus
+vreader_power_off(VReader *reader)
+{
+    return vreader_reset(reader, VCARD_POWER_OFF, NULL, 0);
+}
+
+
+VReaderStatus
+vreader_xfr_bytes(VReader *reader,
+                  unsigned char *send_buf, int send_buf_len,
+                  unsigned char *receive_buf, int *receive_buf_len)
+{
+    VCardAPDU *apdu;
+    VCardResponse *response = NULL;
+    VCardStatus card_status;
+    unsigned short status;
+    VCard *card = vreader_get_card(reader);
+
+    if (card == NULL) {
+        return VREADER_NO_CARD;
+    }
+
+    apdu = vcard_apdu_new(send_buf, send_buf_len, &status);
+    if (apdu == NULL) {
+        response = vcard_make_response(status);
+        card_status = VCARD_DONE;
+    } else {
+        card_status = vcard_process_apdu(card, apdu, &response);
+    }
+    assert(card_status == VCARD_DONE);
+    if (card_status == VCARD_DONE) {
+        int size = MIN(*receive_buf_len, response->b_total_len);
+        memcpy(receive_buf, response->b_data, size);
+        *receive_buf_len = size;
+    }
+    vcard_response_delete(response);
+    vcard_apdu_delete(apdu);
+    vcard_free(card); /* free our reference */
+    return VREADER_OK;
+}
+
+struct VReaderListStruct {
+    VReaderListEntry *head;
+    VReaderListEntry *tail;
+};
+
+struct VReaderListEntryStruct {
+    VReaderListEntry *next;
+    VReaderListEntry *prev;
+    VReader *reader;
+};
+
+
+static VReaderListEntry *
+vreader_list_entry_new(VReader *reader)
+{
+    VReaderListEntry *new_reader_list_entry;
+
+    new_reader_list_entry = (VReaderListEntry *)
+                               qemu_malloc(sizeof(VReaderListEntry));
+    new_reader_list_entry->next = NULL;
+    new_reader_list_entry->prev = NULL;
+    new_reader_list_entry->reader = vreader_reference(reader);
+    return new_reader_list_entry;
+}
+
+static void
+vreader_list_entry_delete(VReaderListEntry *entry)
+{
+    if (entry == NULL) {
+        return;
+    }
+    vreader_free(entry->reader);
+    qemu_free(entry);
+}
+
+
+static VReaderList *
+vreader_list_new(void)
+{
+    VReaderList *new_reader_list;
+
+    new_reader_list = (VReaderList *)qemu_malloc(sizeof(VReaderList));
+    new_reader_list->head = NULL;
+    new_reader_list->tail = NULL;
+    return new_reader_list;
+}
+
+void
+vreader_list_delete(VReaderList *list)
+{
+    VReaderListEntry *current_entry;
+    VReaderListEntry *next_entry = NULL;
+    for (current_entry = vreader_list_get_first(list); current_entry;
+         current_entry = next_entry) {
+        next_entry = vreader_list_get_next(current_entry);
+        vreader_list_entry_delete(current_entry);
+    }
+    list->head = NULL;
+    list->tail = NULL;
+    qemu_free(list);
+}
+
+
+VReaderListEntry *
+vreader_list_get_first(VReaderList *list)
+{
+    return list ? list->head : NULL;
+}
+
+VReaderListEntry *
+vreader_list_get_next(VReaderListEntry *current)
+{
+    return current ? current->next : NULL;
+}
+
+VReader *
+vreader_list_get_reader(VReaderListEntry *entry)
+{
+    return entry ? vreader_reference(entry->reader) : NULL;
+}
+
+static void
+vreader_queue(VReaderList *list, VReaderListEntry *entry)
+{
+    if (entry == NULL) {
+        return;
+    }
+    entry->next = NULL;
+    entry->prev = list->tail;
+    if (list->head) {
+        list->tail->next = entry;
+    } else {
+        list->head = entry;
+    }
+    list->tail = entry;
+}
+
+static void
+vreader_dequeue(VReaderList *list, VReaderListEntry *entry)
+{
+    if (entry == NULL) {
+        return;
+    }
+    if (entry->next == NULL) {
+        list->tail = entry->prev;
+    } else if (entry->prev == NULL) {
+        list->head = entry->next;
+    } else {
+        entry->prev->next = entry->next;
+        entry->next->prev = entry->prev;
+    }
+    if ((list->tail == NULL) || (list->head == NULL)) {
+        list->head = list->tail = NULL;
+    }
+    entry->next = entry->prev = NULL;
+}
+
+static VReaderList *vreader_list;
+static QemuMutex vreader_list_mutex;
+
+static void
+vreader_list_init(void)
+{
+    vreader_list = vreader_list_new();
+    qemu_mutex_init(&vreader_list_mutex);
+}
+
+static void
+vreader_list_lock(void)
+{
+    qemu_mutex_lock(&vreader_list_mutex);
+}
+
+static void
+vreader_list_unlock(void)
+{
+    qemu_mutex_unlock(&vreader_list_mutex);
+}
+
+static VReaderList *
+vreader_copy_list(VReaderList *list)
+{
+    VReaderList *new_list = NULL;
+    VReaderListEntry *current_entry = NULL;
+
+    new_list = vreader_list_new();
+    if (new_list == NULL) {
+        return NULL;
+    }
+    for (current_entry = vreader_list_get_first(list); current_entry;
+         current_entry = vreader_list_get_next(current_entry)) {
+        VReader *reader = vreader_list_get_reader(current_entry);
+        VReaderListEntry *new_entry = vreader_list_entry_new(reader);
+
+        vreader_free(reader);
+        vreader_queue(new_list, new_entry);
+    }
+    return new_list;
+}
+
+VReaderList *
+vreader_get_reader_list(void)
+{
+    VReaderList *new_reader_list;
+
+    vreader_list_lock();
+    new_reader_list = vreader_copy_list(vreader_list);
+    vreader_list_unlock();
+    return new_reader_list;
+}
+
+VReader *
+vreader_get_reader_by_id(vreader_id_t id)
+{
+    VReader *reader = NULL;
+    VReaderListEntry *current_entry = NULL;
+
+    if (id == (vreader_id_t) -1) {
+        return NULL;
+    }
+
+    vreader_list_lock();
+    for (current_entry = vreader_list_get_first(vreader_list); current_entry;
+            current_entry = vreader_list_get_next(current_entry)) {
+        VReader *creader = vreader_list_get_reader(current_entry);
+        if (creader->id == id) {
+            reader = creader;
+            break;
+        }
+        vreader_free(creader);
+    }
+    vreader_list_unlock();
+    return reader;
+}
+
+VReader *
+vreader_get_reader_by_name(const char *name)
+{
+    VReader *reader = NULL;
+    VReaderListEntry *current_entry = NULL;
+
+    vreader_list_lock();
+    for (current_entry = vreader_list_get_first(vreader_list); current_entry;
+            current_entry = vreader_list_get_next(current_entry)) {
+        VReader *creader = vreader_list_get_reader(current_entry);
+        if (strcmp(creader->name, name) == 0) {
+            reader = creader;
+            break;
+        }
+        vreader_free(creader);
+    }
+    vreader_list_unlock();
+    return reader;
+}
+
+/* called from card_emul to initialize the readers */
+VReaderStatus
+vreader_add_reader(VReader *reader)
+{
+    VReaderListEntry *reader_entry;
+
+    reader_entry = vreader_list_entry_new(reader);
+    if (reader_entry == NULL) {
+        return VREADER_OUT_OF_MEMORY;
+    }
+    vreader_list_lock();
+    vreader_queue(vreader_list, reader_entry);
+    vreader_list_unlock();
+    vevent_queue_vevent(vevent_new(VEVENT_READER_INSERT, reader, NULL));
+    return VREADER_OK;
+}
+
+
+VReaderStatus
+vreader_remove_reader(VReader *reader)
+{
+    VReaderListEntry *current_entry;
+
+    vreader_list_lock();
+    for (current_entry = vreader_list_get_first(vreader_list); current_entry;
+         current_entry = vreader_list_get_next(current_entry)) {
+        if (current_entry->reader == reader) {
+            break;
+        }
+    }
+    vreader_dequeue(vreader_list, current_entry);
+    vreader_list_unlock();
+    vreader_list_entry_delete(current_entry);
+    vevent_queue_vevent(vevent_new(VEVENT_READER_REMOVE, reader, NULL));
+    return VREADER_OK;
+}
+
+/*
+ * Generate VEVENT_CARD_INSERT or VEVENT_CARD_REMOVE based on vreader
+ * state. Separated from vreader_insert_card to allow replaying events
+ * for a given state.
+ */
+void
+vreader_queue_card_event(VReader *reader)
+{
+    vevent_queue_vevent(vevent_new(
+        reader->card ? VEVENT_CARD_INSERT : VEVENT_CARD_REMOVE, reader,
+        reader->card));
+}
+
+/*
+ * insert/remove a new card. for removal, card == NULL
+ */
+VReaderStatus
+vreader_insert_card(VReader *reader, VCard *card)
+{
+    vreader_lock(reader);
+    if (reader->card) {
+        /* decrement reference count */
+        vcard_free(reader->card);
+        reader->card = NULL;
+    }
+    reader->card = vcard_reference(card);
+    vreader_unlock(reader);
+    vreader_queue_card_event(reader);
+    return VREADER_OK;
+}
+
+/*
+ * initialize all the static reader structures
+ */
+void
+vreader_init(void)
+{
+    vreader_list_init();
+}
+
diff --git a/libcacard/vreader.h b/libcacard/vreader.h
new file mode 100644
index 0000000000..ec2042136c
--- /dev/null
+++ b/libcacard/vreader.h
@@ -0,0 +1,55 @@
+/*
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef VREADER_H
+#define VREADER_H 1
+
+#include "eventt.h"
+#include "vreadert.h"
+#include "vcardt.h"
+
+/*
+ * calls for reader front end
+ */
+VReaderStatus vreader_power_on(VReader *reader, unsigned char *atr, int *len);
+VReaderStatus vreader_power_off(VReader *reader);
+VReaderStatus vreader_xfr_bytes(VReader *reader, unsigned char *send_buf,
+                                int send_buf_len, unsigned char *receive_buf,
+                                int *receive_buf_len);
+
+/* constructor */
+VReader *vreader_new(const char *readerName, VReaderEmul *emul_private,
+                     VReaderEmulFree private_free);
+/* get a new reference to a reader */
+VReader *vreader_reference(VReader *reader);
+/* "destructor" (readers are reference counted) */
+void vreader_free(VReader *reader);
+
+/* accessors */
+VReaderEmul *vreader_get_private(VReader *);
+VReaderStatus vreader_card_is_present(VReader *reader);
+void vreader_queue_card_event(VReader *reader);
+const char *vreader_get_name(VReader *reader);
+vreader_id_t vreader_get_id(VReader *reader);
+VReaderStatus vreader_set_id(VReader *reader, vreader_id_t id);
+
+/* list operations */
+VReaderList *vreader_get_reader_list(void);
+void vreader_list_delete(VReaderList *list);
+VReader *vreader_list_get_reader(VReaderListEntry *entry);
+VReaderListEntry *vreader_list_get_first(VReaderList *list);
+VReaderListEntry *vreader_list_get_next(VReaderListEntry *list);
+VReader *vreader_get_reader_by_id(vreader_id_t id);
+VReader *vreader_get_reader_by_name(const char *name);
+
+/*
+ * list tools for vcard_emul
+ */
+void vreader_init(void);
+VReaderStatus vreader_add_reader(VReader *reader);
+VReaderStatus vreader_remove_reader(VReader *reader);
+VReaderStatus vreader_insert_card(VReader *reader, VCard *card);
+
+#endif
diff --git a/libcacard/vreadert.h b/libcacard/vreadert.h
new file mode 100644
index 0000000000..f97e0a79ec
--- /dev/null
+++ b/libcacard/vreadert.h
@@ -0,0 +1,24 @@
+/*
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef VREADERT_H
+#define VREADERT_H 1
+
+typedef enum {
+    VREADER_OK = 0,
+    VREADER_NO_CARD,
+    VREADER_OUT_OF_MEMORY
+} VReaderStatus;
+
+typedef unsigned int vreader_id_t;
+typedef struct VReaderStruct VReader;
+typedef struct VReaderListStruct VReaderList;
+typedef struct VReaderListEntryStruct VReaderListEntry;
+
+typedef struct VReaderEmulStruct VReaderEmul;
+typedef void (*VReaderEmulFree)(VReaderEmul *);
+
+#endif
+

From 2ac85b93b0487b362188a62eef685e6f9e7729ce Mon Sep 17 00:00:00 2001
From: Robert Relyea <rrelyea@redhat.com>
Date: Thu, 17 Mar 2011 16:38:30 +0200
Subject: [PATCH 051/386] libcacard: add vscclient

client to talk to ccid-card-passthru and use smartcard on client to
perform actual operations.

v23->v24 changes: (Jes Sorensen review 2)
 * use qemu_socket instead of socket
 * use fprintf(stderr,..) for errors
 * remove unneccessary includes since using qemu_common.h
---
 libcacard/Makefile    |   9 +-
 libcacard/vscclient.c | 652 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 659 insertions(+), 2 deletions(-)
 create mode 100644 libcacard/vscclient.c

diff --git a/libcacard/Makefile b/libcacard/Makefile
index 0211eacb64..4010029173 100644
--- a/libcacard/Makefile
+++ b/libcacard/Makefile
@@ -15,6 +15,11 @@ QEMU_OBJS=$(addprefix ../, $(QEMU_THREAD) $(oslib-obj-y) $(trace-obj-y) qemu-mal
 
 QEMU_CFLAGS+=-I../
 
-clean:
-	rm -f *.o */*.o *.d */*.d *.a */*.a *~ */*~
+vscclient: $(libcacard-y) $(QEMU_OBJS) vscclient.o
+	$(call quiet-command,$(CC) $(libcacard_libs) -lrt -o $@ $^,"  LINK  $(TARGET_DIR)$@")
+
+all: vscclient
+
+clean:
+	rm -f *.o */*.o *.d */*.d *.a */*.a *~ */*~ vscclient
 
diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c
new file mode 100644
index 0000000000..ce33f5a92e
--- /dev/null
+++ b/libcacard/vscclient.c
@@ -0,0 +1,652 @@
+/*
+ * Tester for VSCARD protocol, client side.
+ *
+ * Can be used with ccid-card-passthru.
+ *
+ * Copyright (c) 2011 Red Hat.
+ * Written by Alon Levy.
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include <netdb.h>
+
+#include "qemu-common.h"
+#include "qemu-thread.h"
+#include "qemu_socket.h"
+
+#include "vscard_common.h"
+
+#include "vreader.h"
+#include "vcard_emul.h"
+#include "vevent.h"
+
+int verbose;
+
+int sock;
+
+static void
+print_byte_array(
+    uint8_t *arrBytes,
+    unsigned int nSize
+) {
+    int i;
+    for (i = 0; i < nSize; i++) {
+        printf("%02X ", arrBytes[i]);
+    }
+    printf("\n");
+}
+
+static void
+print_usage(void) {
+    printf("vscclient [-c <certname> .. -e <emul_args> -d <level>%s] "
+            "<host> <port>\n",
+#ifdef USE_PASSTHRU
+    " -p");
+    printf(" -p use passthrough mode\n");
+#else
+   "");
+#endif
+    vcard_emul_usage();
+}
+
+static QemuMutex write_lock;
+
+static int
+send_msg(
+    VSCMsgType type,
+    uint32_t reader_id,
+    const void *msg,
+    unsigned int length
+) {
+    int rv;
+    VSCMsgHeader mhHeader;
+
+    qemu_mutex_lock(&write_lock);
+
+    if (verbose > 10) {
+        printf("sending type=%d id=%d, len =%d (0x%x)\n",
+               type, reader_id, length, length);
+    }
+
+    mhHeader.type = htonl(type);
+    mhHeader.reader_id = 0;
+    mhHeader.length = htonl(length);
+    rv = write(sock, &mhHeader, sizeof(mhHeader));
+    if (rv < 0) {
+        /* Error */
+        fprintf(stderr, "write header error\n");
+        close(sock);
+        qemu_mutex_unlock(&write_lock);
+        return 16;
+    }
+    rv = write(sock, msg, length);
+    if (rv < 0) {
+        /* Error */
+        fprintf(stderr, "write error\n");
+        close(sock);
+        qemu_mutex_unlock(&write_lock);
+        return 16;
+    }
+    qemu_mutex_unlock(&write_lock);
+
+    return 0;
+}
+
+static VReader *pending_reader;
+static QemuMutex pending_reader_lock;
+static QemuCond pending_reader_condition;
+
+#define MAX_ATR_LEN 40
+static void *
+event_thread(void *arg)
+{
+    unsigned char atr[MAX_ATR_LEN];
+    int atr_len = MAX_ATR_LEN;
+    VEvent *event = NULL;
+    unsigned int reader_id;
+
+
+    while (1) {
+        const char *reader_name;
+
+        event = vevent_wait_next_vevent();
+        if (event == NULL) {
+            break;
+        }
+        reader_id = vreader_get_id(event->reader);
+        if (reader_id == VSCARD_UNDEFINED_READER_ID &&
+            event->type != VEVENT_READER_INSERT) {
+            /* ignore events from readers qemu has rejected */
+            /* if qemu is still deciding on this reader, wait to see if need to
+             * forward this event */
+            qemu_mutex_lock(&pending_reader_lock);
+            if (!pending_reader || (pending_reader != event->reader)) {
+                /* wasn't for a pending reader, this reader has already been
+                 * rejected by qemu */
+                qemu_mutex_unlock(&pending_reader_lock);
+                vevent_delete(event);
+                continue;
+            }
+            /* this reader hasn't been told it's status from qemu yet, wait for
+             * that status */
+            while (pending_reader != NULL) {
+                qemu_cond_wait(&pending_reader_condition, &pending_reader_lock);
+            }
+            qemu_mutex_unlock(&pending_reader_lock);
+            /* now recheck the id */
+            reader_id = vreader_get_id(event->reader);
+            if (reader_id == VSCARD_UNDEFINED_READER_ID) {
+                /* this reader was rejected */
+                vevent_delete(event);
+                continue;
+            }
+            /* reader was accepted, now forward the event */
+        }
+        switch (event->type) {
+        case VEVENT_READER_INSERT:
+            /* tell qemu to insert a new CCID reader */
+            /* wait until qemu has responded to our first reader insert
+             * before we send a second. That way we won't confuse the responses
+             * */
+            qemu_mutex_lock(&pending_reader_lock);
+            while (pending_reader != NULL) {
+                qemu_cond_wait(&pending_reader_condition, &pending_reader_lock);
+            }
+            pending_reader = vreader_reference(event->reader);
+            qemu_mutex_unlock(&pending_reader_lock);
+            reader_name = vreader_get_name(event->reader);
+            if (verbose > 10) {
+                printf(" READER INSERT: %s\n", reader_name);
+            }
+            send_msg(VSC_ReaderAdd,
+                reader_id, /* currerntly VSCARD_UNDEFINED_READER_ID */
+                NULL, 0 /* TODO reader_name, strlen(reader_name) */);
+            break;
+        case VEVENT_READER_REMOVE:
+            /* future, tell qemu that an old CCID reader has been removed */
+            if (verbose > 10) {
+                printf(" READER REMOVE: %d\n", reader_id);
+            }
+            send_msg(VSC_ReaderRemove, reader_id, NULL, 0);
+            break;
+        case VEVENT_CARD_INSERT:
+            /* get the ATR (intended as a response to a power on from the
+             * reader */
+            atr_len = MAX_ATR_LEN;
+            vreader_power_on(event->reader, atr, &atr_len);
+            /* ATR call functions as a Card Insert event */
+            if (verbose > 10) {
+                printf(" CARD INSERT %d: ", reader_id);
+                print_byte_array(atr, atr_len);
+            }
+            send_msg(VSC_ATR, reader_id, atr, atr_len);
+            break;
+        case VEVENT_CARD_REMOVE:
+            /* Card removed */
+            if (verbose > 10) {
+                printf(" CARD REMOVE %d:\n", reader_id);
+            }
+            send_msg(VSC_CardRemove, reader_id, NULL, 0);
+            break;
+        default:
+            break;
+        }
+        vevent_delete(event);
+    }
+    return NULL;
+}
+
+
+static unsigned int
+get_id_from_string(char *string, unsigned int default_id)
+{
+    unsigned int id = atoi(string);
+
+    /* don't accidentally swith to zero because no numbers have been supplied */
+    if ((id == 0) && *string != '0') {
+        return default_id;
+    }
+    return id;
+}
+
+static void
+do_command(void)
+{
+    char inbuf[255];
+    char *string;
+    VCardEmulError error;
+    static unsigned int default_reader_id;
+    unsigned int reader_id;
+    VReader *reader = NULL;
+
+    reader_id = default_reader_id;
+    string = fgets(inbuf, sizeof(inbuf), stdin);
+    if (string != NULL) {
+        if (strncmp(string, "exit", 4) == 0) {
+            /* remove all the readers */
+            VReaderList *list = vreader_get_reader_list();
+            VReaderListEntry *reader_entry;
+            printf("Active Readers:\n");
+            for (reader_entry = vreader_list_get_first(list); reader_entry;
+                 reader_entry = vreader_list_get_next(reader_entry)) {
+                VReader *reader = vreader_list_get_reader(reader_entry);
+                vreader_id_t reader_id;
+                reader_id = vreader_get_id(reader);
+                if (reader_id == -1) {
+                    continue;
+                }
+                /* be nice and signal card removal first (qemu probably should
+                 * do this itself) */
+                if (vreader_card_is_present(reader) == VREADER_OK) {
+                    send_msg(VSC_CardRemove, reader_id, NULL, 0);
+                }
+                send_msg(VSC_ReaderRemove, reader_id, NULL, 0);
+            }
+            exit(0);
+        } else if (strncmp(string, "insert", 6) == 0) {
+            if (string[6] == ' ') {
+                reader_id = get_id_from_string(&string[7], reader_id);
+            }
+            reader = vreader_get_reader_by_id(reader_id);
+            if (reader != NULL) {
+                error = vcard_emul_force_card_insert(reader);
+                printf("insert %s, returned %d\n",
+                       reader ? vreader_get_name(reader)
+                       : "invalid reader", error);
+            } else {
+                printf("no reader by id %d found\n", reader_id);
+            }
+        } else if (strncmp(string, "remove", 6) == 0) {
+            if (string[6] == ' ') {
+                reader_id = get_id_from_string(&string[7], reader_id);
+            }
+            reader = vreader_get_reader_by_id(reader_id);
+            if (reader != NULL) {
+                error = vcard_emul_force_card_remove(reader);
+                printf("remove %s, returned %d\n",
+                        reader ? vreader_get_name(reader)
+                        : "invalid reader", error);
+            } else {
+                printf("no reader by id %d found\n", reader_id);
+            }
+        } else if (strncmp(string, "select", 6) == 0) {
+            if (string[6] == ' ') {
+                reader_id = get_id_from_string(&string[7],
+                                               VSCARD_UNDEFINED_READER_ID);
+            }
+            if (reader_id != VSCARD_UNDEFINED_READER_ID) {
+                reader = vreader_get_reader_by_id(reader_id);
+            }
+            if (reader) {
+                printf("Selecting reader %d, %s\n", reader_id,
+                        vreader_get_name(reader));
+                default_reader_id = reader_id;
+            } else {
+                printf("Reader with id %d not found\n", reader_id);
+            }
+        } else if (strncmp(string, "debug", 5) == 0) {
+            if (string[5] == ' ') {
+                verbose = get_id_from_string(&string[6], 0);
+            }
+            printf("debug level = %d\n", verbose);
+        } else if (strncmp(string, "list", 4) == 0) {
+            VReaderList *list = vreader_get_reader_list();
+            VReaderListEntry *reader_entry;
+            printf("Active Readers:\n");
+            for (reader_entry = vreader_list_get_first(list); reader_entry;
+                 reader_entry = vreader_list_get_next(reader_entry)) {
+                VReader *reader = vreader_list_get_reader(reader_entry);
+                vreader_id_t reader_id;
+                reader_id = vreader_get_id(reader);
+                if (reader_id == -1) {
+                    continue;
+                }
+                printf("%3d %s %s\n", reader_id,
+                       vreader_card_is_present(reader) == VREADER_OK ?
+                       "CARD_PRESENT" : "            ",
+                       vreader_get_name(reader));
+            }
+            printf("Inactive Readers:\n");
+            for (reader_entry = vreader_list_get_first(list); reader_entry;
+                 reader_entry = vreader_list_get_next(reader_entry)) {
+                VReader *reader = vreader_list_get_reader(reader_entry);
+                vreader_id_t reader_id;
+                reader_id = vreader_get_id(reader);
+                if (reader_id != -1) {
+                    continue;
+                }
+
+                printf("INA %s %s\n",
+                       vreader_card_is_present(reader) == VREADER_OK ?
+                       "CARD_PRESENT" : "            ",
+                       vreader_get_name(reader));
+            }
+        } else if (*string != 0) {
+            printf("valid commands:\n");
+            printf("insert [reader_id]\n");
+            printf("remove [reader_id]\n");
+            printf("select reader_id\n");
+            printf("list\n");
+            printf("debug [level]\n");
+            printf("exit\n");
+        }
+    }
+    vreader_free(reader);
+    printf("> ");
+    fflush(stdout);
+}
+
+
+#define APDUBufSize 270
+
+/* just for ease of parsing command line arguments. */
+#define MAX_CERTS 100
+
+static int
+connect_to_qemu(
+    const char *host,
+    const char *port
+) {
+    struct addrinfo hints;
+    struct addrinfo *server;
+    int ret;
+
+    sock = qemu_socket(AF_INET, SOCK_STREAM, 0);
+    if (sock < 0) {
+        /* Error */
+        fprintf(stderr, "Error opening socket!\n");
+    }
+
+    memset(&hints, 0, sizeof(struct addrinfo));
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_flags = 0;
+    hints.ai_protocol = 0;          /* Any protocol */
+
+    ret = getaddrinfo(host, port, &hints, &server);
+
+    if (ret != 0) {
+        /* Error */
+        fprintf(stderr, "getaddrinfo failed\n");
+        return 5;
+    }
+
+    if (connect(sock, server->ai_addr, server->ai_addrlen) < 0) {
+        /* Error */
+        fprintf(stderr, "Could not connect\n");
+        return 5;
+    }
+    if (verbose) {
+        printf("Connected (sizeof Header=%zd)!\n", sizeof(VSCMsgHeader));
+    }
+    return sock;
+}
+
+static int on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming)
+{
+    uint32_t *capabilities = (incoming->capabilities);
+    int num_capabilities =
+        1 + ((mhHeader->length - sizeof(VSCMsgInit)) / sizeof(uint32_t));
+    int i;
+    int rv;
+    pthread_t thread_id;
+
+    incoming->version = ntohl(incoming->version);
+    if (incoming->version != VSCARD_VERSION) {
+        if (verbose > 0) {
+            printf("warning: host has version %d, we have %d\n",
+                verbose, VSCARD_VERSION);
+        }
+    }
+    if (incoming->magic != VSCARD_MAGIC) {
+        printf("unexpected magic: got %d, expected %d\n",
+            incoming->magic, VSCARD_MAGIC);
+        return -1;
+    }
+    for (i = 0 ; i < num_capabilities; ++i) {
+        capabilities[i] = ntohl(capabilities[i]);
+    }
+    /* Future: check capabilities */
+    /* remove whatever reader might be left in qemu,
+     * in case of an unclean previous exit. */
+    send_msg(VSC_ReaderRemove, VSCARD_MINIMAL_READER_ID, NULL, 0);
+    /* launch the event_thread. This will trigger reader adds for all the
+     * existing readers */
+    rv = pthread_create(&thread_id, NULL, event_thread, NULL);
+    if (rv < 0) {
+        perror("pthread_create");
+        return rv;
+    }
+    return 0;
+}
+
+int
+main(
+    int argc,
+    char *argv[]
+) {
+    char *qemu_host;
+    char *qemu_port;
+    VSCMsgHeader mhHeader;
+    VSCMsgError *error_msg;
+
+    int rv;
+    int dwSendLength;
+    int dwRecvLength;
+    uint8_t pbRecvBuffer[APDUBufSize];
+    uint8_t pbSendBuffer[APDUBufSize];
+     VReaderStatus reader_status;
+    VReader *reader = NULL;
+    VCardEmulOptions *command_line_options = NULL;
+
+    char *cert_names[MAX_CERTS];
+    char *emul_args = NULL;
+    int cert_count = 0;
+    int c;
+
+    while ((c = getopt(argc, argv, "c:e:pd:")) != -1) {
+        switch (c) {
+        case 'c':
+            if (cert_count >= MAX_CERTS) {
+                printf("too many certificates (max = %d)\n", MAX_CERTS);
+                exit(5);
+            }
+            cert_names[cert_count++] = optarg;
+            break;
+        case 'e':
+            emul_args = optarg;
+            break;
+        case 'p':
+            print_usage();
+            exit(4);
+            break;
+        case 'd':
+            verbose = get_id_from_string(optarg, 1);
+            break;
+        }
+    }
+
+    if (argc - optind != 2) {
+        print_usage();
+        exit(4);
+    }
+
+    if (cert_count > 0) {
+        char *new_args;
+        int len, i;
+        /* if we've given some -c options, we clearly we want do so some
+         * software emulation.  add that emulation now. this is NSS Emulator
+         * specific */
+        if (emul_args == NULL) {
+            emul_args = (char *)"db=\"/etc/pki/nssdb\"";
+        }
+#define SOFT_STRING ",soft=(,Virtual Reader,CAC,,"
+             /* 2 == close paren & null */
+        len = strlen(emul_args) + strlen(SOFT_STRING) + 2;
+        for (i = 0; i < cert_count; i++) {
+            len += strlen(cert_names[i])+1; /* 1 == comma */
+        }
+        new_args = qemu_malloc(len);
+        strcpy(new_args, emul_args);
+        strcat(new_args, SOFT_STRING);
+        for (i = 0; i < cert_count; i++) {
+            strcat(new_args, cert_names[i]);
+            strcat(new_args, ",");
+        }
+        strcat(new_args, ")");
+        emul_args = new_args;
+    }
+    if (emul_args) {
+        command_line_options = vcard_emul_options(emul_args);
+    }
+
+    qemu_host = strdup(argv[argc - 2]);
+    qemu_port = strdup(argv[argc - 1]);
+    sock = connect_to_qemu(qemu_host, qemu_port);
+
+    qemu_mutex_init(&write_lock);
+    qemu_mutex_init(&pending_reader_lock);
+    qemu_cond_init(&pending_reader_condition);
+
+    vcard_emul_init(command_line_options);
+
+    printf("> ");
+    fflush(stdout);
+
+    /* Send init message, Host responds (and then we send reader attachments) */
+    VSCMsgInit init = {
+        .version = htonl(VSCARD_VERSION),
+        .magic = VSCARD_MAGIC,
+        .capabilities = {0}
+    };
+    send_msg(VSC_Init, mhHeader.reader_id, &init, sizeof(init));
+
+    do {
+        fd_set fds;
+
+        FD_ZERO(&fds);
+        FD_SET(1, &fds);
+        FD_SET(sock, &fds);
+
+        /* waiting on input from the socket */
+        rv = select(sock+1, &fds, NULL, NULL, NULL);
+        if (rv < 0) {
+            /* handle error */
+            perror("select");
+            return 7;
+        }
+        if (FD_ISSET(1, &fds)) {
+            do_command();
+        }
+        if (!FD_ISSET(sock, &fds)) {
+            continue;
+        }
+
+        rv = read(sock, &mhHeader, sizeof(mhHeader));
+        if (rv < sizeof(mhHeader)) {
+            /* Error */
+            if (rv < 0) {
+                perror("header read error\n");
+            } else {
+                fprintf(stderr, "header short read %d\n", rv);
+            }
+            return 8;
+        }
+        mhHeader.type = ntohl(mhHeader.type);
+        mhHeader.reader_id = ntohl(mhHeader.reader_id);
+        mhHeader.length = ntohl(mhHeader.length);
+        if (verbose) {
+            printf("Header: type=%d, reader_id=%d length=%d (0x%x)\n",
+                    mhHeader.type, mhHeader.reader_id, mhHeader.length,
+                                               mhHeader.length);
+        }
+        switch (mhHeader.type) {
+        case VSC_APDU:
+        case VSC_Flush:
+        case VSC_Error:
+        case VSC_Init:
+            rv = read(sock, pbSendBuffer, mhHeader.length);
+            break;
+        default:
+            fprintf(stderr, "Unexpected message of type 0x%X\n", mhHeader.type);
+            return 0;
+        }
+        switch (mhHeader.type) {
+        case VSC_APDU:
+            if (rv < 0) {
+                /* Error */
+                fprintf(stderr, "read error\n");
+                close(sock);
+                return 8;
+            }
+            if (verbose) {
+                printf(" recv APDU: ");
+                print_byte_array(pbSendBuffer, mhHeader.length);
+            }
+            /* Transmit recieved APDU */
+            dwSendLength = mhHeader.length;
+            dwRecvLength = sizeof(pbRecvBuffer);
+            reader = vreader_get_reader_by_id(mhHeader.reader_id);
+            reader_status = vreader_xfr_bytes(reader,
+                pbSendBuffer, dwSendLength,
+                pbRecvBuffer, &dwRecvLength);
+            if (reader_status == VREADER_OK) {
+                mhHeader.length = dwRecvLength;
+                if (verbose) {
+                    printf(" send response: ");
+                    print_byte_array(pbRecvBuffer, mhHeader.length);
+                }
+                send_msg(VSC_APDU, mhHeader.reader_id,
+                         pbRecvBuffer, dwRecvLength);
+            } else {
+                rv = reader_status; /* warning: not meaningful */
+                send_msg(VSC_Error, mhHeader.reader_id, &rv, sizeof(uint32_t));
+            }
+            vreader_free(reader);
+            reader = NULL; /* we've freed it, don't use it by accident
+                              again */
+            break;
+        case VSC_Flush:
+            /* TODO: actually flush */
+            send_msg(VSC_FlushComplete, mhHeader.reader_id, NULL, 0);
+            break;
+        case VSC_Error:
+            error_msg = (VSCMsgError *) pbSendBuffer;
+            if (error_msg->code == VSC_SUCCESS) {
+                qemu_mutex_lock(&pending_reader_lock);
+                if (pending_reader) {
+                    vreader_set_id(pending_reader, mhHeader.reader_id);
+                    vreader_free(pending_reader);
+                    pending_reader = NULL;
+                    qemu_cond_signal(&pending_reader_condition);
+                }
+                qemu_mutex_unlock(&pending_reader_lock);
+                break;
+            }
+            printf("warning: qemu refused to add reader\n");
+            if (error_msg->code == VSC_CANNOT_ADD_MORE_READERS) {
+                /* clear pending reader, qemu can't handle any more */
+                qemu_mutex_lock(&pending_reader_lock);
+                if (pending_reader) {
+                    pending_reader = NULL;
+                    /* make sure the event loop doesn't hang */
+                    qemu_cond_signal(&pending_reader_condition);
+                }
+                qemu_mutex_unlock(&pending_reader_lock);
+            }
+            break;
+        case VSC_Init:
+            if (on_host_init(&mhHeader, (VSCMsgInit *)pbSendBuffer) < 0) {
+                return -1;
+            }
+            break;
+        default:
+            printf("Default\n");
+            return 0;
+        }
+    } while (rv >= 0);
+
+    return 0;
+}

From 65794b435c7a3e5945bd78fad8011e3f0f15f668 Mon Sep 17 00:00:00 2001
From: Robert Relyea <rrelyea@redhat.com>
Date: Thu, 17 Mar 2011 16:39:46 +0200
Subject: [PATCH 052/386] libcacard: add docs

---
 docs/libcacard.txt | 483 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 483 insertions(+)
 create mode 100644 docs/libcacard.txt

diff --git a/docs/libcacard.txt b/docs/libcacard.txt
new file mode 100644
index 0000000000..5dee6fa479
--- /dev/null
+++ b/docs/libcacard.txt
@@ -0,0 +1,483 @@
+This file documents the CAC (Common Access Card) library in the libcacard
+subdirectory.
+
+Virtual Smart Card Emulator
+
+This emulator is designed to provide emulation of actual smart cards to a
+virtual card reader running in a guest virtual machine. The emulated smart
+cards can be representations of real smart cards, where the necessary functions
+such as signing, card removal/insertion, etc. are mapped to real, physical
+cards which are shared with the client machine the emulator is running on, or
+the cards could be pure software constructs.
+
+The emulator is structured to allow multiple replacable or additional pieces,
+so it can be easily modified for future requirements. The primary envisioned
+modifications are:
+
+1) The socket connection to the virtual card reader (presumably a CCID reader,
+but other ISO-7816 compatible readers could be used). The code that handles
+this is in vscclient.c.
+
+2) The virtual card low level emulation. This is currently supplied by using
+NSS. This emulation could be replaced by implementations based on other
+security libraries, including but not limitted to openssl+pkcs#11 library,
+raw pkcs#11, Microsoft CAPI, direct opensc calls, etc. The code that handles
+this is in vcard_emul_nss.c.
+
+3) Emulation for new types of cards. The current implementation emulates the
+original DoD CAC standard with separate pki containers. This emulator lives in
+cac.c. More than one card type emulator could be included. Other cards could
+be emulated as well, including PIV, newer versions of CAC, PKCS #15, etc.
+
+--------------------
+Replacing the Socket Based Virtual Reader Interface.
+
+The current implementation contains a replacable module vscclient.c. The
+current vscclient.c implements a sockets interface to the virtual ccid reader
+on the guest. CCID commands that are pertinent to emulation are passed
+across the socket, and their responses are passed back along that same socket.
+The protocol that vscclient uses is defined in vscard_common.h and connects
+to a qemu ccid usb device. Since this socket runs as a client, vscclient.c
+implements a program with a main entry. It also handles argument parsing for
+the emulator.
+
+An application that wants to use the virtual reader can replace vscclient.c
+with it's own implementation that connects to it's own CCID reader.  The calls
+that the CCID reader can call are:
+
+      VReaderList * vreader_get_reader_list();
+
+  This function returns a list of virtual readers.  These readers may map to
+  physical devices, or simulated devices depending on vcard the back end. Each
+  reader in the list should represent a reader to the virtual machine. Virtual
+  USB address mapping is left to the CCID reader front end. This call can be
+  made any time to get an updated list. The returned list is a copy of the
+  internal list that can be referenced by the caller without locking. This copy
+  must be freed by the caller with vreader_list_delete when it is no longer
+  needed.
+
+      VReaderListEntry *vreader_list_get_first(VReaderList *);
+
+  This function gets the first entry on the reader list. Along with
+  vreader_list_get_next(), vreader_list_get_first() can be used to walk the
+  reader list returned from vreader_get_reader_list(). VReaderListEntries are
+  part of the list themselves and do not need to be freed separately from the
+  list. If there are no entries on the list, it will return NULL.
+
+      VReaderListEntry *vreader_list_get_next(VReaderListEntry *);
+
+  This function gets the next entry in the list. If there are no more entries
+  it will return NULL.
+
+      VReader * vreader_list_get_reader(VReaderListEntry *)
+
+  This function returns the reader stored in the reader List entry. Caller gets
+  a new reference to a reader. The caller must free it's reference when it is
+  finished with vreader_free().
+
+      void vreader_free(VReader *reader);
+
+   This function frees a reference to a reader. Reader's are reference counted
+   and are automatically deleted when the last reference is freed.
+
+      void vreader_list_delete(VReaderList *list);
+
+   This function frees the list, all the elements on the list, and all the
+   reader references held by the list.
+
+      VReaderStatus vreader_power_on(VReader *reader, char *atr, int *len);
+
+  This functions simulates a card power on. Virtual cards do not care about
+  the actual voltage and other physical parameters, but it does care that the
+  card is actually on or off. Cycling the card causes the card to reset. If
+  the caller provides enough space, vreader_power_on will return the ATR of
+  the virtual card. The amount of space provided in atr should be indicated
+  in *len. The function modifies *len to be the actual length of of the
+  returned ATR.
+
+      VReaderStatus vreader_power_off(VReader *reader);
+
+  This function simulates a power off of a virtual card.
+
+      VReaderStatus vreader_xfer_bytes(VReader *reader, unsigne char *send_buf,
+                                       int send_buf_len,
+                                       unsigned char *receive_buf,
+                                       int receive_buf_len);
+
+  This functions send a raw apdu to a card and returns the card's response.
+  The CCID front end should return the response back. Most of the emulation
+  is driven from these APDUs.
+
+      VReaderStatus vreader_card_is_present(VReader *reader);
+
+  This function returns whether or not the reader has a card inserted. The
+  vreader_power_on, vreader_power_off, and vreader_xfer_bytes will return
+  VREADER_NO_CARD.
+
+       const char *vreader_get_name(VReader *reader);
+
+  This function returns the name of the reader. The name comes from the card
+  emulator level and is usually related to the name of the physical reader.
+
+       VReaderID vreader_get_id(VReader *reader);
+
+  This function returns the id of a reader. All readers start out with an id
+  of -1. The application can set the id with vreader_set_id.
+
+       VReaderStatus vreader_get_id(VReader *reader, VReaderID id);
+
+  This function sets the reader id. The application is responsible for making
+  sure that the id is unique for all readers it is actively using.
+
+       VReader *vreader_find_reader_by_id(VReaderID id);
+
+  This function returns the reader which matches the id. If two readers match,
+  only one is returned. The function returns NULL if the id is -1.
+
+       Event *vevent_wait_next_vevent();
+
+  This function blocks waiting for reader and card insertion events. There
+  will be one event for each card insertion, each card removal, each reader
+  insertion and each reader removal. At start up, events are created for all
+  the initial readers found, as well as all the cards that are inserted.
+
+       Event *vevent_get_next_vevent();
+
+  This function returns a pending event if it exists, otherwise it returns
+  NULL. It does not block.
+
+----------------
+Card Type Emulator: Adding a New Virtual Card Type
+
+The ISO 7816 card spec describes 2 types of cards:
+ 1) File system cards, where the smartcard is managed by reading and writing
+data to files in a file system. There is currently only boiler plate
+implemented for file system cards.
+ 2) VM cards, where the card has loadable applets which perform the card
+functions. The current implementation supports VM cards.
+
+In the case of VM cards, the difference between various types of cards is
+really what applets have been installed in that card. This structure is
+mirrored in card type emulators. The 7816 emulator already handles the basic
+ISO 7186 commands. Card type emulators simply need to add the virtual applets
+which emulate the real card applets. Card type emulators have exactly one
+public entry point:
+
+       VCARDStatus xxx_card_init(VCard *card, const char *flags,
+                               const unsigned char *cert[],
+                               int cert_len[],
+                               VCardKey *key[],
+                               int cert_count);
+
+  The parameters for this are:
+  card       - the virtual card structure which will prepresent this card.
+  flags      - option flags that may be specific to this card type.
+  cert       - array of binary certificates.
+  cert_len   - array of lengths of each of the certificates specified in cert.
+  key        - array of opaque key structures representing the private keys on
+               the card.
+  cert_count - number of entries in cert, cert_len, and key arrays.
+
+  Any cert, cert_len, or key with the same index are matching sets. That is
+  cert[0] is cert_len[0] long and has the corresponsing private key of key[0].
+
+The card type emulator is expected to own the VCardKeys, but it should copy
+any raw cert data it wants to save. It can create new applets and add them to
+the card using the following functions:
+
+       VCardApplet *vcard_new_applet(VCardProcessAPDU apdu_func,
+                                     VCardResetApplet reset_func,
+                                     const unsigned char *aid,
+                                     int aid_len);
+
+  This function creates a new applet. Applet structures store the following
+  information:
+     1) the AID of the applet (set by aid and aid_len).
+     2) a function to handle APDUs for this applet. (set by apdu_func, more on
+        this below).
+     3) a function to reset the applet state when the applet is selected.
+        (set by reset_func, more on this below).
+     3) applet private data, a data pointer used by the card type emulator to
+        store any data or state it needs to complete requests. (set by a
+        separate call).
+     4) applet private data free, a function used to free the applet private
+        data when the applet itself is destroyed.
+  The created applet can be added to the card with vcard_add_applet below.
+
+        void vcard_set_applet_private(VCardApplet *applet,
+                                      VCardAppletPrivate *private,
+                                      VCardAppletPrivateFree private_free);
+  This function sets the private data and the corresponding free function.
+  VCardAppletPrivate is an opaque data structure to the rest of the emulator.
+  The card type emulator can define it any way it wants by defining
+  struct VCardAppletPrivateStruct {};. If there is already a private data
+  structure on the applet, the old one is freed before the new one is set up.
+  passing two NULL clear any existing private data.
+
+         VCardStatus vcard_add_applet(VCard *card, VCardApplet *applet);
+
+  Add an applet onto the list of applets attached to the card. Once an applet
+  has been added, it can be selected by it's aid, and then commands will be
+  routed to it VCardProcessAPDU function. This function adopts the applet the
+  passed int applet. Note: 2 applets with the same AID should not be added to
+  the same card. It's permissible to add more than one applet. Multiple applets
+  may have the same VCardPRocessAPDU entry point.
+
+The certs and keys should be attached to private data associated with one or
+more appropriate applets for that card. Control will come to the card type
+emulators once one of its applets are selected through the VCardProcessAPDU
+function it specified when it created the applet.
+
+The signature of VCardResetApplet is:
+        VCardStatus (*VCardResetApplet) (VCard *card, int channel);
+  This function will reset the any internal applet state that needs to be
+  cleared after a select applet call. It should return VCARD_DONE;
+
+The signature of VCardProcessAPDU is:
+        VCardStatus (*VCardProcessAPDU)(VCard *card, VCardAPDU *apdu,
+                                         VCardResponse **response);
+  This function examines the APDU and determines whether it should process
+  the apdu directly, reject the apdu as invalid, or pass the apdu on to
+  the basic 7816 emulator for processing.
+      If the 7816 emulator should process the apdu, then the VCardProcessAPDU
+  should return VCARD_NEXT.
+      If there is an error, then VCardProcessAPDU should return an error
+  response using vcard_make_response and the appropriate 7816 error code
+  (see card_7816t.h) or vcard_make_response with a card type specific error
+  code. It should then return VCARD_DONE.
+      If the apdu can be processed correctly, VCardProcessAPDU should do so,
+  set the response value appropriately for that APDU, and return VCARD_DONE.
+  VCardProcessAPDU should always set the response if it returns VCARD_DONE.
+  It should always either return VCARD_DONE or VCARD_NEXT.
+
+Parsing the APDU --
+
+Prior to processing calling the card type emulator's VCardProcessAPDU function, the emulator has already decoded the APDU header and set several fields:
+
+   apdu->a_data - The raw apdu data bytes.
+   apdu->a_len  - The len of the raw apdu data.
+   apdu->a_body - The start of any post header parameter data.
+   apdu->a_Lc   - The parameter length value.
+   apdu->a_Le   - The expected length of any returned data.
+   apdu->a_cla  - The raw apdu class.
+   apdu->a_channel - The channel (decoded from the class).
+   apdu->a_secure_messaging_type - The decoded secure messagin type
+                                   (from class).
+   apdu->a_type - The decode class type.
+   apdu->a_gen_type - the generic class type (7816, PROPRIETARY, RFU, PTS).
+   apdu->a_ins  - The instruction byte.
+   apdu->a_p1   - Parameter 1.
+   apdu->a_p2   - Parameter 2.
+
+Creating a Response --
+
+The expected result of any APDU call is a response. The card type emulator must
+set *response with an appropriate VCardResponse value if it returns VCARD_DONE.
+Reponses could be as simple as returning a 2 byte status word response, to as
+complex as returning a block of data along with a 2 byte response. Which is
+returned will depend on the semantics of the APDU. The following functions will
+create card responses.
+
+        VCardResponse *vcard_make_response(VCard7816Status status);
+
+    This is the most basic function to get a response. This function will
+    return a response the consists soley one 2 byte status code. If that status
+    code is defined in card_7816t.h, then this function is guarrenteed to
+    return a response with that status. If a cart type specific status code
+    is passed and vcard_make_response fails to allocate the appropriate memory
+    for that response, then vcard_make_response will return a VCardResponse
+    of VCARD7816_STATUS_EXC_ERROR_MEMORY. In any case, this function is
+    guarrenteed to return a valid VCardResponse.
+
+        VCardResponse *vcard_response_new(unsigned char *buf, int len,
+                                          VCard7816Status status);
+
+    This function is similar to vcard_make_response except it includes some
+    returned data with the response. It could also fail to allocate enough
+    memory, in which case it will return NULL.
+
+        VCardResponse *vcard_response_new_status_bytes(unsigned char sw1,
+                                                       unsigned char sw2);
+
+    Sometimes in 7816 the response bytes are treated as two separate bytes with
+    split meanings. This function allows you to create a response based on
+    two separate bytes. This function could fail, in which case it will return
+    NULL.
+
+       VCardResponse *vcard_response_new_bytes(unsigned char *buf, int len,
+                                               unsigned char sw1,
+                                               unsigned char sw2);
+
+    This function is the same as vcard_response_new except you may specify
+    the status as two separate bytes like vcard_response_new_status_bytes.
+
+
+Implementing functionality ---
+
+The following helper functions access information about the current card
+and applet.
+
+        VCARDAppletPrivate *vcard_get_current_applet_private(VCard *card,
+                                                             int channel);
+
+    This function returns any private data set by the card type emulator on
+    the currently selected applet. The card type emulator keeps track of the
+    current applet state in this data structure. Any certs and keys associated
+    with a particular applet is also stored here.
+
+        int vcard_emul_get_login_count(VCard *card);
+
+    This function returns the the number of remaing login attempts for this
+    card. If the card emulator does not know, or the card does not have a
+    way of giving this information, this function returns -1.
+
+
+         VCard7816Status vcard_emul_login(VCard *card, unsigned char *pin,
+                                          int pin_len);
+
+    This function logins into the card and return the standard 7816 status
+    word depending on the success or failure of the call.
+
+         void vcard_emul_delete_key(VCardKey *key);
+
+     This function frees the VCardKey passed in to xxxx_card_init. The card
+     type emulator is responsible for freeing this key when it no longer needs
+     it.
+
+         VCard7816Status vcard_emul_rsa_op(VCard *card, VCardKey *key,
+                                           unsigned char *buffer,
+                                           int buffer_size);
+
+     This function does a raw rsa op on the buffer with the given key.
+
+The sample card type emulator is found in cac.c. It implements the cac specific
+applets.  Only those applets needed by the coolkey pkcs#11 driver on the guest
+have been implemented. To support the full range CAC middleware, a complete CAC
+card according to the CAC specs should be implemented here.
+
+------------------------------
+Virtual Card Emulator
+
+This code accesses both real smart cards and simulated smart cards through
+services provided on the client. The current implementation uses NSS, which
+already knows how to talk to various PKCS #11 modules on the client, and is
+portable to most operating systems. A particular emulator can have only one
+virtual card implementation at a time.
+
+The virtual card emulator consists of a series of virtual card services. In
+addition to the services describe above (services starting with
+vcard_emul_xxxx), the virtual card emulator also provides the following
+functions:
+
+    VCardEmulError vcard_emul_init(cont VCardEmulOptions *options);
+
+  The options structure is built by another function in the virtual card
+  interface where a string of virtual card emulator specific strings are
+  mapped to the options. The actual structure is defined by the virutal card
+  emulator and is used to determine the configuration of soft cards, or to
+  determine which physical cards to present to the guest.
+
+  The vcard_emul_init function will build up sets of readers, create any
+  threads that are needed to watch for changes in the reader state. If readers
+  have cards present in them, they are also initialized.
+
+  Readers are created with the function.
+
+          VReader *vreader_new(VReaderEmul *reader_emul,
+                               VReaderEmulFree reader_emul_free);
+
+      The freeFunc is used to free the VReaderEmul * when the reader is
+      destroyed.  The VReaderEmul structure is an opaque structure to the
+      rest of the code, but defined by the virtual card emulator, which can
+      use it to store any reader specific state.
+
+  Once the reader has been created, it can be added to the front end with the
+  call:
+
+           VReaderStatus vreader_add_reader(VReader *reader);
+
+      This function will automatically generate the appropriate new reader
+      events and add the reader to the list.
+
+  To create a new card, the virtual card emulator will call a similiar
+  function.
+
+           VCard *vcard_new(VCardEmul *card_emul,
+                            VCardEmulFree card_emul_free);
+
+      Like vreader_new, this function takes a virtual card emulator specific
+      structure which it uses to keep track of the card state.
+
+  Once the card is created, it is attached to a card type emulator with the
+  following function:
+
+            VCardStatus vcard_init(VCard *vcard, VCardEmulType type,
+                                   const char *flags,
+                                   unsigned char *const *certs,
+                                   int *cert_len,
+                                   VCardKey *key[],
+                                   int cert_count);
+
+      The vcard is the value returned from vcard_new. The type is the
+      card type emulator that this card should presented to the guest as.
+      The flags are card type emulator specific options. The certs,
+      cert_len, and keys are all arrays of length cert_count. These are the
+      the same of the parameters xxxx_card_init() accepts.
+
+   Finally the card is associated with it's reader by the call:
+
+            VReaderStatus vreader_insert_card(VReader *vreader, VCard *vcard);
+
+      This function, like vreader_add_reader, will take care of any event
+      notification for the card insert.
+
+
+    VCardEmulError vcard_emul_force_card_remove(VReader *vreader);
+
+  Force a card that is present to appear to be removed to the guest, even if
+  that card is a physical card and is present.
+
+
+    VCardEmulError vcard_emul_force_card_insert(VReader *reader);
+
+  Force a card that has been removed by vcard_emul_force_card_remove to be
+  reinserted from the point of view of the guest. This will only work if the
+  card is physically present (which is always true fro a soft card).
+
+     void vcard_emul_get_atr(Vcard *card, unsigned char *atr, int *atr_len);
+
+  Return the virtual ATR for the card. By convention this should be the value
+  VCARD_ATR_PREFIX(size) followed by several ascii bytes related to this
+  particular emulator. For instance the NSS emulator returns
+  {VCARD_ATR_PREFIX(3), 'N', 'S', 'S' }. Do ot return more data then *atr_len;
+
+     void vcard_emul_reset(VCard *card, VCardPower power)
+
+   Set the state of 'card' to the current power level and reset its internal
+   state (logout, etc).
+
+-------------------------------------------------------
+List of files and their function:
+README - This file
+card_7816.c - emulate basic 7816 functionality. Parse APDUs.
+card_7816.h - apdu and response services definitions.
+card_7816t.h - 7816 specific structures, types and definitions.
+event.c - event handling code.
+event.h - event handling services definitions.
+eventt.h - event handling structures and types
+vcard.c - handle common virtual card services like creation, destruction, and
+          applet management.
+vcard.h - common virtual card services function definitions.
+vcardt.h - comon virtual card types
+vreader.c - common virtual reader services.
+vreader.h - common virtual reader services definitions.
+vreadert.h - comon virtual reader types.
+vcard_emul_type.c - manage the card type emulators.
+vcard_emul_type.h - definitions for card type emulators.
+cac.c - card type emulator for CAC cards
+vcard_emul.h - virtual card emulator service definitions.
+vcard_emul_nss.c - virtual card emulator implementation for nss.
+vscclient.c - socket connection to guest qemu usb driver.
+vscard_common.h - common header with the guest qemu usb driver.
+mutex.h - header file for machine independent mutexes.
+link_test.c - static test to make sure all the symbols are properly defined.

From 585738a6e62eb586f24782dee34306e7c375f9ba Mon Sep 17 00:00:00 2001
From: Alon Levy <alevy@redhat.com>
Date: Sun, 24 Oct 2010 12:09:18 +0200
Subject: [PATCH 053/386] ccid: add ccid-card-emulated device

This devices uses libcacard (internal) to emulate a smartcard conforming
to the CAC standard. It attaches to the usb-ccid bus. Usage instructions
(example command lines) are in the following patch in docs/ccid.txt. It
uses libcacard which uses nss, so it can work with both hw cards and
certificates (files).

Signed-off-by: Alon Levy <alevy@redhat.com>

---

changes from v20->v21: (Jes Sorenson review)
 * cosmetics
 * use qemu-thread and qemu_malloc/qemu_free

changes from v19->v20:
 * checkpatch.pl

changes from v18->v19:
 * add qdev.desc
 * backend: drop the enumeration property, back to using a string one.

changes from v16->v17:
 * use PROP_TYPE_ENUM for backend

changes from v15->v16:
 * fix error reporting in initfn
 * bump copyright year
 * update copyright license

changes from v1:
 * remove stale comments, use only c-style comments
 * bugfix, forgot to set recv_len
 * change reader name to 'Virtual Reader'
---
 Makefile.objs           |   1 +
 hw/ccid-card-emulated.c | 595 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 596 insertions(+)
 create mode 100644 hw/ccid-card-emulated.c

diff --git a/Makefile.objs b/Makefile.objs
index 8c425241fc..c05f5e59be 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -201,6 +201,7 @@ hw-obj-$(CONFIG_DMA) += dma.o
 hw-obj-$(CONFIG_HPET) += hpet.o
 hw-obj-$(CONFIG_APPLESMC) += applesmc.o
 hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
+hw-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o
 
 # PPC devices
 hw-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c
new file mode 100644
index 0000000000..0b0718426d
--- /dev/null
+++ b/hw/ccid-card-emulated.c
@@ -0,0 +1,595 @@
+/*
+ * CCID Card Device. Emulated card.
+ *
+ * Copyright (c) 2011 Red Hat.
+ * Written by Alon Levy.
+ *
+ * This code is licenced under the GNU LGPL, version 2 or later.
+ */
+
+/*
+ * It can be used to provide access to the local hardware in a non exclusive
+ * way, or it can use certificates. It requires the usb-ccid bus.
+ *
+ * Usage 1: standard, mirror hardware reader+card:
+ * qemu .. -usb -device usb-ccid -device ccid-card-emulated
+ *
+ * Usage 2: use certificates, no hardware required
+ * one time: create the certificates:
+ *  for i in 1 2 3; do
+ *      certutil -d /etc/pki/nssdb -x -t "CT,CT,CT" -S -s "CN=user$i" -n user$i
+ *  done
+ * qemu .. -usb -device usb-ccid \
+ *  -device ccid-card-emulated,cert1=user1,cert2=user2,cert3=user3
+ *
+ * If you use a non default db for the certificates you can specify it using
+ * the db parameter.
+ */
+
+#include <eventt.h>
+#include <vevent.h>
+#include <vreader.h>
+#include <vcard_emul.h>
+
+#include "qemu-thread.h"
+#include "qemu-char.h"
+#include "monitor.h"
+#include "hw/ccid.h"
+
+#define DPRINTF(card, lvl, fmt, ...) \
+do {\
+    if (lvl <= card->debug) {\
+        printf("ccid-card-emul: %s: " fmt , __func__, ## __VA_ARGS__);\
+    } \
+} while (0)
+
+#define EMULATED_DEV_NAME "ccid-card-emulated"
+
+#define BACKEND_NSS_EMULATED_NAME "nss-emulated"
+#define BACKEND_CERTIFICATES_NAME "certificates"
+
+enum {
+    BACKEND_NSS_EMULATED = 1,
+    BACKEND_CERTIFICATES
+};
+
+#define DEFAULT_BACKEND BACKEND_NSS_EMULATED
+
+typedef struct EmulatedState EmulatedState;
+
+enum {
+    EMUL_READER_INSERT = 0,
+    EMUL_READER_REMOVE,
+    EMUL_CARD_INSERT,
+    EMUL_CARD_REMOVE,
+    EMUL_GUEST_APDU,
+    EMUL_RESPONSE_APDU,
+    EMUL_ERROR,
+};
+
+static const char *emul_event_to_string(uint32_t emul_event)
+{
+    switch (emul_event) {
+    case EMUL_READER_INSERT:
+        return "EMUL_READER_INSERT";
+    case EMUL_READER_REMOVE:
+        return "EMUL_READER_REMOVE";
+    case EMUL_CARD_INSERT:
+        return "EMUL_CARD_INSERT";
+    case EMUL_CARD_REMOVE:
+        return "EMUL_CARD_REMOVE";
+    case EMUL_GUEST_APDU:
+        return "EMUL_GUEST_APDU";
+    case EMUL_RESPONSE_APDU:
+        return "EMUL_RESPONSE_APDU";
+    case EMUL_ERROR:
+        return "EMUL_ERROR";
+    }
+    return "UNKNOWN";
+}
+
+typedef struct EmulEvent {
+    QSIMPLEQ_ENTRY(EmulEvent) entry;
+    union {
+        struct {
+            uint32_t type;
+        } gen;
+        struct {
+            uint32_t type;
+            uint64_t code;
+        } error;
+        struct {
+            uint32_t type;
+            uint32_t len;
+            uint8_t data[];
+        } data;
+    } p;
+} EmulEvent;
+
+#define MAX_ATR_SIZE 40
+struct EmulatedState {
+    CCIDCardState base;
+    uint8_t  debug;
+    char    *backend_str;
+    uint32_t backend;
+    char    *cert1;
+    char    *cert2;
+    char    *cert3;
+    char    *db;
+    uint8_t  atr[MAX_ATR_SIZE];
+    uint8_t  atr_length;
+    QSIMPLEQ_HEAD(event_list, EmulEvent) event_list;
+    QemuMutex event_list_mutex;
+    VReader *reader;
+    QSIMPLEQ_HEAD(guest_apdu_list, EmulEvent) guest_apdu_list;
+    QemuMutex vreader_mutex; /* and guest_apdu_list mutex */
+    QemuMutex handle_apdu_mutex;
+    QemuCond handle_apdu_cond;
+    int      pipe[2];
+    int      quit_apdu_thread;
+    QemuMutex apdu_thread_quit_mutex;
+    QemuCond apdu_thread_quit_cond;
+};
+
+static void emulated_apdu_from_guest(CCIDCardState *base,
+    const uint8_t *apdu, uint32_t len)
+{
+    EmulatedState *card = DO_UPCAST(EmulatedState, base, base);
+    EmulEvent *event = (EmulEvent *)qemu_malloc(sizeof(EmulEvent) + len);
+
+    assert(event);
+    event->p.data.type = EMUL_GUEST_APDU;
+    event->p.data.len = len;
+    memcpy(event->p.data.data, apdu, len);
+    qemu_mutex_lock(&card->vreader_mutex);
+    QSIMPLEQ_INSERT_TAIL(&card->guest_apdu_list, event, entry);
+    qemu_mutex_unlock(&card->vreader_mutex);
+    qemu_mutex_lock(&card->handle_apdu_mutex);
+    qemu_cond_signal(&card->handle_apdu_cond);
+    qemu_mutex_unlock(&card->handle_apdu_mutex);
+}
+
+static const uint8_t *emulated_get_atr(CCIDCardState *base, uint32_t *len)
+{
+    EmulatedState *card = DO_UPCAST(EmulatedState, base, base);
+
+    *len = card->atr_length;
+    return card->atr;
+}
+
+static void emulated_push_event(EmulatedState *card, EmulEvent *event)
+{
+    qemu_mutex_lock(&card->event_list_mutex);
+    QSIMPLEQ_INSERT_TAIL(&(card->event_list), event, entry);
+    qemu_mutex_unlock(&card->event_list_mutex);
+    if (write(card->pipe[1], card, 1) != 1) {
+        DPRINTF(card, 1, "write to pipe failed\n");
+    }
+}
+
+static void emulated_push_type(EmulatedState *card, uint32_t type)
+{
+    EmulEvent *event = (EmulEvent *)qemu_malloc(sizeof(EmulEvent));
+
+    assert(event);
+    event->p.gen.type = type;
+    emulated_push_event(card, event);
+}
+
+static void emulated_push_error(EmulatedState *card, uint64_t code)
+{
+    EmulEvent *event = (EmulEvent *)qemu_malloc(sizeof(EmulEvent));
+
+    assert(event);
+    event->p.error.type = EMUL_ERROR;
+    event->p.error.code = code;
+    emulated_push_event(card, event);
+}
+
+static void emulated_push_data_type(EmulatedState *card, uint32_t type,
+    const uint8_t *data, uint32_t len)
+{
+    EmulEvent *event = (EmulEvent *)qemu_malloc(sizeof(EmulEvent) + len);
+
+    assert(event);
+    event->p.data.type = type;
+    event->p.data.len = len;
+    memcpy(event->p.data.data, data, len);
+    emulated_push_event(card, event);
+}
+
+static void emulated_push_reader_insert(EmulatedState *card)
+{
+    emulated_push_type(card, EMUL_READER_INSERT);
+}
+
+static void emulated_push_reader_remove(EmulatedState *card)
+{
+    emulated_push_type(card, EMUL_READER_REMOVE);
+}
+
+static void emulated_push_card_insert(EmulatedState *card,
+    const uint8_t *atr, uint32_t len)
+{
+    emulated_push_data_type(card, EMUL_CARD_INSERT, atr, len);
+}
+
+static void emulated_push_card_remove(EmulatedState *card)
+{
+    emulated_push_type(card, EMUL_CARD_REMOVE);
+}
+
+static void emulated_push_response_apdu(EmulatedState *card,
+    const uint8_t *apdu, uint32_t len)
+{
+    emulated_push_data_type(card, EMUL_RESPONSE_APDU, apdu, len);
+}
+
+#define APDU_BUF_SIZE 270
+static void *handle_apdu_thread(void* arg)
+{
+    EmulatedState *card = arg;
+    uint8_t recv_data[APDU_BUF_SIZE];
+    int recv_len;
+    VReaderStatus reader_status;
+    EmulEvent *event;
+
+    while (1) {
+        qemu_mutex_lock(&card->handle_apdu_mutex);
+        qemu_cond_wait(&card->handle_apdu_cond, &card->handle_apdu_mutex);
+        qemu_mutex_unlock(&card->handle_apdu_mutex);
+        if (card->quit_apdu_thread) {
+            card->quit_apdu_thread = 0; /* debugging */
+            break;
+        }
+        qemu_mutex_lock(&card->vreader_mutex);
+        while (!QSIMPLEQ_EMPTY(&card->guest_apdu_list)) {
+            event = QSIMPLEQ_FIRST(&card->guest_apdu_list);
+            assert((unsigned long)event > 1000);
+            QSIMPLEQ_REMOVE_HEAD(&card->guest_apdu_list, entry);
+            if (event->p.data.type != EMUL_GUEST_APDU) {
+                DPRINTF(card, 1, "unexpected message in handle_apdu_thread\n");
+                qemu_free(event);
+                continue;
+            }
+            if (card->reader == NULL) {
+                DPRINTF(card, 1, "reader is NULL\n");
+                qemu_free(event);
+                continue;
+            }
+            recv_len = sizeof(recv_data);
+            reader_status = vreader_xfr_bytes(card->reader,
+                    event->p.data.data, event->p.data.len,
+                    recv_data, &recv_len);
+            DPRINTF(card, 2, "got back apdu of length %d\n", recv_len);
+            if (reader_status == VREADER_OK) {
+                emulated_push_response_apdu(card, recv_data, recv_len);
+            } else {
+                emulated_push_error(card, reader_status);
+            }
+            qemu_free(event);
+        }
+        qemu_mutex_unlock(&card->vreader_mutex);
+    }
+    qemu_mutex_lock(&card->apdu_thread_quit_mutex);
+    qemu_cond_signal(&card->apdu_thread_quit_cond);
+    qemu_mutex_unlock(&card->apdu_thread_quit_mutex);
+    return NULL;
+}
+
+static void *event_thread(void *arg)
+{
+    int atr_len = MAX_ATR_SIZE;
+    uint8_t atr[MAX_ATR_SIZE];
+    VEvent *event = NULL;
+    EmulatedState *card = arg;
+
+    while (1) {
+        const char *reader_name;
+
+        event = vevent_wait_next_vevent();
+        if (event == NULL || event->type == VEVENT_LAST) {
+            break;
+        }
+        if (event->type != VEVENT_READER_INSERT) {
+            if (card->reader == NULL && event->reader != NULL) {
+                /* Happens after device_add followed by card remove or insert.
+                 * XXX: create synthetic add_reader events if vcard_emul_init
+                 * already called, which happens if device_del and device_add
+                 * are called */
+                card->reader = vreader_reference(event->reader);
+            } else {
+                if (event->reader != card->reader) {
+                    fprintf(stderr,
+                        "ERROR: wrong reader: quiting event_thread\n");
+                    break;
+                }
+            }
+        }
+        switch (event->type) {
+        case VEVENT_READER_INSERT:
+            /* TODO: take a specific reader. i.e. track which reader
+             * we are seeing here, check it is the one we want (the first,
+             * or by a particular name), and ignore if we don't want it.
+             */
+            reader_name = vreader_get_name(event->reader);
+            if (card->reader != NULL) {
+                DPRINTF(card, 2, "READER INSERT - replacing %s with %s\n",
+                    vreader_get_name(card->reader), reader_name);
+                qemu_mutex_lock(&card->vreader_mutex);
+                vreader_free(card->reader);
+                qemu_mutex_unlock(&card->vreader_mutex);
+                emulated_push_reader_remove(card);
+            }
+            qemu_mutex_lock(&card->vreader_mutex);
+            DPRINTF(card, 2, "READER INSERT %s\n", reader_name);
+            card->reader = vreader_reference(event->reader);
+            qemu_mutex_unlock(&card->vreader_mutex);
+            emulated_push_reader_insert(card);
+            break;
+        case VEVENT_READER_REMOVE:
+            DPRINTF(card, 2, " READER REMOVE: %s\n",
+                    vreader_get_name(event->reader));
+            qemu_mutex_lock(&card->vreader_mutex);
+            vreader_free(card->reader);
+            card->reader = NULL;
+            qemu_mutex_unlock(&card->vreader_mutex);
+            emulated_push_reader_remove(card);
+            break;
+        case VEVENT_CARD_INSERT:
+            /* get the ATR (intended as a response to a power on from the
+             * reader */
+            atr_len = MAX_ATR_SIZE;
+            vreader_power_on(event->reader, atr, &atr_len);
+            card->atr_length = (uint8_t)atr_len;
+            DPRINTF(card, 2, " CARD INSERT\n");
+            emulated_push_card_insert(card, atr, atr_len);
+            break;
+        case VEVENT_CARD_REMOVE:
+            DPRINTF(card, 2, " CARD REMOVE\n");
+            emulated_push_card_remove(card);
+            break;
+        case VEVENT_LAST: /* quit */
+            vevent_delete(event);
+            return NULL;
+            break;
+        default:
+            break;
+        }
+        vevent_delete(event);
+    }
+    return NULL;
+}
+
+static void pipe_read(void *opaque)
+{
+    EmulatedState *card = opaque;
+    EmulEvent *event, *next;
+    char dummy;
+    int len;
+
+    do {
+        len = read(card->pipe[0], &dummy, sizeof(dummy));
+    } while (len == sizeof(dummy));
+    qemu_mutex_lock(&card->event_list_mutex);
+    QSIMPLEQ_FOREACH_SAFE(event, &card->event_list, entry, next) {
+        DPRINTF(card, 2, "event %s\n", emul_event_to_string(event->p.gen.type));
+        switch (event->p.gen.type) {
+        case EMUL_RESPONSE_APDU:
+            ccid_card_send_apdu_to_guest(&card->base, event->p.data.data,
+                event->p.data.len);
+            break;
+        case EMUL_READER_INSERT:
+            ccid_card_ccid_attach(&card->base);
+            break;
+        case EMUL_READER_REMOVE:
+            ccid_card_ccid_detach(&card->base);
+            break;
+        case EMUL_CARD_INSERT:
+            assert(event->p.data.len <= MAX_ATR_SIZE);
+            card->atr_length = event->p.data.len;
+            memcpy(card->atr, event->p.data.data, card->atr_length);
+            ccid_card_card_inserted(&card->base);
+            break;
+        case EMUL_CARD_REMOVE:
+            ccid_card_card_removed(&card->base);
+            break;
+        case EMUL_ERROR:
+            ccid_card_card_error(&card->base, event->p.error.code);
+            break;
+        default:
+            DPRINTF(card, 2, "unexpected event\n");
+            break;
+        }
+        qemu_free(event);
+    }
+    QSIMPLEQ_INIT(&card->event_list);
+    qemu_mutex_unlock(&card->event_list_mutex);
+}
+
+static int init_pipe_signaling(EmulatedState *card)
+{
+    if (pipe(card->pipe) < 0) {
+        DPRINTF(card, 2, "pipe creation failed\n");
+        return -1;
+    }
+    fcntl(card->pipe[0], F_SETFL, O_NONBLOCK);
+    fcntl(card->pipe[1], F_SETFL, O_NONBLOCK);
+    fcntl(card->pipe[0], F_SETOWN, getpid());
+    qemu_set_fd_handler(card->pipe[0], pipe_read, NULL, card);
+    return 0;
+}
+
+#define CERTIFICATES_DEFAULT_DB "/etc/pki/nssdb"
+#define CERTIFICATES_ARGS_TEMPLATE\
+    "db=\"%s\" use_hw=no soft=(,Virtual Reader,CAC,,%s,%s,%s)"
+
+static int wrap_vcard_emul_init(VCardEmulOptions *options)
+{
+    static int called;
+    static int options_was_null;
+
+    if (called) {
+        if ((options == NULL) != options_was_null) {
+            printf("%s: warning: running emulated with certificates"
+                   " and emulated side by side is not supported\n",
+                   __func__);
+            return VCARD_EMUL_FAIL;
+        }
+        vcard_emul_replay_insertion_events();
+        return VCARD_EMUL_OK;
+    }
+    options_was_null = (options == NULL);
+    called = 1;
+    return vcard_emul_init(options);
+}
+
+static int emulated_initialize_vcard_from_certificates(EmulatedState *card)
+{
+    char emul_args[200];
+    VCardEmulOptions *options = NULL;
+
+    snprintf(emul_args, sizeof(emul_args) - 1, CERTIFICATES_ARGS_TEMPLATE,
+        card->db ? card->db : CERTIFICATES_DEFAULT_DB,
+        card->cert1, card->cert2, card->cert3);
+    options = vcard_emul_options(emul_args);
+    if (options == NULL) {
+        printf("%s: warning: not using certificates due to"
+               " initialization error\n", __func__);
+    }
+    return wrap_vcard_emul_init(options);
+}
+
+typedef struct EnumTable {
+    const char *name;
+    uint32_t value;
+} EnumTable;
+
+EnumTable backend_enum_table[] = {
+    {BACKEND_NSS_EMULATED_NAME, BACKEND_NSS_EMULATED},
+    {BACKEND_CERTIFICATES_NAME, BACKEND_CERTIFICATES},
+    {NULL, 0},
+};
+
+static uint32_t parse_enumeration(char *str,
+    EnumTable *table, uint32_t not_found_value)
+{
+    uint32_t ret = not_found_value;
+
+    while (table->name != NULL) {
+        if (strcmp(table->name, str) == 0) {
+            ret = table->value;
+            break;
+        }
+        table++;
+    }
+    return ret;
+}
+
+static int emulated_initfn(CCIDCardState *base)
+{
+    EmulatedState *card = DO_UPCAST(EmulatedState, base, base);
+    QemuThread thread_id;
+    VCardEmulError ret;
+    EnumTable *ptable;
+
+    QSIMPLEQ_INIT(&card->event_list);
+    QSIMPLEQ_INIT(&card->guest_apdu_list);
+    qemu_mutex_init(&card->event_list_mutex);
+    qemu_mutex_init(&card->vreader_mutex);
+    qemu_mutex_init(&card->handle_apdu_mutex);
+    qemu_cond_init(&card->handle_apdu_cond);
+    card->reader = NULL;
+    card->quit_apdu_thread = 0;
+    if (init_pipe_signaling(card) < 0) {
+        return -1;
+    }
+    card->backend = parse_enumeration(card->backend_str, backend_enum_table, 0);
+    if (card->backend == 0) {
+        printf("unknown backend, must be one of:\n");
+        for (ptable = backend_enum_table; ptable->name != NULL; ++ptable) {
+            printf("%s\n", ptable->name);
+        }
+        return -1;
+    }
+
+    /* TODO: a passthru backened that works on local machine. third card type?*/
+    if (card->backend == BACKEND_CERTIFICATES) {
+        if (card->cert1 != NULL && card->cert2 != NULL && card->cert3 != NULL) {
+            ret = emulated_initialize_vcard_from_certificates(card);
+        } else {
+            printf("%s: you must provide all three certs for"
+                   " certificates backend\n", EMULATED_DEV_NAME);
+            return -1;
+        }
+    } else {
+        if (card->backend != BACKEND_NSS_EMULATED) {
+            printf("%s: bad backend specified. The options are:\n%s (default),"
+                " %s.\n", EMULATED_DEV_NAME, BACKEND_NSS_EMULATED_NAME,
+                BACKEND_CERTIFICATES_NAME);
+            return -1;
+        }
+        if (card->cert1 != NULL || card->cert2 != NULL || card->cert3 != NULL) {
+            printf("%s: unexpected cert parameters to nss emulated backend\n",
+                   EMULATED_DEV_NAME);
+            return -1;
+        }
+        /* default to mirroring the local hardware readers */
+        ret = wrap_vcard_emul_init(NULL);
+    }
+    if (ret != VCARD_EMUL_OK) {
+        printf("%s: failed to initialize vcard\n", EMULATED_DEV_NAME);
+        return -1;
+    }
+    qemu_thread_create(&thread_id, event_thread, card);
+    qemu_thread_create(&thread_id, handle_apdu_thread, card);
+    return 0;
+}
+
+static int emulated_exitfn(CCIDCardState *base)
+{
+    EmulatedState *card = DO_UPCAST(EmulatedState, base, base);
+    VEvent *vevent = vevent_new(VEVENT_LAST, NULL, NULL);
+
+    vevent_queue_vevent(vevent); /* stop vevent thread */
+    qemu_mutex_lock(&card->apdu_thread_quit_mutex);
+    card->quit_apdu_thread = 1; /* stop handle_apdu thread */
+    qemu_cond_signal(&card->handle_apdu_cond);
+    qemu_cond_wait(&card->apdu_thread_quit_cond,
+                      &card->apdu_thread_quit_mutex);
+    /* handle_apdu thread stopped, can destroy all of it's mutexes */
+    qemu_cond_destroy(&card->handle_apdu_cond);
+    qemu_cond_destroy(&card->apdu_thread_quit_cond);
+    qemu_mutex_destroy(&card->apdu_thread_quit_mutex);
+    qemu_mutex_destroy(&card->handle_apdu_mutex);
+    qemu_mutex_destroy(&card->vreader_mutex);
+    qemu_mutex_destroy(&card->event_list_mutex);
+    return 0;
+}
+
+static CCIDCardInfo emulated_card_info = {
+    .qdev.name = EMULATED_DEV_NAME,
+    .qdev.desc = "emulated smartcard",
+    .qdev.size = sizeof(EmulatedState),
+    .initfn = emulated_initfn,
+    .exitfn = emulated_exitfn,
+    .get_atr = emulated_get_atr,
+    .apdu_from_guest = emulated_apdu_from_guest,
+    .qdev.unplug    = qdev_simple_unplug_cb,
+    .qdev.props     = (Property[]) {
+        DEFINE_PROP_STRING("backend", EmulatedState, backend_str),
+        DEFINE_PROP_STRING("cert1", EmulatedState, cert1),
+        DEFINE_PROP_STRING("cert2", EmulatedState, cert2),
+        DEFINE_PROP_STRING("cert3", EmulatedState, cert3),
+        DEFINE_PROP_STRING("db", EmulatedState, db),
+        DEFINE_PROP_UINT8("debug", EmulatedState, debug, 0),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+};
+
+static void ccid_card_emulated_register_devices(void)
+{
+    ccid_card_qdev_register(&emulated_card_info);
+}
+
+device_init(ccid_card_emulated_register_devices)

From 1056c02b7b1a3daa3765a6b599800a453ee96c5f Mon Sep 17 00:00:00 2001
From: Alon Levy <alevy@redhat.com>
Date: Sun, 12 Dec 2010 18:13:34 +0200
Subject: [PATCH 054/386] ccid: add docs

Add documentation for the usb-ccid device and accompanying two card
devices, ccid-card-emulated and ccid-card-passthru.

Signed-off-by: Alon Levy <alevy@redhat.com>
---
 docs/ccid.txt | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 135 insertions(+)
 create mode 100644 docs/ccid.txt

diff --git a/docs/ccid.txt b/docs/ccid.txt
new file mode 100644
index 0000000000..b8e504a3cc
--- /dev/null
+++ b/docs/ccid.txt
@@ -0,0 +1,135 @@
+Qemu CCID Device Documentation.
+
+Contents
+1. USB CCID device
+2. Building
+3. Using ccid-card-emulated with hardware
+4. Using ccid-card-emulated with certificates
+5. Using ccid-card-passthru with client side hardware
+6. Using ccid-card-passthru with client side certificates
+7. Passthrough protocol scenario
+8. libcacard
+
+1. USB CCID device
+
+The USB CCID device is a USB device implementing the CCID specification, which
+lets one connect smart card readers that implement the same spec. For more
+information see the specification:
+
+ Universal Serial Bus
+ Device Class: Smart Card
+ CCID
+ Specification for
+ Integrated Circuit(s) Cards Interface Devices
+ Revision 1.1
+ April 22rd, 2005
+
+Smartcard are used for authentication, single sign on, decryption in
+public/private schemes and digital signatures. A smartcard reader on the client
+cannot be used on a guest with simple usb passthrough since it will then not be
+available on the client, possibly locking the computer when it is "removed". On
+the other hand this device can let you use the smartcard on both the client and
+the guest machine. It is also possible to have a completely virtual smart card
+reader and smart card (i.e. not backed by a physical device) using this device.
+
+2. Building
+
+The cryptographic functions and access to the physical card is done via NSS.
+
+Installing NSS:
+
+In redhat/fedora:
+    yum install nss-devel
+In ubuntu/debian:
+    apt-get install libnss3-dev
+    (not tested on ubuntu)
+
+Configuring and building:
+    ./configure --enable-smartcard && make
+
+3. Using ccid-card-emulated with hardware
+
+Assuming you have a working smartcard on the host with the current
+user, using NSS, qemu acts as another NSS client using ccid-card-emulated:
+
+    qemu -usb -device usb-ccid -device ccid-card-emualated
+
+4. Using ccid-card-emulated with certificates
+
+You must create the certificates. This is a one time process. We use NSS
+certificates:
+
+    certutil -d /etc/pki/nssdb -x -t "CT,CT,CT" -S -s "CN=cert1" -n cert1
+
+Note: you must have exactly three certificates.
+
+Assuming the current user can access the certificates (use certutil -L to
+verify), you can use the emulated card type with the certificates backend:
+
+    qemu -usb -device usb-ccid -device ccid-card-emulated,backend=certificates,cert1=cert1,cert2=cert2,cert3=cert3
+
+5. Using ccid-card-passthru with client side hardware
+
+on the host specify the ccid-card-passthru device with a suitable chardev:
+
+    qemu -chardev socket,server,host=0.0.0.0,port=2001,id=ccid,nowait -usb -device usb-ccid -device ccid-card-passthru,chardev=ccid
+
+on the client run vscclient, built when you built the libcacard library:
+    libcacard/vscclient <qemu-host> 2001
+
+6. Using ccid-card-passthru with client side certificates
+
+Run qemu as per #5, and run vscclient as follows:
+(Note: vscclient command line interface is in a state of change)
+
+    libcacard/vscclient -e "db=\"/etc/pki/nssdb\" use_hw=no soft=(,Test,CAC,,cert1,cert2,cert3)" <qemu-host> 2001
+
+7. Passthrough protocol scenario
+
+This is a typical interchange of messages when using the passthru card device.
+usb-ccid is a usb device. It defaults to an unattached usb device on startup.
+usb-ccid expects a chardev and expects the protocol defined in
+cac_card/vscard_common.h to be passed over that.
+The usb-ccid device can be in one of three modes:
+ * detached
+ * attached with no card
+ * attached with card
+
+A typical interchange is: (the arrow shows who started each exchange, it can be client
+originated or guest originated)
+
+client event      |      vscclient           |    passthru    |     usb-ccid  |  guest event
+----------------------------------------------------------------------------------------------
+                  |      VSC_Init            |                |               |
+                  |      VSC_ReaderAdd       |                |     attach    |
+                  |                          |                |               |  sees new usb device.
+card inserted ->  |                          |                |               |
+                  |      VSC_ATR             |   insert       |     insert    |  see new card
+                  |                          |                |               |
+                  |      VSC_APDU            |   VSC_APDU     |               | <- guest sends APDU
+client<->physical |                          |                |               |
+card APDU exchange|                          |                |               |
+client response ->|      VSC_APDU            |   VSC_APDU     |               |  receive APDU response
+                                                    ...
+                                    [APDU<->APDU repeats several times]
+                                                    ...
+card removed  ->  |                          |                |               |
+                  |      VSC_CardRemove      |   remove       |    remove     |   card removed
+                                                    ...
+                                    [(card insert, apdu's, card remove) repeat]
+                                                    ...
+kill/quit         |                          |                |               |
+  vscclient       |                          |                |               |
+                  |      VSC_ReaderRemove    |                |    detach     |
+                  |                          |                |               |   usb device removed.
+
+
+8. libcacard
+
+ccid-card-passthru and vscclient use libcacard as the card emulator.
+libcacard implements a completely virtual CAC (DoD standard for smart cards)
+compliant card and uses NSS to actually retrive certificates and do any
+encryption using the backend (real reader + card or file backed certificates).
+
+For documentation of cac_card see README in libcacard subdirectory.
+

From 51d852672cb8536c541ed5b1dc4ee8f989a96cd7 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Fri, 11 Mar 2011 08:12:21 +0000
Subject: [PATCH 055/386] target-arm/neon_helper.c: Use
 make_float32/float32_val macros

Use the softfloat make_float32 and float32_val macros to convert between
softfloat's float32 type and raw uint32_t types, rather than private
conversion functions.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/neon_helper.c | 56 ++++++++++++----------------------------
 1 file changed, 17 insertions(+), 39 deletions(-)

diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index 002a9c11a6..2108664adc 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -21,29 +21,6 @@
 static float_status neon_float_status;
 #define NFS &neon_float_status
 
-/* Helper routines to perform bitwise copies between float and int.  */
-static inline float32 vfp_itos(uint32_t i)
-{
-    union {
-        uint32_t i;
-        float32 s;
-    } v;
-
-    v.i = i;
-    return v.s;
-}
-
-static inline uint32_t vfp_stoi(float32 s)
-{
-    union {
-        uint32_t i;
-        float32 s;
-    } v;
-
-    v.s = s;
-    return v.i;
-}
-
 #define NEON_TYPE1(name, type) \
 typedef struct \
 { \
@@ -1796,50 +1773,51 @@ uint32_t HELPER(neon_qneg_s32)(CPUState *env, uint32_t x)
 /* NEON Float helpers.  */
 uint32_t HELPER(neon_min_f32)(uint32_t a, uint32_t b)
 {
-    float32 f0 = vfp_itos(a);
-    float32 f1 = vfp_itos(b);
+    float32 f0 = make_float32(a);
+    float32 f1 = make_float32(b);
     return (float32_compare_quiet(f0, f1, NFS) == -1) ? a : b;
 }
 
 uint32_t HELPER(neon_max_f32)(uint32_t a, uint32_t b)
 {
-    float32 f0 = vfp_itos(a);
-    float32 f1 = vfp_itos(b);
+    float32 f0 = make_float32(a);
+    float32 f1 = make_float32(b);
     return (float32_compare_quiet(f0, f1, NFS) == 1) ? a : b;
 }
 
 uint32_t HELPER(neon_abd_f32)(uint32_t a, uint32_t b)
 {
-    float32 f0 = vfp_itos(a);
-    float32 f1 = vfp_itos(b);
-    return vfp_stoi((float32_compare_quiet(f0, f1, NFS) == 1)
+    float32 f0 = make_float32(a);
+    float32 f1 = make_float32(b);
+    return float32_val((float32_compare_quiet(f0, f1, NFS) == 1)
                     ? float32_sub(f0, f1, NFS)
                     : float32_sub(f1, f0, NFS));
 }
 
 uint32_t HELPER(neon_add_f32)(uint32_t a, uint32_t b)
 {
-    return vfp_stoi(float32_add(vfp_itos(a), vfp_itos(b), NFS));
+    return float32_val(float32_add(make_float32(a), make_float32(b), NFS));
 }
 
 uint32_t HELPER(neon_sub_f32)(uint32_t a, uint32_t b)
 {
-    return vfp_stoi(float32_sub(vfp_itos(a), vfp_itos(b), NFS));
+    return float32_val(float32_sub(make_float32(a), make_float32(b), NFS));
 }
 
 uint32_t HELPER(neon_mul_f32)(uint32_t a, uint32_t b)
 {
-    return vfp_stoi(float32_mul(vfp_itos(a), vfp_itos(b), NFS));
+    return float32_val(float32_mul(make_float32(a), make_float32(b), NFS));
 }
 
 /* Floating point comparisons produce an integer result.  */
 #define NEON_VOP_FCMP(name, cmp) \
 uint32_t HELPER(neon_##name)(uint32_t a, uint32_t b) \
 { \
-    if (float32_compare_quiet(vfp_itos(a), vfp_itos(b), NFS) cmp 0) \
+    if (float32_compare_quiet(make_float32(a), make_float32(b), NFS) cmp 0) { \
         return ~0; \
-    else \
+    } else { \
         return 0; \
+    } \
 }
 
 NEON_VOP_FCMP(ceq_f32, ==)
@@ -1848,15 +1826,15 @@ NEON_VOP_FCMP(cgt_f32, >)
 
 uint32_t HELPER(neon_acge_f32)(uint32_t a, uint32_t b)
 {
-    float32 f0 = float32_abs(vfp_itos(a));
-    float32 f1 = float32_abs(vfp_itos(b));
+    float32 f0 = float32_abs(make_float32(a));
+    float32 f1 = float32_abs(make_float32(b));
     return (float32_compare_quiet(f0, f1,NFS) >= 0) ? ~0 : 0;
 }
 
 uint32_t HELPER(neon_acgt_f32)(uint32_t a, uint32_t b)
 {
-    float32 f0 = float32_abs(vfp_itos(a));
-    float32 f1 = float32_abs(vfp_itos(b));
+    float32 f0 = float32_abs(make_float32(a));
+    float32 f1 = float32_abs(make_float32(b));
     return (float32_compare_quiet(f0, f1, NFS) > 0) ? ~0 : 0;
 }
 

From c7498daea76948128c1298d78fe9e7e618b5ff7c Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Fri, 11 Mar 2011 08:12:22 +0000
Subject: [PATCH 056/386] target-arm: Return right result for Neon comparison
 with NaNs

Fix the helper functions implementing the Neon floating point comparison
ops (VCGE, VCGT, VCEQ, VACGT, VACGE) to return the right answer when
one of the values being compared is a NaN.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/neon_helper.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index 2108664adc..9d54a75ef3 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -1810,32 +1810,40 @@ uint32_t HELPER(neon_mul_f32)(uint32_t a, uint32_t b)
 }
 
 /* Floating point comparisons produce an integer result.  */
-#define NEON_VOP_FCMP(name, cmp) \
+#define NEON_VOP_FCMP(name, ok) \
 uint32_t HELPER(neon_##name)(uint32_t a, uint32_t b) \
 { \
-    if (float32_compare_quiet(make_float32(a), make_float32(b), NFS) cmp 0) { \
-        return ~0; \
-    } else { \
-        return 0; \
+    switch (float32_compare_quiet(make_float32(a), make_float32(b), NFS)) { \
+    ok return ~0; \
+    default: return 0; \
     } \
 }
 
-NEON_VOP_FCMP(ceq_f32, ==)
-NEON_VOP_FCMP(cge_f32, >=)
-NEON_VOP_FCMP(cgt_f32, >)
+NEON_VOP_FCMP(ceq_f32, case float_relation_equal:)
+NEON_VOP_FCMP(cge_f32, case float_relation_equal: case float_relation_greater:)
+NEON_VOP_FCMP(cgt_f32, case float_relation_greater:)
 
 uint32_t HELPER(neon_acge_f32)(uint32_t a, uint32_t b)
 {
     float32 f0 = float32_abs(make_float32(a));
     float32 f1 = float32_abs(make_float32(b));
-    return (float32_compare_quiet(f0, f1,NFS) >= 0) ? ~0 : 0;
+    switch (float32_compare_quiet(f0, f1, NFS)) {
+    case float_relation_equal:
+    case float_relation_greater:
+        return ~0;
+    default:
+        return 0;
+    }
 }
 
 uint32_t HELPER(neon_acgt_f32)(uint32_t a, uint32_t b)
 {
     float32 f0 = float32_abs(make_float32(a));
     float32 f1 = float32_abs(make_float32(b));
-    return (float32_compare_quiet(f0, f1, NFS) > 0) ? ~0 : 0;
+    if (float32_compare_quiet(f0, f1, NFS) == float_relation_greater) {
+        return ~0;
+    }
+    return 0;
 }
 
 #define ELEM(V, N, SIZE) (((V) >> ((N) * (SIZE))) & ((1ull << (SIZE)) - 1))

From 0e3261098ff41c40ce3381b8ad7cff330458da3d Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Fri, 11 Mar 2011 08:12:23 +0000
Subject: [PATCH 057/386] target-arm: Fix VCLE.F32 #0, VCLT.F32 #0 NaN handling

Implementing the floating-point versions of VCLE #0 and VCLT #0 by
doing a GT comparison and inverting the result gives the wrong
result if the input is a NaN. Implement as a GT comparison with the
operands swapped instead.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 39512bc62f..33417e6825 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -5677,25 +5677,31 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                             gen_neon_rsb(size, tmp, tmp2);
                             tcg_temp_free(tmp2);
                             break;
-                        case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
+                        case 24: /* Float VCGT #0 */
                             tmp2 = tcg_const_i32(0);
                             gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
                             tcg_temp_free(tmp2);
-                            if (op == 27)
-                                tcg_gen_not_i32(tmp, tmp);
                             break;
-                        case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
+                        case 25: /* Float VCGE #0 */
                             tmp2 = tcg_const_i32(0);
                             gen_helper_neon_cge_f32(tmp, tmp, tmp2);
                             tcg_temp_free(tmp2);
-                            if (op == 28)
-                                tcg_gen_not_i32(tmp, tmp);
                             break;
                         case 26: /* Float VCEQ #0 */
                             tmp2 = tcg_const_i32(0);
                             gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
                             tcg_temp_free(tmp2);
                             break;
+                        case 27: /* Float VCLE #0 */
+                            tmp2 = tcg_const_i32(0);
+                            gen_helper_neon_cge_f32(tmp, tmp2, tmp);
+                            tcg_temp_free(tmp2);
+                            break;
+                        case 28: /* Float VCLT #0 */
+                            tmp2 = tcg_const_i32(0);
+                            gen_helper_neon_cgt_f32(tmp, tmp2, tmp);
+                            tcg_temp_free(tmp2);
+                            break;
                         case 30: /* Float VABS */
                             gen_vfp_abs(0);
                             break;

From 79c18be7dfe660ab48f9f535e6cabd38c9f1d73b Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Fri, 11 Mar 2011 08:12:24 +0000
Subject: [PATCH 058/386] target-arm: Correct ABD's handling of negative zeroes

Implement ABD by taking the absolute value of the difference
of the operands (as the ARM ARM specifies) rather than by
flipping the order of the operands to the subtract based
on the results of a comparison. The latter approch gives
the wrong answers for some edge cases like negative zero.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/neon_helper.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index 9d54a75ef3..bf324c62b6 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -1789,9 +1789,7 @@ uint32_t HELPER(neon_abd_f32)(uint32_t a, uint32_t b)
 {
     float32 f0 = make_float32(a);
     float32 f1 = make_float32(b);
-    return float32_val((float32_compare_quiet(f0, f1, NFS) == 1)
-                    ? float32_sub(f0, f1, NFS)
-                    : float32_sub(f1, f0, NFS));
+    return float32_val(float32_abs(float32_sub(f0, f1, NFS)));
 }
 
 uint32_t HELPER(neon_add_f32)(uint32_t a, uint32_t b)

From 274f1b041e0d550750cc6992092ad0197b2c5320 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Fri, 11 Mar 2011 08:12:25 +0000
Subject: [PATCH 059/386] softfloat: Add float*_min() and float*_max()
 functions

Add min and max operations to softfloat. This allows us to implement
propagation of NaNs and handling of negative zero correctly (unlike
the approach of having target helper routines return one of the operands
based on the result of a comparison op).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 fpu/softfloat.h |  4 ++++
 2 files changed, 53 insertions(+)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 08e4ae03d9..03fb9487bd 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6057,6 +6057,55 @@ int float128_compare_quiet( float128 a, float128 b STATUS_PARAM )
     return float128_compare_internal(a, b, 1 STATUS_VAR);
 }
 
+/* min() and max() functions. These can't be implemented as
+ * 'compare and pick one input' because that would mishandle
+ * NaNs and +0 vs -0.
+ */
+#define MINMAX(s, nan_exp)                                              \
+INLINE float ## s float ## s ## _minmax(float ## s a, float ## s b,     \
+                                        int ismin STATUS_PARAM )        \
+{                                                                       \
+    flag aSign, bSign;                                                  \
+    uint ## s ## _t av, bv;                                             \
+    a = float ## s ## _squash_input_denormal(a STATUS_VAR);             \
+    b = float ## s ## _squash_input_denormal(b STATUS_VAR);             \
+    if (float ## s ## _is_any_nan(a) ||                                 \
+        float ## s ## _is_any_nan(b)) {                                 \
+        return propagateFloat ## s ## NaN(a, b STATUS_VAR);             \
+    }                                                                   \
+    aSign = extractFloat ## s ## Sign(a);                               \
+    bSign = extractFloat ## s ## Sign(b);                               \
+    av = float ## s ## _val(a);                                         \
+    bv = float ## s ## _val(b);                                         \
+    if (aSign != bSign) {                                               \
+        if (ismin) {                                                    \
+            return aSign ? a : b;                                       \
+        } else {                                                        \
+            return aSign ? b : a;                                       \
+        }                                                               \
+    } else {                                                            \
+        if (ismin) {                                                    \
+            return (aSign ^ (av < bv)) ? a : b;                         \
+        } else {                                                        \
+            return (aSign ^ (av < bv)) ? b : a;                         \
+        }                                                               \
+    }                                                                   \
+}                                                                       \
+                                                                        \
+float ## s float ## s ## _min(float ## s a, float ## s b STATUS_PARAM)  \
+{                                                                       \
+    return float ## s ## _minmax(a, b, 1 STATUS_VAR);                   \
+}                                                                       \
+                                                                        \
+float ## s float ## s ## _max(float ## s a, float ## s b STATUS_PARAM)  \
+{                                                                       \
+    return float ## s ## _minmax(a, b, 0 STATUS_VAR);                   \
+}
+
+MINMAX(32, 0xff)
+MINMAX(64, 0x7ff)
+
+
 /* Multiply A by 2 raised to the power N.  */
 float32 float32_scalbn( float32 a, int n STATUS_PARAM )
 {
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 5d05fa5cf8..90f4250173 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -324,6 +324,8 @@ int float32_le_quiet( float32, float32 STATUS_PARAM );
 int float32_lt_quiet( float32, float32 STATUS_PARAM );
 int float32_compare( float32, float32 STATUS_PARAM );
 int float32_compare_quiet( float32, float32 STATUS_PARAM );
+float32 float32_min(float32, float32 STATUS_PARAM);
+float32 float32_max(float32, float32 STATUS_PARAM);
 int float32_is_quiet_nan( float32 );
 int float32_is_signaling_nan( float32 );
 float32 float32_maybe_silence_nan( float32 );
@@ -436,6 +438,8 @@ int float64_le_quiet( float64, float64 STATUS_PARAM );
 int float64_lt_quiet( float64, float64 STATUS_PARAM );
 int float64_compare( float64, float64 STATUS_PARAM );
 int float64_compare_quiet( float64, float64 STATUS_PARAM );
+float64 float64_min(float64, float64 STATUS_PARAM);
+float64 float64_max(float64, float64 STATUS_PARAM);
 int float64_is_quiet_nan( float64 a );
 int float64_is_signaling_nan( float64 );
 float64 float64_maybe_silence_nan( float64 );

From 4a9f9cb24de52e93aae7539a004dd20314ca1c0c Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Fri, 11 Mar 2011 08:12:26 +0000
Subject: [PATCH 060/386] target-arm: Use new softfloat min/max functions for
 VMAX, VMIN

Use the new softfloat min/max functions to implement the Neon VMAX
and VMIN instructions. This allows us to get the right behaviour
for NaN and negative zero.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/neon_helper.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index bf324c62b6..71f1a7ead0 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -1773,16 +1773,12 @@ uint32_t HELPER(neon_qneg_s32)(CPUState *env, uint32_t x)
 /* NEON Float helpers.  */
 uint32_t HELPER(neon_min_f32)(uint32_t a, uint32_t b)
 {
-    float32 f0 = make_float32(a);
-    float32 f1 = make_float32(b);
-    return (float32_compare_quiet(f0, f1, NFS) == -1) ? a : b;
+    return float32_val(float32_min(make_float32(a), make_float32(b), NFS));
 }
 
 uint32_t HELPER(neon_max_f32)(uint32_t a, uint32_t b)
 {
-    float32 f0 = make_float32(a);
-    float32 f1 = make_float32(b);
-    return (float32_compare_quiet(f0, f1, NFS) == 1) ? a : b;
+    return float32_val(float32_max(make_float32(a), make_float32(b), NFS));
 }
 
 uint32_t HELPER(neon_abd_f32)(uint32_t a, uint32_t b)

From 622465e1fa4c07d96fcb6e8cbe746b1e3f3ff65e Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 14 Mar 2011 07:23:11 +0000
Subject: [PATCH 061/386] target-arm/helper.c: For float-int conversion helpers
 pass ints as ints

Correct the argument and return types for the float<->int conversion helper
functions so that integer arguments and return values are declared as
uint32_t/uint64_t, not float32/float64. This allows us to remove the
hand-rolled functions which were doing bitwise copies between the types
via unions.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/helper.c  | 151 +++++++++++++++----------------------------
 target-arm/helpers.h |  56 ++++++++--------
 2 files changed, 81 insertions(+), 126 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 78f3d39203..6788a4c383 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2486,135 +2486,90 @@ DO_VFP_cmp(s, float32)
 DO_VFP_cmp(d, float64)
 #undef DO_VFP_cmp
 
-/* Helper routines to perform bitwise copies between float and int.  */
-static inline float32 vfp_itos(uint32_t i)
-{
-    union {
-        uint32_t i;
-        float32 s;
-    } v;
-
-    v.i = i;
-    return v.s;
-}
-
-static inline uint32_t vfp_stoi(float32 s)
-{
-    union {
-        uint32_t i;
-        float32 s;
-    } v;
-
-    v.s = s;
-    return v.i;
-}
-
-static inline float64 vfp_itod(uint64_t i)
-{
-    union {
-        uint64_t i;
-        float64 d;
-    } v;
-
-    v.i = i;
-    return v.d;
-}
-
-static inline uint64_t vfp_dtoi(float64 d)
-{
-    union {
-        uint64_t i;
-        float64 d;
-    } v;
-
-    v.d = d;
-    return v.i;
-}
-
 /* Integer to float conversion.  */
-float32 VFP_HELPER(uito, s)(float32 x, CPUState *env)
+float32 VFP_HELPER(uito, s)(uint32_t x, CPUState *env)
 {
-    return uint32_to_float32(vfp_stoi(x), &env->vfp.fp_status);
+    return uint32_to_float32(x, &env->vfp.fp_status);
 }
 
-float64 VFP_HELPER(uito, d)(float32 x, CPUState *env)
+float64 VFP_HELPER(uito, d)(uint32_t x, CPUState *env)
 {
-    return uint32_to_float64(vfp_stoi(x), &env->vfp.fp_status);
+    return uint32_to_float64(x, &env->vfp.fp_status);
 }
 
-float32 VFP_HELPER(sito, s)(float32 x, CPUState *env)
+float32 VFP_HELPER(sito, s)(uint32_t x, CPUState *env)
 {
-    return int32_to_float32(vfp_stoi(x), &env->vfp.fp_status);
+    return int32_to_float32(x, &env->vfp.fp_status);
 }
 
-float64 VFP_HELPER(sito, d)(float32 x, CPUState *env)
+float64 VFP_HELPER(sito, d)(uint32_t x, CPUState *env)
 {
-    return int32_to_float64(vfp_stoi(x), &env->vfp.fp_status);
+    return int32_to_float64(x, &env->vfp.fp_status);
 }
 
 /* Float to integer conversion.  */
-float32 VFP_HELPER(toui, s)(float32 x, CPUState *env)
+uint32_t VFP_HELPER(toui, s)(float32 x, CPUState *env)
 {
     if (float32_is_any_nan(x)) {
-        return float32_zero;
+        return 0;
     }
-    return vfp_itos(float32_to_uint32(x, &env->vfp.fp_status));
+    return float32_to_uint32(x, &env->vfp.fp_status);
 }
 
-float32 VFP_HELPER(toui, d)(float64 x, CPUState *env)
+uint32_t VFP_HELPER(toui, d)(float64 x, CPUState *env)
 {
     if (float64_is_any_nan(x)) {
-        return float32_zero;
+        return 0;
     }
-    return vfp_itos(float64_to_uint32(x, &env->vfp.fp_status));
+    return float64_to_uint32(x, &env->vfp.fp_status);
 }
 
-float32 VFP_HELPER(tosi, s)(float32 x, CPUState *env)
+uint32_t VFP_HELPER(tosi, s)(float32 x, CPUState *env)
 {
     if (float32_is_any_nan(x)) {
-        return float32_zero;
+        return 0;
     }
-    return vfp_itos(float32_to_int32(x, &env->vfp.fp_status));
+    return float32_to_int32(x, &env->vfp.fp_status);
 }
 
-float32 VFP_HELPER(tosi, d)(float64 x, CPUState *env)
+uint32_t VFP_HELPER(tosi, d)(float64 x, CPUState *env)
 {
     if (float64_is_any_nan(x)) {
-        return float32_zero;
+        return 0;
     }
-    return vfp_itos(float64_to_int32(x, &env->vfp.fp_status));
+    return float64_to_int32(x, &env->vfp.fp_status);
 }
 
-float32 VFP_HELPER(touiz, s)(float32 x, CPUState *env)
+uint32_t VFP_HELPER(touiz, s)(float32 x, CPUState *env)
 {
     if (float32_is_any_nan(x)) {
-        return float32_zero;
+        return 0;
     }
-    return vfp_itos(float32_to_uint32_round_to_zero(x, &env->vfp.fp_status));
+    return float32_to_uint32_round_to_zero(x, &env->vfp.fp_status);
 }
 
-float32 VFP_HELPER(touiz, d)(float64 x, CPUState *env)
+uint32_t VFP_HELPER(touiz, d)(float64 x, CPUState *env)
 {
     if (float64_is_any_nan(x)) {
-        return float32_zero;
+        return 0;
     }
-    return vfp_itos(float64_to_uint32_round_to_zero(x, &env->vfp.fp_status));
+    return float64_to_uint32_round_to_zero(x, &env->vfp.fp_status);
 }
 
-float32 VFP_HELPER(tosiz, s)(float32 x, CPUState *env)
+uint32_t VFP_HELPER(tosiz, s)(float32 x, CPUState *env)
 {
     if (float32_is_any_nan(x)) {
-        return float32_zero;
+        return 0;
     }
-    return vfp_itos(float32_to_int32_round_to_zero(x, &env->vfp.fp_status));
+    return float32_to_int32_round_to_zero(x, &env->vfp.fp_status);
 }
 
-float32 VFP_HELPER(tosiz, d)(float64 x, CPUState *env)
+uint32_t VFP_HELPER(tosiz, d)(float64 x, CPUState *env)
 {
     if (float64_is_any_nan(x)) {
-        return float32_zero;
+        return 0;
     }
-    return vfp_itos(float64_to_int32_round_to_zero(x, &env->vfp.fp_status));
+    return float64_to_int32_round_to_zero(x, &env->vfp.fp_status);
 }
 
 /* floating point conversion */
@@ -2637,33 +2592,33 @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUState *env)
 }
 
 /* VFP3 fixed point conversion.  */
-#define VFP_CONV_FIX(name, p, ftype, itype, sign) \
-ftype VFP_HELPER(name##to, p)(ftype x, uint32_t shift, CPUState *env) \
+#define VFP_CONV_FIX(name, p, fsz, itype, sign) \
+float##fsz VFP_HELPER(name##to, p)(uint##fsz##_t  x, uint32_t shift, \
+                                   CPUState *env) \
 { \
-    ftype tmp; \
-    tmp = sign##int32_to_##ftype ((itype##_t)vfp_##p##toi(x), \
-                                  &env->vfp.fp_status); \
-    return ftype##_scalbn(tmp, -(int)shift, &env->vfp.fp_status); \
+    float##fsz tmp; \
+    tmp = sign##int32_to_##float##fsz ((itype##_t)x, &env->vfp.fp_status); \
+    return float##fsz##_scalbn(tmp, -(int)shift, &env->vfp.fp_status); \
 } \
-ftype VFP_HELPER(to##name, p)(ftype x, uint32_t shift, CPUState *env) \
+uint##fsz##_t VFP_HELPER(to##name, p)(float##fsz x, uint32_t shift, \
+                                      CPUState *env) \
 { \
-    ftype tmp; \
-    if (ftype##_is_any_nan(x)) { \
-        return ftype##_zero; \
+    float##fsz tmp; \
+    if (float##fsz##_is_any_nan(x)) { \
+        return 0; \
     } \
-    tmp = ftype##_scalbn(x, shift, &env->vfp.fp_status); \
-    return vfp_ito##p(ftype##_to_##itype##_round_to_zero(tmp, \
-        &env->vfp.fp_status)); \
+    tmp = float##fsz##_scalbn(x, shift, &env->vfp.fp_status); \
+    return float##fsz##_to_##itype##_round_to_zero(tmp, &env->vfp.fp_status); \
 }
 
-VFP_CONV_FIX(sh, d, float64, int16, )
-VFP_CONV_FIX(sl, d, float64, int32, )
-VFP_CONV_FIX(uh, d, float64, uint16, u)
-VFP_CONV_FIX(ul, d, float64, uint32, u)
-VFP_CONV_FIX(sh, s, float32, int16, )
-VFP_CONV_FIX(sl, s, float32, int32, )
-VFP_CONV_FIX(uh, s, float32, uint16, u)
-VFP_CONV_FIX(ul, s, float32, uint32, u)
+VFP_CONV_FIX(sh, d, 64, int16, )
+VFP_CONV_FIX(sl, d, 64, int32, )
+VFP_CONV_FIX(uh, d, 64, uint16, u)
+VFP_CONV_FIX(ul, d, 64, uint32, u)
+VFP_CONV_FIX(sh, s, 32, int16, )
+VFP_CONV_FIX(sl, s, 32, int32, )
+VFP_CONV_FIX(uh, s, 32, uint16, u)
+VFP_CONV_FIX(ul, s, 32, uint32, u)
 #undef VFP_CONV_FIX
 
 /* Half precision conversions.  */
diff --git a/target-arm/helpers.h b/target-arm/helpers.h
index bd6977c2fe..9de10e352f 100644
--- a/target-arm/helpers.h
+++ b/target-arm/helpers.h
@@ -96,36 +96,36 @@ DEF_HELPER_3(vfp_cmped, void, f64, f64, env)
 DEF_HELPER_2(vfp_fcvtds, f64, f32, env)
 DEF_HELPER_2(vfp_fcvtsd, f32, f64, env)
 
-DEF_HELPER_2(vfp_uitos, f32, f32, env)
-DEF_HELPER_2(vfp_uitod, f64, f32, env)
-DEF_HELPER_2(vfp_sitos, f32, f32, env)
-DEF_HELPER_2(vfp_sitod, f64, f32, env)
+DEF_HELPER_2(vfp_uitos, f32, i32, env)
+DEF_HELPER_2(vfp_uitod, f64, i32, env)
+DEF_HELPER_2(vfp_sitos, f32, i32, env)
+DEF_HELPER_2(vfp_sitod, f64, i32, env)
 
-DEF_HELPER_2(vfp_touis, f32, f32, env)
-DEF_HELPER_2(vfp_touid, f32, f64, env)
-DEF_HELPER_2(vfp_touizs, f32, f32, env)
-DEF_HELPER_2(vfp_touizd, f32, f64, env)
-DEF_HELPER_2(vfp_tosis, f32, f32, env)
-DEF_HELPER_2(vfp_tosid, f32, f64, env)
-DEF_HELPER_2(vfp_tosizs, f32, f32, env)
-DEF_HELPER_2(vfp_tosizd, f32, f64, env)
+DEF_HELPER_2(vfp_touis, i32, f32, env)
+DEF_HELPER_2(vfp_touid, i32, f64, env)
+DEF_HELPER_2(vfp_touizs, i32, f32, env)
+DEF_HELPER_2(vfp_touizd, i32, f64, env)
+DEF_HELPER_2(vfp_tosis, i32, f32, env)
+DEF_HELPER_2(vfp_tosid, i32, f64, env)
+DEF_HELPER_2(vfp_tosizs, i32, f32, env)
+DEF_HELPER_2(vfp_tosizd, i32, f64, env)
 
-DEF_HELPER_3(vfp_toshs, f32, f32, i32, env)
-DEF_HELPER_3(vfp_tosls, f32, f32, i32, env)
-DEF_HELPER_3(vfp_touhs, f32, f32, i32, env)
-DEF_HELPER_3(vfp_touls, f32, f32, i32, env)
-DEF_HELPER_3(vfp_toshd, f64, f64, i32, env)
-DEF_HELPER_3(vfp_tosld, f64, f64, i32, env)
-DEF_HELPER_3(vfp_touhd, f64, f64, i32, env)
-DEF_HELPER_3(vfp_tould, f64, f64, i32, env)
-DEF_HELPER_3(vfp_shtos, f32, f32, i32, env)
-DEF_HELPER_3(vfp_sltos, f32, f32, i32, env)
-DEF_HELPER_3(vfp_uhtos, f32, f32, i32, env)
-DEF_HELPER_3(vfp_ultos, f32, f32, i32, env)
-DEF_HELPER_3(vfp_shtod, f64, f64, i32, env)
-DEF_HELPER_3(vfp_sltod, f64, f64, i32, env)
-DEF_HELPER_3(vfp_uhtod, f64, f64, i32, env)
-DEF_HELPER_3(vfp_ultod, f64, f64, i32, env)
+DEF_HELPER_3(vfp_toshs, i32, f32, i32, env)
+DEF_HELPER_3(vfp_tosls, i32, f32, i32, env)
+DEF_HELPER_3(vfp_touhs, i32, f32, i32, env)
+DEF_HELPER_3(vfp_touls, i32, f32, i32, env)
+DEF_HELPER_3(vfp_toshd, i64, f64, i32, env)
+DEF_HELPER_3(vfp_tosld, i64, f64, i32, env)
+DEF_HELPER_3(vfp_touhd, i64, f64, i32, env)
+DEF_HELPER_3(vfp_tould, i64, f64, i32, env)
+DEF_HELPER_3(vfp_shtos, f32, i32, i32, env)
+DEF_HELPER_3(vfp_sltos, f32, i32, i32, env)
+DEF_HELPER_3(vfp_uhtos, f32, i32, i32, env)
+DEF_HELPER_3(vfp_ultos, f32, i32, i32, env)
+DEF_HELPER_3(vfp_shtod, f64, i64, i32, env)
+DEF_HELPER_3(vfp_sltod, f64, i64, i32, env)
+DEF_HELPER_3(vfp_uhtod, f64, i64, i32, env)
+DEF_HELPER_3(vfp_ultod, f64, i64, i32, env)
 
 DEF_HELPER_2(vfp_fcvt_f16_to_f32, f32, i32, env)
 DEF_HELPER_2(vfp_fcvt_f32_to_f16, i32, f32, env)

From 2055283bcc8292fd63c772ed90a2502f427b2174 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 7 Mar 2011 11:10:32 +0000
Subject: [PATCH 062/386] hw/vexpress.c: Add model of ARM Versatile Express
 board

Add a model of the ARM Versatile Express board (with A9MPx4
daughterboard).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 Makefile.target |   1 +
 hw/vexpress.c   | 224 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 225 insertions(+)
 create mode 100644 hw/vexpress.c

diff --git a/Makefile.target b/Makefile.target
index ace5608016..ddb0931f68 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -333,6 +333,7 @@ obj-arm-y += framebuffer.o
 obj-arm-y += syborg.o syborg_fb.o syborg_interrupt.o syborg_keyboard.o
 obj-arm-y += syborg_serial.o syborg_timer.o syborg_pointer.o syborg_rtc.o
 obj-arm-y += syborg_virtio.o
+obj-arm-y += vexpress.o
 
 obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
 obj-sh4-y += sh_timer.o sh_serial.o sh_intc.o sh_pci.o sm501.o
diff --git a/hw/vexpress.c b/hw/vexpress.c
new file mode 100644
index 0000000000..9ffd332dee
--- /dev/null
+++ b/hw/vexpress.c
@@ -0,0 +1,224 @@
+/*
+ * ARM Versatile Express emulation.
+ *
+ * Copyright (c) 2010 - 2011 B Labs Ltd.
+ * Copyright (c) 2011 Linaro Limited
+ * Written by Bahadir Balban, Amit Mahajan, Peter Maydell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "sysbus.h"
+#include "arm-misc.h"
+#include "primecell.h"
+#include "devices.h"
+#include "net.h"
+#include "sysemu.h"
+#include "boards.h"
+
+#define SMP_BOOT_ADDR 0xe0000000
+
+#define VEXPRESS_BOARD_ID 0x8e0
+
+static struct arm_boot_info vexpress_binfo = {
+    .smp_loader_start = SMP_BOOT_ADDR,
+};
+
+static void vexpress_a9_init(ram_addr_t ram_size,
+                     const char *boot_device,
+                     const char *kernel_filename, const char *kernel_cmdline,
+                     const char *initrd_filename, const char *cpu_model)
+{
+    CPUState *env = NULL;
+    ram_addr_t ram_offset, vram_offset, sram_offset;
+    DeviceState *dev, *sysctl;
+    SysBusDevice *busdev;
+    qemu_irq *irqp;
+    qemu_irq pic[64];
+    int n;
+    qemu_irq cpu_irq[4];
+    uint32_t proc_id;
+    uint32_t sys_id;
+    ram_addr_t low_ram_size, vram_size, sram_size;
+
+    if (!cpu_model) {
+        cpu_model = "cortex-a9";
+    }
+
+    for (n = 0; n < smp_cpus; n++) {
+        env = cpu_init(cpu_model);
+        if (!env) {
+            fprintf(stderr, "Unable to find CPU definition\n");
+            exit(1);
+        }
+        irqp = arm_pic_init_cpu(env);
+        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
+    }
+
+    if (ram_size > 0x40000000) {
+        /* 1GB is the maximum the address space permits */
+        fprintf(stderr, "vexpress: cannot model more than 1GB RAM\n");
+        exit(1);
+    }
+
+    ram_offset = qemu_ram_alloc(NULL, "vexpress.highmem", ram_size);
+    low_ram_size = ram_size;
+    if (low_ram_size > 0x4000000) {
+        low_ram_size = 0x4000000;
+    }
+    /* RAM is from 0x60000000 upwards. The bottom 64MB of the
+     * address space should in theory be remappable to various
+     * things including ROM or RAM; we always map the RAM there.
+     */
+    cpu_register_physical_memory(0x0, low_ram_size, ram_offset | IO_MEM_RAM);
+    cpu_register_physical_memory(0x60000000, ram_size,
+                                 ram_offset | IO_MEM_RAM);
+
+    /* 0x1e000000 A9MPCore (SCU) private memory region */
+    dev = qdev_create(NULL, "a9mpcore_priv");
+    qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
+    qdev_init_nofail(dev);
+    busdev = sysbus_from_qdev(dev);
+    vexpress_binfo.smp_priv_base = 0x1e000000;
+    sysbus_mmio_map(busdev, 0, vexpress_binfo.smp_priv_base);
+    for (n = 0; n < smp_cpus; n++) {
+        sysbus_connect_irq(busdev, n, cpu_irq[n]);
+    }
+    /* Interrupts [42:0] are from the motherboard;
+     * [47:43] are reserved; [63:48] are daughterboard
+     * peripherals. Note that some documentation numbers
+     * external interrupts starting from 32 (because the
+     * A9MP has internal interrupts 0..31).
+     */
+    for (n = 0; n < 64; n++) {
+        pic[n] = qdev_get_gpio_in(dev, n);
+    }
+
+    /* Motherboard peripherals CS7 : 0x10000000 .. 0x10020000 */
+    sys_id = 0x1190f500;
+    proc_id = 0x0c000191;
+
+    /* 0x10000000 System registers */
+    sysctl = qdev_create(NULL, "realview_sysctl");
+    qdev_prop_set_uint32(sysctl, "sys_id", sys_id);
+    qdev_init_nofail(sysctl);
+    qdev_prop_set_uint32(sysctl, "proc_id", proc_id);
+    sysbus_mmio_map(sysbus_from_qdev(sysctl), 0, 0x10000000);
+
+    /* 0x10001000 SP810 system control */
+    /* 0x10002000 serial bus PCI */
+    /* 0x10004000 PL041 audio */
+
+    dev = sysbus_create_varargs("pl181", 0x10005000, pic[9], pic[10], NULL);
+    /* Wire up MMC card detect and read-only signals */
+    qdev_connect_gpio_out(dev, 0,
+                          qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT));
+    qdev_connect_gpio_out(dev, 1,
+                          qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN));
+
+    sysbus_create_simple("pl050_keyboard", 0x10006000, pic[12]);
+    sysbus_create_simple("pl050_mouse", 0x10007000, pic[13]);
+
+    sysbus_create_simple("pl011", 0x10009000, pic[5]);
+    sysbus_create_simple("pl011", 0x1000a000, pic[6]);
+    sysbus_create_simple("pl011", 0x1000b000, pic[7]);
+    sysbus_create_simple("pl011", 0x1000c000, pic[8]);
+
+    /* 0x1000f000 SP805 WDT */
+
+    sysbus_create_simple("sp804", 0x10011000, pic[2]);
+    sysbus_create_simple("sp804", 0x10012000, pic[3]);
+
+    /* 0x10016000 Serial Bus DVI */
+
+    sysbus_create_simple("pl031", 0x10017000, pic[4]); /* RTC */
+
+    /* 0x1001a000 Compact Flash */
+
+    /* 0x1001f000 PL111 CLCD (motherboard) */
+
+    /* Daughterboard peripherals : 0x10020000 .. 0x20000000 */
+
+    /* 0x10020000 PL111 CLCD (daughterboard) */
+    sysbus_create_simple("pl110", 0x10020000, pic[44]);
+
+    /* 0x10060000 AXI RAM */
+    /* 0x100e0000 PL341 Dynamic Memory Controller */
+    /* 0x100e1000 PL354 Static Memory Controller */
+    /* 0x100e2000 System Configuration Controller */
+
+    sysbus_create_simple("sp804", 0x100e4000, pic[48]);
+    /* 0x100e5000 SP805 Watchdog module */
+    /* 0x100e6000 BP147 TrustZone Protection Controller */
+    /* 0x100e9000 PL301 'Fast' AXI matrix */
+    /* 0x100ea000 PL301 'Slow' AXI matrix */
+    /* 0x100ec000 TrustZone Address Space Controller */
+    /* 0x10200000 CoreSight debug APB */
+    /* 0x1e00a000 PL310 L2 Cache Controller */
+
+    /* CS0: NOR0 flash          : 0x40000000 .. 0x44000000 */
+    /* CS4: NOR1 flash          : 0x44000000 .. 0x48000000 */
+    /* CS2: SRAM                : 0x48000000 .. 0x4a000000 */
+    sram_size = 0x2000000;
+    sram_offset = qemu_ram_alloc(NULL, "vexpress.sram", sram_size);
+    cpu_register_physical_memory(0x48000000, sram_size,
+                                 sram_offset | IO_MEM_RAM);
+
+    /* CS3: USB, ethernet, VRAM : 0x4c000000 .. 0x50000000 */
+
+    /* 0x4c000000 Video RAM */
+    vram_size = 0x800000;
+    vram_offset = qemu_ram_alloc(NULL, "vexpress.vram", vram_size);
+    cpu_register_physical_memory(0x4c000000, vram_size,
+                                 vram_offset | IO_MEM_RAM);
+
+    /* 0x4e000000 LAN9118 Ethernet */
+    if (nd_table[0].vlan) {
+        lan9118_init(&nd_table[0], 0x4e000000, pic[15]);
+    }
+
+    /* 0x4f000000 ISP1761 USB */
+
+    /* ??? Hack to map an additional page of ram for the secondary CPU
+       startup code.  I guess this works on real hardware because the
+       BootROM happens to be in ROM/flash or in memory that isn't clobbered
+       until after Linux boots the secondary CPUs.  */
+    ram_offset = qemu_ram_alloc(NULL, "vexpress.hack", 0x1000);
+    cpu_register_physical_memory(SMP_BOOT_ADDR, 0x1000,
+                                 ram_offset | IO_MEM_RAM);
+
+    vexpress_binfo.ram_size = ram_size;
+    vexpress_binfo.kernel_filename = kernel_filename;
+    vexpress_binfo.kernel_cmdline = kernel_cmdline;
+    vexpress_binfo.initrd_filename = initrd_filename;
+    vexpress_binfo.nb_cpus = smp_cpus;
+    vexpress_binfo.board_id = VEXPRESS_BOARD_ID;
+    vexpress_binfo.loader_start = 0x60000000;
+    arm_load_kernel(first_cpu, &vexpress_binfo);
+}
+
+
+static QEMUMachine vexpress_a9_machine = {
+    .name = "vexpress-a9",
+    .desc = "ARM Versatile Express for Cortex-A9",
+    .init = vexpress_a9_init,
+    .use_scsi = 1,
+    .max_cpus = 4,
+};
+
+static void vexpress_machine_init(void)
+{
+    qemu_register_machine(&vexpress_a9_machine);
+}
+
+machine_init(vexpress_machine_init);

From 4ff9786c67f7c7180f33ec146e9acc9ce90adfa9 Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Sun, 13 Mar 2011 15:44:02 +0100
Subject: [PATCH 063/386] Fix trivial "endianness bugs"

Replace endianess -> endianness.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 audio/sdlaudio.c              | 20 ++++++++++----------
 block/vdi.c                   |  4 ++--
 target-microblaze/translate.c |  2 +-
 target-mips/cpu.h             |  2 +-
 usb-bsd.c                     |  2 +-
 5 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c
index b74dcfa734..a847aa90f7 100644
--- a/audio/sdlaudio.c
+++ b/audio/sdlaudio.c
@@ -139,36 +139,36 @@ static int aud_to_sdlfmt (audfmt_e fmt)
     }
 }
 
-static int sdl_to_audfmt (int sdlfmt, audfmt_e *fmt, int *endianess)
+static int sdl_to_audfmt(int sdlfmt, audfmt_e *fmt, int *endianness)
 {
     switch (sdlfmt) {
     case AUDIO_S8:
-        *endianess = 0;
+        *endianness = 0;
         *fmt = AUD_FMT_S8;
         break;
 
     case AUDIO_U8:
-        *endianess = 0;
+        *endianness = 0;
         *fmt = AUD_FMT_U8;
         break;
 
     case AUDIO_S16LSB:
-        *endianess = 0;
+        *endianness = 0;
         *fmt = AUD_FMT_S16;
         break;
 
     case AUDIO_U16LSB:
-        *endianess = 0;
+        *endianness = 0;
         *fmt = AUD_FMT_U16;
         break;
 
     case AUDIO_S16MSB:
-        *endianess = 1;
+        *endianness = 1;
         *fmt = AUD_FMT_S16;
         break;
 
     case AUDIO_U16MSB:
-        *endianess = 1;
+        *endianness = 1;
         *fmt = AUD_FMT_U16;
         break;
 
@@ -338,7 +338,7 @@ static int sdl_init_out (HWVoiceOut *hw, struct audsettings *as)
     SDLVoiceOut *sdl = (SDLVoiceOut *) hw;
     SDLAudioState *s = &glob_sdl;
     SDL_AudioSpec req, obt;
-    int endianess;
+    int endianness;
     int err;
     audfmt_e effective_fmt;
     struct audsettings obt_as;
@@ -354,7 +354,7 @@ static int sdl_init_out (HWVoiceOut *hw, struct audsettings *as)
         return -1;
     }
 
-    err = sdl_to_audfmt (obt.format, &effective_fmt, &endianess);
+    err = sdl_to_audfmt(obt.format, &effective_fmt, &endianness);
     if (err) {
         sdl_close (s);
         return -1;
@@ -363,7 +363,7 @@ static int sdl_init_out (HWVoiceOut *hw, struct audsettings *as)
     obt_as.freq = obt.freq;
     obt_as.nchannels = obt.channels;
     obt_as.fmt = effective_fmt;
-    obt_as.endianness = endianess;
+    obt_as.endianness = endianness;
 
     audio_pcm_init_info (&hw->info, &obt_as);
     hw->samples = obt.samples;
diff --git a/block/vdi.c b/block/vdi.c
index 90540792d3..701745bf8c 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -113,7 +113,7 @@ void uuid_unparse(const uuid_t uu, char *out);
  */
 #define VDI_TEXT "<<< QEMU VM Virtual Disk Image >>>\n"
 
-/* Unallocated blocks use this index (no need to convert endianess). */
+/* Unallocated blocks use this index (no need to convert endianness). */
 #define VDI_UNALLOCATED UINT32_MAX
 
 #if !defined(CONFIG_UUID)
@@ -194,7 +194,7 @@ typedef struct {
     uint32_t block_sectors;
     /* First sector of block map. */
     uint32_t bmap_sector;
-    /* VDI header (converted to host endianess). */
+    /* VDI header (converted to host endianness). */
     VdiHeader header;
 } BDRVVdiState;
 
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index fdb2b40df9..b54b169b18 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -923,7 +923,7 @@ static void dec_load(DisasContext *dc)
     /*
      * When doing reverse accesses we need to do two things.
      *
-     * 1. Reverse the address wrt endianess.
+     * 1. Reverse the address wrt endianness.
      * 2. Byteswap the data lanes on the way back into the CPU core.
      */
     if (rev && size != 4) {
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 2419aa93d2..0b98d10266 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -63,7 +63,7 @@ union fpr_t {
     uint32_t w[2]; /* binary single fixed-point */
 };
 /* define FP_ENDIAN_IDX to access the same location
- * in the fpr_t union regardless of the host endianess
+ * in the fpr_t union regardless of the host endianness
  */
 #if defined(HOST_WORDS_BIGENDIAN)
 #  define FP_ENDIAN_IDX 1
diff --git a/usb-bsd.c b/usb-bsd.c
index abcb60c6f1..50ccd489fe 100644
--- a/usb-bsd.c
+++ b/usb-bsd.c
@@ -464,7 +464,7 @@ static int usb_host_scan(void *opaque, USBScanFunc *func)
                 printf("usb_host_scan: couldn't get device information for %s - %s\n",
                        devbuf, strerror(errno));
 
-            // XXX: might need to fixup endianess of word values before copying over
+            /* XXX: might need to fixup endianness of word values before copying over */
 
             vendor_id = dev_info.udi_vendorNo;
             product_id = dev_info.udi_productNo;

From 9bcfc7daabb138b0fe3d64d74892942d482e5bbd Mon Sep 17 00:00:00 2001
From: Isaku Yamahata <yamahata@valinux.co.jp>
Date: Wed, 16 Mar 2011 18:05:01 +0900
Subject: [PATCH 064/386] ioapic: when switches to level trigger mode,
 interrupts raised repeatedly.

- the trigger mode is edge at first
- During initializatoin, the interrupt is raised as edge which is masked.
  The corresponding bit of irr is set.
- Then the mode is switched to level and it's unmasked.
- the bit of irr is set, so the interrupt is raised repeatedly by
  ioapic_service().
- OS considers that the irq line is broken and falls back to polling mode.

This patch fixes the issues.
After raising edige, clear the bit of irr.

> Bringing up interface eth0:
> Determining IP information for eth0...irq 18: nobody cared (try booting with the "irqpoll" option)
> Pid: 4126, comm: ip Not tainted 2.6.38-rc7 #1
> Call Trace:
>  <IRQ>  [<ffffffff8105b009>] ? __report_bad_irq+0x38/0x87
>  [<ffffffff8105b177>] ? note_interrupt+0x11f/0x188
>  [<ffffffff8105bacf>] ? handle_fasteoi_irq+0xa7/0xd1
>  [<ffffffff810046ff>] ? handle_irq+0x83/0x8c
>  [<ffffffff81003eb9>] ? do_IRQ+0x48/0xaf
>  [<ffffffff81300513>] ? ret_from_intr+0x0/0xe
>  [<ffffffff81031ab8>] ? __do_softirq+0x4f/0x114
>  [<ffffffff81002d6c>] ? call_softirq+0x1c/0x28
>  [<ffffffff81004647>] ? do_softirq+0x33/0x68
>  [<ffffffff810316fb>] ? irq_exit+0x36/0x38
>  [<ffffffff81015f2c>] ? smp_apic_timer_interrupt+0x88/0x96
>  [<ffffffff81002853>] ? apic_timer_interrupt+0x13/0x20
>  <EOI>  [<ffffffff810177ed>] ? __ioapic_set_affinity+0x68/0x7c
>  [<ffffffff813000f0>] ? _raw_spin_unlock_irqrestore+0x8/0xa
>  [<ffffffff8105a84f>] ? __setup_irq+0x224/0x2cb
>  [<ffffffff8120e3c5>] ? e1000_intr+0x0/0x103
>  [<ffffffff8105a9c7>] ? request_threaded_irq+0xd1/0x114
>  [<ffffffff8120e396>] ? e1000_request_irq+0x34/0x63
>  [<ffffffff8121237d>] ? e1000_open+0x81/0x11f
>  [<ffffffff8129097c>] ? call_netdevice_notifiers+0x45/0x4a
>  [<ffffffff81290d8d>] ? __dev_open+0x97/0xc4
>  [<ffffffff8128e9c5>] ? __dev_change_flags+0xb9/0x13d
>  [<ffffffff81290cc1>] ? dev_change_flags+0x1c/0x51
>  [<ffffffff812d0542>] ? devinet_ioctl+0x26e/0x594
>  [<ffffffff812d174c>] ? inet_ioctl+0x92/0xaa
>  [<ffffffff81281d75>] ? T.1003+0x13/0x32
>  [<ffffffff81282152>] ? sock_ioctl+0x1f2/0x1ff
>  [<ffffffff810ae2d3>] ? do_vfs_ioctl+0x498/0x4e7
>  [<ffffffff81281203>] ? sock_alloc_file+0xb3/0x115
>  [<ffffffff8109f79f>] ? fd_install+0x31/0x5d
>  [<ffffffff810ae364>] ? sys_ioctl+0x42/0x65
>  [<ffffffff81001f3b>] ? system_call_fastpath+0x16/0x1b
> handlers:
> [<ffffffff8120e3c5>] (e1000_intr+0x0/0x103)
> Disabling IRQ #18

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/ioapic.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/ioapic.c b/hw/ioapic.c
index 569327d1e9..8557e5cac6 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -164,6 +164,7 @@ static void ioapic_set_irq(void *opaque, int vector, int level)
             if (level) {
                 s->irr |= mask;
                 ioapic_service(s);
+                s->irr &= ~mask;
             }
         }
     }

From 2917dce477f91e933052f5555b4c6be961ff624e Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Sun, 3 Apr 2011 21:36:36 +0200
Subject: [PATCH 065/386] tests/cris: Fix some errors and potential crashes

These errors were reported by cppcheck:

tests/cris/check_openpf1.c:30: error:
Mismatching allocation and deallocation: f

tests/cris/check_openpf2.c:13: error:
Mismatching allocation and deallocation: f

tests/cris/check_stat3.c:16: error:
Buffer overrun possible for long cmd-line args

tests/cris/check_stat4.c:18: error:
Buffer overrun possible for long cmd-line args

The first two are obvious coding errors (fopen needs fclose, not close).

The last two may seem less important (nobody will start test code
with an argument of more than 1022 characters which raises a buffer
overrun). Fixing them nevertheless helps with static code checks
like those done by cppcheck.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 tests/cris/check_openpf1.c | 2 +-
 tests/cris/check_openpf2.c | 2 +-
 tests/cris/check_stat3.c   | 2 +-
 tests/cris/check_stat4.c   | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/tests/cris/check_openpf1.c b/tests/cris/check_openpf1.c
index 1d71e0bddb..fdcf4c5c3f 100644
--- a/tests/cris/check_openpf1.c
+++ b/tests/cris/check_openpf1.c
@@ -27,7 +27,7 @@ int main (int argc, char *argv[])
   f = fopen (fnam, "rb");
   if (f == NULL)
     abort ();
-  close (f);
+  fclose(f);
 
   /* Cover another execution path.  */
   if (fopen ("/nonexistent", "rb") != NULL
diff --git a/tests/cris/check_openpf2.c b/tests/cris/check_openpf2.c
index f44a8f34bb..5d56189f8e 100644
--- a/tests/cris/check_openpf2.c
+++ b/tests/cris/check_openpf2.c
@@ -10,7 +10,7 @@ int main (int argc, char *argv[])
   FILE *f = fopen ("check_openpf2.c", "rb");
   if (f == NULL)
     abort ();
-  close (f);
+  fclose(f);
   printf ("pass\n");
   return 0;
 }
diff --git a/tests/cris/check_stat3.c b/tests/cris/check_stat3.c
index 3b5b217a1c..36a9d5d274 100644
--- a/tests/cris/check_stat3.c
+++ b/tests/cris/check_stat3.c
@@ -13,7 +13,7 @@ int main (int argc, char *argv[])
   char path[1024] = "/";
   struct stat buf;
 
-  strcat (path, argv[0]);
+  strncat(path, argv[0], sizeof(path) - 2);
   if (stat (".", &buf) != 0
       || !S_ISDIR (buf.st_mode))
     abort ();
diff --git a/tests/cris/check_stat4.c b/tests/cris/check_stat4.c
index e1955cab34..04f21fe7c4 100644
--- a/tests/cris/check_stat4.c
+++ b/tests/cris/check_stat4.c
@@ -15,7 +15,7 @@ int main (int argc, char *argv[])
   char path[1024] = "/";
   struct stat buf;
 
-  strcat (path, argv[0]);
+  strncat(path, argv[0], sizeof(path) - 2);
   if (lstat (".", &buf) != 0
       || !S_ISDIR (buf.st_mode))
     abort ();

From 425189a8ffc1247cc803bf6e1ffea42c47831684 Mon Sep 17 00:00:00 2001
From: Jan Kiszka <jan.kiszka@siemens.com>
Date: Tue, 22 Mar 2011 11:02:09 +0100
Subject: [PATCH 066/386] gdbstub: Catch and report more vmstop reasons

When the VM goes into stop state while there is a gdb frontend attached,
it makes sense to inform gdb about this fact and at least a bit about
the stop reason. Basically, all stops are interesting except for the
temporary VMSTOP_SAVE/LOADVM.

The patch maps the relevant VMSTOP reasons on unique and more or less
associatable signals that gdb understands.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 gdbstub.c | 49 +++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 39 insertions(+), 10 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 1e9f9312de..0838948c5c 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -45,7 +45,12 @@
 enum {
     GDB_SIGNAL_0 = 0,
     GDB_SIGNAL_INT = 2,
+    GDB_SIGNAL_QUIT = 3,
     GDB_SIGNAL_TRAP = 5,
+    GDB_SIGNAL_ABRT = 6,
+    GDB_SIGNAL_ALRM = 14,
+    GDB_SIGNAL_IO = 23,
+    GDB_SIGNAL_XCPU = 24,
     GDB_SIGNAL_UNKNOWN = 143
 };
 
@@ -2270,14 +2275,11 @@ static void gdb_vm_state_change(void *opaque, int running, int reason)
     const char *type;
     int ret;
 
-    if (running || (reason != VMSTOP_DEBUG && reason != VMSTOP_USER) ||
-        s->state == RS_INACTIVE || s->state == RS_SYSCALL) {
+    if (running || s->state == RS_INACTIVE || s->state == RS_SYSCALL) {
         return;
     }
-    /* disable single step if it was enable */
-    cpu_single_step(env, 0);
-
-    if (reason == VMSTOP_DEBUG) {
+    switch (reason) {
+    case VMSTOP_DEBUG:
         if (env->watchpoint_hit) {
             switch (env->watchpoint_hit->flags & BP_MEM_ACCESS) {
             case BP_MEM_READ:
@@ -2294,17 +2296,44 @@ static void gdb_vm_state_change(void *opaque, int running, int reason)
                      "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
                      GDB_SIGNAL_TRAP, gdb_id(env), type,
                      env->watchpoint_hit->vaddr);
-            put_packet(s, buf);
             env->watchpoint_hit = NULL;
-            return;
+            goto send_packet;
         }
-	tb_flush(env);
+        tb_flush(env);
         ret = GDB_SIGNAL_TRAP;
-    } else {
+        break;
+    case VMSTOP_USER:
         ret = GDB_SIGNAL_INT;
+        break;
+    case VMSTOP_SHUTDOWN:
+        ret = GDB_SIGNAL_QUIT;
+        break;
+    case VMSTOP_DISKFULL:
+        ret = GDB_SIGNAL_IO;
+        break;
+    case VMSTOP_WATCHDOG:
+        ret = GDB_SIGNAL_ALRM;
+        break;
+    case VMSTOP_PANIC:
+        ret = GDB_SIGNAL_ABRT;
+        break;
+    case VMSTOP_SAVEVM:
+    case VMSTOP_LOADVM:
+        return;
+    case VMSTOP_MIGRATE:
+        ret = GDB_SIGNAL_XCPU;
+        break;
+    default:
+        ret = GDB_SIGNAL_UNKNOWN;
+        break;
     }
     snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, gdb_id(env));
+
+send_packet:
     put_packet(s, buf);
+
+    /* disable single step if it was enabled */
+    cpu_single_step(env, 0);
 }
 #endif
 

From d17161f6cc48a30b5e0c65a7d78ac47b069af06b Mon Sep 17 00:00:00 2001
From: Kevin Wolf <mail@kevin-wolf.de>
Date: Sat, 26 Mar 2011 19:37:56 +0100
Subject: [PATCH 067/386] e1000: Mask out lower bits of RDBAL/TDBAL

Rx and Tx descriptors are 16 byte aligned, so the lower bits are
ignored by real hardware. In fact, they always read back as zero on real
hardware, but probably nobody relies on that.

Signed-off-by: Kevin Wolf <mail@kevin-wolf.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/e1000.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/hw/e1000.c b/hw/e1000.c
index 55daae0eba..fe3e812610 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -517,6 +517,14 @@ txdesc_writeback(target_phys_addr_t base, struct e1000_tx_desc *dp)
     return E1000_ICR_TXDW;
 }
 
+static uint64_t tx_desc_base(E1000State *s)
+{
+    uint64_t bah = s->mac_reg[TDBAH];
+    uint64_t bal = s->mac_reg[TDBAL] & ~0xf;
+
+    return (bah << 32) + bal;
+}
+
 static void
 start_xmit(E1000State *s)
 {
@@ -530,7 +538,7 @@ start_xmit(E1000State *s)
     }
 
     while (s->mac_reg[TDH] != s->mac_reg[TDT]) {
-        base = ((uint64_t)s->mac_reg[TDBAH] << 32) + s->mac_reg[TDBAL] +
+        base = tx_desc_base(s) +
                sizeof(struct e1000_tx_desc) * s->mac_reg[TDH];
         cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
 
@@ -651,6 +659,14 @@ e1000_can_receive(VLANClientState *nc)
     return (s->mac_reg[RCTL] & E1000_RCTL_EN) && e1000_has_rxbufs(s, 1);
 }
 
+static uint64_t rx_desc_base(E1000State *s)
+{
+    uint64_t bah = s->mac_reg[RDBAH];
+    uint64_t bal = s->mac_reg[RDBAL] & ~0xf;
+
+    return (bah << 32) + bal;
+}
+
 static ssize_t
 e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
 {
@@ -700,8 +716,7 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
         if (desc_size > s->rxbuf_size) {
             desc_size = s->rxbuf_size;
         }
-        base = ((uint64_t)s->mac_reg[RDBAH] << 32) + s->mac_reg[RDBAL] +
-               sizeof(desc) * s->mac_reg[RDH];
+        base = rx_desc_base(s) + sizeof(desc) * s->mac_reg[RDH];
         cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
         desc.special = vlan_special;
         desc.status |= (vlan_status | E1000_RXD_STAT_DD);

From 22156ab498acf5f8104801148732ae8e83f336a0 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Date: Mon, 28 Mar 2011 22:00:30 +0100
Subject: [PATCH 068/386] net: Remove unused net-checksum.c file

The common checksum functions were moved to net/checksum.c in commit
7200ac3c7c8eefe574193b49eeff09f120e11ec7 but the original net-checksum.c
was never deleted from the source tree.  Remove it now since all users
of the checksum functions link against net/checksum.o and net-checksum.c
is not even compiled anymore.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 net-checksum.c | 86 --------------------------------------------------
 1 file changed, 86 deletions(-)
 delete mode 100644 net-checksum.c

diff --git a/net-checksum.c b/net-checksum.c
deleted file mode 100644
index 4956c5cefa..0000000000
--- a/net-checksum.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  IP checksumming functions.
- *  (c) 2008 Gerd Hoffmann <kraxel@redhat.com>
- *
- *  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; under version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "hw/hw.h"
-#include "net.h"
-
-#define PROTO_TCP  6
-#define PROTO_UDP 17
-
-uint32_t net_checksum_add(int len, uint8_t *buf)
-{
-    uint32_t sum = 0;
-    int i;
-
-    for (i = 0; i < len; i++) {
-	if (i & 1)
-	    sum += (uint32_t)buf[i];
-	else
-	    sum += (uint32_t)buf[i] << 8;
-    }
-    return sum;
-}
-
-uint16_t net_checksum_finish(uint32_t sum)
-{
-    while (sum>>16)
-	sum = (sum & 0xFFFF)+(sum >> 16);
-    return ~sum;
-}
-
-uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto,
-                             uint8_t *addrs, uint8_t *buf)
-{
-    uint32_t sum = 0;
-
-    sum += net_checksum_add(length, buf);         // payload
-    sum += net_checksum_add(8, addrs);            // src + dst address
-    sum += proto + length;                        // protocol & length
-    return net_checksum_finish(sum);
-}
-
-void net_checksum_calculate(uint8_t *data, int length)
-{
-    int hlen, plen, proto, csum_offset;
-    uint16_t csum;
-
-    if ((data[14] & 0xf0) != 0x40)
-	return; /* not IPv4 */
-    hlen  = (data[14] & 0x0f) * 4;
-    plen  = (data[16] << 8 | data[17]) - hlen;
-    proto = data[23];
-
-    switch (proto) {
-    case PROTO_TCP:
-	csum_offset = 16;
-	break;
-    case PROTO_UDP:
-	csum_offset = 6;
-	break;
-    default:
-	return;
-    }
-
-    if (plen < csum_offset+2)
-	return;
-
-    data[14+hlen+csum_offset]   = 0;
-    data[14+hlen+csum_offset+1] = 0;
-    csum = net_checksum_tcpudp(plen, proto, data+14+12, data+14+hlen);
-    data[14+hlen+csum_offset]   = csum >> 8;
-    data[14+hlen+csum_offset+1] = csum & 0xff;
-}

From f1d3fb04d55f46d39073e7089a5be43a16e80aa9 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Wed, 30 Mar 2011 22:03:38 +0100
Subject: [PATCH 069/386] vl.c: Tidy up message printed when we exit on a
 signal

Tidy up the message printed when qemu exits due to a signal, so that
it's clearer where the message is coming from and that it's not just
stray debug output.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Acked-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 vl.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/vl.c b/vl.c
index d3d81e08fb..5c80600c71 100644
--- a/vl.c
+++ b/vl.c
@@ -1169,8 +1169,15 @@ int qemu_shutdown_requested(void)
 void qemu_kill_report(void)
 {
     if (shutdown_signal != -1) {
-        fprintf(stderr, "Got signal %d from pid %d\n",
-                         shutdown_signal, shutdown_pid);
+        fprintf(stderr, "qemu: terminating on signal %d", shutdown_signal);
+        if (shutdown_pid == 0) {
+            /* This happens for eg ^C at the terminal, so it's worth
+             * avoiding printing an odd message in that case.
+             */
+            fputc('\n', stderr);
+        } else {
+            fprintf(stderr, " from pid %d\n", shutdown_pid);
+        }
         shutdown_signal = -1;
     }
 }

From 0ce235a7ee5a1852c0a18d4764ac0a6700805c83 Mon Sep 17 00:00:00 2001
From: Gleb Natapov <gleb@redhat.com>
Date: Thu, 31 Mar 2011 11:27:23 +0200
Subject: [PATCH 070/386] register signal handler after initializing SDL.

SDL library initialization mangles signal handlers, so QEMU should
register them after initializing SDL. This was the case before and code
even have a comment about that. Fix it to be so again.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 vl.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/vl.c b/vl.c
index 5c80600c71..4d9e503d7c 100644
--- a/vl.c
+++ b/vl.c
@@ -3059,9 +3059,6 @@ int main(int argc, char **argv, char **envp)
 
     cpu_synchronize_all_post_init();
 
-    /* must be after terminal init, SDL library changes signal handlers */
-    os_setup_signal_handling();
-
     set_numa_modes();
 
     current_machine = machine;
@@ -3117,6 +3114,9 @@ int main(int argc, char **argv, char **envp)
         break;
     }
 
+    /* must be after terminal init, SDL library changes signal handlers */
+    os_setup_signal_handling();
+
 #ifdef CONFIG_VNC
     /* init remote displays */
     if (vnc_display) {

From 6d65516f774c62a1abde3e52b689ac743b9ccc71 Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Sun, 3 Apr 2011 08:55:35 +0200
Subject: [PATCH 071/386] w32: Fix compilation (wrong include file)

arpa/inet.h is not available for w32, so commit
edbb21363fbfe40e050f583df921484cbc31c79d breaks
w32 compilations.

This is fixed by using qemu_socket.h.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Reviewed-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/ccid-card-passthru.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
index 8506fed4fc..28eb9d18f8 100644
--- a/hw/ccid-card-passthru.c
+++ b/hw/ccid-card-passthru.c
@@ -8,9 +8,8 @@
  * See the COPYING file in the top-level directory.
  */
 
-#include <arpa/inet.h>
-
 #include "qemu-char.h"
+#include "qemu_socket.h"
 #include "monitor.h"
 #include "hw/ccid.h"
 #include "libcacard/vscard_common.h"

From 1b01b4e717ada625575c207105b0b270c0b8467d Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Tue, 29 Mar 2011 15:29:28 +0200
Subject: [PATCH 072/386] Only build ivshmem when CONFIG_PCI && CONFIG_KVM

The ivshmem depends on PCI and KVM, not only KVM. Reflect this
in the Makefile, so we don't get build errors on s390x.

Signed-off-by: Alexander Graf <agraf@suse.de>
CC: Cam Macdonell <cam@cs.ualberta.ca>
CC: Juan Quintela <quintela@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 Makefile.target | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/Makefile.target b/Makefile.target
index ddb0931f68..04e20dde95 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -209,7 +209,13 @@ QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
 obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
 
 # Inter-VM PCI shared memory
-obj-$(CONFIG_KVM) += ivshmem.o
+CONFIG_IVSHMEM =
+ifeq ($(CONFIG_KVM), y)
+  ifeq ($(CONFIG_PCI), y)
+    CONFIG_IVSHMEM = y
+  endif
+endif
+obj-$(CONFIG_IVSHMEM) += ivshmem.o
 
 # Hardware support
 obj-i386-y += vga.o

From 29f82b37e5341b96e514373854411c4fcb935fc0 Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Tue, 29 Mar 2011 15:29:29 +0200
Subject: [PATCH 073/386] virtio: use generic name when possible

We have two different virtio buses: pci and s390. The abstraction path
taken in qemu is to have generic aliases for each device type in the
architecture specific qdev devices.

So let's make use of these aliases whenever we can and define them
whenever we can.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 blockdev.c           | 2 +-
 hw/s390-virtio-bus.c | 2 ++
 hw/virtio-pci.c      | 3 +++
 vl.c                 | 6 +++---
 4 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index ecf2252d83..bbe92fe196 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -503,7 +503,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
     case IF_VIRTIO:
         /* add virtio block device */
         opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0);
-        qemu_opt_set(opts, "driver", "virtio-blk-pci");
+        qemu_opt_set(opts, "driver", "virtio-blk");
         qemu_opt_set(opts, "drive", dinfo->id);
         if (devaddr)
             qemu_opt_set(opts, "addr", devaddr);
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index 784dc01b97..d44eff25aa 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -325,6 +325,7 @@ static const VirtIOBindings virtio_s390_bindings = {
 static VirtIOS390DeviceInfo s390_virtio_net = {
     .init = s390_virtio_net_init,
     .qdev.name = "virtio-net-s390",
+    .qdev.alias = "virtio-net",
     .qdev.size = sizeof(VirtIOS390Device),
     .qdev.props = (Property[]) {
         DEFINE_NIC_PROPERTIES(VirtIOS390Device, nic),
@@ -340,6 +341,7 @@ static VirtIOS390DeviceInfo s390_virtio_net = {
 static VirtIOS390DeviceInfo s390_virtio_blk = {
     .init = s390_virtio_blk_init,
     .qdev.name = "virtio-blk-s390",
+    .qdev.alias = "virtio-blk",
     .qdev.size = sizeof(VirtIOS390Device),
     .qdev.props = (Property[]) {
         DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, block),
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index df10703b29..555f23f1da 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -873,6 +873,7 @@ static PCIDeviceInfo virtio_info[] = {
         .qdev.reset = virtio_pci_reset,
     },{
         .qdev.name  = "virtio-net-pci",
+        .qdev.alias = "virtio-net",
         .qdev.size  = sizeof(VirtIOPCIProxy),
         .init       = virtio_net_init_pci,
         .exit       = virtio_net_exit_pci,
@@ -911,6 +912,7 @@ static PCIDeviceInfo virtio_info[] = {
         .qdev.reset = virtio_pci_reset,
     },{
         .qdev.name = "virtio-balloon-pci",
+        .qdev.alias = "virtio-balloon",
         .qdev.size = sizeof(VirtIOPCIProxy),
         .init      = virtio_balloon_init_pci,
         .exit      = virtio_exit_pci,
@@ -922,6 +924,7 @@ static PCIDeviceInfo virtio_info[] = {
     },{
 #ifdef CONFIG_VIRTFS
         .qdev.name = "virtio-9p-pci",
+        .qdev.alias = "virtio-9p",
         .qdev.size = sizeof(VirtIOPCIProxy),
         .init      = virtio_9p_init_pci,
         .qdev.props = (Property[]) {
diff --git a/vl.c b/vl.c
index 4d9e503d7c..de232b75e6 100644
--- a/vl.c
+++ b/vl.c
@@ -1598,7 +1598,7 @@ static int balloon_parse(const char *arg)
             /* create empty opts */
             opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0);
         }
-        qemu_opt_set(opts, "driver", "virtio-balloon-pci");
+        qemu_opt_set(opts, "driver", "virtio-balloon");
         return 0;
     }
 
@@ -2484,12 +2484,12 @@ int main(int argc, char **argv, char **envp)
                          qemu_opt_get(opts, "path"),
                          qemu_opt_get(opts, "security_model"));
 
-                len = strlen("virtio-9p-pci,fsdev=,mount_tag=");
+                len = strlen("virtio-9p,fsdev=,mount_tag=");
                 len += 2*strlen(qemu_opt_get(opts, "mount_tag"));
                 arg_9p = qemu_malloc((len + 1) * sizeof(*arg_9p));
 
                 snprintf(arg_9p, (len + 1) * sizeof(*arg_9p),
-                         "virtio-9p-pci,fsdev=%s,mount_tag=%s",
+                         "virtio-9p,fsdev=%s,mount_tag=%s",
                          qemu_opt_get(opts, "mount_tag"),
                          qemu_opt_get(opts, "mount_tag"));
 

From 359507eed1b6d8ae2392e0c8fe32d5f0de9d1d75 Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Tue, 29 Mar 2011 15:29:30 +0200
Subject: [PATCH 074/386] s390x: fix KVM target

During Jan's rework of the generic KVM layer, he added some more error checks
and actually aborted if something went wrong. Unfortunately, one of the s390
internal error codes slipped through, aborting the VM without needing to.

This patch fixes booting of S390x virtual machines in KVM.

Signed-off-by: Alexander Graf <agraf@suse.de>
CC: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-s390x/kvm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 91232038ea..ae7dc561b3 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -441,7 +441,7 @@ static int handle_instruction(CPUState *env, struct kvm_run *run)
     if (r < 0) {
         enter_pgmcheck(env, 0x0001);
     }
-    return r;
+    return 0;
 }
 
 static int handle_intercept(CPUState *env)

From 6be9b4147adb27f78ec944af5abfc97e7cd0d066 Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Tue, 29 Mar 2011 15:29:31 +0200
Subject: [PATCH 075/386] s390x: fix s390-virtio-serial

Commit 6b331efb733a0f913ddc0b7762a1307dec304061 broke the s390 proxy version
of virtio-serial by only taking its PCI brother into account.

So let's adjust s390-virtio-serial the same way as its PCI counterpart, making
it compile and work again.

Signed-off-by: Alexander Graf <agraf@suse.de>
CC: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/s390-virtio-bus.c | 6 +++---
 hw/s390-virtio-bus.h | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index d44eff25aa..58af164880 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -139,7 +139,7 @@ static int s390_virtio_serial_init(VirtIOS390Device *dev)
 
     bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
 
-    vdev = virtio_serial_init((DeviceState *)dev, dev->max_virtserial_ports);
+    vdev = virtio_serial_init((DeviceState *)dev, &dev->serial);
     if (!vdev) {
         return -1;
     }
@@ -355,8 +355,8 @@ static VirtIOS390DeviceInfo s390_virtio_serial = {
     .qdev.alias = "virtio-serial",
     .qdev.size = sizeof(VirtIOS390Device),
     .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("max_ports", VirtIOS390Device, max_virtserial_ports,
-                           31),
+        DEFINE_PROP_UINT32("max_ports", VirtIOS390Device,
+                           serial.max_virtserial_ports, 31),
         DEFINE_PROP_END_OF_LIST(),
     },
 };
diff --git a/hw/s390-virtio-bus.h b/hw/s390-virtio-bus.h
index 33379a3ba4..edf6d04570 100644
--- a/hw/s390-virtio-bus.h
+++ b/hw/s390-virtio-bus.h
@@ -18,6 +18,7 @@
  */
 
 #include "virtio-net.h"
+#include "virtio-serial.h"
 
 #define VIRTIO_DEV_OFFS_TYPE		0	/* 8 bits */
 #define VIRTIO_DEV_OFFS_NUM_VQ		1	/* 8 bits */
@@ -43,8 +44,7 @@ typedef struct VirtIOS390Device {
     BlockConf block;
     NICConf nic;
     uint32_t host_features;
-    /* Max. number of ports we can have for a the virtio-serial device */
-    uint32_t max_virtserial_ports;
+    virtio_serial_conf serial;
     virtio_net_conf net;
 } VirtIOS390Device;
 

From db500609847caa9d43a1186bb7ab2df56fa8e1b0 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Tue, 29 Mar 2011 15:29:32 +0200
Subject: [PATCH 076/386] s390x: Enable disassembler for s390x

This patch enables the instruction disassembler when using an
S390x target.

Signed-off-by: Ulrich Hecht <uli@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 disas.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/disas.c b/disas.c
index c76f36f590..17b4ce47b2 100644
--- a/disas.c
+++ b/disas.c
@@ -215,6 +215,9 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
         disasm_info.mach = bfd_mach_cris_v32;
         print_insn = print_insn_crisv32;
     }
+#elif defined(TARGET_S390X)
+    disasm_info.mach = bfd_mach_s390_64;
+    print_insn = print_insn_s390;
 #elif defined(TARGET_MICROBLAZE)
     disasm_info.mach = bfd_arch_microblaze;
     print_insn = print_insn_microblaze;
@@ -414,6 +417,9 @@ void monitor_disas(Monitor *mon, CPUState *env,
 #elif defined(TARGET_SH4)
     disasm_info.mach = bfd_mach_sh4;
     print_insn = print_insn_sh;
+#elif defined(TARGET_S390X)
+    disasm_info.mach = bfd_mach_s390_64;
+    print_insn = print_insn_s390;
 #else
     monitor_printf(mon, "0x" TARGET_FMT_lx
                    ": Asm output not supported on this arch\n", pc);

From bc434676dc99f492492b8d0b23a0e49262202029 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Tue, 29 Mar 2011 15:29:33 +0200
Subject: [PATCH 077/386] s390x: Enable nptl for s390x

S390x user emulation can do nptl. Reflect this in the configure script.

Signed-off-by: Ulrich Hecht <uli@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 configure | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configure b/configure
index 2ef5c75054..e91525fd1c 100755
--- a/configure
+++ b/configure
@@ -3150,6 +3150,7 @@ case "$target_arch2" in
     target_phys_bits=64
   ;;
   s390x)
+    target_nptl="yes"
     target_phys_bits=64
   ;;
   *)

From 490f4edcdf64524fb29a758e381985b6b0cf002f Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Tue, 29 Mar 2011 15:29:34 +0200
Subject: [PATCH 078/386] s390x: enable CPU_QuadU

S390x uses the QuadU type, so let's enable it.

Signed-off-by: Ulrich Hecht <uli@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 cpu-all.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cpu-all.h b/cpu-all.h
index 4f4631d79c..4cc445ffc3 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -138,7 +138,7 @@ typedef union {
     uint64_t ll;
 } CPU_DoubleU;
 
-#ifdef TARGET_SPARC
+#if defined(TARGET_SPARC) || defined(TARGET_S390X)
 typedef union {
     float128 q;
 #if defined(HOST_WORDS_BIGENDIAN) \

From 449aa4a4915f4d2f43126eec6031cfc96ef06687 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Mon, 4 Apr 2011 07:14:03 +0200
Subject: [PATCH 079/386] Revert "ioapic: when switches to level trigger mode,
 interrupts raised repeatedly."

This reverts commit 9bcfc7daabb138b0fe3d64d74892942d482e5bbd.
---
 hw/ioapic.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/ioapic.c b/hw/ioapic.c
index 8557e5cac6..569327d1e9 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -164,7 +164,6 @@ static void ioapic_set_irq(void *opaque, int vector, int level)
             if (level) {
                 s->irr |= mask;
                 ioapic_service(s);
-                s->irr &= ~mask;
             }
         }
     }

From 25a8bb96f4a9dcb27dc55027b81d9646273a937b Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Mon, 7 Mar 2011 23:32:32 +0100
Subject: [PATCH 080/386] lm32: add Milkymist AC97 support

This patch adds support for the Milkymist AC97 compatible sound output and
input core.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 Makefile.target     |   1 +
 configure           |   3 +
 hw/milkymist-ac97.c | 335 ++++++++++++++++++++++++++++++++++++++++++++
 trace-events        |  12 ++
 4 files changed, 351 insertions(+)
 create mode 100644 hw/milkymist-ac97.c

diff --git a/Makefile.target b/Makefile.target
index 04e20dde95..0610bb8c81 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -267,6 +267,7 @@ obj-lm32-y += lm32_juart.o
 obj-lm32-y += lm32_timer.o
 obj-lm32-y += lm32_uart.o
 obj-lm32-y += lm32_sys.o
+obj-lm32-y += milkymist-ac97.o
 
 obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o
 obj-mips-y += mips_addr.o mips_timer.o mips_int.o
diff --git a/configure b/configure
index e91525fd1c..2e7b4f8718 100755
--- a/configure
+++ b/configure
@@ -3350,6 +3350,9 @@ if test "$target_softmmu" = "yes" ; then
   arm)
     cflags="-DHAS_AUDIO $cflags"
   ;;
+  lm32)
+    cflags="-DHAS_AUDIO $cflags"
+  ;;
   i386|mips|ppc)
     cflags="-DHAS_AUDIO -DHAS_AUDIO_CHOICE $cflags"
   ;;
diff --git a/hw/milkymist-ac97.c b/hw/milkymist-ac97.c
new file mode 100644
index 0000000000..6c9e318aa2
--- /dev/null
+++ b/hw/milkymist-ac97.c
@@ -0,0 +1,335 @@
+/*
+ *  QEMU model of the Milkymist System Controller.
+ *
+ *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Specification available at:
+ *   http://www.milkymist.org/socdoc/ac97.pdf
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "trace.h"
+#include "audio/audio.h"
+#include "qemu-error.h"
+
+enum {
+    R_AC97_CTRL = 0,
+    R_AC97_ADDR,
+    R_AC97_DATAOUT,
+    R_AC97_DATAIN,
+    R_D_CTRL,
+    R_D_ADDR,
+    R_D_REMAINING,
+    R_RESERVED,
+    R_U_CTRL,
+    R_U_ADDR,
+    R_U_REMAINING,
+    R_MAX
+};
+
+enum {
+    AC97_CTRL_RQEN  = (1<<0),
+    AC97_CTRL_WRITE = (1<<1),
+};
+
+enum {
+    CTRL_EN = (1<<0),
+};
+
+struct MilkymistAC97State {
+    SysBusDevice busdev;
+
+    QEMUSoundCard card;
+    SWVoiceIn *voice_in;
+    SWVoiceOut *voice_out;
+
+    uint32_t regs[R_MAX];
+
+    qemu_irq crrequest_irq;
+    qemu_irq crreply_irq;
+    qemu_irq dmar_irq;
+    qemu_irq dmaw_irq;
+};
+typedef struct MilkymistAC97State MilkymistAC97State;
+
+static void update_voices(MilkymistAC97State *s)
+{
+    if (s->regs[R_D_CTRL] & CTRL_EN) {
+        AUD_set_active_out(s->voice_out, 1);
+    } else {
+        AUD_set_active_out(s->voice_out, 0);
+    }
+
+    if (s->regs[R_U_CTRL] & CTRL_EN) {
+        AUD_set_active_in(s->voice_in, 1);
+    } else {
+        AUD_set_active_in(s->voice_in, 0);
+    }
+}
+
+static uint32_t ac97_read(void *opaque, target_phys_addr_t addr)
+{
+    MilkymistAC97State *s = opaque;
+    uint32_t r = 0;
+
+    addr >>= 2;
+    switch (addr) {
+    case R_AC97_CTRL:
+    case R_AC97_ADDR:
+    case R_AC97_DATAOUT:
+    case R_AC97_DATAIN:
+    case R_D_CTRL:
+    case R_D_ADDR:
+    case R_D_REMAINING:
+    case R_U_CTRL:
+    case R_U_ADDR:
+    case R_U_REMAINING:
+        r = s->regs[addr];
+        break;
+
+    default:
+        error_report("milkymist_ac97: read access to unkown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+
+    trace_milkymist_ac97_memory_read(addr << 2, r);
+
+    return r;
+}
+
+static void ac97_write(void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    MilkymistAC97State *s = opaque;
+
+    trace_milkymist_ac97_memory_write(addr, value);
+
+    addr >>= 2;
+    switch (addr) {
+    case R_AC97_CTRL:
+        /* always raise an IRQ according to the direction */
+        if (value & AC97_CTRL_RQEN) {
+            if (value & AC97_CTRL_WRITE) {
+                trace_milkymist_ac97_pulse_irq_crrequest();
+                qemu_irq_pulse(s->crrequest_irq);
+            } else {
+                trace_milkymist_ac97_pulse_irq_crreply();
+                qemu_irq_pulse(s->crreply_irq);
+            }
+        }
+
+        /* RQEN is self clearing */
+        s->regs[addr] = value & ~AC97_CTRL_RQEN;
+        break;
+    case R_D_CTRL:
+    case R_U_CTRL:
+        s->regs[addr] = value;
+        update_voices(s);
+        break;
+    case R_AC97_ADDR:
+    case R_AC97_DATAOUT:
+    case R_AC97_DATAIN:
+    case R_D_ADDR:
+    case R_D_REMAINING:
+    case R_U_ADDR:
+    case R_U_REMAINING:
+        s->regs[addr] = value;
+        break;
+
+    default:
+        error_report("milkymist_ac97: write access to unkown register 0x"
+                TARGET_FMT_plx, addr);
+        break;
+    }
+
+}
+
+static CPUReadMemoryFunc * const ac97_read_fn[] = {
+    NULL,
+    NULL,
+    &ac97_read,
+};
+
+static CPUWriteMemoryFunc * const ac97_write_fn[] = {
+    NULL,
+    NULL,
+    &ac97_write,
+};
+
+static void ac97_in_cb(void *opaque, int avail_b)
+{
+    MilkymistAC97State *s = opaque;
+    uint8_t buf[4096];
+    uint32_t remaining = s->regs[R_U_REMAINING];
+    int temp = audio_MIN(remaining, avail_b);
+    uint32_t addr = s->regs[R_U_ADDR];
+    int transferred = 0;
+
+    trace_milkymist_ac97_in_cb(avail_b, remaining);
+
+    /* prevent from raising an IRQ */
+    if (temp == 0) {
+        return;
+    }
+
+    while (temp) {
+        int acquired, to_copy;
+
+        to_copy = audio_MIN(temp, sizeof(buf));
+        acquired = AUD_read(s->voice_in, buf, to_copy);
+        if (!acquired) {
+            break;
+        }
+
+        cpu_physical_memory_write(addr, buf, acquired);
+
+        temp -= acquired;
+        addr += acquired;
+        transferred += acquired;
+    }
+
+    trace_milkymist_ac97_in_cb_transferred(transferred);
+
+    s->regs[R_U_ADDR] = addr;
+    s->regs[R_U_REMAINING] -= transferred;
+
+    if ((s->regs[R_U_CTRL] & CTRL_EN) && (s->regs[R_U_REMAINING] == 0)) {
+        trace_milkymist_ac97_pulse_irq_dmaw();
+        qemu_irq_pulse(s->dmaw_irq);
+    }
+}
+
+static void ac97_out_cb(void *opaque, int free_b)
+{
+    MilkymistAC97State *s = opaque;
+    uint8_t buf[4096];
+    uint32_t remaining = s->regs[R_D_REMAINING];
+    int temp = audio_MIN(remaining, free_b);
+    uint32_t addr = s->regs[R_D_ADDR];
+    int transferred = 0;
+
+    trace_milkymist_ac97_out_cb(free_b, remaining);
+
+    /* prevent from raising an IRQ */
+    if (temp == 0) {
+        return;
+    }
+
+    while (temp) {
+        int copied, to_copy;
+
+        to_copy = audio_MIN(temp, sizeof(buf));
+        cpu_physical_memory_read(addr, buf, to_copy);
+        copied = AUD_write(s->voice_out, buf, to_copy);
+        if (!copied) {
+            break;
+        }
+        temp -= copied;
+        addr += copied;
+        transferred += copied;
+    }
+
+    trace_milkymist_ac97_out_cb_transferred(transferred);
+
+    s->regs[R_D_ADDR] = addr;
+    s->regs[R_D_REMAINING] -= transferred;
+
+    if ((s->regs[R_D_CTRL] & CTRL_EN) && (s->regs[R_D_REMAINING] == 0)) {
+        trace_milkymist_ac97_pulse_irq_dmar();
+        qemu_irq_pulse(s->dmar_irq);
+    }
+}
+
+static void milkymist_ac97_reset(DeviceState *d)
+{
+    MilkymistAC97State *s = container_of(d, MilkymistAC97State, busdev.qdev);
+    int i;
+
+    for (i = 0; i < R_MAX; i++) {
+        s->regs[i] = 0;
+    }
+
+    AUD_set_active_in(s->voice_in, 0);
+    AUD_set_active_out(s->voice_out, 0);
+}
+
+static int ac97_post_load(void *opaque, int version_id)
+{
+    MilkymistAC97State *s = opaque;
+
+    update_voices(s);
+
+    return 0;
+}
+
+static int milkymist_ac97_init(SysBusDevice *dev)
+{
+    MilkymistAC97State *s = FROM_SYSBUS(typeof(*s), dev);
+    int ac97_regs;
+
+    struct audsettings as;
+    sysbus_init_irq(dev, &s->crrequest_irq);
+    sysbus_init_irq(dev, &s->crreply_irq);
+    sysbus_init_irq(dev, &s->dmar_irq);
+    sysbus_init_irq(dev, &s->dmaw_irq);
+
+    AUD_register_card("Milkymist AC'97", &s->card);
+
+    as.freq = 48000;
+    as.nchannels = 2;
+    as.fmt = AUD_FMT_S16;
+    as.endianness = 1;
+
+    s->voice_in = AUD_open_in(&s->card, s->voice_in,
+            "mm_ac97.in", s, ac97_in_cb, &as);
+    s->voice_out = AUD_open_out(&s->card, s->voice_out,
+            "mm_ac97.out", s, ac97_out_cb, &as);
+
+    ac97_regs = cpu_register_io_memory(ac97_read_fn, ac97_write_fn, s,
+            DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, R_MAX * 4, ac97_regs);
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_milkymist_ac97 = {
+    .name = "milkymist-ac97",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .post_load = ac97_post_load,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(regs, MilkymistAC97State, R_MAX),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static SysBusDeviceInfo milkymist_ac97_info = {
+    .init = milkymist_ac97_init,
+    .qdev.name  = "milkymist-ac97",
+    .qdev.size  = sizeof(MilkymistAC97State),
+    .qdev.vmsd  = &vmstate_milkymist_ac97,
+    .qdev.reset = milkymist_ac97_reset,
+};
+
+static void milkymist_ac97_register(void)
+{
+    sysbus_register_withprop(&milkymist_ac97_info);
+}
+
+device_init(milkymist_ac97_register)
diff --git a/trace-events b/trace-events
index 90c9e0b5e7..fc8caa8e54 100644
--- a/trace-events
+++ b/trace-events
@@ -286,3 +286,15 @@ disable lm32_uart_irq_state(int level) "irq state %d"
 
 # hw/lm32_sys.c
 disable lm32_sys_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
+
+# hw/milkymist-ac97.c
+disable milkymist_ac97_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_ac97_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_ac97_pulse_irq_crrequest(void) "Pulse IRQ CR request"
+disable milkymist_ac97_pulse_irq_crreply(void) "Pulse IRQ CR reply"
+disable milkymist_ac97_pulse_irq_dmaw(void) "Pulse IRQ DMA write"
+disable milkymist_ac97_pulse_irq_dmar(void) "Pulse IRQ DMA read"
+disable milkymist_ac97_in_cb(int avail, uint32_t remaining) "avail %d remaining %u"
+disable milkymist_ac97_in_cb_transferred(int transferred) "transferred %d"
+disable milkymist_ac97_out_cb(int free, uint32_t remaining) "free %d remaining %u"
+disable milkymist_ac97_out_cb_transferred(int transferred) "transferred %d"

From e4dc6d2cdca3e64fe09d3c76a56294b7b7aa7d7f Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Mon, 7 Mar 2011 23:32:33 +0100
Subject: [PATCH 081/386] lm32: add Milkymist HPDMC support

This patch adds support for the Milkymist's High Performance Dynamic Memory
Controller. This is just a dumb model without any functionality. While the
real hardware acts for example as a bridge between software and hardware
for sending SDRAM commans, this model will only eat up these commands and
always returns the expected hardware states, eg. PLL locked etc.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 Makefile.target      |   1 +
 hw/milkymist-hpdmc.c | 161 +++++++++++++++++++++++++++++++++++++++++++
 trace-events         |   4 ++
 3 files changed, 166 insertions(+)
 create mode 100644 hw/milkymist-hpdmc.c

diff --git a/Makefile.target b/Makefile.target
index 0610bb8c81..0e4f69379b 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -268,6 +268,7 @@ obj-lm32-y += lm32_timer.o
 obj-lm32-y += lm32_uart.o
 obj-lm32-y += lm32_sys.o
 obj-lm32-y += milkymist-ac97.o
+obj-lm32-y += milkymist-hpdmc.o
 
 obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o
 obj-mips-y += mips_addr.o mips_timer.o mips_int.o
diff --git a/hw/milkymist-hpdmc.c b/hw/milkymist-hpdmc.c
new file mode 100644
index 0000000000..c0962fb528
--- /dev/null
+++ b/hw/milkymist-hpdmc.c
@@ -0,0 +1,161 @@
+/*
+ *  QEMU model of the Milkymist High Performance Dynamic Memory Controller.
+ *
+ *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Specification available at:
+ *   http://www.milkymist.org/socdoc/hpdmc.pdf
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "trace.h"
+#include "qemu-error.h"
+
+enum {
+    R_SYSTEM = 0,
+    R_BYPASS,
+    R_TIMING,
+    R_IODELAY,
+    R_MAX
+};
+
+enum {
+    IODELAY_DQSDELAY_RDY = (1<<5),
+    IODELAY_PLL1_LOCKED  = (1<<6),
+    IODELAY_PLL2_LOCKED  = (1<<7),
+};
+
+struct MilkymistHpdmcState {
+    SysBusDevice busdev;
+
+    uint32_t regs[R_MAX];
+};
+typedef struct MilkymistHpdmcState MilkymistHpdmcState;
+
+static uint32_t hpdmc_read(void *opaque, target_phys_addr_t addr)
+{
+    MilkymistHpdmcState *s = opaque;
+    uint32_t r = 0;
+
+    addr >>= 2;
+    switch (addr) {
+    case R_SYSTEM:
+    case R_BYPASS:
+    case R_TIMING:
+    case R_IODELAY:
+        r = s->regs[addr];
+        break;
+
+    default:
+        error_report("milkymist_hpdmc: read access to unknown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+
+    trace_milkymist_hpdmc_memory_read(addr << 2, r);
+
+    return r;
+}
+
+static void hpdmc_write(void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    MilkymistHpdmcState *s = opaque;
+
+    trace_milkymist_hpdmc_memory_write(addr, value);
+
+    addr >>= 2;
+    switch (addr) {
+    case R_SYSTEM:
+    case R_BYPASS:
+    case R_TIMING:
+        s->regs[addr] = value;
+        break;
+    case R_IODELAY:
+        /* ignore writes */
+        break;
+
+    default:
+        error_report("milkymist_hpdmc: write access to unknown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+}
+
+static CPUReadMemoryFunc * const hpdmc_read_fn[] = {
+    NULL,
+    NULL,
+    &hpdmc_read,
+};
+
+static CPUWriteMemoryFunc * const hpdmc_write_fn[] = {
+    NULL,
+    NULL,
+    &hpdmc_write,
+};
+
+static void milkymist_hpdmc_reset(DeviceState *d)
+{
+    MilkymistHpdmcState *s = container_of(d, MilkymistHpdmcState, busdev.qdev);
+    int i;
+
+    for (i = 0; i < R_MAX; i++) {
+        s->regs[i] = 0;
+    }
+
+    /* defaults */
+    s->regs[R_IODELAY] = IODELAY_DQSDELAY_RDY | IODELAY_PLL1_LOCKED
+                         | IODELAY_PLL2_LOCKED;
+}
+
+static int milkymist_hpdmc_init(SysBusDevice *dev)
+{
+    MilkymistHpdmcState *s = FROM_SYSBUS(typeof(*s), dev);
+    int hpdmc_regs;
+
+    hpdmc_regs = cpu_register_io_memory(hpdmc_read_fn, hpdmc_write_fn, s,
+            DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, R_MAX * 4, hpdmc_regs);
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_milkymist_hpdmc = {
+    .name = "milkymist-hpdmc",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(regs, MilkymistHpdmcState, R_MAX),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static SysBusDeviceInfo milkymist_hpdmc_info = {
+    .init = milkymist_hpdmc_init,
+    .qdev.name  = "milkymist-hpdmc",
+    .qdev.size  = sizeof(MilkymistHpdmcState),
+    .qdev.vmsd  = &vmstate_milkymist_hpdmc,
+    .qdev.reset = milkymist_hpdmc_reset,
+};
+
+static void milkymist_hpdmc_register(void)
+{
+    sysbus_register_withprop(&milkymist_hpdmc_info);
+}
+
+device_init(milkymist_hpdmc_register)
diff --git a/trace-events b/trace-events
index fc8caa8e54..9ccf82c9da 100644
--- a/trace-events
+++ b/trace-events
@@ -298,3 +298,7 @@ disable milkymist_ac97_in_cb(int avail, uint32_t remaining) "avail %d remaining
 disable milkymist_ac97_in_cb_transferred(int transferred) "transferred %d"
 disable milkymist_ac97_out_cb(int free, uint32_t remaining) "free %d remaining %u"
 disable milkymist_ac97_out_cb_transferred(int transferred) "transferred %d"
+
+# hw/milkymist-hpdmc.c
+disable milkymist_hpdmc_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_hpdmc_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"

From b4e37d98560c41afb944c616ce5c1df8577c35da Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Mon, 7 Mar 2011 23:32:34 +0100
Subject: [PATCH 082/386] lm32: add Milkymist memory card support

This patch adds support for Milkymist's memory card core.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 Makefile.target                  |   1 +
 default-configs/lm32-softmmu.mak |   1 +
 hw/milkymist-memcard.c           | 294 +++++++++++++++++++++++++++++++
 trace-events                     |   8 +-
 4 files changed, 302 insertions(+), 2 deletions(-)
 create mode 100644 hw/milkymist-memcard.c

diff --git a/Makefile.target b/Makefile.target
index 0e4f69379b..d58358b900 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -269,6 +269,7 @@ obj-lm32-y += lm32_uart.o
 obj-lm32-y += lm32_sys.o
 obj-lm32-y += milkymist-ac97.o
 obj-lm32-y += milkymist-hpdmc.o
+obj-lm32-y += milkymist-memcard.o
 
 obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o
 obj-mips-y += mips_addr.o mips_timer.o mips_int.o
diff --git a/default-configs/lm32-softmmu.mak b/default-configs/lm32-softmmu.mak
index ab774a2509..3e7f57e700 100644
--- a/default-configs/lm32-softmmu.mak
+++ b/default-configs/lm32-softmmu.mak
@@ -2,3 +2,4 @@
 
 CONFIG_PTIMER=y
 CONFIG_PFLASH_CFI02=y
+CONFIG_SD=y
diff --git a/hw/milkymist-memcard.c b/hw/milkymist-memcard.c
new file mode 100644
index 0000000000..06077af82a
--- /dev/null
+++ b/hw/milkymist-memcard.c
@@ -0,0 +1,294 @@
+/*
+ *  QEMU model of the Milkymist SD Card Controller.
+ *
+ *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Specification available at:
+ *   http://www.milkymist.org/socdoc/memcard.pdf
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "sysemu.h"
+#include "trace.h"
+#include "qemu-error.h"
+#include "blockdev.h"
+#include "sd.h"
+
+enum {
+    ENABLE_CMD_TX   = (1<<0),
+    ENABLE_CMD_RX   = (1<<1),
+    ENABLE_DAT_TX   = (1<<2),
+    ENABLE_DAT_RX   = (1<<3),
+};
+
+enum {
+    PENDING_CMD_TX   = (1<<0),
+    PENDING_CMD_RX   = (1<<1),
+    PENDING_DAT_TX   = (1<<2),
+    PENDING_DAT_RX   = (1<<3),
+};
+
+enum {
+    START_CMD_TX    = (1<<0),
+    START_DAT_RX    = (1<<1),
+};
+
+enum {
+    R_CLK2XDIV = 0,
+    R_ENABLE,
+    R_PENDING,
+    R_START,
+    R_CMD,
+    R_DAT,
+    R_MAX
+};
+
+struct MilkymistMemcardState {
+    SysBusDevice busdev;
+    SDState *card;
+
+    int command_write_ptr;
+    int response_read_ptr;
+    int response_len;
+    int ignore_next_cmd;
+    int enabled;
+    uint8_t command[6];
+    uint8_t response[17];
+    uint32_t regs[R_MAX];
+};
+typedef struct MilkymistMemcardState MilkymistMemcardState;
+
+static void update_pending_bits(MilkymistMemcardState *s)
+{
+    /* transmits are instantaneous, thus tx pending bits are never set */
+    s->regs[R_PENDING] = 0;
+    /* if rx is enabled the corresponding pending bits are always set */
+    if (s->regs[R_ENABLE] & ENABLE_CMD_RX) {
+        s->regs[R_PENDING] |= PENDING_CMD_RX;
+    }
+    if (s->regs[R_ENABLE] & ENABLE_DAT_RX) {
+        s->regs[R_PENDING] |= PENDING_DAT_RX;
+    }
+}
+
+static void memcard_sd_command(MilkymistMemcardState *s)
+{
+    SDRequest req;
+
+    req.cmd = s->command[0] & 0x3f;
+    req.arg = (s->command[1] << 24) | (s->command[2] << 16)
+              | (s->command[3] << 8) | s->command[4];
+    req.crc = s->command[5];
+
+    s->response[0] = req.cmd;
+    s->response_len = sd_do_command(s->card, &req, s->response+1);
+    s->response_read_ptr = 0;
+
+    if (s->response_len == 16) {
+        /* R2 response */
+        s->response[0] = 0x3f;
+        s->response_len += 1;
+    } else if (s->response_len == 4) {
+        /* no crc calculation, insert dummy byte */
+        s->response[5] = 0;
+        s->response_len += 2;
+    }
+
+    if (req.cmd == 0) {
+        /* next write is a dummy byte to clock the initialization of the sd
+         * card */
+        s->ignore_next_cmd = 1;
+    }
+}
+
+static uint32_t memcard_read(void *opaque, target_phys_addr_t addr)
+{
+    MilkymistMemcardState *s = opaque;
+    uint32_t r = 0;
+
+    addr >>= 2;
+    switch (addr) {
+    case R_CMD:
+        if (!s->enabled) {
+            r = 0xff;
+        } else {
+            r = s->response[s->response_read_ptr++];
+            if (s->response_read_ptr > s->response_len) {
+                error_report("milkymist_memcard: "
+                        "read more cmd bytes than available. Clipping.");
+                s->response_read_ptr = 0;
+            }
+        }
+        break;
+    case R_DAT:
+        if (!s->enabled) {
+            r = 0xffffffff;
+        } else {
+            r = 0;
+            r |= sd_read_data(s->card) << 24;
+            r |= sd_read_data(s->card) << 16;
+            r |= sd_read_data(s->card) << 8;
+            r |= sd_read_data(s->card);
+        }
+        break;
+    case R_CLK2XDIV:
+    case R_ENABLE:
+    case R_PENDING:
+    case R_START:
+        r = s->regs[addr];
+        break;
+
+    default:
+        error_report("milkymist_memcard: read access to unkown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+
+    trace_milkymist_memcard_memory_read(addr << 2, r);
+
+    return r;
+}
+
+static void memcard_write(void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    MilkymistMemcardState *s = opaque;
+
+    trace_milkymist_memcard_memory_write(addr, value);
+
+    addr >>= 2;
+    switch (addr) {
+    case R_PENDING:
+        /* clear rx pending bits */
+        s->regs[R_PENDING] &= ~(value & (PENDING_CMD_RX | PENDING_DAT_RX));
+        update_pending_bits(s);
+        break;
+    case R_CMD:
+        if (!s->enabled) {
+            break;
+        }
+        if (s->ignore_next_cmd) {
+            s->ignore_next_cmd = 0;
+            break;
+        }
+        s->command[s->command_write_ptr] = value & 0xff;
+        s->command_write_ptr = (s->command_write_ptr + 1) % 6;
+        if (s->command_write_ptr == 0) {
+            memcard_sd_command(s);
+        }
+        break;
+    case R_DAT:
+        if (!s->enabled) {
+            break;
+        }
+        sd_write_data(s->card, (value >> 24) & 0xff);
+        sd_write_data(s->card, (value >> 16) & 0xff);
+        sd_write_data(s->card, (value >> 8) & 0xff);
+        sd_write_data(s->card, value & 0xff);
+        break;
+    case R_ENABLE:
+        s->regs[addr] = value;
+        update_pending_bits(s);
+        break;
+    case R_CLK2XDIV:
+    case R_START:
+        s->regs[addr] = value;
+        break;
+
+    default:
+        error_report("milkymist_memcard: write access to unkown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+}
+
+static CPUReadMemoryFunc * const memcard_read_fn[] = {
+    NULL,
+    NULL,
+    &memcard_read,
+};
+
+static CPUWriteMemoryFunc * const memcard_write_fn[] = {
+    NULL,
+    NULL,
+    &memcard_write,
+};
+
+static void milkymist_memcard_reset(DeviceState *d)
+{
+    MilkymistMemcardState *s =
+            container_of(d, MilkymistMemcardState, busdev.qdev);
+    int i;
+
+    s->command_write_ptr = 0;
+    s->response_read_ptr = 0;
+    s->response_len = 0;
+
+    for (i = 0; i < R_MAX; i++) {
+        s->regs[i] = 0;
+    }
+}
+
+static int milkymist_memcard_init(SysBusDevice *dev)
+{
+    MilkymistMemcardState *s = FROM_SYSBUS(typeof(*s), dev);
+    DriveInfo *dinfo;
+    int memcard_regs;
+
+    dinfo = drive_get_next(IF_SD);
+    s->card = sd_init(dinfo ? dinfo->bdrv : NULL, 0);
+    s->enabled = dinfo ? bdrv_is_inserted(dinfo->bdrv) : 0;
+
+    memcard_regs = cpu_register_io_memory(memcard_read_fn, memcard_write_fn, s,
+            DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, R_MAX * 4, memcard_regs);
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_milkymist_memcard = {
+    .name = "milkymist-memcard",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_INT32(command_write_ptr, MilkymistMemcardState),
+        VMSTATE_INT32(response_read_ptr, MilkymistMemcardState),
+        VMSTATE_INT32(response_len, MilkymistMemcardState),
+        VMSTATE_INT32(ignore_next_cmd, MilkymistMemcardState),
+        VMSTATE_INT32(enabled, MilkymistMemcardState),
+        VMSTATE_UINT8_ARRAY(command, MilkymistMemcardState, 6),
+        VMSTATE_UINT8_ARRAY(response, MilkymistMemcardState, 17),
+        VMSTATE_UINT32_ARRAY(regs, MilkymistMemcardState, R_MAX),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static SysBusDeviceInfo milkymist_memcard_info = {
+    .init = milkymist_memcard_init,
+    .qdev.name  = "milkymist-memcard",
+    .qdev.size  = sizeof(MilkymistMemcardState),
+    .qdev.vmsd  = &vmstate_milkymist_memcard,
+    .qdev.reset = milkymist_memcard_reset,
+};
+
+static void milkymist_memcard_register(void)
+{
+    sysbus_register_withprop(&milkymist_memcard_info);
+}
+
+device_init(milkymist_memcard_register)
diff --git a/trace-events b/trace-events
index 9ccf82c9da..7627595713 100644
--- a/trace-events
+++ b/trace-events
@@ -300,5 +300,9 @@ disable milkymist_ac97_out_cb(int free, uint32_t remaining) "free %d remaining %
 disable milkymist_ac97_out_cb_transferred(int transferred) "transferred %d"
 
 # hw/milkymist-hpdmc.c
-disable milkymist_hpdmc_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_hpdmc_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_hpdmc_memory_read(uint32_t addr, uint32_t value) "addr=%08x value=%08x"
+disable milkymist_hpdmc_memory_write(uint32_t addr, uint32_t value) "addr=%08x value=%08x"
+
+# hw/milkymist-memcard.c
+disable milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"

From 0742454485d8fe5c88de390af0b20ce6c6e164b2 Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Mon, 7 Mar 2011 23:32:35 +0100
Subject: [PATCH 083/386] lm32: add Milkymist Minimac support

This patch adds support for Milkymist's minimal Ethernet MAC.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 Makefile.target        |   1 +
 hw/milkymist-minimac.c | 568 +++++++++++++++++++++++++++++++++++++++++
 trace-events           |  12 +
 3 files changed, 581 insertions(+)
 create mode 100644 hw/milkymist-minimac.c

diff --git a/Makefile.target b/Makefile.target
index d58358b900..6fd8a17116 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -270,6 +270,7 @@ obj-lm32-y += lm32_sys.o
 obj-lm32-y += milkymist-ac97.o
 obj-lm32-y += milkymist-hpdmc.o
 obj-lm32-y += milkymist-memcard.o
+obj-lm32-y += milkymist-minimac.o
 
 obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o
 obj-mips-y += mips_addr.o mips_timer.o mips_int.o
diff --git a/hw/milkymist-minimac.c b/hw/milkymist-minimac.c
new file mode 100644
index 0000000000..b07f18d8a7
--- /dev/null
+++ b/hw/milkymist-minimac.c
@@ -0,0 +1,568 @@
+/*
+ *  QEMU model of the Milkymist minimac block.
+ *
+ *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Specification available at:
+ *   http://www.milkymist.org/socdoc/minimac.pdf
+ *
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "trace.h"
+#include "net.h"
+#include "qemu-error.h"
+
+#include <zlib.h>
+
+enum {
+    R_SETUP = 0,
+    R_MDIO,
+    R_STATE0,
+    R_ADDR0,
+    R_COUNT0,
+    R_STATE1,
+    R_ADDR1,
+    R_COUNT1,
+    R_STATE2,
+    R_ADDR2,
+    R_COUNT2,
+    R_STATE3,
+    R_ADDR3,
+    R_COUNT3,
+    R_TXADDR,
+    R_TXCOUNT,
+    R_MAX
+};
+
+enum {
+    SETUP_RX_RST = (1<<0),
+    SETUP_TX_RST = (1<<2),
+};
+
+enum {
+    MDIO_DO  = (1<<0),
+    MDIO_DI  = (1<<1),
+    MDIO_OE  = (1<<2),
+    MDIO_CLK = (1<<3),
+};
+
+enum {
+    STATE_EMPTY   = 0,
+    STATE_LOADED  = 1,
+    STATE_PENDING = 2,
+};
+
+enum {
+    MDIO_OP_WRITE = 1,
+    MDIO_OP_READ  = 2,
+};
+
+enum mdio_state {
+    MDIO_STATE_IDLE,
+    MDIO_STATE_READING,
+    MDIO_STATE_WRITING,
+};
+
+enum {
+    R_PHY_ID1  = 2,
+    R_PHY_ID2  = 3,
+    R_PHY_MAX  = 32
+};
+
+#define MINIMAC_MTU 1530
+
+struct MilkymistMinimacMdioState {
+    int last_clk;
+    int count;
+    uint32_t data;
+    uint16_t data_out;
+    int state;
+
+    uint8_t phy_addr;
+    uint8_t reg_addr;
+};
+typedef struct MilkymistMinimacMdioState MilkymistMinimacMdioState;
+
+struct MilkymistMinimacState {
+    SysBusDevice busdev;
+    NICState *nic;
+    NICConf conf;
+    char *phy_model;
+
+    qemu_irq rx_irq;
+    qemu_irq tx_irq;
+
+    uint32_t regs[R_MAX];
+
+    MilkymistMinimacMdioState mdio;
+
+    uint16_t phy_regs[R_PHY_MAX];
+};
+typedef struct MilkymistMinimacState MilkymistMinimacState;
+
+static const uint8_t preamble_sfd[] = {
+        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5
+};
+
+static void minimac_mdio_write_reg(MilkymistMinimacState *s,
+        uint8_t phy_addr, uint8_t reg_addr, uint16_t value)
+{
+    trace_milkymist_minimac_mdio_write(phy_addr, reg_addr, value);
+
+    /* nop */
+}
+
+static uint16_t minimac_mdio_read_reg(MilkymistMinimacState *s,
+        uint8_t phy_addr, uint8_t reg_addr)
+{
+    uint16_t r = s->phy_regs[reg_addr];
+
+    trace_milkymist_minimac_mdio_read(phy_addr, reg_addr, r);
+
+    return r;
+}
+
+static void minimac_update_mdio(MilkymistMinimacState *s)
+{
+    MilkymistMinimacMdioState *m = &s->mdio;
+
+    /* detect rising clk edge */
+    if (m->last_clk == 0 && (s->regs[R_MDIO] & MDIO_CLK)) {
+        /* shift data in */
+        int bit = ((s->regs[R_MDIO] & MDIO_DO)
+                   && (s->regs[R_MDIO] & MDIO_OE)) ? 1 : 0;
+        m->data = (m->data << 1) | bit;
+
+        /* check for sync */
+        if (m->data == 0xffffffff) {
+            m->count = 32;
+        }
+
+        if (m->count == 16) {
+            uint8_t start = (m->data >> 14) & 0x3;
+            uint8_t op = (m->data >> 12) & 0x3;
+            uint8_t ta = (m->data) & 0x3;
+
+            if (start == 1 && op == MDIO_OP_WRITE && ta == 2) {
+                m->state = MDIO_STATE_WRITING;
+            } else if (start == 1 && op == MDIO_OP_READ && (ta & 1) == 0) {
+                m->state = MDIO_STATE_READING;
+            } else {
+                m->state = MDIO_STATE_IDLE;
+            }
+
+            if (m->state != MDIO_STATE_IDLE) {
+                m->phy_addr = (m->data >> 7) & 0x1f;
+                m->reg_addr = (m->data >> 2) & 0x1f;
+            }
+
+            if (m->state == MDIO_STATE_READING) {
+                m->data_out = minimac_mdio_read_reg(s, m->phy_addr,
+                        m->reg_addr);
+            }
+        }
+
+        if (m->count < 16 && m->state == MDIO_STATE_READING) {
+            int bit = (m->data_out & 0x8000) ? 1 : 0;
+            m->data_out <<= 1;
+
+            if (bit) {
+                s->regs[R_MDIO] |= MDIO_DI;
+            } else {
+                s->regs[R_MDIO] &= ~MDIO_DI;
+            }
+        }
+
+        if (m->count == 0 && m->state) {
+            if (m->state == MDIO_STATE_WRITING) {
+                uint16_t data = m->data & 0xffff;
+                minimac_mdio_write_reg(s, m->phy_addr, m->reg_addr, data);
+            }
+            m->state = MDIO_STATE_IDLE;
+        }
+        m->count--;
+    }
+
+    m->last_clk = (s->regs[R_MDIO] & MDIO_CLK) ? 1 : 0;
+}
+
+static size_t assemble_frame(uint8_t *buf, size_t size,
+        const uint8_t *payload, size_t payload_size)
+{
+    uint32_t crc;
+
+    if (size < payload_size + 12) {
+        error_report("milkymist_minimac: received too big ethernet frame");
+        return 0;
+    }
+
+    /* prepend preamble and sfd */
+    memcpy(buf, preamble_sfd, 8);
+
+    /* now copy the payload */
+    memcpy(buf + 8, payload, payload_size);
+
+    /* pad frame if needed */
+    if (payload_size < 60) {
+        memset(buf + payload_size + 8, 0, 60 - payload_size);
+        payload_size = 60;
+    }
+
+    /* append fcs */
+    crc = cpu_to_le32(crc32(0, buf + 8, payload_size));
+    memcpy(buf + payload_size + 8, &crc, 4);
+
+    return payload_size + 12;
+}
+
+static void minimac_tx(MilkymistMinimacState *s)
+{
+    uint8_t buf[MINIMAC_MTU];
+    uint32_t txcount = s->regs[R_TXCOUNT];
+
+    /* do nothing if transmission logic is in reset */
+    if (s->regs[R_SETUP] & SETUP_TX_RST) {
+        return;
+    }
+
+    if (txcount < 64) {
+        error_report("milkymist_minimac: ethernet frame too small (%u < %u)\n",
+                txcount, 64);
+        return;
+    }
+
+    if (txcount > MINIMAC_MTU) {
+        error_report("milkymist_minimac: MTU exceeded (%u > %u)\n",
+                txcount, MINIMAC_MTU);
+        return;
+    }
+
+    /* dma */
+    cpu_physical_memory_read(s->regs[R_TXADDR], buf, txcount);
+
+    if (memcmp(buf, preamble_sfd, 8) != 0) {
+        error_report("milkymist_minimac: frame doesn't contain the preamble "
+                "and/or the SFD (%02x %02x %02x %02x %02x %02x %02x %02x)\n",
+                buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
+        return;
+    }
+
+    trace_milkymist_minimac_tx_frame(txcount - 12);
+
+    /* send packet, skipping preamble and sfd */
+    qemu_send_packet_raw(&s->nic->nc, buf + 8, txcount - 12);
+
+    s->regs[R_TXCOUNT] = 0;
+
+    trace_milkymist_minimac_pulse_irq_tx();
+    qemu_irq_pulse(s->tx_irq);
+}
+
+static ssize_t minimac_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
+{
+    MilkymistMinimacState *s = DO_UPCAST(NICState, nc, nc)->opaque;
+
+    uint32_t r_addr;
+    uint32_t r_count;
+    uint32_t r_state;
+
+    uint8_t frame_buf[MINIMAC_MTU];
+    size_t frame_size;
+
+    trace_milkymist_minimac_rx_frame(buf, size);
+
+    /* discard frames if nic is in reset */
+    if (s->regs[R_SETUP] & SETUP_RX_RST) {
+        return size;
+    }
+
+    /* choose appropriate slot */
+    if (s->regs[R_STATE0] == STATE_LOADED) {
+        r_addr = R_ADDR0;
+        r_count = R_COUNT0;
+        r_state = R_STATE0;
+    } else if (s->regs[R_STATE1] == STATE_LOADED) {
+        r_addr = R_ADDR1;
+        r_count = R_COUNT1;
+        r_state = R_STATE1;
+    } else if (s->regs[R_STATE2] == STATE_LOADED) {
+        r_addr = R_ADDR2;
+        r_count = R_COUNT2;
+        r_state = R_STATE2;
+    } else if (s->regs[R_STATE3] == STATE_LOADED) {
+        r_addr = R_ADDR3;
+        r_count = R_COUNT3;
+        r_state = R_STATE3;
+    } else {
+        trace_milkymist_minimac_drop_rx_frame(buf);
+        return size;
+    }
+
+    /* assemble frame */
+    frame_size = assemble_frame(frame_buf, sizeof(frame_buf), buf, size);
+
+    if (frame_size == 0) {
+        return size;
+    }
+
+    trace_milkymist_minimac_rx_transfer(buf, frame_size);
+
+    /* do dma */
+    cpu_physical_memory_write(s->regs[r_addr], frame_buf, frame_size);
+
+    /* update slot */
+    s->regs[r_count] = frame_size;
+    s->regs[r_state] = STATE_PENDING;
+
+    trace_milkymist_minimac_pulse_irq_rx();
+    qemu_irq_pulse(s->rx_irq);
+
+    return size;
+}
+
+static uint32_t
+minimac_read(void *opaque, target_phys_addr_t addr)
+{
+    MilkymistMinimacState *s = opaque;
+    uint32_t r = 0;
+
+    addr >>= 2;
+    switch (addr) {
+    case R_SETUP:
+    case R_MDIO:
+    case R_STATE0:
+    case R_ADDR0:
+    case R_COUNT0:
+    case R_STATE1:
+    case R_ADDR1:
+    case R_COUNT1:
+    case R_STATE2:
+    case R_ADDR2:
+    case R_COUNT2:
+    case R_STATE3:
+    case R_ADDR3:
+    case R_COUNT3:
+    case R_TXADDR:
+    case R_TXCOUNT:
+        r = s->regs[addr];
+        break;
+
+    default:
+        error_report("milkymist_minimac: read access to unknown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+
+    trace_milkymist_minimac_memory_read(addr << 2, r);
+
+    return r;
+}
+
+static void
+minimac_write(void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    MilkymistMinimacState *s = opaque;
+
+    trace_milkymist_minimac_memory_read(addr, value);
+
+    addr >>= 2;
+    switch (addr) {
+    case R_MDIO:
+    {
+        /* MDIO_DI is read only */
+        int mdio_di = (s->regs[R_MDIO] & MDIO_DI);
+        s->regs[R_MDIO] = value;
+        if (mdio_di) {
+            s->regs[R_MDIO] |= mdio_di;
+        } else {
+            s->regs[R_MDIO] &= ~mdio_di;
+        }
+
+        minimac_update_mdio(s);
+    } break;
+    case R_TXCOUNT:
+        s->regs[addr] = value;
+        if (value > 0) {
+            minimac_tx(s);
+        }
+        break;
+    case R_SETUP:
+    case R_STATE0:
+    case R_ADDR0:
+    case R_COUNT0:
+    case R_STATE1:
+    case R_ADDR1:
+    case R_COUNT1:
+    case R_STATE2:
+    case R_ADDR2:
+    case R_COUNT2:
+    case R_STATE3:
+    case R_ADDR3:
+    case R_COUNT3:
+    case R_TXADDR:
+        s->regs[addr] = value;
+        break;
+
+    default:
+        error_report("milkymist_minimac: write access to unknown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+}
+
+static CPUReadMemoryFunc * const minimac_read_fn[] = {
+    NULL,
+    NULL,
+    &minimac_read,
+};
+
+static CPUWriteMemoryFunc * const minimac_write_fn[] = {
+    NULL,
+    NULL,
+    &minimac_write,
+};
+
+static int minimac_can_rx(VLANClientState *nc)
+{
+    MilkymistMinimacState *s = DO_UPCAST(NICState, nc, nc)->opaque;
+
+    /* discard frames if nic is in reset */
+    if (s->regs[R_SETUP] & SETUP_RX_RST) {
+        return 1;
+    }
+
+    if (s->regs[R_STATE0] == STATE_LOADED) {
+        return 1;
+    }
+    if (s->regs[R_STATE1] == STATE_LOADED) {
+        return 1;
+    }
+    if (s->regs[R_STATE2] == STATE_LOADED) {
+        return 1;
+    }
+    if (s->regs[R_STATE3] == STATE_LOADED) {
+        return 1;
+    }
+
+    return 0;
+}
+
+static void minimac_cleanup(VLANClientState *nc)
+{
+    MilkymistMinimacState *s = DO_UPCAST(NICState, nc, nc)->opaque;
+
+    s->nic = NULL;
+}
+
+static void milkymist_minimac_reset(DeviceState *d)
+{
+    MilkymistMinimacState *s =
+            container_of(d, MilkymistMinimacState, busdev.qdev);
+    int i;
+
+    for (i = 0; i < R_MAX; i++) {
+        s->regs[i] = 0;
+    }
+    for (i = 0; i < R_PHY_MAX; i++) {
+        s->phy_regs[i] = 0;
+    }
+
+    /* defaults */
+    s->phy_regs[R_PHY_ID1] = 0x0022; /* Micrel KSZ8001L */
+    s->phy_regs[R_PHY_ID2] = 0x161a;
+}
+
+static NetClientInfo net_milkymist_minimac_info = {
+    .type = NET_CLIENT_TYPE_NIC,
+    .size = sizeof(NICState),
+    .can_receive = minimac_can_rx,
+    .receive = minimac_rx,
+    .cleanup = minimac_cleanup,
+};
+
+static int milkymist_minimac_init(SysBusDevice *dev)
+{
+    MilkymistMinimacState *s = FROM_SYSBUS(typeof(*s), dev);
+    int regs;
+
+    sysbus_init_irq(dev, &s->rx_irq);
+    sysbus_init_irq(dev, &s->tx_irq);
+
+    regs = cpu_register_io_memory(minimac_read_fn, minimac_write_fn, s,
+            DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, R_MAX * 4, regs);
+
+    qemu_macaddr_default_if_unset(&s->conf.macaddr);
+    s->nic = qemu_new_nic(&net_milkymist_minimac_info, &s->conf,
+                          dev->qdev.info->name, dev->qdev.id, s);
+    qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_milkymist_minimac_mdio = {
+    .name = "milkymist_minimac_mdio",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_INT32(last_clk, MilkymistMinimacMdioState),
+        VMSTATE_INT32(count, MilkymistMinimacMdioState),
+        VMSTATE_UINT32(data, MilkymistMinimacMdioState),
+        VMSTATE_UINT16(data_out, MilkymistMinimacMdioState),
+        VMSTATE_INT32(state, MilkymistMinimacMdioState),
+        VMSTATE_UINT8(phy_addr, MilkymistMinimacMdioState),
+        VMSTATE_UINT8(reg_addr, MilkymistMinimacMdioState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_milkymist_minimac = {
+    .name = "milkymist-minimac",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(regs, MilkymistMinimacState, R_MAX),
+        VMSTATE_UINT16_ARRAY(phy_regs, MilkymistMinimacState, R_PHY_MAX),
+        VMSTATE_STRUCT(mdio, MilkymistMinimacState, 0,
+                vmstate_milkymist_minimac_mdio, MilkymistMinimacMdioState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static SysBusDeviceInfo milkymist_minimac_info = {
+    .init = milkymist_minimac_init,
+    .qdev.name  = "milkymist-minimac",
+    .qdev.size  = sizeof(MilkymistMinimacState),
+    .qdev.vmsd  = &vmstate_milkymist_minimac,
+    .qdev.reset = milkymist_minimac_reset,
+    .qdev.props = (Property[]) {
+        DEFINE_NIC_PROPERTIES(MilkymistMinimacState, conf),
+        DEFINE_PROP_STRING("phy_model", MilkymistMinimacState, phy_model),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
+static void milkymist_minimac_register(void)
+{
+    sysbus_register_withprop(&milkymist_minimac_info);
+}
+
+device_init(milkymist_minimac_register)
diff --git a/trace-events b/trace-events
index 7627595713..2becf85afd 100644
--- a/trace-events
+++ b/trace-events
@@ -306,3 +306,15 @@ disable milkymist_hpdmc_memory_write(uint32_t addr, uint32_t value) "addr=%08x v
 # hw/milkymist-memcard.c
 disable milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
 disable milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+
+# hw/milkymist-minimac.c
+disable milkymist_minimac_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_minimac_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_minimac_mdio_write(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
+disable milkymist_minimac_mdio_read(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
+disable milkymist_minimac_tx_frame(uint32_t length) "length %u"
+disable milkymist_minimac_rx_frame(const void *buf, uint32_t length) "buf %p length %u"
+disable milkymist_minimac_drop_rx_frame(const void *buf) "buf %p"
+disable milkymist_minimac_rx_transfer(const void *buf, uint32_t length) "buf %p length %d"
+disable milkymist_minimac_pulse_irq_rx(void) "Pulse IRQ RX"
+disable milkymist_minimac_pulse_irq_tx(void) "Pulse IRQ TX"

From 5ee18b9c6843fa69da3c3ed92c57e01102614e34 Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Mon, 7 Mar 2011 23:32:36 +0100
Subject: [PATCH 084/386] lm32: add Milkymist PFPU support

This patch adds support for Milkymist's Programmable FPU.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 Makefile.target     |   1 +
 hw/milkymist-pfpu.c | 536 ++++++++++++++++++++++++++++++++++++++++++++
 trace-events        |   6 +
 3 files changed, 543 insertions(+)
 create mode 100644 hw/milkymist-pfpu.c

diff --git a/Makefile.target b/Makefile.target
index 6fd8a17116..0a87446f15 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -271,6 +271,7 @@ obj-lm32-y += milkymist-ac97.o
 obj-lm32-y += milkymist-hpdmc.o
 obj-lm32-y += milkymist-memcard.o
 obj-lm32-y += milkymist-minimac.o
+obj-lm32-y += milkymist-pfpu.o
 
 obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o
 obj-mips-y += mips_addr.o mips_timer.o mips_int.o
diff --git a/hw/milkymist-pfpu.c b/hw/milkymist-pfpu.c
new file mode 100644
index 0000000000..4831e00b81
--- /dev/null
+++ b/hw/milkymist-pfpu.c
@@ -0,0 +1,536 @@
+/*
+ *  QEMU model of the Milkymist programmable FPU.
+ *
+ *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Specification available at:
+ *   http://www.milkymist.org/socdoc/pfpu.pdf
+ *
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "trace.h"
+#include "qemu-log.h"
+#include "qemu-error.h"
+#include <math.h>
+
+/* #define TRACE_EXEC */
+
+#ifdef TRACE_EXEC
+#    define D_EXEC(x) x
+#else
+#    define D_EXEC(x)
+#endif
+
+enum {
+    R_CTL = 0,
+    R_MESHBASE,
+    R_HMESHLAST,
+    R_VMESHLAST,
+    R_CODEPAGE,
+    R_VERTICES,
+    R_COLLISIONS,
+    R_STRAYWRITES,
+    R_LASTDMA,
+    R_PC,
+    R_DREGBASE,
+    R_CODEBASE,
+    R_MAX
+};
+
+enum {
+    CTL_START_BUSY = (1<<0),
+};
+
+enum {
+    OP_NOP = 0,
+    OP_FADD,
+    OP_FSUB,
+    OP_FMUL,
+    OP_FABS,
+    OP_F2I,
+    OP_I2F,
+    OP_VECTOUT,
+    OP_SIN,
+    OP_COS,
+    OP_ABOVE,
+    OP_EQUAL,
+    OP_COPY,
+    OP_IF,
+    OP_TSIGN,
+    OP_QUAKE,
+};
+
+enum {
+    GPR_X = 0,
+    GPR_Y = 1,
+    GPR_FLAGS = 2,
+};
+
+enum {
+    LATENCY_FADD = 5,
+    LATENCY_FSUB = 5,
+    LATENCY_FMUL = 7,
+    LATENCY_FABS = 2,
+    LATENCY_F2I = 2,
+    LATENCY_I2F = 3,
+    LATENCY_VECTOUT = 0,
+    LATENCY_SIN = 4,
+    LATENCY_COS = 4,
+    LATENCY_ABOVE = 2,
+    LATENCY_EQUAL = 2,
+    LATENCY_COPY = 2,
+    LATENCY_IF = 2,
+    LATENCY_TSIGN = 2,
+    LATENCY_QUAKE = 2,
+    MAX_LATENCY = 7
+};
+
+#define GPR_BEGIN       0x100
+#define GPR_END         0x17f
+#define MICROCODE_BEGIN 0x200
+#define MICROCODE_END   0x3ff
+#define MICROCODE_WORDS 2048
+
+#define REINTERPRET_CAST(type, val) (*((type *)&(val)))
+
+#ifdef TRACE_EXEC
+static const char *opcode_to_str[] = {
+    "NOP", "FADD", "FSUB", "FMUL", "FABS", "F2I", "I2F", "VECTOUT",
+    "SIN", "COS", "ABOVE", "EQUAL", "COPY", "IF", "TSIGN", "QUAKE",
+};
+#endif
+
+struct MilkymistPFPUState {
+    SysBusDevice busdev;
+    CharDriverState *chr;
+    qemu_irq irq;
+
+    uint32_t regs[R_MAX];
+    uint32_t gp_regs[128];
+    uint32_t microcode[MICROCODE_WORDS];
+
+    int output_queue_pos;
+    uint32_t output_queue[MAX_LATENCY];
+};
+typedef struct MilkymistPFPUState MilkymistPFPUState;
+
+static inline target_phys_addr_t
+get_dma_address(uint32_t base, uint32_t x, uint32_t y)
+{
+    return base + 8 * (128 * y + x);
+}
+
+static inline void
+output_queue_insert(MilkymistPFPUState *s, uint32_t val, int pos)
+{
+    s->output_queue[(s->output_queue_pos + pos) % MAX_LATENCY] = val;
+}
+
+static inline uint32_t
+output_queue_remove(MilkymistPFPUState *s)
+{
+    return s->output_queue[s->output_queue_pos];
+}
+
+static inline void
+output_queue_advance(MilkymistPFPUState *s)
+{
+    s->output_queue[s->output_queue_pos] = 0;
+    s->output_queue_pos = (s->output_queue_pos + 1) % MAX_LATENCY;
+}
+
+static int pfpu_decode_insn(MilkymistPFPUState *s)
+{
+    uint32_t pc = s->regs[R_PC];
+    uint32_t insn = s->microcode[pc];
+    uint32_t reg_a = (insn >> 18) & 0x7f;
+    uint32_t reg_b = (insn >> 11) & 0x7f;
+    uint32_t op = (insn >> 7) & 0xf;
+    uint32_t reg_d = insn & 0x7f;
+    uint32_t r;
+    int latency = 0;
+
+    switch (op) {
+    case OP_NOP:
+        break;
+    case OP_FADD:
+    {
+        float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
+        float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]);
+        float t = a + b;
+        r = REINTERPRET_CAST(uint32_t, t);
+        latency = LATENCY_FADD;
+        D_EXEC(qemu_log("ADD a=%f b=%f t=%f, r=%08x\n", a, b, t, r));
+    } break;
+    case OP_FSUB:
+    {
+        float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
+        float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]);
+        float t = a - b;
+        r = REINTERPRET_CAST(uint32_t, t);
+        latency = LATENCY_FSUB;
+        D_EXEC(qemu_log("SUB a=%f b=%f t=%f, r=%08x\n", a, b, t, r));
+    } break;
+    case OP_FMUL:
+    {
+        float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
+        float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]);
+        float t = a * b;
+        r = REINTERPRET_CAST(uint32_t, t);
+        latency = LATENCY_FMUL;
+        D_EXEC(qemu_log("MUL a=%f b=%f t=%f, r=%08x\n", a, b, t, r));
+    } break;
+    case OP_FABS:
+    {
+        float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
+        float t = fabsf(a);
+        r = REINTERPRET_CAST(uint32_t, t);
+        latency = LATENCY_FABS;
+        D_EXEC(qemu_log("ABS a=%f t=%f, r=%08x\n", a, t, r));
+    } break;
+    case OP_F2I:
+    {
+        float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
+        int32_t t = a;
+        r = REINTERPRET_CAST(uint32_t, t);
+        latency = LATENCY_F2I;
+        D_EXEC(qemu_log("F2I a=%f t=%d, r=%08x\n", a, t, r));
+    } break;
+    case OP_I2F:
+    {
+        int32_t a = REINTERPRET_CAST(int32_t, s->gp_regs[reg_a]);
+        float t = a;
+        r = REINTERPRET_CAST(uint32_t, t);
+        latency = LATENCY_I2F;
+        D_EXEC(qemu_log("I2F a=%08x t=%f, r=%08x\n", a, t, r));
+    } break;
+    case OP_VECTOUT:
+    {
+        uint32_t a = cpu_to_be32(s->gp_regs[reg_a]);
+        uint32_t b = cpu_to_be32(s->gp_regs[reg_b]);
+        target_phys_addr_t dma_ptr =
+            get_dma_address(s->regs[R_MESHBASE],
+                    s->gp_regs[GPR_X], s->gp_regs[GPR_Y]);
+        cpu_physical_memory_write(dma_ptr, (uint8_t *)&a, 4);
+        cpu_physical_memory_write(dma_ptr + 4, (uint8_t *)&b, 4);
+        s->regs[R_LASTDMA] = dma_ptr + 4;
+        D_EXEC(qemu_log("VECTOUT a=%08x b=%08x dma=%08x\n", a, b, dma_ptr));
+        trace_milkymist_pfpu_vectout(a, b, dma_ptr);
+    } break;
+    case OP_SIN:
+    {
+        int32_t a = REINTERPRET_CAST(int32_t, s->gp_regs[reg_a]);
+        float t = sinf(a * (1.0f / (M_PI * 4096.0f)));
+        r = REINTERPRET_CAST(uint32_t, t);
+        latency = LATENCY_SIN;
+        D_EXEC(qemu_log("SIN a=%d t=%f, r=%08x\n", a, t, r));
+    } break;
+    case OP_COS:
+    {
+        int32_t a = REINTERPRET_CAST(int32_t, s->gp_regs[reg_a]);
+        float t = cosf(a * (1.0f / (M_PI * 4096.0f)));
+        r = REINTERPRET_CAST(uint32_t, t);
+        latency = LATENCY_COS;
+        D_EXEC(qemu_log("COS a=%d t=%f, r=%08x\n", a, t, r));
+    } break;
+    case OP_ABOVE:
+    {
+        float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
+        float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]);
+        float t = (a > b) ? 1.0f : 0.0f;
+        r = REINTERPRET_CAST(uint32_t, t);
+        latency = LATENCY_ABOVE;
+        D_EXEC(qemu_log("ABOVE a=%f b=%f t=%f, r=%08x\n", a, b, t, r));
+    } break;
+    case OP_EQUAL:
+    {
+        float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
+        float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]);
+        float t = (a == b) ? 1.0f : 0.0f;
+        r = REINTERPRET_CAST(uint32_t, t);
+        latency = LATENCY_EQUAL;
+        D_EXEC(qemu_log("EQUAL a=%f b=%f t=%f, r=%08x\n", a, b, t, r));
+    } break;
+    case OP_COPY:
+    {
+        r = s->gp_regs[reg_a];
+        latency = LATENCY_COPY;
+        D_EXEC(qemu_log("COPY"));
+    } break;
+    case OP_IF:
+    {
+        float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
+        float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]);
+        uint32_t f = s->gp_regs[GPR_FLAGS];
+        float t = (f != 0) ? a : b;
+        r = REINTERPRET_CAST(uint32_t, t);
+        latency = LATENCY_IF;
+        D_EXEC(qemu_log("IF f=%u a=%f b=%f t=%f, r=%08x\n", f, a, b, t, r));
+    } break;
+    case OP_TSIGN:
+    {
+        float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
+        float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]);
+        float t = (b < 0) ? -a : a;
+        r = REINTERPRET_CAST(uint32_t, t);
+        latency = LATENCY_TSIGN;
+        D_EXEC(qemu_log("TSIGN a=%f b=%f t=%f, r=%08x\n", a, b, t, r));
+    } break;
+    case OP_QUAKE:
+    {
+        uint32_t a = s->gp_regs[reg_a];
+        r = 0x5f3759df - (a >> 1);
+        latency = LATENCY_QUAKE;
+        D_EXEC(qemu_log("QUAKE a=%d r=%08x\n", a, r));
+    } break;
+
+    default:
+        error_report("milkymist_pfpu: unknown opcode %d\n", op);
+        break;
+    }
+
+    if (!reg_d) {
+        D_EXEC(qemu_log("%04d %8s R%03d, R%03d <L=%d, E=%04d>\n",
+                    s->regs[R_PC], opcode_to_str[op], reg_a, reg_b, latency,
+                    s->regs[R_PC] + latency));
+    } else {
+        D_EXEC(qemu_log("%04d %8s R%03d, R%03d <L=%d, E=%04d> -> R%03d\n",
+                    s->regs[R_PC], opcode_to_str[op], reg_a, reg_b, latency,
+                    s->regs[R_PC] + latency, reg_d));
+    }
+
+    if (op == OP_VECTOUT) {
+        return 0;
+    }
+
+    /* store output for this cycle */
+    if (reg_d) {
+        uint32_t val = output_queue_remove(s);
+        D_EXEC(qemu_log("R%03d <- 0x%08x\n", reg_d, val));
+        s->gp_regs[reg_d] = val;
+    }
+
+    output_queue_advance(s);
+
+    /* store op output */
+    if (op != OP_NOP) {
+        output_queue_insert(s, r, latency-1);
+    }
+
+    /* advance PC */
+    s->regs[R_PC]++;
+
+    return 1;
+};
+
+static void pfpu_start(MilkymistPFPUState *s)
+{
+    int x, y;
+    int i;
+
+    for (y = 0; y <= s->regs[R_VMESHLAST]; y++) {
+        for (x = 0; x <= s->regs[R_HMESHLAST]; x++) {
+            D_EXEC(qemu_log("\nprocessing x=%d y=%d\n", x, y));
+
+            /* set current position */
+            s->gp_regs[GPR_X] = x;
+            s->gp_regs[GPR_Y] = y;
+
+            /* run microcode on this position */
+            i = 0;
+            while (pfpu_decode_insn(s)) {
+                /* decode at most MICROCODE_WORDS instructions */
+                if (i++ >= MICROCODE_WORDS) {
+                    error_report("milkymist_pfpu: too many instructions "
+                            "executed in microcode. No VECTOUT?\n");
+                    break;
+                }
+            }
+
+            /* reset pc for next run */
+            s->regs[R_PC] = 0;
+        }
+    }
+
+    s->regs[R_VERTICES] = x * y;
+
+    trace_milkymist_pfpu_pulse_irq();
+    qemu_irq_pulse(s->irq);
+}
+
+static inline int get_microcode_address(MilkymistPFPUState *s, uint32_t addr)
+{
+    return (512 * s->regs[R_CODEPAGE]) + addr - MICROCODE_BEGIN;
+}
+
+static uint32_t pfpu_read(void *opaque, target_phys_addr_t addr)
+{
+    MilkymistPFPUState *s = opaque;
+    uint32_t r = 0;
+
+    addr >>= 2;
+    switch (addr) {
+    case R_CTL:
+    case R_MESHBASE:
+    case R_HMESHLAST:
+    case R_VMESHLAST:
+    case R_CODEPAGE:
+    case R_VERTICES:
+    case R_COLLISIONS:
+    case R_STRAYWRITES:
+    case R_LASTDMA:
+    case R_PC:
+    case R_DREGBASE:
+    case R_CODEBASE:
+        r = s->regs[addr];
+        break;
+    case GPR_BEGIN ... GPR_END:
+        r = s->gp_regs[addr - GPR_BEGIN];
+        break;
+    case MICROCODE_BEGIN ...  MICROCODE_END:
+        r = s->microcode[get_microcode_address(s, addr)];
+        break;
+
+    default:
+        error_report("milkymist_pfpu: read access to unknown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+
+    trace_milkymist_pfpu_memory_read(addr << 2, r);
+
+    return r;
+}
+
+static void
+pfpu_write(void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    MilkymistPFPUState *s = opaque;
+
+    trace_milkymist_pfpu_memory_write(addr, value);
+
+    addr >>= 2;
+    switch (addr) {
+    case R_CTL:
+        if (value & CTL_START_BUSY) {
+            pfpu_start(s);
+        }
+        break;
+    case R_MESHBASE:
+    case R_HMESHLAST:
+    case R_VMESHLAST:
+    case R_CODEPAGE:
+    case R_VERTICES:
+    case R_COLLISIONS:
+    case R_STRAYWRITES:
+    case R_LASTDMA:
+    case R_PC:
+    case R_DREGBASE:
+    case R_CODEBASE:
+        s->regs[addr] = value;
+        break;
+    case GPR_BEGIN ...  GPR_END:
+        s->gp_regs[addr - GPR_BEGIN] = value;
+        break;
+    case MICROCODE_BEGIN ...  MICROCODE_END:
+        s->microcode[get_microcode_address(s, addr)] = value;
+        break;
+
+    default:
+        error_report("milkymist_pfpu: write access to unknown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+}
+
+static CPUReadMemoryFunc * const pfpu_read_fn[] = {
+    NULL,
+    NULL,
+    &pfpu_read,
+};
+
+static CPUWriteMemoryFunc * const pfpu_write_fn[] = {
+    NULL,
+    NULL,
+    &pfpu_write,
+};
+
+static void milkymist_pfpu_reset(DeviceState *d)
+{
+    MilkymistPFPUState *s = container_of(d, MilkymistPFPUState, busdev.qdev);
+    int i;
+
+    for (i = 0; i < R_MAX; i++) {
+        s->regs[i] = 0;
+    }
+    for (i = 0; i < 128; i++) {
+        s->gp_regs[i] = 0;
+    }
+    for (i = 0; i < MICROCODE_WORDS; i++) {
+        s->microcode[i] = 0;
+    }
+    s->output_queue_pos = 0;
+    for (i = 0; i < MAX_LATENCY; i++) {
+        s->output_queue[i] = 0;
+    }
+}
+
+static int milkymist_pfpu_init(SysBusDevice *dev)
+{
+    MilkymistPFPUState *s = FROM_SYSBUS(typeof(*s), dev);
+    int pfpu_regs;
+
+    sysbus_init_irq(dev, &s->irq);
+
+    pfpu_regs = cpu_register_io_memory(pfpu_read_fn, pfpu_write_fn, s,
+            DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, MICROCODE_END * 4, pfpu_regs);
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_milkymist_pfpu = {
+    .name = "milkymist-pfpu",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(regs, MilkymistPFPUState, R_MAX),
+        VMSTATE_UINT32_ARRAY(gp_regs, MilkymistPFPUState, 128),
+        VMSTATE_UINT32_ARRAY(microcode, MilkymistPFPUState, MICROCODE_WORDS),
+        VMSTATE_INT32(output_queue_pos, MilkymistPFPUState),
+        VMSTATE_UINT32_ARRAY(output_queue, MilkymistPFPUState, MAX_LATENCY),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static SysBusDeviceInfo milkymist_pfpu_info = {
+    .init = milkymist_pfpu_init,
+    .qdev.name  = "milkymist-pfpu",
+    .qdev.size  = sizeof(MilkymistPFPUState),
+    .qdev.vmsd  = &vmstate_milkymist_pfpu,
+    .qdev.reset = milkymist_pfpu_reset,
+};
+
+static void milkymist_pfpu_register(void)
+{
+    sysbus_register_withprop(&milkymist_pfpu_info);
+}
+
+device_init(milkymist_pfpu_register)
diff --git a/trace-events b/trace-events
index 2becf85afd..b3fa971d2d 100644
--- a/trace-events
+++ b/trace-events
@@ -318,3 +318,9 @@ disable milkymist_minimac_drop_rx_frame(const void *buf) "buf %p"
 disable milkymist_minimac_rx_transfer(const void *buf, uint32_t length) "buf %p length %d"
 disable milkymist_minimac_pulse_irq_rx(void) "Pulse IRQ RX"
 disable milkymist_minimac_pulse_irq_tx(void) "Pulse IRQ TX"
+
+# hw/milkymist-pfpu.c
+disable milkymist_pfpu_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_pfpu_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_pfpu_vectout(uint32_t a, uint32_t b, uint32_t dma_ptr) "a %08x b %08x dma_ptr %08x"
+disable milkymist_pfpu_pulse_irq(void) "Pulse IRQ"

From 87a381ec341bd0195db0531db10f29d603eff49a Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Mon, 7 Mar 2011 23:32:37 +0100
Subject: [PATCH 085/386] lm32: add Milkymist SoftUSB support

This patch adds support for Milkymist's SoftUSB core. This model differ
from the real hardware in its functionality. The real hardware consits of a
tiny freely programmable microcontroller which controls the USB ports. For
simplicity reasons, this model emulates only keyboard and mouse input
devices, eg. input events translates directly to the corresponding expected
messages.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 Makefile.target        |   1 +
 hw/milkymist-softusb.c | 357 +++++++++++++++++++++++++++++++++++++++++
 trace-events           |   8 +
 3 files changed, 366 insertions(+)
 create mode 100644 hw/milkymist-softusb.c

diff --git a/Makefile.target b/Makefile.target
index 0a87446f15..8924626c30 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -272,6 +272,7 @@ obj-lm32-y += milkymist-hpdmc.o
 obj-lm32-y += milkymist-memcard.o
 obj-lm32-y += milkymist-minimac.o
 obj-lm32-y += milkymist-pfpu.o
+obj-lm32-y += milkymist-softusb.o
 
 obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o
 obj-mips-y += mips_addr.o mips_timer.o mips_int.o
diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c
new file mode 100644
index 0000000000..1565260279
--- /dev/null
+++ b/hw/milkymist-softusb.c
@@ -0,0 +1,357 @@
+/*
+ *  QEMU model of the Milkymist SoftUSB block.
+ *
+ *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Specification available at:
+ *   not available yet
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "trace.h"
+#include "console.h"
+#include "usb.h"
+#include "qemu-error.h"
+
+enum {
+    R_CTRL = 0,
+    R_MAX
+};
+
+enum {
+    CTRL_RESET = (1<<0),
+};
+
+#define COMLOC_DEBUG_PRODUCE 0x1000
+#define COMLOC_DEBUG_BASE    0x1001
+#define COMLOC_MEVT_PRODUCE  0x1101
+#define COMLOC_MEVT_BASE     0x1102
+#define COMLOC_KEVT_PRODUCE  0x1142
+#define COMLOC_KEVT_BASE     0x1143
+
+struct MilkymistSoftUsbState {
+    SysBusDevice busdev;
+    USBBus usbbus;
+    USBPort usbport[2];
+    USBDevice *usbdev;
+
+    qemu_irq irq;
+
+    /* device properties */
+    uint32_t pmem_base;
+    uint32_t pmem_size;
+    uint32_t dmem_base;
+    uint32_t dmem_size;
+
+    /* device registers */
+    uint32_t regs[R_MAX];
+
+    /* mouse state */
+    int mouse_dx;
+    int mouse_dy;
+    int mouse_dz;
+    uint8_t mouse_buttons_state;
+
+    /* keyboard state */
+    uint8_t kbd_usb_buffer[8];
+};
+typedef struct MilkymistSoftUsbState MilkymistSoftUsbState;
+
+static uint32_t softusb_read(void *opaque, target_phys_addr_t addr)
+{
+    MilkymistSoftUsbState *s = opaque;
+    uint32_t r = 0;
+
+    addr >>= 2;
+    switch (addr) {
+    case R_CTRL:
+        r = s->regs[addr];
+        break;
+
+    default:
+        error_report("milkymist_softusb: read access to unknown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+
+    trace_milkymist_softusb_memory_read(addr << 2, r);
+
+    return r;
+}
+
+static void
+softusb_write(void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    MilkymistSoftUsbState *s = opaque;
+
+    trace_milkymist_softusb_memory_write(addr, value);
+
+    addr >>= 2;
+    switch (addr) {
+    case R_CTRL:
+        s->regs[addr] = value;
+        break;
+
+    default:
+        error_report("milkymist_softusb: write access to unknown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+}
+
+static CPUReadMemoryFunc * const softusb_read_fn[] = {
+    NULL,
+    NULL,
+    &softusb_read,
+};
+
+static CPUWriteMemoryFunc * const softusb_write_fn[] = {
+    NULL,
+    NULL,
+    &softusb_write,
+};
+
+static inline void softusb_read_dmem(MilkymistSoftUsbState *s,
+        uint32_t offset, uint8_t *buf, uint32_t len)
+{
+    if (offset + len >= s->dmem_size) {
+        error_report("milkymist_softusb: read dmem out of bounds "
+                "at offset 0x%x, len %d\n", offset, len);
+        return;
+    }
+
+    cpu_physical_memory_read(s->dmem_base + offset, buf, len);
+}
+
+static inline void softusb_write_dmem(MilkymistSoftUsbState *s,
+        uint32_t offset, uint8_t *buf, uint32_t len)
+{
+    if (offset + len >= s->dmem_size) {
+        error_report("milkymist_softusb: write dmem out of bounds "
+                "at offset 0x%x, len %d\n", offset, len);
+        return;
+    }
+
+    cpu_physical_memory_write(s->dmem_base + offset, buf, len);
+}
+
+static inline void softusb_read_pmem(MilkymistSoftUsbState *s,
+        uint32_t offset, uint8_t *buf, uint32_t len)
+{
+    if (offset + len >= s->pmem_size) {
+        error_report("milkymist_softusb: read pmem out of bounds "
+                "at offset 0x%x, len %d\n", offset, len);
+        return;
+    }
+
+    cpu_physical_memory_read(s->pmem_base + offset, buf, len);
+}
+
+static inline void softusb_write_pmem(MilkymistSoftUsbState *s,
+        uint32_t offset, uint8_t *buf, uint32_t len)
+{
+    if (offset + len >= s->pmem_size) {
+        error_report("milkymist_softusb: write pmem out of bounds "
+                "at offset 0x%x, len %d\n", offset, len);
+        return;
+    }
+
+    cpu_physical_memory_write(s->pmem_base + offset, buf, len);
+}
+
+static void softusb_mouse_changed(MilkymistSoftUsbState *s)
+{
+    uint8_t m;
+    uint8_t buf[4];
+
+    buf[0] = s->mouse_buttons_state;
+    buf[1] = s->mouse_dx;
+    buf[2] = s->mouse_dy;
+    buf[3] = s->mouse_dz;
+
+    softusb_read_dmem(s, COMLOC_MEVT_PRODUCE, &m, 1);
+    trace_milkymist_softusb_mevt(m);
+    softusb_write_dmem(s, COMLOC_MEVT_BASE + 4 * m, buf, 4);
+    m = (m + 1) & 0xf;
+    softusb_write_dmem(s, COMLOC_MEVT_PRODUCE, &m, 1);
+
+    trace_milkymist_softusb_pulse_irq();
+    qemu_irq_pulse(s->irq);
+}
+
+static void softusb_kbd_changed(MilkymistSoftUsbState *s)
+{
+    uint8_t m;
+
+    softusb_read_dmem(s, COMLOC_KEVT_PRODUCE, &m, 1);
+    trace_milkymist_softusb_kevt(m);
+    softusb_write_dmem(s, COMLOC_KEVT_BASE + 8 * m, s->kbd_usb_buffer, 8);
+    m = (m + 1) & 0x7;
+    softusb_write_dmem(s, COMLOC_KEVT_PRODUCE, &m, 1);
+
+    trace_milkymist_softusb_pulse_irq();
+    qemu_irq_pulse(s->irq);
+}
+
+static void softusb_mouse_event(void *opaque,
+       int dx, int dy, int dz, int buttons_state)
+{
+    MilkymistSoftUsbState *s = opaque;
+
+    /* if device is in reset, do nothing */
+    if (s->regs[R_CTRL] & CTRL_RESET) {
+        return;
+    }
+
+    trace_milkymist_softusb_mouse_event(dx, dy, dz, buttons_state);
+
+    s->mouse_dx = dx;
+    s->mouse_dy = dy;
+    s->mouse_dz = dz;
+    s->mouse_buttons_state = buttons_state;
+
+    softusb_mouse_changed(s);
+}
+
+static void softusb_usbdev_datain(void *opaque)
+{
+    MilkymistSoftUsbState *s = opaque;
+
+    USBPacket p;
+
+    p.pid = USB_TOKEN_IN;
+    p.devep = 1;
+    p.data = s->kbd_usb_buffer;
+    p.len = sizeof(s->kbd_usb_buffer);
+    s->usbdev->info->handle_data(s->usbdev, &p);
+
+    softusb_kbd_changed(s);
+}
+
+static void softusb_attach(USBPort *port)
+{
+}
+
+static USBPortOps softusb_ops = {
+    .attach = softusb_attach,
+};
+
+static void milkymist_softusb_reset(DeviceState *d)
+{
+    MilkymistSoftUsbState *s =
+            container_of(d, MilkymistSoftUsbState, busdev.qdev);
+    int i;
+
+    for (i = 0; i < R_MAX; i++) {
+        s->regs[i] = 0;
+    }
+    s->mouse_dx = 0;
+    s->mouse_dy = 0;
+    s->mouse_dz = 0;
+    s->mouse_buttons_state = 0;
+    memset(s->kbd_usb_buffer, 0, sizeof(s->kbd_usb_buffer));
+
+    /* defaults */
+    s->regs[R_CTRL] = CTRL_RESET;
+}
+
+static int milkymist_softusb_init(SysBusDevice *dev)
+{
+    MilkymistSoftUsbState *s = FROM_SYSBUS(typeof(*s), dev);
+    int softusb_regs;
+    ram_addr_t pmem_ram;
+    ram_addr_t dmem_ram;
+
+    sysbus_init_irq(dev, &s->irq);
+
+    softusb_regs = cpu_register_io_memory(softusb_read_fn, softusb_write_fn, s,
+            DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, R_MAX * 4, softusb_regs);
+
+    /* register pmem and dmem */
+    pmem_ram = qemu_ram_alloc(NULL, "milkymist_softusb.pmem", s->pmem_size);
+    cpu_register_physical_memory(s->pmem_base, s->pmem_size,
+            pmem_ram | IO_MEM_RAM);
+    dmem_ram = qemu_ram_alloc(NULL, "milkymist_softusb.dmem", s->dmem_size);
+    cpu_register_physical_memory(s->dmem_base, s->dmem_size,
+            dmem_ram | IO_MEM_RAM);
+
+    qemu_add_mouse_event_handler(softusb_mouse_event, s, 0, "Milkymist Mouse");
+
+    /* create our usb bus */
+    usb_bus_new(&s->usbbus, NULL);
+
+    /* our two ports */
+    usb_register_port(&s->usbbus, &s->usbport[0], NULL, 0, &softusb_ops,
+            USB_SPEED_MASK_LOW);
+    usb_register_port(&s->usbbus, &s->usbport[1], NULL, 1, &softusb_ops,
+            USB_SPEED_MASK_LOW);
+
+    /* and finally create an usb keyboard */
+    s->usbdev = usb_create_simple(&s->usbbus, "usb-kbd");
+    usb_hid_datain_cb(s->usbdev, s, softusb_usbdev_datain);
+    s->usbdev->info->handle_reset(s->usbdev);
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_milkymist_softusb = {
+    .name = "milkymist-softusb",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(regs, MilkymistSoftUsbState, R_MAX),
+        VMSTATE_INT32(mouse_dx, MilkymistSoftUsbState),
+        VMSTATE_INT32(mouse_dy, MilkymistSoftUsbState),
+        VMSTATE_INT32(mouse_dz, MilkymistSoftUsbState),
+        VMSTATE_UINT8(mouse_buttons_state, MilkymistSoftUsbState),
+        VMSTATE_BUFFER(kbd_usb_buffer, MilkymistSoftUsbState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static SysBusDeviceInfo milkymist_softusb_info = {
+    .init = milkymist_softusb_init,
+    .qdev.name  = "milkymist-softusb",
+    .qdev.size  = sizeof(MilkymistSoftUsbState),
+    .qdev.vmsd  = &vmstate_milkymist_softusb,
+    .qdev.reset = milkymist_softusb_reset,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT32(
+                "pmem_base", MilkymistSoftUsbState, pmem_base, 0xa0000000
+        ),
+        DEFINE_PROP_UINT32(
+                "pmem_size", MilkymistSoftUsbState, pmem_size, 0x00001000
+        ),
+        DEFINE_PROP_UINT32(
+                "dmem_base", MilkymistSoftUsbState, dmem_base, 0xa0020000
+        ),
+        DEFINE_PROP_UINT32(
+                "dmem_size", MilkymistSoftUsbState, dmem_size, 0x00002000
+        ),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
+static void milkymist_softusb_register(void)
+{
+    sysbus_register_withprop(&milkymist_softusb_info);
+}
+
+device_init(milkymist_softusb_register)
diff --git a/trace-events b/trace-events
index b3fa971d2d..74cce75eec 100644
--- a/trace-events
+++ b/trace-events
@@ -324,3 +324,11 @@ disable milkymist_pfpu_memory_read(uint32_t addr, uint32_t value) "addr %08x val
 disable milkymist_pfpu_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
 disable milkymist_pfpu_vectout(uint32_t a, uint32_t b, uint32_t dma_ptr) "a %08x b %08x dma_ptr %08x"
 disable milkymist_pfpu_pulse_irq(void) "Pulse IRQ"
+
+# hw/milkymist-softusb.c
+disable milkymist_softusb_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_softusb_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_softusb_mevt(uint8_t m) "m %d"
+disable milkymist_softusb_kevt(uint8_t m) "m %d"
+disable milkymist_softusb_mouse_event(int dx, int dy, int dz, int bs) "dx %d dy %d dz %d bs %02x"
+disable milkymist_softusb_pulse_irq(void) "Pulse IRQ"

From 9683242448541b6fb5511421af3d8f0c6cd19477 Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Mon, 7 Mar 2011 23:32:38 +0100
Subject: [PATCH 086/386] lm32: add Milkymist System Controller support

This patch adds support for Milkymist's System Controller core. The model
has the following features:
 - support for shutting down and restarting the board
 - provide two timers and GPIO
 - provide registers for system identification and reading the boards
   capabilities

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 Makefile.target       |   1 +
 hw/milkymist-sysctl.c | 330 ++++++++++++++++++++++++++++++++++++++++++
 trace-events          |  11 ++
 3 files changed, 342 insertions(+)
 create mode 100644 hw/milkymist-sysctl.c

diff --git a/Makefile.target b/Makefile.target
index 8924626c30..c1175652f9 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -273,6 +273,7 @@ obj-lm32-y += milkymist-memcard.o
 obj-lm32-y += milkymist-minimac.o
 obj-lm32-y += milkymist-pfpu.o
 obj-lm32-y += milkymist-softusb.o
+obj-lm32-y += milkymist-sysctl.o
 
 obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o
 obj-mips-y += mips_addr.o mips_timer.o mips_int.o
diff --git a/hw/milkymist-sysctl.c b/hw/milkymist-sysctl.c
new file mode 100644
index 0000000000..eaea543bf3
--- /dev/null
+++ b/hw/milkymist-sysctl.c
@@ -0,0 +1,330 @@
+/*
+ *  QEMU model of the Milkymist System Controller.
+ *
+ *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Specification available at:
+ *   http://www.milkymist.org/socdoc/sysctl.pdf
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "sysemu.h"
+#include "trace.h"
+#include "qemu-timer.h"
+#include "qemu-error.h"
+
+enum {
+    CTRL_ENABLE      = (1<<0),
+    CTRL_AUTORESTART = (1<<1),
+};
+
+enum {
+    ICAP_READY       = (1<<0),
+};
+
+enum {
+    R_GPIO_IN = 0,
+    R_GPIO_OUT,
+    R_GPIO_INTEN,
+    R_RESERVED0,
+    R_TIMER0_CONTROL,
+    R_TIMER0_COMPARE,
+    R_TIMER0_COUNTER,
+    R_RESERVED1,
+    R_TIMER1_CONTROL,
+    R_TIMER1_COMPARE,
+    R_TIMER1_COUNTER,
+    R_RESERVED2,
+    R_RESERVED3,
+    R_ICAP,
+    R_CAPABILITIES,
+    R_SYSTEM_ID,
+    R_MAX
+};
+
+struct MilkymistSysctlState {
+    SysBusDevice busdev;
+
+    QEMUBH *bh0;
+    QEMUBH *bh1;
+    ptimer_state *ptimer0;
+    ptimer_state *ptimer1;
+
+    uint32_t freq_hz;
+    uint32_t capabilities;
+    uint32_t systemid;
+    uint32_t strappings;
+
+    uint32_t regs[R_MAX];
+
+    qemu_irq gpio_irq;
+    qemu_irq timer0_irq;
+    qemu_irq timer1_irq;
+};
+typedef struct MilkymistSysctlState MilkymistSysctlState;
+
+static void sysctl_icap_write(MilkymistSysctlState *s, uint32_t value)
+{
+    trace_milkymist_sysctl_icap_write(value);
+    switch (value & 0xffff) {
+    case 0x000e:
+        qemu_system_shutdown_request();
+        break;
+    }
+}
+
+static uint32_t sysctl_read(void *opaque, target_phys_addr_t addr)
+{
+    MilkymistSysctlState *s = opaque;
+    uint32_t r = 0;
+
+    addr >>= 2;
+    switch (addr) {
+    case R_TIMER0_COUNTER:
+        r = (uint32_t)ptimer_get_count(s->ptimer0);
+        /* milkymist timer counts up */
+        r = s->regs[R_TIMER0_COMPARE] - r;
+        break;
+    case R_TIMER1_COUNTER:
+        r = (uint32_t)ptimer_get_count(s->ptimer1);
+        /* milkymist timer counts up */
+        r = s->regs[R_TIMER1_COMPARE] - r;
+        break;
+    case R_GPIO_IN:
+    case R_GPIO_OUT:
+    case R_GPIO_INTEN:
+    case R_TIMER0_CONTROL:
+    case R_TIMER0_COMPARE:
+    case R_TIMER1_CONTROL:
+    case R_TIMER1_COMPARE:
+    case R_ICAP:
+    case R_CAPABILITIES:
+    case R_SYSTEM_ID:
+        r = s->regs[addr];
+        break;
+
+    default:
+        error_report("milkymist_sysctl: read access to unkown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+
+    trace_milkymist_sysctl_memory_read(addr << 2, r);
+
+    return r;
+}
+
+static void sysctl_write(void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    MilkymistSysctlState *s = opaque;
+
+    trace_milkymist_sysctl_memory_write(addr, value);
+
+    addr >>= 2;
+    switch (addr) {
+    case R_GPIO_OUT:
+    case R_GPIO_INTEN:
+    case R_TIMER0_COUNTER:
+        if (value > s->regs[R_TIMER0_COUNTER]) {
+            value = s->regs[R_TIMER0_COUNTER];
+            error_report("milkymist_sysctl: timer0: trying to write a "
+                    "value greater than the limit. Clipping.");
+        }
+        /* milkymist timer counts up */
+        value = s->regs[R_TIMER0_COUNTER] - value;
+        ptimer_set_count(s->ptimer0, value);
+        break;
+    case R_TIMER1_COUNTER:
+        if (value > s->regs[R_TIMER1_COUNTER]) {
+            value = s->regs[R_TIMER1_COUNTER];
+            error_report("milkymist_sysctl: timer1: trying to write a "
+                    "value greater than the limit. Clipping.");
+        }
+        /* milkymist timer counts up */
+        value = s->regs[R_TIMER1_COUNTER] - value;
+        ptimer_set_count(s->ptimer1, value);
+        break;
+    case R_TIMER0_COMPARE:
+        ptimer_set_limit(s->ptimer0, value, 0);
+        s->regs[addr] = value;
+        break;
+    case R_TIMER1_COMPARE:
+        ptimer_set_limit(s->ptimer1, value, 0);
+        s->regs[addr] = value;
+        break;
+    case R_TIMER0_CONTROL:
+        s->regs[addr] = value;
+        if (s->regs[R_TIMER0_CONTROL] & CTRL_ENABLE) {
+            trace_milkymist_sysctl_start_timer1();
+            ptimer_run(s->ptimer0, 0);
+        } else {
+            trace_milkymist_sysctl_stop_timer1();
+            ptimer_stop(s->ptimer0);
+        }
+        break;
+    case R_TIMER1_CONTROL:
+        s->regs[addr] = value;
+        if (s->regs[R_TIMER1_CONTROL] & CTRL_ENABLE) {
+            trace_milkymist_sysctl_start_timer1();
+            ptimer_run(s->ptimer1, 0);
+        } else {
+            trace_milkymist_sysctl_stop_timer1();
+            ptimer_stop(s->ptimer1);
+        }
+        break;
+    case R_ICAP:
+        sysctl_icap_write(s, value);
+        break;
+    case R_SYSTEM_ID:
+        qemu_system_reset_request();
+        break;
+
+    case R_GPIO_IN:
+    case R_CAPABILITIES:
+        error_report("milkymist_sysctl: write to read-only register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+
+    default:
+        error_report("milkymist_sysctl: write access to unkown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+}
+
+static CPUReadMemoryFunc * const sysctl_read_fn[] = {
+    NULL,
+    NULL,
+    &sysctl_read,
+};
+
+static CPUWriteMemoryFunc * const sysctl_write_fn[] = {
+    NULL,
+    NULL,
+    &sysctl_write,
+};
+
+static void timer0_hit(void *opaque)
+{
+    MilkymistSysctlState *s = opaque;
+
+    if (!(s->regs[R_TIMER0_CONTROL] & CTRL_AUTORESTART)) {
+        s->regs[R_TIMER0_CONTROL] &= ~CTRL_ENABLE;
+        trace_milkymist_sysctl_stop_timer0();
+        ptimer_stop(s->ptimer0);
+    }
+
+    trace_milkymist_sysctl_pulse_irq_timer0();
+    qemu_irq_pulse(s->timer0_irq);
+}
+
+static void timer1_hit(void *opaque)
+{
+    MilkymistSysctlState *s = opaque;
+
+    if (!(s->regs[R_TIMER1_CONTROL] & CTRL_AUTORESTART)) {
+        s->regs[R_TIMER1_CONTROL] &= ~CTRL_ENABLE;
+        trace_milkymist_sysctl_stop_timer1();
+        ptimer_stop(s->ptimer1);
+    }
+
+    trace_milkymist_sysctl_pulse_irq_timer1();
+    qemu_irq_pulse(s->timer1_irq);
+}
+
+static void milkymist_sysctl_reset(DeviceState *d)
+{
+    MilkymistSysctlState *s =
+            container_of(d, MilkymistSysctlState, busdev.qdev);
+    int i;
+
+    for (i = 0; i < R_MAX; i++) {
+        s->regs[i] = 0;
+    }
+
+    ptimer_stop(s->ptimer0);
+    ptimer_stop(s->ptimer1);
+
+    /* defaults */
+    s->regs[R_ICAP] = ICAP_READY;
+    s->regs[R_SYSTEM_ID] = s->systemid;
+    s->regs[R_CAPABILITIES] = s->capabilities;
+    s->regs[R_GPIO_IN] = s->strappings;
+}
+
+static int milkymist_sysctl_init(SysBusDevice *dev)
+{
+    MilkymistSysctlState *s = FROM_SYSBUS(typeof(*s), dev);
+    int sysctl_regs;
+
+    sysbus_init_irq(dev, &s->gpio_irq);
+    sysbus_init_irq(dev, &s->timer0_irq);
+    sysbus_init_irq(dev, &s->timer1_irq);
+
+    s->bh0 = qemu_bh_new(timer0_hit, s);
+    s->bh1 = qemu_bh_new(timer1_hit, s);
+    s->ptimer0 = ptimer_init(s->bh0);
+    s->ptimer1 = ptimer_init(s->bh1);
+    ptimer_set_freq(s->ptimer0, s->freq_hz);
+    ptimer_set_freq(s->ptimer1, s->freq_hz);
+
+    sysctl_regs = cpu_register_io_memory(sysctl_read_fn, sysctl_write_fn, s,
+            DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, R_MAX * 4, sysctl_regs);
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_milkymist_sysctl = {
+    .name = "milkymist-sysctl",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(regs, MilkymistSysctlState, R_MAX),
+        VMSTATE_PTIMER(ptimer0, MilkymistSysctlState),
+        VMSTATE_PTIMER(ptimer1, MilkymistSysctlState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static SysBusDeviceInfo milkymist_sysctl_info = {
+    .init = milkymist_sysctl_init,
+    .qdev.name  = "milkymist-sysctl",
+    .qdev.size  = sizeof(MilkymistSysctlState),
+    .qdev.vmsd  = &vmstate_milkymist_sysctl,
+    .qdev.reset = milkymist_sysctl_reset,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT32("frequency", MilkymistSysctlState,
+                freq_hz, 80000000),
+        DEFINE_PROP_UINT32("capabilities", MilkymistSysctlState,
+                capabilities, 0x00000000),
+        DEFINE_PROP_UINT32("systemid", MilkymistSysctlState,
+                systemid, 0x10014d31),
+        DEFINE_PROP_UINT32("gpio_strappings", MilkymistSysctlState,
+                strappings, 0x00000001),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
+static void milkymist_sysctl_register(void)
+{
+    sysbus_register_withprop(&milkymist_sysctl_info);
+}
+
+device_init(milkymist_sysctl_register)
diff --git a/trace-events b/trace-events
index 74cce75eec..f6fc40397b 100644
--- a/trace-events
+++ b/trace-events
@@ -332,3 +332,14 @@ disable milkymist_softusb_mevt(uint8_t m) "m %d"
 disable milkymist_softusb_kevt(uint8_t m) "m %d"
 disable milkymist_softusb_mouse_event(int dx, int dy, int dz, int bs) "dx %d dy %d dz %d bs %02x"
 disable milkymist_softusb_pulse_irq(void) "Pulse IRQ"
+
+# hw/milkymist-sysctl.c
+disable milkymist_sysctl_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_sysctl_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_sysctl_icap_write(uint32_t value) "value %08x"
+disable milkymist_sysctl_start_timer0(void) "Start timer0"
+disable milkymist_sysctl_stop_timer0(void) "Stop timer0"
+disable milkymist_sysctl_start_timer1(void) "Start timer1"
+disable milkymist_sysctl_stop_timer1(void) "Stop timer1"
+disable milkymist_sysctl_pulse_irq_timer0(void) "Pulse IRQ Timer0"
+disable milkymist_sysctl_pulse_irq_timer1(void) "Pulse IRQ Timer1"

From 20ff075bb3340c5278a0da38ad1f4d602565aa06 Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Mon, 7 Mar 2011 23:32:39 +0100
Subject: [PATCH 087/386] configure: add opengl detection

This patch introduce a new config option CONFIG_OPENGL.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 configure | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/configure b/configure
index 2e7b4f8718..faaed60540 100755
--- a/configure
+++ b/configure
@@ -720,6 +720,10 @@ for opt do
   ;;
   --enable-vhost-net) vhost_net="yes"
   ;;
+  --disable-opengl) opengl="no"
+  ;;
+  --enable-opengl) opengl="yes"
+  ;;
   --*dir)
   ;;
   --disable-rbd) rbd="no"
@@ -1944,6 +1948,27 @@ EOF
   fi
 fi
 
+##########################################
+# opengl probe, used by milkymist-tmu2
+if test "$opengl" != "no" ; then
+  opengl_libs="-lGL"
+  cat > $TMPC << EOF
+#include <X11/Xlib.h>
+#include <GL/gl.h>
+#include <GL/glx.h>
+int main(void) { GL_VERSION; return 0; }
+EOF
+  if compile_prog "" "-lGL" ; then
+    opengl=yes
+       libs_softmmu="$opengl_libs $libs_softmmu"
+  else
+    if test "$opengl" = "yes" ; then
+      feature_not_found "opengl"
+    fi
+    opengl=no
+  fi
+fi
+
 #
 # Check for xxxat() functions when we are building linux-user
 # emulator.  This is done because older glibc versions don't
@@ -2582,6 +2607,7 @@ echo "spice support     $spice"
 echo "rbd support       $rbd"
 echo "xfsctl support    $xfs"
 echo "nss used          $smartcard_nss"
+echo "OpenGL support    $opengl"
 
 if test $sdl_too_old = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -2872,6 +2898,10 @@ if test "$smartcard_nss" = "yes" ; then
   echo "CONFIG_SMARTCARD_NSS=y" >> $config_host_mak
 fi
 
+if test "$opengl" = "yes" ; then
+  echo "CONFIG_OPENGL=y" >> $config_host_mak
+fi
+
 # XXX: suppress that
 if [ "$bsd" = "yes" ] ; then
   echo "CONFIG_BSD=y" >> $config_host_mak

From 0670dadd64be8c06d176e797bfc1943ecbce6eb2 Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Mon, 7 Mar 2011 23:32:40 +0100
Subject: [PATCH 088/386] lm32: add Milkymist TMU2 support

This patch adds support for Milkymist's texture mapping unit. For fast
computation this model needs hardware accelerated 3D graphics support
(OpenGL). There is no graphical output, all computations belong to internal
framebuffers only.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 Makefile.target     |   1 +
 hw/milkymist-tmu2.c | 481 ++++++++++++++++++++++++++++++++++++++++++++
 trace-events        |   6 +
 3 files changed, 488 insertions(+)
 create mode 100644 hw/milkymist-tmu2.c

diff --git a/Makefile.target b/Makefile.target
index c1175652f9..6581519064 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -274,6 +274,7 @@ obj-lm32-y += milkymist-minimac.o
 obj-lm32-y += milkymist-pfpu.o
 obj-lm32-y += milkymist-softusb.o
 obj-lm32-y += milkymist-sysctl.o
+obj-lm32-$(CONFIG_OPENGL) += milkymist-tmu2.o
 
 obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o
 obj-mips-y += mips_addr.o mips_timer.o mips_int.o
diff --git a/hw/milkymist-tmu2.c b/hw/milkymist-tmu2.c
new file mode 100644
index 0000000000..9cebe3173b
--- /dev/null
+++ b/hw/milkymist-tmu2.c
@@ -0,0 +1,481 @@
+/*
+ *  QEMU model of the Milkymist texture mapping unit.
+ *
+ *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *  Copyright (c) 2010 Sebastien Bourdeauducq
+ *                       <sebastien.bourdeauducq@lekernel.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Specification available at:
+ *   http://www.milkymist.org/socdoc/tmu2.pdf
+ *
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "trace.h"
+#include "qemu-error.h"
+
+#include <X11/Xlib.h>
+#include <GL/gl.h>
+#include <GL/glx.h>
+
+enum {
+    R_CTL = 0,
+    R_HMESHLAST,
+    R_VMESHLAST,
+    R_BRIGHTNESS,
+    R_CHROMAKEY,
+    R_VERTICESADDR,
+    R_TEXFBUF,
+    R_TEXHRES,
+    R_TEXVRES,
+    R_TEXHMASK,
+    R_TEXVMASK,
+    R_DSTFBUF,
+    R_DSTHRES,
+    R_DSTVRES,
+    R_DSTHOFFSET,
+    R_DSTVOFFSET,
+    R_DSTSQUAREW,
+    R_DSTSQUAREH,
+    R_ALPHA,
+    R_MAX
+};
+
+enum {
+    CTL_START_BUSY  = (1<<0),
+    CTL_CHROMAKEY   = (1<<1),
+};
+
+enum {
+    MAX_BRIGHTNESS = 63,
+    MAX_ALPHA      = 63,
+};
+
+enum {
+    MESH_MAXSIZE = 128,
+};
+
+struct vertex {
+    int x;
+    int y;
+} __attribute__((packed));
+
+struct MilkymistTMU2State {
+    SysBusDevice busdev;
+    CharDriverState *chr;
+    qemu_irq irq;
+
+    uint32_t regs[R_MAX];
+
+    Display *dpy;
+    GLXFBConfig glx_fb_config;
+    GLXContext glx_context;
+};
+typedef struct MilkymistTMU2State MilkymistTMU2State;
+
+static const int glx_fbconfig_attr[] = {
+    GLX_GREEN_SIZE, 5,
+    GLX_GREEN_SIZE, 6,
+    GLX_BLUE_SIZE, 5,
+    None
+};
+
+static int tmu2_glx_init(MilkymistTMU2State *s)
+{
+    GLXFBConfig *configs;
+    int nelements;
+
+    s->dpy = XOpenDisplay(NULL); /* FIXME: call XCloseDisplay() */
+    if (s->dpy == NULL) {
+        return 1;
+    }
+
+    configs = glXChooseFBConfig(s->dpy, 0, glx_fbconfig_attr, &nelements);
+    if (configs == NULL) {
+        return 1;
+    }
+
+    s->glx_fb_config = *configs;
+    XFree(configs);
+
+    /* FIXME: call glXDestroyContext() */
+    s->glx_context = glXCreateNewContext(s->dpy, s->glx_fb_config,
+            GLX_RGBA_TYPE, NULL, 1);
+    if (s->glx_context == NULL) {
+        return 1;
+    }
+
+    return 0;
+}
+
+static void tmu2_gl_map(struct vertex *mesh, int texhres, int texvres,
+        int hmeshlast, int vmeshlast, int ho, int vo, int sw, int sh)
+{
+    int x, y;
+    int x0, y0, x1, y1;
+    int u0, v0, u1, v1, u2, v2, u3, v3;
+    double xscale = 1.0 / ((double)(64 * texhres));
+    double yscale = 1.0 / ((double)(64 * texvres));
+
+    glLoadIdentity();
+    glTranslatef(ho, vo, 0);
+    glEnable(GL_TEXTURE_2D);
+    glBegin(GL_QUADS);
+
+    for (y = 0; y < vmeshlast; y++) {
+        y0 = y * sh;
+        y1 = y0 + sh;
+        for (x = 0; x < hmeshlast; x++) {
+            x0 = x * sw;
+            x1 = x0 + sw;
+
+            u0 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x].x);
+            v0 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x].y);
+            u1 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x + 1].x);
+            v1 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x + 1].y);
+            u2 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x + 1].x);
+            v2 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x + 1].y);
+            u3 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x].x);
+            v3 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x].y);
+
+            glTexCoord2d(((double)u0) * xscale, ((double)v0) * yscale);
+            glVertex3i(x0, y0, 0);
+            glTexCoord2d(((double)u1) * xscale, ((double)v1) * yscale);
+            glVertex3i(x1, y0, 0);
+            glTexCoord2d(((double)u2) * xscale, ((double)v2) * yscale);
+            glVertex3i(x1, y1, 0);
+            glTexCoord2d(((double)u3) * xscale, ((double)v3) * yscale);
+            glVertex3i(x0, y1, 0);
+        }
+    }
+
+    glEnd();
+}
+
+static void tmu2_start(MilkymistTMU2State *s)
+{
+    int pbuffer_attrib[6] = {
+        GLX_PBUFFER_WIDTH,
+        0,
+        GLX_PBUFFER_HEIGHT,
+        0,
+        GLX_PRESERVED_CONTENTS,
+        True
+    };
+
+    GLXPbuffer pbuffer;
+    GLuint texture;
+    void *fb;
+    target_phys_addr_t fb_len;
+    void *mesh;
+    target_phys_addr_t mesh_len;
+    float m;
+
+    trace_milkymist_tmu2_start();
+
+    /* Create and set up a suitable OpenGL context */
+    pbuffer_attrib[1] = s->regs[R_DSTHRES];
+    pbuffer_attrib[3] = s->regs[R_DSTVRES];
+    pbuffer = glXCreatePbuffer(s->dpy, s->glx_fb_config, pbuffer_attrib);
+    glXMakeContextCurrent(s->dpy, pbuffer, pbuffer, s->glx_context);
+
+    /* Fixup endianness. TODO: would it work on BE hosts? */
+    glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
+    glPixelStorei(GL_PACK_SWAP_BYTES, 1);
+
+    /* Row alignment */
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
+    glPixelStorei(GL_PACK_ALIGNMENT, 2);
+
+    /* Read the QEMU source framebuffer into an OpenGL texture */
+    glGenTextures(1, &texture);
+    glBindTexture(GL_TEXTURE_2D, texture);
+    fb_len = 2*s->regs[R_TEXHRES]*s->regs[R_TEXVRES];
+    fb = cpu_physical_memory_map(s->regs[R_TEXFBUF], &fb_len, 0);
+    if (fb == NULL) {
+        glDeleteTextures(1, &texture);
+        glXMakeContextCurrent(s->dpy, None, None, NULL);
+        glXDestroyPbuffer(s->dpy, pbuffer);
+        return;
+    }
+    glTexImage2D(GL_TEXTURE_2D, 0, 3, s->regs[R_TEXHRES], s->regs[R_TEXVRES],
+            0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, fb);
+    cpu_physical_memory_unmap(fb, fb_len, 0, fb_len);
+
+    /* Set up texturing options */
+    /* WARNING:
+     * Many cases of TMU2 masking are not supported by OpenGL.
+     * We only implement the most common ones:
+     *  - full bilinear filtering vs. nearest texel
+     *  - texture clamping vs. texture wrapping
+     */
+    if ((s->regs[R_TEXHMASK] & 0x3f) > 0x20) {
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    } else {
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    }
+    if ((s->regs[R_TEXHMASK] >> 6) & s->regs[R_TEXHRES]) {
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+    } else {
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    }
+    if ((s->regs[R_TEXVMASK] >> 6) & s->regs[R_TEXVRES]) {
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+    } else {
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    }
+
+    /* Translucency and decay */
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    m = (float)(s->regs[R_BRIGHTNESS] + 1) / 64.0f;
+    glColor4f(m, m, m, (float)(s->regs[R_ALPHA] + 1) / 64.0f);
+
+    /* Read the QEMU dest. framebuffer into the OpenGL framebuffer */
+    fb_len = 2 * s->regs[R_DSTHRES] * s->regs[R_DSTVRES];
+    fb = cpu_physical_memory_map(s->regs[R_DSTFBUF], &fb_len, 0);
+    if (fb == NULL) {
+        glDeleteTextures(1, &texture);
+        glXMakeContextCurrent(s->dpy, None, None, NULL);
+        glXDestroyPbuffer(s->dpy, pbuffer);
+        return;
+    }
+
+    glDrawPixels(s->regs[R_DSTHRES], s->regs[R_DSTVRES], GL_RGB,
+            GL_UNSIGNED_SHORT_5_6_5, fb);
+    cpu_physical_memory_unmap(fb, fb_len, 0, fb_len);
+    glViewport(0, 0, s->regs[R_DSTHRES], s->regs[R_DSTVRES]);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrtho(0.0, s->regs[R_DSTHRES], 0.0, s->regs[R_DSTVRES], -1.0, 1.0);
+    glMatrixMode(GL_MODELVIEW);
+
+    /* Map the texture */
+    mesh_len = MESH_MAXSIZE*MESH_MAXSIZE*sizeof(struct vertex);
+    mesh = cpu_physical_memory_map(s->regs[R_VERTICESADDR], &mesh_len, 0);
+    if (mesh == NULL) {
+        glDeleteTextures(1, &texture);
+        glXMakeContextCurrent(s->dpy, None, None, NULL);
+        glXDestroyPbuffer(s->dpy, pbuffer);
+        return;
+    }
+
+    tmu2_gl_map((struct vertex *)mesh,
+        s->regs[R_TEXHRES], s->regs[R_TEXVRES],
+        s->regs[R_HMESHLAST], s->regs[R_VMESHLAST],
+        s->regs[R_DSTHOFFSET], s->regs[R_DSTVOFFSET],
+        s->regs[R_DSTSQUAREW], s->regs[R_DSTSQUAREH]);
+    cpu_physical_memory_unmap(mesh, mesh_len, 0, mesh_len);
+
+    /* Write back the OpenGL framebuffer to the QEMU framebuffer */
+    fb_len = 2 * s->regs[R_DSTHRES] * s->regs[R_DSTVRES];
+    fb = cpu_physical_memory_map(s->regs[R_DSTFBUF], &fb_len, 1);
+    if (fb == NULL) {
+        glDeleteTextures(1, &texture);
+        glXMakeContextCurrent(s->dpy, None, None, NULL);
+        glXDestroyPbuffer(s->dpy, pbuffer);
+        return;
+    }
+
+    glReadPixels(0, 0, s->regs[R_DSTHRES], s->regs[R_DSTVRES], GL_RGB,
+            GL_UNSIGNED_SHORT_5_6_5, fb);
+    cpu_physical_memory_unmap(fb, fb_len, 1, fb_len);
+
+    /* Free OpenGL allocs */
+    glDeleteTextures(1, &texture);
+    glXMakeContextCurrent(s->dpy, None, None, NULL);
+    glXDestroyPbuffer(s->dpy, pbuffer);
+
+    s->regs[R_CTL] &= ~CTL_START_BUSY;
+
+    trace_milkymist_tmu2_pulse_irq();
+    qemu_irq_pulse(s->irq);
+}
+
+static uint32_t tmu2_read(void *opaque, target_phys_addr_t addr)
+{
+    MilkymistTMU2State *s = opaque;
+    uint32_t r = 0;
+
+    addr >>= 2;
+    switch (addr) {
+    case R_CTL:
+    case R_HMESHLAST:
+    case R_VMESHLAST:
+    case R_BRIGHTNESS:
+    case R_CHROMAKEY:
+    case R_VERTICESADDR:
+    case R_TEXFBUF:
+    case R_TEXHRES:
+    case R_TEXVRES:
+    case R_TEXHMASK:
+    case R_TEXVMASK:
+    case R_DSTFBUF:
+    case R_DSTHRES:
+    case R_DSTVRES:
+    case R_DSTHOFFSET:
+    case R_DSTVOFFSET:
+    case R_DSTSQUAREW:
+    case R_DSTSQUAREH:
+    case R_ALPHA:
+        r = s->regs[addr];
+        break;
+
+    default:
+        error_report("milkymist_tmu2: read access to unknown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+
+    trace_milkymist_tmu2_memory_read(addr << 2, r);
+
+    return r;
+}
+
+static void tmu2_check_registers(MilkymistTMU2State *s)
+{
+    if (s->regs[R_BRIGHTNESS] > MAX_BRIGHTNESS) {
+        error_report("milkymist_tmu2: max brightness is %d\n", MAX_BRIGHTNESS);
+    }
+
+    if (s->regs[R_ALPHA] > MAX_ALPHA) {
+        error_report("milkymist_tmu2: max alpha is %d\n", MAX_ALPHA);
+    }
+
+    if (s->regs[R_VERTICESADDR] & 0x07) {
+        error_report("milkymist_tmu2: vertex mesh address has to be 64-bit "
+                "aligned\n");
+    }
+
+    if (s->regs[R_TEXFBUF] & 0x01) {
+        error_report("milkymist_tmu2: texture buffer address has to be "
+                "16-bit aligned\n");
+    }
+}
+
+static void tmu2_write(void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    MilkymistTMU2State *s = opaque;
+
+    trace_milkymist_tmu2_memory_write(addr, value);
+
+    addr >>= 2;
+    switch (addr) {
+    case R_CTL:
+        s->regs[addr] = value;
+        if (value & CTL_START_BUSY) {
+            tmu2_start(s);
+        }
+        break;
+    case R_BRIGHTNESS:
+    case R_HMESHLAST:
+    case R_VMESHLAST:
+    case R_CHROMAKEY:
+    case R_VERTICESADDR:
+    case R_TEXFBUF:
+    case R_TEXHRES:
+    case R_TEXVRES:
+    case R_TEXHMASK:
+    case R_TEXVMASK:
+    case R_DSTFBUF:
+    case R_DSTHRES:
+    case R_DSTVRES:
+    case R_DSTHOFFSET:
+    case R_DSTVOFFSET:
+    case R_DSTSQUAREW:
+    case R_DSTSQUAREH:
+    case R_ALPHA:
+        s->regs[addr] = value;
+        break;
+
+    default:
+        error_report("milkymist_tmu2: write access to unknown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+
+    tmu2_check_registers(s);
+}
+
+static CPUReadMemoryFunc * const tmu2_read_fn[] = {
+    NULL,
+    NULL,
+    &tmu2_read,
+};
+
+static CPUWriteMemoryFunc * const tmu2_write_fn[] = {
+    NULL,
+    NULL,
+    &tmu2_write,
+};
+
+static void milkymist_tmu2_reset(DeviceState *d)
+{
+    MilkymistTMU2State *s = container_of(d, MilkymistTMU2State, busdev.qdev);
+    int i;
+
+    for (i = 0; i < R_MAX; i++) {
+        s->regs[i] = 0;
+    }
+}
+
+static int milkymist_tmu2_init(SysBusDevice *dev)
+{
+    MilkymistTMU2State *s = FROM_SYSBUS(typeof(*s), dev);
+    int tmu2_regs;
+
+    if (tmu2_glx_init(s)) {
+        return 1;
+    }
+
+    sysbus_init_irq(dev, &s->irq);
+
+    tmu2_regs = cpu_register_io_memory(tmu2_read_fn, tmu2_write_fn, s,
+            DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, R_MAX * 4, tmu2_regs);
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_milkymist_tmu2 = {
+    .name = "milkymist-tmu2",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(regs, MilkymistTMU2State, R_MAX),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static SysBusDeviceInfo milkymist_tmu2_info = {
+    .init = milkymist_tmu2_init,
+    .qdev.name  = "milkymist-tmu2",
+    .qdev.size  = sizeof(MilkymistTMU2State),
+    .qdev.vmsd  = &vmstate_milkymist_tmu2,
+    .qdev.reset = milkymist_tmu2_reset,
+};
+
+static void milkymist_tmu2_register(void)
+{
+    sysbus_register_withprop(&milkymist_tmu2_info);
+}
+
+device_init(milkymist_tmu2_register)
diff --git a/trace-events b/trace-events
index f6fc40397b..3a88adfdad 100644
--- a/trace-events
+++ b/trace-events
@@ -343,3 +343,9 @@ disable milkymist_sysctl_start_timer1(void) "Start timer1"
 disable milkymist_sysctl_stop_timer1(void) "Stop timer1"
 disable milkymist_sysctl_pulse_irq_timer0(void) "Pulse IRQ Timer0"
 disable milkymist_sysctl_pulse_irq_timer1(void) "Pulse IRQ Timer1"
+
+# hw/milkymist-tmu2.c
+disable milkymist_tmu2_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_tmu2_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_tmu2_start(void) "Start TMU"
+disable milkymist_tmu2_pulse_irq(void) "Pulse IRQ"

From 883de16b464554e195fe7e20daaa9525cfeaf3a2 Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Mon, 7 Mar 2011 23:32:41 +0100
Subject: [PATCH 089/386] lm32: add Milkymist UART support

This patch adds support for Milkymist's simple UART.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 Makefile.target     |   1 +
 hw/milkymist-uart.c | 180 ++++++++++++++++++++++++++++++++++++++++++++
 trace-events        |   6 ++
 3 files changed, 187 insertions(+)
 create mode 100644 hw/milkymist-uart.c

diff --git a/Makefile.target b/Makefile.target
index 6581519064..c009117e47 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -275,6 +275,7 @@ obj-lm32-y += milkymist-pfpu.o
 obj-lm32-y += milkymist-softusb.o
 obj-lm32-y += milkymist-sysctl.o
 obj-lm32-$(CONFIG_OPENGL) += milkymist-tmu2.o
+obj-lm32-y += milkymist-uart.o
 
 obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o
 obj-mips-y += mips_addr.o mips_timer.o mips_int.o
diff --git a/hw/milkymist-uart.c b/hw/milkymist-uart.c
new file mode 100644
index 0000000000..56c90da0b6
--- /dev/null
+++ b/hw/milkymist-uart.c
@@ -0,0 +1,180 @@
+/*
+ *  QEMU model of the Milkymist UART block.
+ *
+ *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Specification available at:
+ *   http://www.milkymist.org/socdoc/uart.pdf
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "trace.h"
+#include "qemu-char.h"
+#include "qemu-error.h"
+
+enum {
+    R_RXTX = 0,
+    R_DIV,
+    R_MAX
+};
+
+struct MilkymistUartState {
+    SysBusDevice busdev;
+    CharDriverState *chr;
+    qemu_irq rx_irq;
+    qemu_irq tx_irq;
+
+    uint32_t regs[R_MAX];
+};
+typedef struct MilkymistUartState MilkymistUartState;
+
+static uint32_t uart_read(void *opaque, target_phys_addr_t addr)
+{
+    MilkymistUartState *s = opaque;
+    uint32_t r = 0;
+
+    addr >>= 2;
+    switch (addr) {
+    case R_RXTX:
+    case R_DIV:
+        r = s->regs[addr];
+        break;
+
+    default:
+        error_report("milkymist_uart: read access to unknown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+
+    trace_milkymist_uart_memory_read(addr << 2, r);
+
+    return r;
+}
+
+static void uart_write(void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    MilkymistUartState *s = opaque;
+    unsigned char ch = value;
+
+    trace_milkymist_uart_memory_write(addr, value);
+
+    addr >>= 2;
+    switch (addr) {
+    case R_RXTX:
+        if (s->chr) {
+            qemu_chr_write(s->chr, &ch, 1);
+        }
+        trace_milkymist_uart_pulse_irq_tx();
+        qemu_irq_pulse(s->tx_irq);
+        break;
+    case R_DIV:
+        s->regs[addr] = value;
+        break;
+
+    default:
+        error_report("milkymist_uart: write access to unknown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+}
+
+static CPUReadMemoryFunc * const uart_read_fn[] = {
+    NULL,
+    NULL,
+    &uart_read,
+};
+
+static CPUWriteMemoryFunc * const uart_write_fn[] = {
+    NULL,
+    NULL,
+    &uart_write,
+};
+
+static void uart_rx(void *opaque, const uint8_t *buf, int size)
+{
+    MilkymistUartState *s = opaque;
+
+    s->regs[R_RXTX] = *buf;
+    trace_milkymist_uart_pulse_irq_rx();
+    qemu_irq_pulse(s->rx_irq);
+}
+
+static int uart_can_rx(void *opaque)
+{
+    return 1;
+}
+
+static void uart_event(void *opaque, int event)
+{
+}
+
+static void milkymist_uart_reset(DeviceState *d)
+{
+    MilkymistUartState *s = container_of(d, MilkymistUartState, busdev.qdev);
+    int i;
+
+    for (i = 0; i < R_MAX; i++) {
+        s->regs[i] = 0;
+    }
+}
+
+static int milkymist_uart_init(SysBusDevice *dev)
+{
+    MilkymistUartState *s = FROM_SYSBUS(typeof(*s), dev);
+    int uart_regs;
+
+    sysbus_init_irq(dev, &s->rx_irq);
+    sysbus_init_irq(dev, &s->tx_irq);
+
+    uart_regs = cpu_register_io_memory(uart_read_fn, uart_write_fn, s,
+            DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, R_MAX * 4, uart_regs);
+
+    s->chr = qdev_init_chardev(&dev->qdev);
+    if (s->chr) {
+        qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
+    }
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_milkymist_uart = {
+    .name = "milkymist-uart",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(regs, MilkymistUartState, R_MAX),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static SysBusDeviceInfo milkymist_uart_info = {
+    .init = milkymist_uart_init,
+    .qdev.name  = "milkymist-uart",
+    .qdev.size  = sizeof(MilkymistUartState),
+    .qdev.vmsd  = &vmstate_milkymist_uart,
+    .qdev.reset = milkymist_uart_reset,
+};
+
+static void milkymist_uart_register(void)
+{
+    sysbus_register_withprop(&milkymist_uart_info);
+}
+
+device_init(milkymist_uart_register)
diff --git a/trace-events b/trace-events
index 3a88adfdad..55f3de532a 100644
--- a/trace-events
+++ b/trace-events
@@ -349,3 +349,9 @@ disable milkymist_tmu2_memory_read(uint32_t addr, uint32_t value) "addr %08x val
 disable milkymist_tmu2_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
 disable milkymist_tmu2_start(void) "Start TMU"
 disable milkymist_tmu2_pulse_irq(void) "Pulse IRQ"
+
+# hw/milkymist-uart.c
+disable milkymist_uart_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_uart_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_uart_pulse_irq_rx(void) "Pulse IRQ RX"
+disable milkymist_uart_pulse_irq_tx(void) "Pulse IRQ TX"

From d23948b15a9920fb7f6374b55a6db1ecff81f3ee Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Mon, 7 Mar 2011 23:32:42 +0100
Subject: [PATCH 090/386] lm32: add Milkymist VGAFB support

This patch adds support for Milkymist's VGA framebuffer.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 Makefile.target               |   2 +
 hw/milkymist-vgafb.c          | 318 ++++++++++++++++++++++++++++++++++
 hw/milkymist-vgafb_template.h |  74 ++++++++
 trace-events                  |   4 +
 4 files changed, 398 insertions(+)
 create mode 100644 hw/milkymist-vgafb.c
 create mode 100644 hw/milkymist-vgafb_template.h

diff --git a/Makefile.target b/Makefile.target
index c009117e47..2a65e15be9 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -276,6 +276,8 @@ obj-lm32-y += milkymist-softusb.o
 obj-lm32-y += milkymist-sysctl.o
 obj-lm32-$(CONFIG_OPENGL) += milkymist-tmu2.o
 obj-lm32-y += milkymist-uart.o
+obj-lm32-y += milkymist-vgafb.o
+obj-lm32-y += framebuffer.o
 
 obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o
 obj-mips-y += mips_addr.o mips_timer.o mips_int.o
diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
new file mode 100644
index 0000000000..8922731511
--- /dev/null
+++ b/hw/milkymist-vgafb.c
@@ -0,0 +1,318 @@
+
+/*
+ *  QEMU model of the Milkymist VGA framebuffer.
+ *
+ *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Specification available at:
+ *   http://www.milkymist.org/socdoc/vgafb.pdf
+ */
+
+#include "hw.h"
+#include "sysbus.h"
+#include "trace.h"
+#include "console.h"
+#include "framebuffer.h"
+#include "pixel_ops.h"
+#include "qemu-error.h"
+
+#define BITS 8
+#include "milkymist-vgafb_template.h"
+#define BITS 15
+#include "milkymist-vgafb_template.h"
+#define BITS 16
+#include "milkymist-vgafb_template.h"
+#define BITS 24
+#include "milkymist-vgafb_template.h"
+#define BITS 32
+#include "milkymist-vgafb_template.h"
+
+enum {
+    R_CTRL = 0,
+    R_HRES,
+    R_HSYNC_START,
+    R_HSYNC_END,
+    R_HSCAN,
+    R_VRES,
+    R_VSYNC_START,
+    R_VSYNC_END,
+    R_VSCAN,
+    R_BASEADDRESS,
+    R_BASEADDRESS_ACT,
+    R_BURST_COUNT,
+    R_SOURCE_CLOCK,
+    R_MAX
+};
+
+enum {
+    CTRL_RESET = (1<<0),
+};
+
+struct MilkymistVgafbState {
+    SysBusDevice busdev;
+    DisplayState *ds;
+
+    int invalidate;
+    uint32_t fb_offset;
+    uint32_t fb_mask;
+
+    uint32_t regs[R_MAX];
+};
+typedef struct MilkymistVgafbState MilkymistVgafbState;
+
+static int vgafb_enabled(MilkymistVgafbState *s)
+{
+    return !(s->regs[R_CTRL] & CTRL_RESET);
+}
+
+static void vgafb_update_display(void *opaque)
+{
+    MilkymistVgafbState *s = opaque;
+    int first = 0;
+    int last = 0;
+    drawfn fn;
+
+    if (!vgafb_enabled(s)) {
+        return;
+    }
+
+    int dest_width = s->regs[R_HRES];
+
+    switch (ds_get_bits_per_pixel(s->ds)) {
+    case 0:
+        return;
+    case 8:
+        fn = draw_line_8;
+        break;
+    case 15:
+        fn = draw_line_15;
+        dest_width *= 2;
+        break;
+    case 16:
+        fn = draw_line_16;
+        dest_width *= 2;
+        break;
+    case 24:
+        fn = draw_line_24;
+        dest_width *= 3;
+        break;
+    case 32:
+        fn = draw_line_32;
+        dest_width *= 4;
+        break;
+    default:
+        hw_error("milkymist_vgafb: bad color depth\n");
+        break;
+    }
+
+    framebuffer_update_display(s->ds,
+                               s->regs[R_BASEADDRESS] + s->fb_offset,
+                               s->regs[R_HRES],
+                               s->regs[R_VRES],
+                               s->regs[R_HRES] * 2,
+                               dest_width,
+                               0,
+                               s->invalidate,
+                               fn,
+                               NULL,
+                               &first, &last);
+
+    if (first >= 0) {
+        dpy_update(s->ds, 0, first, s->regs[R_HRES], last - first + 1);
+    }
+    s->invalidate = 0;
+}
+
+static void vgafb_invalidate_display(void *opaque)
+{
+    MilkymistVgafbState *s = opaque;
+    s->invalidate = 1;
+}
+
+static void vgafb_resize(MilkymistVgafbState *s)
+{
+    if (!vgafb_enabled(s)) {
+        return;
+    }
+
+    qemu_console_resize(s->ds, s->regs[R_HRES], s->regs[R_VRES]);
+    s->invalidate = 1;
+}
+
+static uint32_t vgafb_read(void *opaque, target_phys_addr_t addr)
+{
+    MilkymistVgafbState *s = opaque;
+    uint32_t r = 0;
+
+    addr >>= 2;
+    switch (addr) {
+    case R_CTRL:
+    case R_HRES:
+    case R_HSYNC_START:
+    case R_HSYNC_END:
+    case R_HSCAN:
+    case R_VRES:
+    case R_VSYNC_START:
+    case R_VSYNC_END:
+    case R_VSCAN:
+    case R_BASEADDRESS:
+    case R_BURST_COUNT:
+    case R_SOURCE_CLOCK:
+        r = s->regs[addr];
+    break;
+    case R_BASEADDRESS_ACT:
+        r = s->regs[R_BASEADDRESS];
+    break;
+
+    default:
+        error_report("milkymist_vgafb: read access to unknown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+
+    trace_milkymist_vgafb_memory_read(addr << 2, r);
+
+    return r;
+}
+
+static void
+vgafb_write(void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    MilkymistVgafbState *s = opaque;
+
+    trace_milkymist_vgafb_memory_write(addr, value);
+
+    addr >>= 2;
+    switch (addr) {
+    case R_CTRL:
+    case R_HSYNC_START:
+    case R_HSYNC_END:
+    case R_HSCAN:
+    case R_VSYNC_START:
+    case R_VSYNC_END:
+    case R_VSCAN:
+    case R_BURST_COUNT:
+    case R_SOURCE_CLOCK:
+        s->regs[addr] = value;
+        break;
+    case R_BASEADDRESS:
+        if (value & 0x1f) {
+            error_report("milkymist_vgafb: framebuffer base address have to "
+                     "be 32 byte aligned");
+            break;
+        }
+        s->regs[addr] = value & s->fb_mask;
+        s->invalidate = 1;
+        break;
+    case R_HRES:
+    case R_VRES:
+        s->regs[addr] = value;
+        vgafb_resize(s);
+        break;
+    case R_BASEADDRESS_ACT:
+        error_report("milkymist_vgafb: write to read-only register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+
+    default:
+        error_report("milkymist_vgafb: write access to unknown register 0x"
+                TARGET_FMT_plx, addr << 2);
+        break;
+    }
+}
+
+static CPUReadMemoryFunc * const vgafb_read_fn[] = {
+   NULL,
+   NULL,
+   &vgafb_read
+};
+
+static CPUWriteMemoryFunc * const vgafb_write_fn[] = {
+   NULL,
+   NULL,
+   &vgafb_write
+};
+
+static void milkymist_vgafb_reset(DeviceState *d)
+{
+    MilkymistVgafbState *s = container_of(d, MilkymistVgafbState, busdev.qdev);
+    int i;
+
+    for (i = 0; i < R_MAX; i++) {
+        s->regs[i] = 0;
+    }
+
+    /* defaults */
+    s->regs[R_CTRL] = CTRL_RESET;
+    s->regs[R_HRES] = 640;
+    s->regs[R_VRES] = 480;
+    s->regs[R_BASEADDRESS] = 0;
+}
+
+static int milkymist_vgafb_init(SysBusDevice *dev)
+{
+    MilkymistVgafbState *s = FROM_SYSBUS(typeof(*s), dev);
+    int vgafb_regs;
+
+    vgafb_regs = cpu_register_io_memory(vgafb_read_fn, vgafb_write_fn, s,
+            DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, R_MAX * 4, vgafb_regs);
+
+    s->ds = graphic_console_init(vgafb_update_display,
+                                 vgafb_invalidate_display,
+                                 NULL, NULL, s);
+
+    return 0;
+}
+
+static int vgafb_post_load(void *opaque, int version_id)
+{
+    vgafb_invalidate_display(opaque);
+    return 0;
+}
+
+static const VMStateDescription vmstate_milkymist_vgafb = {
+    .name = "milkymist-vgafb",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .post_load = vgafb_post_load,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(regs, MilkymistVgafbState, R_MAX),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static SysBusDeviceInfo milkymist_vgafb_info = {
+    .init = milkymist_vgafb_init,
+    .qdev.name  = "milkymist-vgafb",
+    .qdev.size  = sizeof(MilkymistVgafbState),
+    .qdev.vmsd  = &vmstate_milkymist_vgafb,
+    .qdev.reset = milkymist_vgafb_reset,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT32("fb_offset", MilkymistVgafbState, fb_offset, 0x0),
+        DEFINE_PROP_UINT32("fb_mask", MilkymistVgafbState, fb_mask, 0xffffffff),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
+static void milkymist_vgafb_register(void)
+{
+    sysbus_register_withprop(&milkymist_vgafb_info);
+}
+
+device_init(milkymist_vgafb_register)
diff --git a/hw/milkymist-vgafb_template.h b/hw/milkymist-vgafb_template.h
new file mode 100644
index 0000000000..69af9ef3f6
--- /dev/null
+++ b/hw/milkymist-vgafb_template.h
@@ -0,0 +1,74 @@
+/*
+ *  QEMU model of the Milkymist VGA framebuffer.
+ *
+ *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#if BITS == 8
+#define COPY_PIXEL(to, r, g, b)                    \
+    do {                                           \
+        *to = rgb_to_pixel8(r, g, b);              \
+        to += 1;                                   \
+    } while (0)
+#elif BITS == 15
+#define COPY_PIXEL(to, r, g, b)                    \
+    do {                                           \
+        *(uint16_t *)to = rgb_to_pixel15(r, g, b); \
+        to += 2;                                   \
+    } while (0)
+#elif BITS == 16
+#define COPY_PIXEL(to, r, g, b)                    \
+    do {                                           \
+        *(uint16_t *)to = rgb_to_pixel16(r, g, b); \
+        to += 2;                                   \
+    } while (0)
+#elif BITS == 24
+#define COPY_PIXEL(to, r, g, b)                    \
+    do {                                           \
+        uint32 tmp = rgb_to_pixel24(r, g, b);      \
+        *(to++) =         tmp & 0xff;              \
+        *(to++) =  (tmp >> 8) & 0xff;              \
+        *(to++) = (tmp >> 16) & 0xff;              \
+    } while (0)
+#elif BITS == 32
+#define COPY_PIXEL(to, r, g, b)                    \
+    do {                                           \
+        *(uint32_t *)to = rgb_to_pixel32(r, g, b); \
+        to += 4;                                   \
+    } while (0)
+#else
+#error unknown bit depth
+#endif
+
+static void glue(draw_line_, BITS)(void *opaque, uint8_t *d, const uint8_t *s,
+        int width, int deststep)
+{
+    uint16_t rgb565;
+    uint8_t r, g, b;
+
+    while (width--) {
+        rgb565 = lduw_raw(s);
+        r = ((rgb565 >> 11) & 0x1f) << 3;
+        g = ((rgb565 >>  5) & 0x3f) << 2;
+        b = ((rgb565 >>  0) & 0x1f) << 3;
+        COPY_PIXEL(d, r, g, b);
+        s += 2;
+    }
+}
+
+#undef BITS
+#undef COPY_PIXEL
diff --git a/trace-events b/trace-events
index 55f3de532a..06efdb7753 100644
--- a/trace-events
+++ b/trace-events
@@ -355,3 +355,7 @@ disable milkymist_uart_memory_read(uint32_t addr, uint32_t value) "addr %08x val
 disable milkymist_uart_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
 disable milkymist_uart_pulse_irq_rx(void) "Pulse IRQ RX"
 disable milkymist_uart_pulse_irq_tx(void) "Pulse IRQ TX"
+
+# hw/milkymist-vgafb.c
+disable milkymist_vgafb_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_vgafb_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"

From 38d3339398ec0cffa53834ed32306836a4ad2c78 Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Mon, 7 Mar 2011 23:32:43 +0100
Subject: [PATCH 091/386] lm32: add milkymist hw support functions

This patch adds wrappers for easy creation of the qdev devices.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 hw/milkymist-hw.h | 204 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 204 insertions(+)
 create mode 100644 hw/milkymist-hw.h

diff --git a/hw/milkymist-hw.h b/hw/milkymist-hw.h
new file mode 100644
index 0000000000..15acdbccd6
--- /dev/null
+++ b/hw/milkymist-hw.h
@@ -0,0 +1,204 @@
+#ifndef QEMU_HW_MILKYMIST_H
+#define QEMU_HW_MILKYMIST_H
+
+static inline DeviceState *milkymist_uart_create(target_phys_addr_t base,
+        qemu_irq rx_irq, qemu_irq tx_irq)
+{
+    DeviceState *dev;
+
+    dev = qdev_create(NULL, "milkymist-uart");
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 0, rx_irq);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 1, tx_irq);
+
+    return dev;
+}
+
+static inline DeviceState *milkymist_hpdmc_create(target_phys_addr_t base)
+{
+    DeviceState *dev;
+
+    dev = qdev_create(NULL, "milkymist-hpdmc");
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+
+    return dev;
+}
+
+static inline DeviceState *milkymist_memcard_create(target_phys_addr_t base)
+{
+    DeviceState *dev;
+
+    dev = qdev_create(NULL, "milkymist-memcard");
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+
+    return dev;
+}
+
+static inline DeviceState *milkymist_vgafb_create(target_phys_addr_t base,
+        uint32_t fb_offset, uint32_t fb_mask)
+{
+    DeviceState *dev;
+
+    dev = qdev_create(NULL, "milkymist-vgafb");
+    qdev_prop_set_uint32(dev, "fb_offset", fb_offset);
+    qdev_prop_set_uint32(dev, "fb_mask", fb_mask);
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+
+    return dev;
+}
+
+static inline DeviceState *milkymist_sysctl_create(target_phys_addr_t base,
+        qemu_irq gpio_irq, qemu_irq timer0_irq, qemu_irq timer1_irq,
+        uint32_t freq_hz, uint32_t system_id, uint32_t capabilities,
+        uint32_t gpio_strappings)
+{
+    DeviceState *dev;
+
+    dev = qdev_create(NULL, "milkymist-sysctl");
+    qdev_prop_set_uint32(dev, "frequency", freq_hz);
+    qdev_prop_set_uint32(dev, "systemid", system_id);
+    qdev_prop_set_uint32(dev, "capabilities", capabilities);
+    qdev_prop_set_uint32(dev, "gpio_strappings", gpio_strappings);
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 0, gpio_irq);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 1, timer0_irq);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 2, timer1_irq);
+
+    return dev;
+}
+
+static inline DeviceState *milkymist_pfpu_create(target_phys_addr_t base,
+        qemu_irq irq)
+{
+    DeviceState *dev;
+
+    dev = qdev_create(NULL, "milkymist-pfpu");
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq);
+    return dev;
+}
+
+#ifdef CONFIG_OPENGL
+#include <X11/Xlib.h>
+#include <GL/glx.h>
+static const int glx_fbconfig_attr[] = {
+    GLX_GREEN_SIZE, 5,
+    GLX_GREEN_SIZE, 6,
+    GLX_BLUE_SIZE, 5,
+    None
+};
+#endif
+
+static inline DeviceState *milkymist_tmu2_create(target_phys_addr_t base,
+        qemu_irq irq)
+{
+#ifdef CONFIG_OPENGL
+    DeviceState *dev;
+    Display *d;
+    GLXFBConfig *configs;
+    int nelements;
+    int ver_major, ver_minor;
+
+    if (display_type == DT_NOGRAPHIC) {
+        return NULL;
+    }
+
+    /* check that GLX will work */
+    d = XOpenDisplay(NULL);
+    if (d == NULL) {
+        return NULL;
+    }
+
+    if (!glXQueryVersion(d, &ver_major, &ver_minor)) {
+        /* Yeah, sometimes getting the GLX version can fail.
+         * Isn't X beautiful? */
+        XCloseDisplay(d);
+        return NULL;
+    }
+
+    if ((ver_major < 1) || ((ver_major == 1) && (ver_minor < 3))) {
+        printf("Your GLX version is %d.%d,"
+          "but TMU emulation needs at least 1.3. TMU disabled.\n",
+          ver_major, ver_minor);
+        XCloseDisplay(d);
+        return NULL;
+    }
+
+    configs = glXChooseFBConfig(d, 0, glx_fbconfig_attr, &nelements);
+    if (configs == NULL) {
+        XCloseDisplay(d);
+        return NULL;
+    }
+
+    XFree(configs);
+    XCloseDisplay(d);
+
+    dev = qdev_create(NULL, "milkymist-tmu2");
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq);
+
+    return dev;
+#else
+    return NULL;
+#endif
+}
+
+static inline DeviceState *milkymist_ac97_create(target_phys_addr_t base,
+        qemu_irq crrequest_irq, qemu_irq crreply_irq, qemu_irq dmar_irq,
+        qemu_irq dmaw_irq)
+{
+    DeviceState *dev;
+
+    dev = qdev_create(NULL, "milkymist-ac97");
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 0, crrequest_irq);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 1, crreply_irq);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 2, dmar_irq);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 3, dmaw_irq);
+
+    return dev;
+}
+
+static inline DeviceState *milkymist_minimac_create(target_phys_addr_t base,
+        qemu_irq rx_irq, qemu_irq tx_irq)
+{
+    DeviceState *dev;
+
+    qemu_check_nic_model(&nd_table[0], "minimac");
+    dev = qdev_create(NULL, "milkymist-minimac");
+    qdev_set_nic_properties(dev, &nd_table[0]);
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 0, rx_irq);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 1, tx_irq);
+
+    return dev;
+}
+
+static inline DeviceState *milkymist_softusb_create(target_phys_addr_t base,
+        qemu_irq irq, uint32_t pmem_base, uint32_t pmem_size,
+        uint32_t dmem_base, uint32_t dmem_size)
+{
+    DeviceState *dev;
+
+    dev = qdev_create(NULL, "milkymist-softusb");
+    qdev_prop_set_uint32(dev, "pmem_base", pmem_base);
+    qdev_prop_set_uint32(dev, "pmem_size", pmem_size);
+    qdev_prop_set_uint32(dev, "dmem_base", dmem_base);
+    qdev_prop_set_uint32(dev, "dmem_size", dmem_size);
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq);
+
+    return dev;
+}
+
+#endif /* QEMU_HW_MILKYMIST_H */

From 5052d2277fdcc08afda245ebfce3163935dc7dfb Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Mon, 7 Mar 2011 23:32:44 +0100
Subject: [PATCH 092/386] lm32: add support for the Milkymist board

This patch adds almost complete support for the Milkymist system-on-chip
(http://www.milkymist.org).

Additional to running bare metal applications, booting a linux kernel with
initrd is supported.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 Makefile.target                  |   1 +
 default-configs/lm32-softmmu.mak |   1 +
 hw/milkymist.c                   | 216 +++++++++++++++++++++++++++++++
 3 files changed, 218 insertions(+)
 create mode 100644 hw/milkymist.c

diff --git a/Makefile.target b/Makefile.target
index 2a65e15be9..2f7671454c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -260,6 +260,7 @@ obj-ppc-y += xilinx_ethlite.o
 
 # LM32 boards
 obj-lm32-y += lm32_boards.o
+obj-lm32-y += milkymist.o
 
 # LM32 peripherals
 obj-lm32-y += lm32_pic.o
diff --git a/default-configs/lm32-softmmu.mak b/default-configs/lm32-softmmu.mak
index 3e7f57e700..0d19974b40 100644
--- a/default-configs/lm32-softmmu.mak
+++ b/default-configs/lm32-softmmu.mak
@@ -1,5 +1,6 @@
 # Default configuration for lm32-softmmu
 
 CONFIG_PTIMER=y
+CONFIG_PFLASH_CFI01=y
 CONFIG_PFLASH_CFI02=y
 CONFIG_SD=y
diff --git a/hw/milkymist.c b/hw/milkymist.c
new file mode 100644
index 0000000000..8defad8024
--- /dev/null
+++ b/hw/milkymist.c
@@ -0,0 +1,216 @@
+/*
+ *  QEMU model for the Milkymist board.
+ *
+ *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "sysbus.h"
+#include "hw.h"
+#include "net.h"
+#include "flash.h"
+#include "sysemu.h"
+#include "devices.h"
+#include "boards.h"
+#include "loader.h"
+#include "elf.h"
+#include "blockdev.h"
+#include "milkymist-hw.h"
+#include "lm32.h"
+
+#define BIOS_FILENAME    "mmone-bios.bin"
+#define BIOS_OFFSET      0x00860000
+#define BIOS_SIZE        (512*1024)
+#define KERNEL_LOAD_ADDR 0x40000000
+
+typedef struct {
+    CPUState *env;
+    target_phys_addr_t bootstrap_pc;
+    target_phys_addr_t flash_base;
+    target_phys_addr_t initrd_base;
+    size_t initrd_size;
+    target_phys_addr_t cmdline_base;
+} ResetInfo;
+
+static void cpu_irq_handler(void *opaque, int irq, int level)
+{
+    CPUState *env = opaque;
+
+    if (level) {
+        cpu_interrupt(env, CPU_INTERRUPT_HARD);
+    } else {
+        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+    }
+}
+
+static void main_cpu_reset(void *opaque)
+{
+    ResetInfo *reset_info = opaque;
+    CPUState *env = reset_info->env;
+
+    cpu_reset(env);
+
+    /* init defaults */
+    env->pc = reset_info->bootstrap_pc;
+    env->regs[R_R1] = reset_info->cmdline_base;
+    env->regs[R_R2] = reset_info->initrd_base;
+    env->regs[R_R3] = reset_info->initrd_base + reset_info->initrd_size;
+    env->eba = reset_info->flash_base;
+    env->deba = reset_info->flash_base;
+}
+
+static void
+milkymist_init(ram_addr_t ram_size_not_used,
+                          const char *boot_device,
+                          const char *kernel_filename,
+                          const char *kernel_cmdline,
+                          const char *initrd_filename, const char *cpu_model)
+{
+    CPUState *env;
+    int kernel_size;
+    DriveInfo *dinfo;
+    ram_addr_t phys_sdram;
+    ram_addr_t phys_flash;
+    qemu_irq irq[32], *cpu_irq;
+    int i;
+    char *bios_filename;
+    ResetInfo *reset_info;
+
+    /* memory map */
+    target_phys_addr_t flash_base   = 0x00000000;
+    size_t flash_sector_size        = 128 * 1024;
+    size_t flash_size               = 32 * 1024 * 1024;
+    target_phys_addr_t sdram_base   = 0x40000000;
+    size_t sdram_size               = 128 * 1024 * 1024;
+
+    target_phys_addr_t initrd_base  = sdram_base + 0x1002000;
+    target_phys_addr_t cmdline_base = sdram_base + 0x1000000;
+    size_t initrd_max = sdram_size - 0x1002000;
+
+    reset_info = qemu_mallocz(sizeof(ResetInfo));
+
+    if (cpu_model == NULL) {
+        cpu_model = "lm32-full";
+    }
+    env = cpu_init(cpu_model);
+    reset_info->env = env;
+
+    cpu_lm32_set_phys_msb_ignore(env, 1);
+
+    phys_sdram = qemu_ram_alloc(NULL, "milkymist.sdram", sdram_size);
+    cpu_register_physical_memory(sdram_base, sdram_size,
+            phys_sdram | IO_MEM_RAM);
+
+    phys_flash = qemu_ram_alloc(NULL, "milkymist.flash", flash_size);
+    dinfo = drive_get(IF_PFLASH, 0, 0);
+    /* Numonyx JS28F256J3F105 */
+    pflash_cfi01_register(flash_base, phys_flash,
+                          dinfo ? dinfo->bdrv : NULL, flash_sector_size,
+                          flash_size / flash_sector_size, 2,
+                          0x00, 0x89, 0x00, 0x1d, 1);
+
+    /* create irq lines */
+    cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
+    env->pic_state = lm32_pic_init(*cpu_irq);
+    for (i = 0; i < 32; i++) {
+        irq[i] = qdev_get_gpio_in(env->pic_state, i);
+    }
+
+    /* load bios rom */
+    if (bios_name == NULL) {
+        bios_name = BIOS_FILENAME;
+    }
+    bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+
+    if (bios_filename) {
+        load_image_targphys(bios_filename, BIOS_OFFSET, BIOS_SIZE);
+    }
+
+    reset_info->bootstrap_pc = BIOS_OFFSET;
+
+    /* if no kernel is given no valid bios rom is a fatal error */
+    if (!kernel_filename && !dinfo && !bios_filename) {
+        fprintf(stderr, "qemu: could not load Milkymist One bios '%s'\n",
+                bios_name);
+        exit(1);
+    }
+
+    milkymist_uart_create(0x60000000, irq[0], irq[1]);
+    milkymist_sysctl_create(0x60001000, irq[2], irq[3], irq[4],
+            80000000, 0x10014d31, 0x0000041f, 0x00000001);
+    milkymist_hpdmc_create(0x60002000);
+    milkymist_vgafb_create(0x60003000, 0x40000000, 0x0fffffff);
+    milkymist_memcard_create(0x60004000);
+    milkymist_ac97_create(0x60005000, irq[5], irq[6], irq[7], irq[8]);
+    milkymist_pfpu_create(0x60006000, irq[9]);
+    milkymist_tmu2_create(0x60007000, irq[10]);
+    milkymist_minimac_create(0x60008000, irq[11], irq[12]);
+    milkymist_softusb_create(0x6000f000, irq[17],
+            0x20000000, 0x1000, 0x20020000, 0x2000);
+
+    /* make sure juart isn't the first chardev */
+    env->juart_state = lm32_juart_init();
+
+    if (kernel_filename) {
+        uint64_t entry;
+
+        /* Boots a kernel elf binary.  */
+        kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL,
+                               1, ELF_MACHINE, 0);
+        reset_info->bootstrap_pc = entry;
+
+        if (kernel_size < 0) {
+            kernel_size = load_image_targphys(kernel_filename, sdram_base,
+                                              sdram_size);
+            reset_info->bootstrap_pc = sdram_base;
+        }
+
+        if (kernel_size < 0) {
+            fprintf(stderr, "qemu: could not load kernel '%s'\n",
+                    kernel_filename);
+            exit(1);
+        }
+    }
+
+    if (kernel_cmdline && strlen(kernel_cmdline)) {
+        pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE,
+                kernel_cmdline);
+        reset_info->cmdline_base = (uint32_t)cmdline_base;
+    }
+
+    if (initrd_filename) {
+        size_t initrd_size;
+        initrd_size = load_image_targphys(initrd_filename, initrd_base,
+                initrd_max);
+        reset_info->initrd_base = (uint32_t)initrd_base;
+        reset_info->initrd_size = (uint32_t)initrd_size;
+    }
+
+    qemu_register_reset(main_cpu_reset, reset_info);
+}
+
+static QEMUMachine milkymist_machine = {
+    .name = "milkymist",
+    .desc = "Milkymist One",
+    .init = milkymist_init,
+    .is_default = 0
+};
+
+static void milkymist_machine_init(void)
+{
+    qemu_register_machine(&milkymist_machine);
+}
+
+machine_init(milkymist_machine_init);

From d118aa6b4a8fecb1c5a4747fd0f88a015883bf85 Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Mon, 7 Mar 2011 23:32:45 +0100
Subject: [PATCH 093/386] MAINTAINERS: add Milkymist board

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 MAINTAINERS | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9f3ff0e471..e6f853dfff 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -214,6 +214,11 @@ M: Michael Walle <michael@walle.cc>
 S: Maintained
 F: hw/lm32_boards.c
 
+milkymist
+M: Michael Walle <michael@walle.cc>
+S: Maintained
+F: hw/milkymist.c
+
 M68K Machines
 -------------
 an5206

From c53c1258a455cbe9afd7e5c572578646df30d438 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Mon, 4 Apr 2011 14:48:08 +1000
Subject: [PATCH 094/386] Fix non-portable format string in usb-ccid.c

At one point, usb-ccid.c attempts to use a %lX format specifier to print
a uint64_t, which is only correct on some host platforms.  This patch
corrects the statement to use the stdint specified PRIX64 constant instead.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/usb-ccid.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
index 723b2e325f..44156cc1d8 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -1199,7 +1199,7 @@ void ccid_card_card_error(CCIDCardState *card, uint64_t error)
 
     s->bmCommandStatus = COMMAND_STATUS_FAILED;
     s->last_answer_error = error;
-    DPRINTF(s, 1, "VSC_Error: %lX\n", s->last_answer_error);
+    DPRINTF(s, 1, "VSC_Error: %" PRIX64 "\n", s->last_answer_error);
     /* TODO: these error's should be more verbose and propogated to the guest.*/
     /*
      * We flush all pending answers on CardRemove message in ccid-card-passthru,

From 348883d4828d7434e1053407818598f7fb15e594 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 4 Apr 2011 11:46:32 +0100
Subject: [PATCH 095/386] Makefile.target: Allow target helpers to be in any
 *_helper.c file

Build all files matching *_helper.c with HELPER_CFLAGS, not just
op_helper.c. This allows you to put target helper functions which
use the global 'env' variable in multiple source files.

This only affects the ARM target as all the other targets currently only
have op_helper.c.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 Makefile.target | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile.target b/Makefile.target
index 2f7671454c..d5761b72f5 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -94,7 +94,7 @@ tcg/tcg.o: cpu.h
 
 # HELPER_CFLAGS is used for all the code compiled with static register
 # variables
-op_helper.o cpu-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+%_helper.o cpu-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
 
 # Note: this is a workaround. The real fix is to avoid compiling
 # cpu_signal_handler() in cpu-exec.c.

From 2a3f75b42ac255be09ec2939b96c549ec830efd3 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 4 Apr 2011 11:46:33 +0100
Subject: [PATCH 096/386] target-arm: Use global env in neon_helper.c helpers

Use the global 'env' variable in the helper functions in neon_helper.c.
This means we don't need to pass env as an argument to them any more.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/helpers.h     | 134 ++++++++++++++++++------------------
 target-arm/neon_helper.c | 144 +++++++++++++++++++--------------------
 target-arm/translate.c   | 119 +++++++++++++++-----------------
 3 files changed, 191 insertions(+), 206 deletions(-)

diff --git a/target-arm/helpers.h b/target-arm/helpers.h
index 9de10e352f..0705b9c70a 100644
--- a/target-arm/helpers.h
+++ b/target-arm/helpers.h
@@ -154,22 +154,22 @@ DEF_HELPER_2(sar_cc, i32, i32, i32)
 DEF_HELPER_2(ror_cc, i32, i32, i32)
 
 /* neon_helper.c */
-DEF_HELPER_3(neon_qadd_u8, i32, env, i32, i32)
-DEF_HELPER_3(neon_qadd_s8, i32, env, i32, i32)
-DEF_HELPER_3(neon_qadd_u16, i32, env, i32, i32)
-DEF_HELPER_3(neon_qadd_s16, i32, env, i32, i32)
-DEF_HELPER_3(neon_qadd_u32, i32, env, i32, i32)
-DEF_HELPER_3(neon_qadd_s32, i32, env, i32, i32)
-DEF_HELPER_3(neon_qsub_u8, i32, env, i32, i32)
-DEF_HELPER_3(neon_qsub_s8, i32, env, i32, i32)
-DEF_HELPER_3(neon_qsub_u16, i32, env, i32, i32)
-DEF_HELPER_3(neon_qsub_s16, i32, env, i32, i32)
-DEF_HELPER_3(neon_qsub_u32, i32, env, i32, i32)
-DEF_HELPER_3(neon_qsub_s32, i32, env, i32, i32)
-DEF_HELPER_3(neon_qadd_u64, i64, env, i64, i64)
-DEF_HELPER_3(neon_qadd_s64, i64, env, i64, i64)
-DEF_HELPER_3(neon_qsub_u64, i64, env, i64, i64)
-DEF_HELPER_3(neon_qsub_s64, i64, env, i64, i64)
+DEF_HELPER_2(neon_qadd_u8, i32, i32, i32)
+DEF_HELPER_2(neon_qadd_s8, i32, i32, i32)
+DEF_HELPER_2(neon_qadd_u16, i32, i32, i32)
+DEF_HELPER_2(neon_qadd_s16, i32, i32, i32)
+DEF_HELPER_2(neon_qadd_u32, i32, i32, i32)
+DEF_HELPER_2(neon_qadd_s32, i32, i32, i32)
+DEF_HELPER_2(neon_qsub_u8, i32, i32, i32)
+DEF_HELPER_2(neon_qsub_s8, i32, i32, i32)
+DEF_HELPER_2(neon_qsub_u16, i32, i32, i32)
+DEF_HELPER_2(neon_qsub_s16, i32, i32, i32)
+DEF_HELPER_2(neon_qsub_u32, i32, i32, i32)
+DEF_HELPER_2(neon_qsub_s32, i32, i32, i32)
+DEF_HELPER_2(neon_qadd_u64, i64, i64, i64)
+DEF_HELPER_2(neon_qadd_s64, i64, i64, i64)
+DEF_HELPER_2(neon_qsub_u64, i64, i64, i64)
+DEF_HELPER_2(neon_qsub_s64, i64, i64, i64)
 
 DEF_HELPER_2(neon_hadd_s8, i32, i32, i32)
 DEF_HELPER_2(neon_hadd_u8, i32, i32, i32)
@@ -247,26 +247,26 @@ DEF_HELPER_2(neon_rshl_u32, i32, i32, i32)
 DEF_HELPER_2(neon_rshl_s32, i32, i32, i32)
 DEF_HELPER_2(neon_rshl_u64, i64, i64, i64)
 DEF_HELPER_2(neon_rshl_s64, i64, i64, i64)
-DEF_HELPER_3(neon_qshl_u8, i32, env, i32, i32)
-DEF_HELPER_3(neon_qshl_s8, i32, env, i32, i32)
-DEF_HELPER_3(neon_qshl_u16, i32, env, i32, i32)
-DEF_HELPER_3(neon_qshl_s16, i32, env, i32, i32)
-DEF_HELPER_3(neon_qshl_u32, i32, env, i32, i32)
-DEF_HELPER_3(neon_qshl_s32, i32, env, i32, i32)
-DEF_HELPER_3(neon_qshl_u64, i64, env, i64, i64)
-DEF_HELPER_3(neon_qshl_s64, i64, env, i64, i64)
-DEF_HELPER_3(neon_qshlu_s8, i32, env, i32, i32);
-DEF_HELPER_3(neon_qshlu_s16, i32, env, i32, i32);
-DEF_HELPER_3(neon_qshlu_s32, i32, env, i32, i32);
-DEF_HELPER_3(neon_qshlu_s64, i64, env, i64, i64);
-DEF_HELPER_3(neon_qrshl_u8, i32, env, i32, i32)
-DEF_HELPER_3(neon_qrshl_s8, i32, env, i32, i32)
-DEF_HELPER_3(neon_qrshl_u16, i32, env, i32, i32)
-DEF_HELPER_3(neon_qrshl_s16, i32, env, i32, i32)
-DEF_HELPER_3(neon_qrshl_u32, i32, env, i32, i32)
-DEF_HELPER_3(neon_qrshl_s32, i32, env, i32, i32)
-DEF_HELPER_3(neon_qrshl_u64, i64, env, i64, i64)
-DEF_HELPER_3(neon_qrshl_s64, i64, env, i64, i64)
+DEF_HELPER_2(neon_qshl_u8, i32, i32, i32)
+DEF_HELPER_2(neon_qshl_s8, i32, i32, i32)
+DEF_HELPER_2(neon_qshl_u16, i32, i32, i32)
+DEF_HELPER_2(neon_qshl_s16, i32, i32, i32)
+DEF_HELPER_2(neon_qshl_u32, i32, i32, i32)
+DEF_HELPER_2(neon_qshl_s32, i32, i32, i32)
+DEF_HELPER_2(neon_qshl_u64, i64, i64, i64)
+DEF_HELPER_2(neon_qshl_s64, i64, i64, i64)
+DEF_HELPER_2(neon_qshlu_s8, i32, i32, i32);
+DEF_HELPER_2(neon_qshlu_s16, i32, i32, i32);
+DEF_HELPER_2(neon_qshlu_s32, i32, i32, i32);
+DEF_HELPER_2(neon_qshlu_s64, i64, i64, i64);
+DEF_HELPER_2(neon_qrshl_u8, i32, i32, i32)
+DEF_HELPER_2(neon_qrshl_s8, i32, i32, i32)
+DEF_HELPER_2(neon_qrshl_u16, i32, i32, i32)
+DEF_HELPER_2(neon_qrshl_s16, i32, i32, i32)
+DEF_HELPER_2(neon_qrshl_u32, i32, i32, i32)
+DEF_HELPER_2(neon_qrshl_s32, i32, i32, i32)
+DEF_HELPER_2(neon_qrshl_u64, i64, i64, i64)
+DEF_HELPER_2(neon_qrshl_s64, i64, i64, i64)
 
 DEF_HELPER_2(neon_add_u8, i32, i32, i32)
 DEF_HELPER_2(neon_add_u16, i32, i32, i32)
@@ -295,22 +295,22 @@ DEF_HELPER_1(neon_cls_s16, i32, i32)
 DEF_HELPER_1(neon_cls_s32, i32, i32)
 DEF_HELPER_1(neon_cnt_u8, i32, i32)
 
-DEF_HELPER_3(neon_qdmulh_s16, i32, env, i32, i32)
-DEF_HELPER_3(neon_qrdmulh_s16, i32, env, i32, i32)
-DEF_HELPER_3(neon_qdmulh_s32, i32, env, i32, i32)
-DEF_HELPER_3(neon_qrdmulh_s32, i32, env, i32, i32)
+DEF_HELPER_2(neon_qdmulh_s16, i32, i32, i32)
+DEF_HELPER_2(neon_qrdmulh_s16, i32, i32, i32)
+DEF_HELPER_2(neon_qdmulh_s32, i32, i32, i32)
+DEF_HELPER_2(neon_qrdmulh_s32, i32, i32, i32)
 
 DEF_HELPER_1(neon_narrow_u8, i32, i64)
 DEF_HELPER_1(neon_narrow_u16, i32, i64)
-DEF_HELPER_2(neon_unarrow_sat8, i32, env, i64)
-DEF_HELPER_2(neon_narrow_sat_u8, i32, env, i64)
-DEF_HELPER_2(neon_narrow_sat_s8, i32, env, i64)
-DEF_HELPER_2(neon_unarrow_sat16, i32, env, i64)
-DEF_HELPER_2(neon_narrow_sat_u16, i32, env, i64)
-DEF_HELPER_2(neon_narrow_sat_s16, i32, env, i64)
-DEF_HELPER_2(neon_unarrow_sat32, i32, env, i64)
-DEF_HELPER_2(neon_narrow_sat_u32, i32, env, i64)
-DEF_HELPER_2(neon_narrow_sat_s32, i32, env, i64)
+DEF_HELPER_1(neon_unarrow_sat8, i32, i64)
+DEF_HELPER_1(neon_narrow_sat_u8, i32, i64)
+DEF_HELPER_1(neon_narrow_sat_s8, i32, i64)
+DEF_HELPER_1(neon_unarrow_sat16, i32, i64)
+DEF_HELPER_1(neon_narrow_sat_u16, i32, i64)
+DEF_HELPER_1(neon_narrow_sat_s16, i32, i64)
+DEF_HELPER_1(neon_unarrow_sat32, i32, i64)
+DEF_HELPER_1(neon_narrow_sat_u32, i32, i64)
+DEF_HELPER_1(neon_narrow_sat_s32, i32, i64)
 DEF_HELPER_1(neon_narrow_high_u8, i32, i64)
 DEF_HELPER_1(neon_narrow_high_u16, i32, i64)
 DEF_HELPER_1(neon_narrow_round_high_u8, i32, i64)
@@ -326,8 +326,8 @@ DEF_HELPER_2(neon_paddl_u16, i64, i64, i64)
 DEF_HELPER_2(neon_paddl_u32, i64, i64, i64)
 DEF_HELPER_2(neon_subl_u16, i64, i64, i64)
 DEF_HELPER_2(neon_subl_u32, i64, i64, i64)
-DEF_HELPER_3(neon_addl_saturate_s32, i64, env, i64, i64)
-DEF_HELPER_3(neon_addl_saturate_s64, i64, env, i64, i64)
+DEF_HELPER_2(neon_addl_saturate_s32, i64, i64, i64)
+DEF_HELPER_2(neon_addl_saturate_s64, i64, i64, i64)
 DEF_HELPER_2(neon_abdl_u16, i64, i32, i32)
 DEF_HELPER_2(neon_abdl_s16, i64, i32, i32)
 DEF_HELPER_2(neon_abdl_u32, i64, i32, i32)
@@ -343,12 +343,12 @@ DEF_HELPER_1(neon_negl_u16, i64, i64)
 DEF_HELPER_1(neon_negl_u32, i64, i64)
 DEF_HELPER_1(neon_negl_u64, i64, i64)
 
-DEF_HELPER_2(neon_qabs_s8, i32, env, i32)
-DEF_HELPER_2(neon_qabs_s16, i32, env, i32)
-DEF_HELPER_2(neon_qabs_s32, i32, env, i32)
-DEF_HELPER_2(neon_qneg_s8, i32, env, i32)
-DEF_HELPER_2(neon_qneg_s16, i32, env, i32)
-DEF_HELPER_2(neon_qneg_s32, i32, env, i32)
+DEF_HELPER_1(neon_qabs_s8, i32, i32)
+DEF_HELPER_1(neon_qabs_s16, i32, i32)
+DEF_HELPER_1(neon_qabs_s32, i32, i32)
+DEF_HELPER_1(neon_qneg_s8, i32, i32)
+DEF_HELPER_1(neon_qneg_s16, i32, i32)
+DEF_HELPER_1(neon_qneg_s32, i32, i32)
 
 DEF_HELPER_2(neon_min_f32, i32, i32, i32)
 DEF_HELPER_2(neon_max_f32, i32, i32, i32)
@@ -461,15 +461,15 @@ DEF_HELPER_3(iwmmxt_muladdswl, i64, i64, i32, i32)
 
 DEF_HELPER_2(set_teecr, void, env, i32)
 
-DEF_HELPER_3(neon_unzip8, void, env, i32, i32)
-DEF_HELPER_3(neon_unzip16, void, env, i32, i32)
-DEF_HELPER_3(neon_qunzip8, void, env, i32, i32)
-DEF_HELPER_3(neon_qunzip16, void, env, i32, i32)
-DEF_HELPER_3(neon_qunzip32, void, env, i32, i32)
-DEF_HELPER_3(neon_zip8, void, env, i32, i32)
-DEF_HELPER_3(neon_zip16, void, env, i32, i32)
-DEF_HELPER_3(neon_qzip8, void, env, i32, i32)
-DEF_HELPER_3(neon_qzip16, void, env, i32, i32)
-DEF_HELPER_3(neon_qzip32, void, env, i32, i32)
+DEF_HELPER_2(neon_unzip8, void, i32, i32)
+DEF_HELPER_2(neon_unzip16, void, i32, i32)
+DEF_HELPER_2(neon_qunzip8, void, i32, i32)
+DEF_HELPER_2(neon_qunzip16, void, i32, i32)
+DEF_HELPER_2(neon_qunzip32, void, i32, i32)
+DEF_HELPER_2(neon_zip8, void, i32, i32)
+DEF_HELPER_2(neon_zip16, void, i32, i32)
+DEF_HELPER_2(neon_qzip8, void, i32, i32)
+DEF_HELPER_2(neon_qzip16, void, i32, i32)
+DEF_HELPER_2(neon_qzip32, void, i32, i32)
 
 #include "def-helper.h"
diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index 71f1a7ead0..315e69337e 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -10,7 +10,7 @@
 #include <stdio.h>
 
 #include "cpu.h"
-#include "exec-all.h"
+#include "exec.h"
 #include "helpers.h"
 
 #define SIGNBIT (uint32_t)0x80000000
@@ -116,10 +116,6 @@ NEON_TYPE1(u32, uint32_t)
 uint32_t HELPER(glue(neon_,name))(uint32_t arg1, uint32_t arg2) \
 NEON_VOP_BODY(vtype, n)
 
-#define NEON_VOP_ENV(name, vtype, n) \
-uint32_t HELPER(glue(neon_,name))(CPUState *env, uint32_t arg1, uint32_t arg2) \
-NEON_VOP_BODY(vtype, n)
-
 /* Pairwise operations.  */
 /* For 32-bit elements each segment only contains a single element, so
    the elementwise and pairwise operations are the same.  */
@@ -168,14 +164,14 @@ uint32_t HELPER(glue(neon_,name))(uint32_t arg) \
         dest = tmp; \
     }} while(0)
 #define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint8_t)
-NEON_VOP_ENV(qadd_u8, neon_u8, 4)
+NEON_VOP(qadd_u8, neon_u8, 4)
 #undef NEON_FN
 #define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint16_t)
-NEON_VOP_ENV(qadd_u16, neon_u16, 2)
+NEON_VOP(qadd_u16, neon_u16, 2)
 #undef NEON_FN
 #undef NEON_USAT
 
-uint32_t HELPER(neon_qadd_u32)(CPUState *env, uint32_t a, uint32_t b)
+uint32_t HELPER(neon_qadd_u32)(uint32_t a, uint32_t b)
 {
     uint32_t res = a + b;
     if (res < a) {
@@ -185,7 +181,7 @@ uint32_t HELPER(neon_qadd_u32)(CPUState *env, uint32_t a, uint32_t b)
     return res;
 }
 
-uint64_t HELPER(neon_qadd_u64)(CPUState *env, uint64_t src1, uint64_t src2)
+uint64_t HELPER(neon_qadd_u64)(uint64_t src1, uint64_t src2)
 {
     uint64_t res;
 
@@ -210,14 +206,14 @@ uint64_t HELPER(neon_qadd_u64)(CPUState *env, uint64_t src1, uint64_t src2)
     dest = tmp; \
     } while(0)
 #define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int8_t)
-NEON_VOP_ENV(qadd_s8, neon_s8, 4)
+NEON_VOP(qadd_s8, neon_s8, 4)
 #undef NEON_FN
 #define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int16_t)
-NEON_VOP_ENV(qadd_s16, neon_s16, 2)
+NEON_VOP(qadd_s16, neon_s16, 2)
 #undef NEON_FN
 #undef NEON_SSAT
 
-uint32_t HELPER(neon_qadd_s32)(CPUState *env, uint32_t a, uint32_t b)
+uint32_t HELPER(neon_qadd_s32)(uint32_t a, uint32_t b)
 {
     uint32_t res = a + b;
     if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) {
@@ -227,7 +223,7 @@ uint32_t HELPER(neon_qadd_s32)(CPUState *env, uint32_t a, uint32_t b)
     return res;
 }
 
-uint64_t HELPER(neon_qadd_s64)(CPUState *env, uint64_t src1, uint64_t src2)
+uint64_t HELPER(neon_qadd_s64)(uint64_t src1, uint64_t src2)
 {
     uint64_t res;
 
@@ -248,14 +244,14 @@ uint64_t HELPER(neon_qadd_s64)(CPUState *env, uint64_t src1, uint64_t src2)
         dest = tmp; \
     }} while(0)
 #define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint8_t)
-NEON_VOP_ENV(qsub_u8, neon_u8, 4)
+NEON_VOP(qsub_u8, neon_u8, 4)
 #undef NEON_FN
 #define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint16_t)
-NEON_VOP_ENV(qsub_u16, neon_u16, 2)
+NEON_VOP(qsub_u16, neon_u16, 2)
 #undef NEON_FN
 #undef NEON_USAT
 
-uint32_t HELPER(neon_qsub_u32)(CPUState *env, uint32_t a, uint32_t b)
+uint32_t HELPER(neon_qsub_u32)(uint32_t a, uint32_t b)
 {
     uint32_t res = a - b;
     if (res > a) {
@@ -265,7 +261,7 @@ uint32_t HELPER(neon_qsub_u32)(CPUState *env, uint32_t a, uint32_t b)
     return res;
 }
 
-uint64_t HELPER(neon_qsub_u64)(CPUState *env, uint64_t src1, uint64_t src2)
+uint64_t HELPER(neon_qsub_u64)(uint64_t src1, uint64_t src2)
 {
     uint64_t res;
 
@@ -291,14 +287,14 @@ uint64_t HELPER(neon_qsub_u64)(CPUState *env, uint64_t src1, uint64_t src2)
     dest = tmp; \
     } while(0)
 #define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int8_t)
-NEON_VOP_ENV(qsub_s8, neon_s8, 4)
+NEON_VOP(qsub_s8, neon_s8, 4)
 #undef NEON_FN
 #define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int16_t)
-NEON_VOP_ENV(qsub_s16, neon_s16, 2)
+NEON_VOP(qsub_s16, neon_s16, 2)
 #undef NEON_FN
 #undef NEON_SSAT
 
-uint32_t HELPER(neon_qsub_s32)(CPUState *env, uint32_t a, uint32_t b)
+uint32_t HELPER(neon_qsub_s32)(uint32_t a, uint32_t b)
 {
     uint32_t res = a - b;
     if (((res ^ a) & SIGNBIT) && ((a ^ b) & SIGNBIT)) {
@@ -308,7 +304,7 @@ uint32_t HELPER(neon_qsub_s32)(CPUState *env, uint32_t a, uint32_t b)
     return res;
 }
 
-uint64_t HELPER(neon_qsub_s64)(CPUState *env, uint64_t src1, uint64_t src2)
+uint64_t HELPER(neon_qsub_s64)(uint64_t src1, uint64_t src2)
 {
     uint64_t res;
 
@@ -659,12 +655,12 @@ uint64_t HELPER(neon_rshl_u64)(uint64_t val, uint64_t shiftop)
             dest = ~0; \
         } \
     }} while (0)
-NEON_VOP_ENV(qshl_u8, neon_u8, 4)
-NEON_VOP_ENV(qshl_u16, neon_u16, 2)
-NEON_VOP_ENV(qshl_u32, neon_u32, 1)
+NEON_VOP(qshl_u8, neon_u8, 4)
+NEON_VOP(qshl_u16, neon_u16, 2)
+NEON_VOP(qshl_u32, neon_u32, 1)
 #undef NEON_FN
 
-uint64_t HELPER(neon_qshl_u64)(CPUState *env, uint64_t val, uint64_t shiftop)
+uint64_t HELPER(neon_qshl_u64)(uint64_t val, uint64_t shiftop)
 {
     int8_t shift = (int8_t)shiftop;
     if (shift >= 64) {
@@ -714,12 +710,12 @@ uint64_t HELPER(neon_qshl_u64)(CPUState *env, uint64_t val, uint64_t shiftop)
             } \
         } \
     }} while (0)
-NEON_VOP_ENV(qshl_s8, neon_s8, 4)
-NEON_VOP_ENV(qshl_s16, neon_s16, 2)
-NEON_VOP_ENV(qshl_s32, neon_s32, 1)
+NEON_VOP(qshl_s8, neon_s8, 4)
+NEON_VOP(qshl_s16, neon_s16, 2)
+NEON_VOP(qshl_s32, neon_s32, 1)
 #undef NEON_FN
 
-uint64_t HELPER(neon_qshl_s64)(CPUState *env, uint64_t valop, uint64_t shiftop)
+uint64_t HELPER(neon_qshl_s64)(uint64_t valop, uint64_t shiftop)
 {
     int8_t shift = (uint8_t)shiftop;
     int64_t val = valop;
@@ -769,26 +765,26 @@ uint64_t HELPER(neon_qshl_s64)(CPUState *env, uint64_t valop, uint64_t shiftop)
             } \
         } \
     }} while (0)
-NEON_VOP_ENV(qshlu_s8, neon_u8, 4)
-NEON_VOP_ENV(qshlu_s16, neon_u16, 2)
+NEON_VOP(qshlu_s8, neon_u8, 4)
+NEON_VOP(qshlu_s16, neon_u16, 2)
 #undef NEON_FN
 
-uint32_t HELPER(neon_qshlu_s32)(CPUState *env, uint32_t valop, uint32_t shiftop)
+uint32_t HELPER(neon_qshlu_s32)(uint32_t valop, uint32_t shiftop)
 {
     if ((int32_t)valop < 0) {
         SET_QC();
         return 0;
     }
-    return helper_neon_qshl_u32(env, valop, shiftop);
+    return helper_neon_qshl_u32(valop, shiftop);
 }
 
-uint64_t HELPER(neon_qshlu_s64)(CPUState *env, uint64_t valop, uint64_t shiftop)
+uint64_t HELPER(neon_qshlu_s64)(uint64_t valop, uint64_t shiftop)
 {
     if ((int64_t)valop < 0) {
         SET_QC();
         return 0;
     }
-    return helper_neon_qshl_u64(env, valop, shiftop);
+    return helper_neon_qshl_u64(valop, shiftop);
 }
 
 /* FIXME: This is wrong.  */
@@ -815,13 +811,13 @@ uint64_t HELPER(neon_qshlu_s64)(CPUState *env, uint64_t valop, uint64_t shiftop)
             dest = ~0; \
         } \
     }} while (0)
-NEON_VOP_ENV(qrshl_u8, neon_u8, 4)
-NEON_VOP_ENV(qrshl_u16, neon_u16, 2)
+NEON_VOP(qrshl_u8, neon_u8, 4)
+NEON_VOP(qrshl_u16, neon_u16, 2)
 #undef NEON_FN
 
 /* The addition of the rounding constant may overflow, so we use an
  * intermediate 64 bits accumulator.  */
-uint32_t HELPER(neon_qrshl_u32)(CPUState *env, uint32_t val, uint32_t shiftop)
+uint32_t HELPER(neon_qrshl_u32)(uint32_t val, uint32_t shiftop)
 {
     uint32_t dest;
     int8_t shift = (int8_t)shiftop;
@@ -851,7 +847,7 @@ uint32_t HELPER(neon_qrshl_u32)(CPUState *env, uint32_t val, uint32_t shiftop)
 
 /* Handling addition overflow with 64 bits inputs values is more
  * tricky than with 32 bits values.  */
-uint64_t HELPER(neon_qrshl_u64)(CPUState *env, uint64_t val, uint64_t shiftop)
+uint64_t HELPER(neon_qrshl_u64)(uint64_t val, uint64_t shiftop)
 {
     int8_t shift = (int8_t)shiftop;
     if (shift >= 64) {
@@ -912,13 +908,13 @@ uint64_t HELPER(neon_qrshl_u64)(CPUState *env, uint64_t val, uint64_t shiftop)
             } \
         } \
     }} while (0)
-NEON_VOP_ENV(qrshl_s8, neon_s8, 4)
-NEON_VOP_ENV(qrshl_s16, neon_s16, 2)
+NEON_VOP(qrshl_s8, neon_s8, 4)
+NEON_VOP(qrshl_s16, neon_s16, 2)
 #undef NEON_FN
 
 /* The addition of the rounding constant may overflow, so we use an
  * intermediate 64 bits accumulator.  */
-uint32_t HELPER(neon_qrshl_s32)(CPUState *env, uint32_t valop, uint32_t shiftop)
+uint32_t HELPER(neon_qrshl_s32)(uint32_t valop, uint32_t shiftop)
 {
     int32_t dest;
     int32_t val = (int32_t)valop;
@@ -947,7 +943,7 @@ uint32_t HELPER(neon_qrshl_s32)(CPUState *env, uint32_t valop, uint32_t shiftop)
 
 /* Handling addition overflow with 64 bits inputs values is more
  * tricky than with 32 bits values.  */
-uint64_t HELPER(neon_qrshl_s64)(CPUState *env, uint64_t valop, uint64_t shiftop)
+uint64_t HELPER(neon_qrshl_s64)(uint64_t valop, uint64_t shiftop)
 {
     int8_t shift = (uint8_t)shiftop;
     int64_t val = valop;
@@ -1156,10 +1152,10 @@ uint32_t HELPER(neon_cnt_u8)(uint32_t x)
     dest = tmp >> 16; \
     } while(0)
 #define NEON_FN(dest, src1, src2) NEON_QDMULH16(dest, src1, src2, 0)
-NEON_VOP_ENV(qdmulh_s16, neon_s16, 2)
+NEON_VOP(qdmulh_s16, neon_s16, 2)
 #undef NEON_FN
 #define NEON_FN(dest, src1, src2) NEON_QDMULH16(dest, src1, src2, 1)
-NEON_VOP_ENV(qrdmulh_s16, neon_s16, 2)
+NEON_VOP(qrdmulh_s16, neon_s16, 2)
 #undef NEON_FN
 #undef NEON_QDMULH16
 
@@ -1182,10 +1178,10 @@ NEON_VOP_ENV(qrdmulh_s16, neon_s16, 2)
     dest = tmp >> 32; \
     } while(0)
 #define NEON_FN(dest, src1, src2) NEON_QDMULH32(dest, src1, src2, 0)
-NEON_VOP_ENV(qdmulh_s32, neon_s32, 1)
+NEON_VOP(qdmulh_s32, neon_s32, 1)
 #undef NEON_FN
 #define NEON_FN(dest, src1, src2) NEON_QDMULH32(dest, src1, src2, 1)
-NEON_VOP_ENV(qrdmulh_s32, neon_s32, 1)
+NEON_VOP(qrdmulh_s32, neon_s32, 1)
 #undef NEON_FN
 #undef NEON_QDMULH32
 
@@ -1226,7 +1222,7 @@ uint32_t HELPER(neon_narrow_round_high_u16)(uint64_t x)
     return ((x >> 16) & 0xffff) | ((x >> 32) & 0xffff0000);
 }
 
-uint32_t HELPER(neon_unarrow_sat8)(CPUState *env, uint64_t x)
+uint32_t HELPER(neon_unarrow_sat8)(uint64_t x)
 {
     uint16_t s;
     uint8_t d;
@@ -1253,7 +1249,7 @@ uint32_t HELPER(neon_unarrow_sat8)(CPUState *env, uint64_t x)
     return res;
 }
 
-uint32_t HELPER(neon_narrow_sat_u8)(CPUState *env, uint64_t x)
+uint32_t HELPER(neon_narrow_sat_u8)(uint64_t x)
 {
     uint16_t s;
     uint8_t d;
@@ -1276,7 +1272,7 @@ uint32_t HELPER(neon_narrow_sat_u8)(CPUState *env, uint64_t x)
     return res;
 }
 
-uint32_t HELPER(neon_narrow_sat_s8)(CPUState *env, uint64_t x)
+uint32_t HELPER(neon_narrow_sat_s8)(uint64_t x)
 {
     int16_t s;
     uint8_t d;
@@ -1299,7 +1295,7 @@ uint32_t HELPER(neon_narrow_sat_s8)(CPUState *env, uint64_t x)
     return res;
 }
 
-uint32_t HELPER(neon_unarrow_sat16)(CPUState *env, uint64_t x)
+uint32_t HELPER(neon_unarrow_sat16)(uint64_t x)
 {
     uint32_t high;
     uint32_t low;
@@ -1322,7 +1318,7 @@ uint32_t HELPER(neon_unarrow_sat16)(CPUState *env, uint64_t x)
     return low | (high << 16);
 }
 
-uint32_t HELPER(neon_narrow_sat_u16)(CPUState *env, uint64_t x)
+uint32_t HELPER(neon_narrow_sat_u16)(uint64_t x)
 {
     uint32_t high;
     uint32_t low;
@@ -1339,7 +1335,7 @@ uint32_t HELPER(neon_narrow_sat_u16)(CPUState *env, uint64_t x)
     return low | (high << 16);
 }
 
-uint32_t HELPER(neon_narrow_sat_s16)(CPUState *env, uint64_t x)
+uint32_t HELPER(neon_narrow_sat_s16)(uint64_t x)
 {
     int32_t low;
     int32_t high;
@@ -1356,7 +1352,7 @@ uint32_t HELPER(neon_narrow_sat_s16)(CPUState *env, uint64_t x)
     return (uint16_t)low | (high << 16);
 }
 
-uint32_t HELPER(neon_unarrow_sat32)(CPUState *env, uint64_t x)
+uint32_t HELPER(neon_unarrow_sat32)(uint64_t x)
 {
     if (x & 0x8000000000000000ull) {
         SET_QC();
@@ -1369,7 +1365,7 @@ uint32_t HELPER(neon_unarrow_sat32)(CPUState *env, uint64_t x)
     return x;
 }
 
-uint32_t HELPER(neon_narrow_sat_u32)(CPUState *env, uint64_t x)
+uint32_t HELPER(neon_narrow_sat_u32)(uint64_t x)
 {
     if (x > 0xffffffffu) {
         SET_QC();
@@ -1378,7 +1374,7 @@ uint32_t HELPER(neon_narrow_sat_u32)(CPUState *env, uint64_t x)
     return x;
 }
 
-uint32_t HELPER(neon_narrow_sat_s32)(CPUState *env, uint64_t x)
+uint32_t HELPER(neon_narrow_sat_s32)(uint64_t x)
 {
     if ((int64_t)x != (int32_t)x) {
         SET_QC();
@@ -1485,7 +1481,7 @@ uint64_t HELPER(neon_subl_u32)(uint64_t a, uint64_t b)
     return (a - b) ^ mask;
 }
 
-uint64_t HELPER(neon_addl_saturate_s32)(CPUState *env, uint64_t a, uint64_t b)
+uint64_t HELPER(neon_addl_saturate_s32)(uint64_t a, uint64_t b)
 {
     uint32_t x, y;
     uint32_t low, high;
@@ -1507,7 +1503,7 @@ uint64_t HELPER(neon_addl_saturate_s32)(CPUState *env, uint64_t a, uint64_t b)
     return low | ((uint64_t)high << 32);
 }
 
-uint64_t HELPER(neon_addl_saturate_s64)(CPUState *env, uint64_t a, uint64_t b)
+uint64_t HELPER(neon_addl_saturate_s64)(uint64_t a, uint64_t b)
 {
     uint64_t result;
 
@@ -1679,7 +1675,7 @@ uint64_t HELPER(neon_negl_u64)(uint64_t x)
     } else if (x < 0) { \
         x = -x; \
     }} while (0)
-uint32_t HELPER(neon_qabs_s8)(CPUState *env, uint32_t x)
+uint32_t HELPER(neon_qabs_s8)(uint32_t x)
 {
     neon_s8 vec;
     NEON_UNPACK(neon_s8, vec, x);
@@ -1699,7 +1695,7 @@ uint32_t HELPER(neon_qabs_s8)(CPUState *env, uint32_t x)
     } else { \
         x = -x; \
     }} while (0)
-uint32_t HELPER(neon_qneg_s8)(CPUState *env, uint32_t x)
+uint32_t HELPER(neon_qneg_s8)(uint32_t x)
 {
     neon_s8 vec;
     NEON_UNPACK(neon_s8, vec, x);
@@ -1719,7 +1715,7 @@ uint32_t HELPER(neon_qneg_s8)(CPUState *env, uint32_t x)
     } else if (x < 0) { \
         x = -x; \
     }} while (0)
-uint32_t HELPER(neon_qabs_s16)(CPUState *env, uint32_t x)
+uint32_t HELPER(neon_qabs_s16)(uint32_t x)
 {
     neon_s16 vec;
     NEON_UNPACK(neon_s16, vec, x);
@@ -1737,7 +1733,7 @@ uint32_t HELPER(neon_qabs_s16)(CPUState *env, uint32_t x)
     } else { \
         x = -x; \
     }} while (0)
-uint32_t HELPER(neon_qneg_s16)(CPUState *env, uint32_t x)
+uint32_t HELPER(neon_qneg_s16)(uint32_t x)
 {
     neon_s16 vec;
     NEON_UNPACK(neon_s16, vec, x);
@@ -1748,7 +1744,7 @@ uint32_t HELPER(neon_qneg_s16)(CPUState *env, uint32_t x)
 }
 #undef DO_QNEG16
 
-uint32_t HELPER(neon_qabs_s32)(CPUState *env, uint32_t x)
+uint32_t HELPER(neon_qabs_s32)(uint32_t x)
 {
     if (x == SIGNBIT) {
         SET_QC();
@@ -1759,7 +1755,7 @@ uint32_t HELPER(neon_qabs_s32)(CPUState *env, uint32_t x)
     return x;
 }
 
-uint32_t HELPER(neon_qneg_s32)(CPUState *env, uint32_t x)
+uint32_t HELPER(neon_qneg_s32)(uint32_t x)
 {
     if (x == SIGNBIT) {
         SET_QC();
@@ -1842,7 +1838,7 @@ uint32_t HELPER(neon_acgt_f32)(uint32_t a, uint32_t b)
 
 #define ELEM(V, N, SIZE) (((V) >> ((N) * (SIZE))) & ((1ull << (SIZE)) - 1))
 
-void HELPER(neon_qunzip8)(CPUState *env, uint32_t rd, uint32_t rm)
+void HELPER(neon_qunzip8)(uint32_t rd, uint32_t rm)
 {
     uint64_t zm0 = float64_val(env->vfp.regs[rm]);
     uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
@@ -1870,7 +1866,7 @@ void HELPER(neon_qunzip8)(CPUState *env, uint32_t rd, uint32_t rm)
     env->vfp.regs[rd + 1] = make_float64(d1);
 }
 
-void HELPER(neon_qunzip16)(CPUState *env, uint32_t rd, uint32_t rm)
+void HELPER(neon_qunzip16)(uint32_t rd, uint32_t rm)
 {
     uint64_t zm0 = float64_val(env->vfp.regs[rm]);
     uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
@@ -1890,7 +1886,7 @@ void HELPER(neon_qunzip16)(CPUState *env, uint32_t rd, uint32_t rm)
     env->vfp.regs[rd + 1] = make_float64(d1);
 }
 
-void HELPER(neon_qunzip32)(CPUState *env, uint32_t rd, uint32_t rm)
+void HELPER(neon_qunzip32)(uint32_t rd, uint32_t rm)
 {
     uint64_t zm0 = float64_val(env->vfp.regs[rm]);
     uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
@@ -1906,7 +1902,7 @@ void HELPER(neon_qunzip32)(CPUState *env, uint32_t rd, uint32_t rm)
     env->vfp.regs[rd + 1] = make_float64(d1);
 }
 
-void HELPER(neon_unzip8)(CPUState *env, uint32_t rd, uint32_t rm)
+void HELPER(neon_unzip8)(uint32_t rd, uint32_t rm)
 {
     uint64_t zm = float64_val(env->vfp.regs[rm]);
     uint64_t zd = float64_val(env->vfp.regs[rd]);
@@ -1922,7 +1918,7 @@ void HELPER(neon_unzip8)(CPUState *env, uint32_t rd, uint32_t rm)
     env->vfp.regs[rd] = make_float64(d0);
 }
 
-void HELPER(neon_unzip16)(CPUState *env, uint32_t rd, uint32_t rm)
+void HELPER(neon_unzip16)(uint32_t rd, uint32_t rm)
 {
     uint64_t zm = float64_val(env->vfp.regs[rm]);
     uint64_t zd = float64_val(env->vfp.regs[rd]);
@@ -1934,7 +1930,7 @@ void HELPER(neon_unzip16)(CPUState *env, uint32_t rd, uint32_t rm)
     env->vfp.regs[rd] = make_float64(d0);
 }
 
-void HELPER(neon_qzip8)(CPUState *env, uint32_t rd, uint32_t rm)
+void HELPER(neon_qzip8)(uint32_t rd, uint32_t rm)
 {
     uint64_t zm0 = float64_val(env->vfp.regs[rm]);
     uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
@@ -1962,7 +1958,7 @@ void HELPER(neon_qzip8)(CPUState *env, uint32_t rd, uint32_t rm)
     env->vfp.regs[rd + 1] = make_float64(d1);
 }
 
-void HELPER(neon_qzip16)(CPUState *env, uint32_t rd, uint32_t rm)
+void HELPER(neon_qzip16)(uint32_t rd, uint32_t rm)
 {
     uint64_t zm0 = float64_val(env->vfp.regs[rm]);
     uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
@@ -1982,7 +1978,7 @@ void HELPER(neon_qzip16)(CPUState *env, uint32_t rd, uint32_t rm)
     env->vfp.regs[rd + 1] = make_float64(d1);
 }
 
-void HELPER(neon_qzip32)(CPUState *env, uint32_t rd, uint32_t rm)
+void HELPER(neon_qzip32)(uint32_t rd, uint32_t rm)
 {
     uint64_t zm0 = float64_val(env->vfp.regs[rm]);
     uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
@@ -1998,7 +1994,7 @@ void HELPER(neon_qzip32)(CPUState *env, uint32_t rd, uint32_t rm)
     env->vfp.regs[rd + 1] = make_float64(d1);
 }
 
-void HELPER(neon_zip8)(CPUState *env, uint32_t rd, uint32_t rm)
+void HELPER(neon_zip8)(uint32_t rd, uint32_t rm)
 {
     uint64_t zm = float64_val(env->vfp.regs[rm]);
     uint64_t zd = float64_val(env->vfp.regs[rd]);
@@ -2014,7 +2010,7 @@ void HELPER(neon_zip8)(CPUState *env, uint32_t rd, uint32_t rm)
     env->vfp.regs[rd] = make_float64(d0);
 }
 
-void HELPER(neon_zip16)(CPUState *env, uint32_t rd, uint32_t rm)
+void HELPER(neon_zip16)(uint32_t rd, uint32_t rm)
 {
     uint64_t zm = float64_val(env->vfp.regs[rm]);
     uint64_t zd = float64_val(env->vfp.regs[rd]);
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 33417e6825..53c40acca9 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3656,13 +3656,13 @@ static int gen_neon_unzip(int rd, int rm, int size, int q)
     if (q) {
         switch (size) {
         case 0:
-            gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
+            gen_helper_neon_qunzip8(tmp, tmp2);
             break;
         case 1:
-            gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
+            gen_helper_neon_qunzip16(tmp, tmp2);
             break;
         case 2:
-            gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
+            gen_helper_neon_qunzip32(tmp, tmp2);
             break;
         default:
             abort();
@@ -3670,10 +3670,10 @@ static int gen_neon_unzip(int rd, int rm, int size, int q)
     } else {
         switch (size) {
         case 0:
-            gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
+            gen_helper_neon_unzip8(tmp, tmp2);
             break;
         case 1:
-            gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
+            gen_helper_neon_unzip16(tmp, tmp2);
             break;
         default:
             abort();
@@ -3695,13 +3695,13 @@ static int gen_neon_zip(int rd, int rm, int size, int q)
     if (q) {
         switch (size) {
         case 0:
-            gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
+            gen_helper_neon_qzip8(tmp, tmp2);
             break;
         case 1:
-            gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
+            gen_helper_neon_qzip16(tmp, tmp2);
             break;
         case 2:
-            gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
+            gen_helper_neon_qzip32(tmp, tmp2);
             break;
         default:
             abort();
@@ -3709,10 +3709,10 @@ static int gen_neon_zip(int rd, int rm, int size, int q)
     } else {
         switch (size) {
         case 0:
-            gen_helper_neon_zip8(cpu_env, tmp, tmp2);
+            gen_helper_neon_zip8(tmp, tmp2);
             break;
         case 1:
-            gen_helper_neon_zip16(cpu_env, tmp, tmp2);
+            gen_helper_neon_zip16(tmp, tmp2);
             break;
         default:
             abort();
@@ -4063,9 +4063,9 @@ static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
 static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
 {
     switch (size) {
-    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
-    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
-    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
+    case 0: gen_helper_neon_narrow_sat_s8(dest, src); break;
+    case 1: gen_helper_neon_narrow_sat_s16(dest, src); break;
+    case 2: gen_helper_neon_narrow_sat_s32(dest, src); break;
     default: abort();
     }
 }
@@ -4073,9 +4073,9 @@ static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
 static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
 {
     switch (size) {
-    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
-    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
-    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
+    case 0: gen_helper_neon_narrow_sat_u8(dest, src); break;
+    case 1: gen_helper_neon_narrow_sat_u16(dest, src); break;
+    case 2: gen_helper_neon_narrow_sat_u32(dest, src); break;
     default: abort();
     }
 }
@@ -4083,9 +4083,9 @@ static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
 static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src)
 {
     switch (size) {
-    case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
-    case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
-    case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
+    case 0: gen_helper_neon_unarrow_sat8(dest, src); break;
+    case 1: gen_helper_neon_unarrow_sat16(dest, src); break;
+    case 2: gen_helper_neon_unarrow_sat32(dest, src); break;
     default: abort();
     }
 }
@@ -4177,8 +4177,8 @@ static inline void gen_neon_negl(TCGv_i64 var, int size)
 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
 {
     switch (size) {
-    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
-    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
+    case 1: gen_helper_neon_addl_saturate_s32(op0, op0, op1); break;
+    case 2: gen_helper_neon_addl_saturate_s64(op0, op0, op1); break;
     default: abort();
     }
 }
@@ -4271,20 +4271,16 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 switch (op) {
                 case 1: /* VQADD */
                     if (u) {
-                        gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
-                                                 cpu_V0, cpu_V1);
+                        gen_helper_neon_qadd_u64(cpu_V0, cpu_V0, cpu_V1);
                     } else {
-                        gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
-                                                 cpu_V0, cpu_V1);
+                        gen_helper_neon_qadd_s64(cpu_V0, cpu_V0, cpu_V1);
                     }
                     break;
                 case 5: /* VQSUB */
                     if (u) {
-                        gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
-                                                 cpu_V0, cpu_V1);
+                        gen_helper_neon_qsub_u64(cpu_V0, cpu_V0, cpu_V1);
                     } else {
-                        gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
-                                                 cpu_V0, cpu_V1);
+                        gen_helper_neon_qsub_s64(cpu_V0, cpu_V0, cpu_V1);
                     }
                     break;
                 case 8: /* VSHL */
@@ -4296,11 +4292,9 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                     break;
                 case 9: /* VQSHL */
                     if (u) {
-                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
-                                                 cpu_V1, cpu_V0);
+                        gen_helper_neon_qshl_u64(cpu_V0, cpu_V1, cpu_V0);
                     } else {
-                        gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
-                                                 cpu_V1, cpu_V0);
+                        gen_helper_neon_qshl_s64(cpu_V0, cpu_V1, cpu_V0);
                     }
                     break;
                 case 10: /* VRSHL */
@@ -4312,11 +4306,9 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                     break;
                 case 11: /* VQRSHL */
                     if (u) {
-                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
-                                                  cpu_V1, cpu_V0);
+                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_V1, cpu_V0);
                     } else {
-                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
-                                                  cpu_V1, cpu_V0);
+                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_V1, cpu_V0);
                     }
                     break;
                 case 16:
@@ -4388,7 +4380,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
             GEN_NEON_INTEGER_OP(hadd);
             break;
         case 1: /* VQADD */
-            GEN_NEON_INTEGER_OP_ENV(qadd);
+            GEN_NEON_INTEGER_OP(qadd);
             break;
         case 2: /* VRHADD */
             GEN_NEON_INTEGER_OP(rhadd);
@@ -4431,7 +4423,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
             GEN_NEON_INTEGER_OP(hsub);
             break;
         case 5: /* VQSUB */
-            GEN_NEON_INTEGER_OP_ENV(qsub);
+            GEN_NEON_INTEGER_OP(qsub);
             break;
         case 6: /* VCGT */
             GEN_NEON_INTEGER_OP(cgt);
@@ -4443,13 +4435,13 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
             GEN_NEON_INTEGER_OP(shl);
             break;
         case 9: /* VQSHL */
-            GEN_NEON_INTEGER_OP_ENV(qshl);
+            GEN_NEON_INTEGER_OP(qshl);
             break;
         case 10: /* VRSHL */
             GEN_NEON_INTEGER_OP(rshl);
             break;
         case 11: /* VQRSHL */
-            GEN_NEON_INTEGER_OP_ENV(qrshl);
+            GEN_NEON_INTEGER_OP(qrshl);
             break;
         case 12: /* VMAX */
             GEN_NEON_INTEGER_OP(max);
@@ -4532,14 +4524,14 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
         case 22: /* Hultiply high.  */
             if (!u) { /* VQDMULH */
                 switch (size) {
-                case 1: gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2); break;
-                case 2: gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2); break;
+                case 1: gen_helper_neon_qdmulh_s16(tmp, tmp, tmp2); break;
+                case 2: gen_helper_neon_qdmulh_s32(tmp, tmp, tmp2); break;
                 default: return 1;
                 }
             } else { /* VQRDHMUL */
                 switch (size) {
-                case 1: gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2); break;
-                case 2: gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); break;
+                case 1: gen_helper_neon_qrdmulh_s16(tmp, tmp, tmp2); break;
+                case 2: gen_helper_neon_qrdmulh_s32(tmp, tmp, tmp2); break;
                 default: return 1;
                 }
             }
@@ -4710,7 +4702,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                             break;
                         case 6: /* VQSHLU */
                             if (u) {
-                                gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
+                                gen_helper_neon_qshlu_s64(cpu_V0,
                                                           cpu_V0, cpu_V1);
                             } else {
                                 return 1;
@@ -4718,10 +4710,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                             break;
                         case 7: /* VQSHL */
                             if (u) {
-                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
+                                gen_helper_neon_qshl_u64(cpu_V0,
                                                          cpu_V0, cpu_V1);
                             } else {
-                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
+                                gen_helper_neon_qshl_s64(cpu_V0,
                                                          cpu_V0, cpu_V1);
                             }
                             break;
@@ -4780,23 +4772,20 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                             }
                             switch (size) {
                             case 0:
-                                gen_helper_neon_qshlu_s8(tmp, cpu_env,
-                                                         tmp, tmp2);
+                                gen_helper_neon_qshlu_s8(tmp, tmp, tmp2);
                                 break;
                             case 1:
-                                gen_helper_neon_qshlu_s16(tmp, cpu_env,
-                                                          tmp, tmp2);
+                                gen_helper_neon_qshlu_s16(tmp, tmp, tmp2);
                                 break;
                             case 2:
-                                gen_helper_neon_qshlu_s32(tmp, cpu_env,
-                                                          tmp, tmp2);
+                                gen_helper_neon_qshlu_s32(tmp, tmp, tmp2);
                                 break;
                             default:
                                 return 1;
                             }
                             break;
                         case 7: /* VQSHL */
-                            GEN_NEON_INTEGER_OP_ENV(qshl);
+                            GEN_NEON_INTEGER_OP(qshl);
                             break;
                         }
                         tcg_temp_free_i32(tmp2);
@@ -5259,15 +5248,15 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                         tmp2 = neon_load_reg(rn, pass);
                         if (op == 12) {
                             if (size == 1) {
-                                gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
+                                gen_helper_neon_qdmulh_s16(tmp, tmp, tmp2);
                             } else {
-                                gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
+                                gen_helper_neon_qdmulh_s32(tmp, tmp, tmp2);
                             }
                         } else if (op == 13) {
                             if (size == 1) {
-                                gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
+                                gen_helper_neon_qrdmulh_s16(tmp, tmp, tmp2);
                             } else {
-                                gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
+                                gen_helper_neon_qrdmulh_s32(tmp, tmp, tmp2);
                             }
                         } else if (op & 1) {
                             gen_helper_neon_mul_f32(tmp, tmp, tmp2);
@@ -5614,17 +5603,17 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                             break;
                         case 14: /* VQABS */
                             switch (size) {
-                            case 0: gen_helper_neon_qabs_s8(tmp, cpu_env, tmp); break;
-                            case 1: gen_helper_neon_qabs_s16(tmp, cpu_env, tmp); break;
-                            case 2: gen_helper_neon_qabs_s32(tmp, cpu_env, tmp); break;
+                            case 0: gen_helper_neon_qabs_s8(tmp, tmp); break;
+                            case 1: gen_helper_neon_qabs_s16(tmp, tmp); break;
+                            case 2: gen_helper_neon_qabs_s32(tmp, tmp); break;
                             default: return 1;
                             }
                             break;
                         case 15: /* VQNEG */
                             switch (size) {
-                            case 0: gen_helper_neon_qneg_s8(tmp, cpu_env, tmp); break;
-                            case 1: gen_helper_neon_qneg_s16(tmp, cpu_env, tmp); break;
-                            case 2: gen_helper_neon_qneg_s32(tmp, cpu_env, tmp); break;
+                            case 0: gen_helper_neon_qneg_s8(tmp, tmp); break;
+                            case 1: gen_helper_neon_qneg_s16(tmp, tmp); break;
+                            case 2: gen_helper_neon_qneg_s32(tmp, tmp); break;
                             default: return 1;
                             }
                             break;

From 947a2fa21b61703802a660a938cabd7b3600ee79 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 4 Apr 2011 11:46:34 +0100
Subject: [PATCH 097/386] target-arm: Use global env in iwmmxt_helper.c helpers

Use the global 'env' variable in the helper functions in iwmmxt_helper.c.
This means we don't need to pass env as an argument to them any more.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/helpers.h       | 108 ++++++++++++++++-----------------
 target-arm/iwmmxt_helper.c |  80 +++++++++++--------------
 target-arm/translate.c     | 119 +++++++++++++++++--------------------
 3 files changed, 144 insertions(+), 163 deletions(-)

diff --git a/target-arm/helpers.h b/target-arm/helpers.h
index 0705b9c70a..ae701e8451 100644
--- a/target-arm/helpers.h
+++ b/target-arm/helpers.h
@@ -375,47 +375,47 @@ DEF_HELPER_2(iwmmxt_macsw, i64, i64, i64)
 DEF_HELPER_2(iwmmxt_macuw, i64, i64, i64)
 DEF_HELPER_1(iwmmxt_setpsr_nz, i32, i64)
 
-#define DEF_IWMMXT_HELPER_SIZE_ENV(name) \
-DEF_HELPER_3(iwmmxt_##name##b, i64, env, i64, i64) \
-DEF_HELPER_3(iwmmxt_##name##w, i64, env, i64, i64) \
-DEF_HELPER_3(iwmmxt_##name##l, i64, env, i64, i64) \
+#define DEF_IWMMXT_HELPER_SIZE(name) \
+DEF_HELPER_2(iwmmxt_##name##b, i64, i64, i64) \
+DEF_HELPER_2(iwmmxt_##name##w, i64, i64, i64) \
+DEF_HELPER_2(iwmmxt_##name##l, i64, i64, i64) \
 
-DEF_IWMMXT_HELPER_SIZE_ENV(unpackl)
-DEF_IWMMXT_HELPER_SIZE_ENV(unpackh)
+DEF_IWMMXT_HELPER_SIZE(unpackl)
+DEF_IWMMXT_HELPER_SIZE(unpackh)
 
-DEF_HELPER_2(iwmmxt_unpacklub, i64, env, i64)
-DEF_HELPER_2(iwmmxt_unpackluw, i64, env, i64)
-DEF_HELPER_2(iwmmxt_unpacklul, i64, env, i64)
-DEF_HELPER_2(iwmmxt_unpackhub, i64, env, i64)
-DEF_HELPER_2(iwmmxt_unpackhuw, i64, env, i64)
-DEF_HELPER_2(iwmmxt_unpackhul, i64, env, i64)
-DEF_HELPER_2(iwmmxt_unpacklsb, i64, env, i64)
-DEF_HELPER_2(iwmmxt_unpacklsw, i64, env, i64)
-DEF_HELPER_2(iwmmxt_unpacklsl, i64, env, i64)
-DEF_HELPER_2(iwmmxt_unpackhsb, i64, env, i64)
-DEF_HELPER_2(iwmmxt_unpackhsw, i64, env, i64)
-DEF_HELPER_2(iwmmxt_unpackhsl, i64, env, i64)
+DEF_HELPER_1(iwmmxt_unpacklub, i64, i64)
+DEF_HELPER_1(iwmmxt_unpackluw, i64, i64)
+DEF_HELPER_1(iwmmxt_unpacklul, i64, i64)
+DEF_HELPER_1(iwmmxt_unpackhub, i64, i64)
+DEF_HELPER_1(iwmmxt_unpackhuw, i64, i64)
+DEF_HELPER_1(iwmmxt_unpackhul, i64, i64)
+DEF_HELPER_1(iwmmxt_unpacklsb, i64, i64)
+DEF_HELPER_1(iwmmxt_unpacklsw, i64, i64)
+DEF_HELPER_1(iwmmxt_unpacklsl, i64, i64)
+DEF_HELPER_1(iwmmxt_unpackhsb, i64, i64)
+DEF_HELPER_1(iwmmxt_unpackhsw, i64, i64)
+DEF_HELPER_1(iwmmxt_unpackhsl, i64, i64)
 
-DEF_IWMMXT_HELPER_SIZE_ENV(cmpeq)
-DEF_IWMMXT_HELPER_SIZE_ENV(cmpgtu)
-DEF_IWMMXT_HELPER_SIZE_ENV(cmpgts)
+DEF_IWMMXT_HELPER_SIZE(cmpeq)
+DEF_IWMMXT_HELPER_SIZE(cmpgtu)
+DEF_IWMMXT_HELPER_SIZE(cmpgts)
 
-DEF_IWMMXT_HELPER_SIZE_ENV(mins)
-DEF_IWMMXT_HELPER_SIZE_ENV(minu)
-DEF_IWMMXT_HELPER_SIZE_ENV(maxs)
-DEF_IWMMXT_HELPER_SIZE_ENV(maxu)
+DEF_IWMMXT_HELPER_SIZE(mins)
+DEF_IWMMXT_HELPER_SIZE(minu)
+DEF_IWMMXT_HELPER_SIZE(maxs)
+DEF_IWMMXT_HELPER_SIZE(maxu)
 
-DEF_IWMMXT_HELPER_SIZE_ENV(subn)
-DEF_IWMMXT_HELPER_SIZE_ENV(addn)
-DEF_IWMMXT_HELPER_SIZE_ENV(subu)
-DEF_IWMMXT_HELPER_SIZE_ENV(addu)
-DEF_IWMMXT_HELPER_SIZE_ENV(subs)
-DEF_IWMMXT_HELPER_SIZE_ENV(adds)
+DEF_IWMMXT_HELPER_SIZE(subn)
+DEF_IWMMXT_HELPER_SIZE(addn)
+DEF_IWMMXT_HELPER_SIZE(subu)
+DEF_IWMMXT_HELPER_SIZE(addu)
+DEF_IWMMXT_HELPER_SIZE(subs)
+DEF_IWMMXT_HELPER_SIZE(adds)
 
-DEF_HELPER_3(iwmmxt_avgb0, i64, env, i64, i64)
-DEF_HELPER_3(iwmmxt_avgb1, i64, env, i64, i64)
-DEF_HELPER_3(iwmmxt_avgw0, i64, env, i64, i64)
-DEF_HELPER_3(iwmmxt_avgw1, i64, env, i64, i64)
+DEF_HELPER_2(iwmmxt_avgb0, i64, i64, i64)
+DEF_HELPER_2(iwmmxt_avgb1, i64, i64, i64)
+DEF_HELPER_2(iwmmxt_avgw0, i64, i64, i64)
+DEF_HELPER_2(iwmmxt_avgw1, i64, i64, i64)
 
 DEF_HELPER_2(iwmmxt_msadb, i64, i64, i64)
 
@@ -434,26 +434,26 @@ DEF_HELPER_1(iwmmxt_msbb, i32, i64)
 DEF_HELPER_1(iwmmxt_msbw, i32, i64)
 DEF_HELPER_1(iwmmxt_msbl, i32, i64)
 
-DEF_HELPER_3(iwmmxt_srlw, i64, env, i64, i32)
-DEF_HELPER_3(iwmmxt_srll, i64, env, i64, i32)
-DEF_HELPER_3(iwmmxt_srlq, i64, env, i64, i32)
-DEF_HELPER_3(iwmmxt_sllw, i64, env, i64, i32)
-DEF_HELPER_3(iwmmxt_slll, i64, env, i64, i32)
-DEF_HELPER_3(iwmmxt_sllq, i64, env, i64, i32)
-DEF_HELPER_3(iwmmxt_sraw, i64, env, i64, i32)
-DEF_HELPER_3(iwmmxt_sral, i64, env, i64, i32)
-DEF_HELPER_3(iwmmxt_sraq, i64, env, i64, i32)
-DEF_HELPER_3(iwmmxt_rorw, i64, env, i64, i32)
-DEF_HELPER_3(iwmmxt_rorl, i64, env, i64, i32)
-DEF_HELPER_3(iwmmxt_rorq, i64, env, i64, i32)
-DEF_HELPER_3(iwmmxt_shufh, i64, env, i64, i32)
+DEF_HELPER_2(iwmmxt_srlw, i64, i64, i32)
+DEF_HELPER_2(iwmmxt_srll, i64, i64, i32)
+DEF_HELPER_2(iwmmxt_srlq, i64, i64, i32)
+DEF_HELPER_2(iwmmxt_sllw, i64, i64, i32)
+DEF_HELPER_2(iwmmxt_slll, i64, i64, i32)
+DEF_HELPER_2(iwmmxt_sllq, i64, i64, i32)
+DEF_HELPER_2(iwmmxt_sraw, i64, i64, i32)
+DEF_HELPER_2(iwmmxt_sral, i64, i64, i32)
+DEF_HELPER_2(iwmmxt_sraq, i64, i64, i32)
+DEF_HELPER_2(iwmmxt_rorw, i64, i64, i32)
+DEF_HELPER_2(iwmmxt_rorl, i64, i64, i32)
+DEF_HELPER_2(iwmmxt_rorq, i64, i64, i32)
+DEF_HELPER_2(iwmmxt_shufh, i64, i64, i32)
 
-DEF_HELPER_3(iwmmxt_packuw, i64, env, i64, i64)
-DEF_HELPER_3(iwmmxt_packul, i64, env, i64, i64)
-DEF_HELPER_3(iwmmxt_packuq, i64, env, i64, i64)
-DEF_HELPER_3(iwmmxt_packsw, i64, env, i64, i64)
-DEF_HELPER_3(iwmmxt_packsl, i64, env, i64, i64)
-DEF_HELPER_3(iwmmxt_packsq, i64, env, i64, i64)
+DEF_HELPER_2(iwmmxt_packuw, i64, i64, i64)
+DEF_HELPER_2(iwmmxt_packul, i64, i64, i64)
+DEF_HELPER_2(iwmmxt_packuq, i64, i64, i64)
+DEF_HELPER_2(iwmmxt_packsw, i64, i64, i64)
+DEF_HELPER_2(iwmmxt_packsl, i64, i64, i64)
+DEF_HELPER_2(iwmmxt_packsq, i64, i64, i64)
 
 DEF_HELPER_3(iwmmxt_muladdsl, i64, i64, i32, i32)
 DEF_HELPER_3(iwmmxt_muladdsw, i64, i64, i32, i32)
diff --git a/target-arm/iwmmxt_helper.c b/target-arm/iwmmxt_helper.c
index 3332f708c9..3941f1fd89 100644
--- a/target-arm/iwmmxt_helper.c
+++ b/target-arm/iwmmxt_helper.c
@@ -23,7 +23,7 @@
 #include <stdio.h>
 
 #include "cpu.h"
-#include "exec-all.h"
+#include "exec.h"
 #include "helpers.h"
 
 /* iwMMXt macros extracted from GNU gdb.  */
@@ -162,8 +162,7 @@ uint64_t HELPER(iwmmxt_macuw)(uint64_t a, uint64_t b)
     SIMD64_SET(NBIT64(x), SIMD_NBIT) | \
     SIMD64_SET(ZBIT64(x), SIMD_ZBIT)
 #define IWMMXT_OP_UNPACK(S, SH0, SH1, SH2, SH3)			\
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, b)))(CPUState *env, \
-                                                 uint64_t a, uint64_t b) \
+uint64_t HELPER(glue(iwmmxt_unpack, glue(S, b)))(uint64_t a, uint64_t b) \
 {								\
     a =							        \
         (((a >> SH0) & 0xff) << 0) | (((b >> SH0) & 0xff) << 8) |	\
@@ -177,8 +176,7 @@ uint64_t HELPER(glue(iwmmxt_unpack, glue(S, b)))(CPUState *env, \
         NZBIT8(a >> 48, 6) | NZBIT8(a >> 56, 7);		\
     return a;                                                   \
 }								\
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, w)))(CPUState *env, \
-                                        uint64_t a, uint64_t b) \
+uint64_t HELPER(glue(iwmmxt_unpack, glue(S, w)))(uint64_t a, uint64_t b) \
 {								\
     a =							        \
         (((a >> SH0) & 0xffff) << 0) |				\
@@ -190,8 +188,7 @@ uint64_t HELPER(glue(iwmmxt_unpack, glue(S, w)))(CPUState *env, \
         NZBIT8(a >> 32, 2) | NZBIT8(a >> 48, 3);		\
     return a;                                                   \
 }								\
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, l)))(CPUState *env, \
-                                        uint64_t a, uint64_t b) \
+uint64_t HELPER(glue(iwmmxt_unpack, glue(S, l)))(uint64_t a, uint64_t b) \
 {								\
     a =							        \
         (((a >> SH0) & 0xffffffff) << 0) |			\
@@ -200,8 +197,7 @@ uint64_t HELPER(glue(iwmmxt_unpack, glue(S, l)))(CPUState *env, \
         NZBIT32(a >> 0, 0) | NZBIT32(a >> 32, 1);		\
     return a;                                                   \
 }								\
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, ub)))(CPUState *env, \
-                                                  uint64_t x)   \
+uint64_t HELPER(glue(iwmmxt_unpack, glue(S, ub)))(uint64_t x)   \
 {								\
     x =							        \
         (((x >> SH0) & 0xff) << 0) |				\
@@ -213,8 +209,7 @@ uint64_t HELPER(glue(iwmmxt_unpack, glue(S, ub)))(CPUState *env, \
         NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3);		\
     return x;                                                   \
 }								\
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, uw)))(CPUState *env, \
-                                                  uint64_t x)   \
+uint64_t HELPER(glue(iwmmxt_unpack, glue(S, uw)))(uint64_t x)   \
 {								\
     x =							        \
         (((x >> SH0) & 0xffff) << 0) |				\
@@ -223,15 +218,13 @@ uint64_t HELPER(glue(iwmmxt_unpack, glue(S, uw)))(CPUState *env, \
         NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1);		\
     return x;                                                   \
 }								\
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, ul)))(CPUState *env, \
-                                                  uint64_t x)   \
+uint64_t HELPER(glue(iwmmxt_unpack, glue(S, ul)))(uint64_t x)   \
 {								\
     x = (((x >> SH0) & 0xffffffff) << 0);			\
     env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x >> 0);	\
     return x;                                                   \
 }								\
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, sb)))(CPUState *env, \
-                                                  uint64_t x)   \
+uint64_t HELPER(glue(iwmmxt_unpack, glue(S, sb)))(uint64_t x)   \
 {								\
     x =							        \
         ((uint64_t) EXTEND8H((x >> SH0) & 0xff) << 0) |	        \
@@ -243,8 +236,7 @@ uint64_t HELPER(glue(iwmmxt_unpack, glue(S, sb)))(CPUState *env, \
         NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3);		\
     return x;                                                   \
 }								\
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, sw)))(CPUState *env, \
-                                                  uint64_t x)   \
+uint64_t HELPER(glue(iwmmxt_unpack, glue(S, sw)))(uint64_t x)   \
 {								\
     x =							        \
         ((uint64_t) EXTEND16((x >> SH0) & 0xffff) << 0) |	\
@@ -253,8 +245,7 @@ uint64_t HELPER(glue(iwmmxt_unpack, glue(S, sw)))(CPUState *env, \
         NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1);		\
     return x;                                                   \
 }								\
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, sl)))(CPUState *env, \
-                                                  uint64_t x)   \
+uint64_t HELPER(glue(iwmmxt_unpack, glue(S, sl)))(uint64_t x)   \
 {								\
     x = EXTEND32((x >> SH0) & 0xffffffff);			\
     env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x >> 0);	\
@@ -264,8 +255,7 @@ IWMMXT_OP_UNPACK(l, 0, 8, 16, 24)
 IWMMXT_OP_UNPACK(h, 32, 40, 48, 56)
 
 #define IWMMXT_OP_CMP(SUFF, Tb, Tw, Tl, O)			\
-uint64_t HELPER(glue(iwmmxt_, glue(SUFF, b)))(CPUState *env,    \
-                                        uint64_t a, uint64_t b) \
+uint64_t HELPER(glue(iwmmxt_, glue(SUFF, b)))(uint64_t a, uint64_t b) \
 {								\
     a =							        \
         CMP(0, Tb, O, 0xff) | CMP(8, Tb, O, 0xff) |		\
@@ -279,8 +269,7 @@ uint64_t HELPER(glue(iwmmxt_, glue(SUFF, b)))(CPUState *env,    \
         NZBIT8(a >> 48, 6) | NZBIT8(a >> 56, 7);		\
     return a;                                                   \
 }								\
-uint64_t HELPER(glue(iwmmxt_, glue(SUFF, w)))(CPUState *env,    \
-                                        uint64_t a, uint64_t b) \
+uint64_t HELPER(glue(iwmmxt_, glue(SUFF, w)))(uint64_t a, uint64_t b) \
 {								\
     a = CMP(0, Tw, O, 0xffff) | CMP(16, Tw, O, 0xffff) |	\
         CMP(32, Tw, O, 0xffff) | CMP(48, Tw, O, 0xffff);	\
@@ -289,8 +278,7 @@ uint64_t HELPER(glue(iwmmxt_, glue(SUFF, w)))(CPUState *env,    \
         NZBIT16(a >> 32, 2) | NZBIT16(a >> 48, 3);		\
     return a;                                                   \
 }								\
-uint64_t HELPER(glue(iwmmxt_, glue(SUFF, l)))(CPUState *env,    \
-                                        uint64_t a, uint64_t b) \
+uint64_t HELPER(glue(iwmmxt_, glue(SUFF, l)))(uint64_t a, uint64_t b) \
 {								\
     a = CMP(0, Tl, O, 0xffffffff) |				\
         CMP(32, Tl, O, 0xffffffff);				\
@@ -329,7 +317,7 @@ IWMMXT_OP_CMP(adds, int8_t, int16_t, int32_t, +)
 #define AVGB(SHR) ((( \
         ((a >> SHR) & 0xff) + ((b >> SHR) & 0xff) + round) >> 1) << SHR)
 #define IWMMXT_OP_AVGB(r)                                                 \
-uint64_t HELPER(iwmmxt_avgb##r)(CPUState *env, uint64_t a, uint64_t b)    \
+uint64_t HELPER(iwmmxt_avgb##r)(uint64_t a, uint64_t b)                   \
 {                                                                         \
     const int round = r;                                                  \
     a = AVGB(0) | AVGB(8) | AVGB(16) | AVGB(24) |                         \
@@ -353,7 +341,7 @@ IWMMXT_OP_AVGB(1)
 #define AVGW(SHR) ((( \
         ((a >> SHR) & 0xffff) + ((b >> SHR) & 0xffff) + round) >> 1) << SHR)
 #define IWMMXT_OP_AVGW(r)                                               \
-uint64_t HELPER(iwmmxt_avgw##r)(CPUState *env, uint64_t a, uint64_t b)  \
+uint64_t HELPER(iwmmxt_avgw##r)(uint64_t a, uint64_t b)                 \
 {                                                                       \
     const int round = r;                                                \
     a = AVGW(0) | AVGW(16) | AVGW(32) | AVGW(48);                       \
@@ -464,7 +452,7 @@ uint32_t HELPER(iwmmxt_msbl)(uint64_t x)
 }
 
 /* FIXME: Split wCASF setting into a separate op to avoid env use.  */
-uint64_t HELPER(iwmmxt_srlw)(CPUState *env, uint64_t x, uint32_t n)
+uint64_t HELPER(iwmmxt_srlw)(uint64_t x, uint32_t n)
 {
     x = (((x & (0xffffll << 0)) >> n) & (0xffffll << 0)) |
         (((x & (0xffffll << 16)) >> n) & (0xffffll << 16)) |
@@ -476,7 +464,7 @@ uint64_t HELPER(iwmmxt_srlw)(CPUState *env, uint64_t x, uint32_t n)
     return x;
 }
 
-uint64_t HELPER(iwmmxt_srll)(CPUState *env, uint64_t x, uint32_t n)
+uint64_t HELPER(iwmmxt_srll)(uint64_t x, uint32_t n)
 {
     x = ((x & (0xffffffffll << 0)) >> n) |
         ((x >> n) & (0xffffffffll << 32));
@@ -485,14 +473,14 @@ uint64_t HELPER(iwmmxt_srll)(CPUState *env, uint64_t x, uint32_t n)
     return x;
 }
 
-uint64_t HELPER(iwmmxt_srlq)(CPUState *env, uint64_t x, uint32_t n)
+uint64_t HELPER(iwmmxt_srlq)(uint64_t x, uint32_t n)
 {
     x >>= n;
     env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x);
     return x;
 }
 
-uint64_t HELPER(iwmmxt_sllw)(CPUState *env, uint64_t x, uint32_t n)
+uint64_t HELPER(iwmmxt_sllw)(uint64_t x, uint32_t n)
 {
     x = (((x & (0xffffll << 0)) << n) & (0xffffll << 0)) |
         (((x & (0xffffll << 16)) << n) & (0xffffll << 16)) |
@@ -504,7 +492,7 @@ uint64_t HELPER(iwmmxt_sllw)(CPUState *env, uint64_t x, uint32_t n)
     return x;
 }
 
-uint64_t HELPER(iwmmxt_slll)(CPUState *env, uint64_t x, uint32_t n)
+uint64_t HELPER(iwmmxt_slll)(uint64_t x, uint32_t n)
 {
     x = ((x << n) & (0xffffffffll << 0)) |
         ((x & (0xffffffffll << 32)) << n);
@@ -513,14 +501,14 @@ uint64_t HELPER(iwmmxt_slll)(CPUState *env, uint64_t x, uint32_t n)
     return x;
 }
 
-uint64_t HELPER(iwmmxt_sllq)(CPUState *env, uint64_t x, uint32_t n)
+uint64_t HELPER(iwmmxt_sllq)(uint64_t x, uint32_t n)
 {
     x <<= n;
     env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x);
     return x;
 }
 
-uint64_t HELPER(iwmmxt_sraw)(CPUState *env, uint64_t x, uint32_t n)
+uint64_t HELPER(iwmmxt_sraw)(uint64_t x, uint32_t n)
 {
     x = ((uint64_t) ((EXTEND16(x >> 0) >> n) & 0xffff) << 0) |
         ((uint64_t) ((EXTEND16(x >> 16) >> n) & 0xffff) << 16) |
@@ -532,7 +520,7 @@ uint64_t HELPER(iwmmxt_sraw)(CPUState *env, uint64_t x, uint32_t n)
     return x;
 }
 
-uint64_t HELPER(iwmmxt_sral)(CPUState *env, uint64_t x, uint32_t n)
+uint64_t HELPER(iwmmxt_sral)(uint64_t x, uint32_t n)
 {
     x = (((EXTEND32(x >> 0) >> n) & 0xffffffff) << 0) |
         (((EXTEND32(x >> 32) >> n) & 0xffffffff) << 32);
@@ -541,14 +529,14 @@ uint64_t HELPER(iwmmxt_sral)(CPUState *env, uint64_t x, uint32_t n)
     return x;
 }
 
-uint64_t HELPER(iwmmxt_sraq)(CPUState *env, uint64_t x, uint32_t n)
+uint64_t HELPER(iwmmxt_sraq)(uint64_t x, uint32_t n)
 {
     x = (int64_t) x >> n;
     env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x);
     return x;
 }
 
-uint64_t HELPER(iwmmxt_rorw)(CPUState *env, uint64_t x, uint32_t n)
+uint64_t HELPER(iwmmxt_rorw)(uint64_t x, uint32_t n)
 {
     x = ((((x & (0xffffll << 0)) >> n) |
           ((x & (0xffffll << 0)) << (16 - n))) & (0xffffll << 0)) |
@@ -564,7 +552,7 @@ uint64_t HELPER(iwmmxt_rorw)(CPUState *env, uint64_t x, uint32_t n)
     return x;
 }
 
-uint64_t HELPER(iwmmxt_rorl)(CPUState *env, uint64_t x, uint32_t n)
+uint64_t HELPER(iwmmxt_rorl)(uint64_t x, uint32_t n)
 {
     x = ((x & (0xffffffffll << 0)) >> n) |
         ((x >> n) & (0xffffffffll << 32)) |
@@ -575,14 +563,14 @@ uint64_t HELPER(iwmmxt_rorl)(CPUState *env, uint64_t x, uint32_t n)
     return x;
 }
 
-uint64_t HELPER(iwmmxt_rorq)(CPUState *env, uint64_t x, uint32_t n)
+uint64_t HELPER(iwmmxt_rorq)(uint64_t x, uint32_t n)
 {
     x = (x >> n) | (x << (64 - n));
     env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x);
     return x;
 }
 
-uint64_t HELPER(iwmmxt_shufh)(CPUState *env, uint64_t x, uint32_t n)
+uint64_t HELPER(iwmmxt_shufh)(uint64_t x, uint32_t n)
 {
     x = (((x >> ((n << 4) & 0x30)) & 0xffff) << 0) |
         (((x >> ((n << 2) & 0x30)) & 0xffff) << 16) |
@@ -595,7 +583,7 @@ uint64_t HELPER(iwmmxt_shufh)(CPUState *env, uint64_t x, uint32_t n)
 }
 
 /* TODO: Unsigned-Saturation */
-uint64_t HELPER(iwmmxt_packuw)(CPUState *env, uint64_t a, uint64_t b)
+uint64_t HELPER(iwmmxt_packuw)(uint64_t a, uint64_t b)
 {
     a = (((a >> 0) & 0xff) << 0) | (((a >> 16) & 0xff) << 8) |
         (((a >> 32) & 0xff) << 16) | (((a >> 48) & 0xff) << 24) |
@@ -609,7 +597,7 @@ uint64_t HELPER(iwmmxt_packuw)(CPUState *env, uint64_t a, uint64_t b)
     return a;
 }
 
-uint64_t HELPER(iwmmxt_packul)(CPUState *env, uint64_t a, uint64_t b)
+uint64_t HELPER(iwmmxt_packul)(uint64_t a, uint64_t b)
 {
     a = (((a >> 0) & 0xffff) << 0) | (((a >> 32) & 0xffff) << 16) |
         (((b >> 0) & 0xffff) << 32) | (((b >> 32) & 0xffff) << 48);
@@ -619,7 +607,7 @@ uint64_t HELPER(iwmmxt_packul)(CPUState *env, uint64_t a, uint64_t b)
     return a;
 }
 
-uint64_t HELPER(iwmmxt_packuq)(CPUState *env, uint64_t a, uint64_t b)
+uint64_t HELPER(iwmmxt_packuq)(uint64_t a, uint64_t b)
 {
     a = (a & 0xffffffff) | ((b & 0xffffffff) << 32);
     env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
@@ -628,7 +616,7 @@ uint64_t HELPER(iwmmxt_packuq)(CPUState *env, uint64_t a, uint64_t b)
 }
 
 /* TODO: Signed-Saturation */
-uint64_t HELPER(iwmmxt_packsw)(CPUState *env, uint64_t a, uint64_t b)
+uint64_t HELPER(iwmmxt_packsw)(uint64_t a, uint64_t b)
 {
     a = (((a >> 0) & 0xff) << 0) | (((a >> 16) & 0xff) << 8) |
         (((a >> 32) & 0xff) << 16) | (((a >> 48) & 0xff) << 24) |
@@ -642,7 +630,7 @@ uint64_t HELPER(iwmmxt_packsw)(CPUState *env, uint64_t a, uint64_t b)
     return a;
 }
 
-uint64_t HELPER(iwmmxt_packsl)(CPUState *env, uint64_t a, uint64_t b)
+uint64_t HELPER(iwmmxt_packsl)(uint64_t a, uint64_t b)
 {
     a = (((a >> 0) & 0xffff) << 0) | (((a >> 32) & 0xffff) << 16) |
         (((b >> 0) & 0xffff) << 32) | (((b >> 32) & 0xffff) << 48);
@@ -652,7 +640,7 @@ uint64_t HELPER(iwmmxt_packsl)(CPUState *env, uint64_t a, uint64_t b)
     return a;
 }
 
-uint64_t HELPER(iwmmxt_packsq)(CPUState *env, uint64_t a, uint64_t b)
+uint64_t HELPER(iwmmxt_packsq)(uint64_t a, uint64_t b)
 {
     a = (a & 0xffffffff) | ((b & 0xffffffff) << 32);
     env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 53c40acca9..c6cb39ad2b 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -1159,22 +1159,15 @@ static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
     gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
 }
 
-#define IWMMXT_OP_ENV(name) \
-static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
-{ \
-    iwmmxt_load_reg(cpu_V1, rn); \
-    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
-}
+#define IWMMXT_OP_SIZE(name) \
+IWMMXT_OP(name##b) \
+IWMMXT_OP(name##w) \
+IWMMXT_OP(name##l)
 
-#define IWMMXT_OP_ENV_SIZE(name) \
-IWMMXT_OP_ENV(name##b) \
-IWMMXT_OP_ENV(name##w) \
-IWMMXT_OP_ENV(name##l)
-
-#define IWMMXT_OP_ENV1(name) \
+#define IWMMXT_OP_1(name) \
 static inline void gen_op_iwmmxt_##name##_M0(void) \
 { \
-    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
+    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0); \
 }
 
 IWMMXT_OP(maddsq)
@@ -1188,51 +1181,51 @@ IWMMXT_OP(muluhw)
 IWMMXT_OP(macsw)
 IWMMXT_OP(macuw)
 
-IWMMXT_OP_ENV_SIZE(unpackl)
-IWMMXT_OP_ENV_SIZE(unpackh)
+IWMMXT_OP_SIZE(unpackl)
+IWMMXT_OP_SIZE(unpackh)
 
-IWMMXT_OP_ENV1(unpacklub)
-IWMMXT_OP_ENV1(unpackluw)
-IWMMXT_OP_ENV1(unpacklul)
-IWMMXT_OP_ENV1(unpackhub)
-IWMMXT_OP_ENV1(unpackhuw)
-IWMMXT_OP_ENV1(unpackhul)
-IWMMXT_OP_ENV1(unpacklsb)
-IWMMXT_OP_ENV1(unpacklsw)
-IWMMXT_OP_ENV1(unpacklsl)
-IWMMXT_OP_ENV1(unpackhsb)
-IWMMXT_OP_ENV1(unpackhsw)
-IWMMXT_OP_ENV1(unpackhsl)
+IWMMXT_OP_1(unpacklub)
+IWMMXT_OP_1(unpackluw)
+IWMMXT_OP_1(unpacklul)
+IWMMXT_OP_1(unpackhub)
+IWMMXT_OP_1(unpackhuw)
+IWMMXT_OP_1(unpackhul)
+IWMMXT_OP_1(unpacklsb)
+IWMMXT_OP_1(unpacklsw)
+IWMMXT_OP_1(unpacklsl)
+IWMMXT_OP_1(unpackhsb)
+IWMMXT_OP_1(unpackhsw)
+IWMMXT_OP_1(unpackhsl)
 
-IWMMXT_OP_ENV_SIZE(cmpeq)
-IWMMXT_OP_ENV_SIZE(cmpgtu)
-IWMMXT_OP_ENV_SIZE(cmpgts)
+IWMMXT_OP_SIZE(cmpeq)
+IWMMXT_OP_SIZE(cmpgtu)
+IWMMXT_OP_SIZE(cmpgts)
 
-IWMMXT_OP_ENV_SIZE(mins)
-IWMMXT_OP_ENV_SIZE(minu)
-IWMMXT_OP_ENV_SIZE(maxs)
-IWMMXT_OP_ENV_SIZE(maxu)
+IWMMXT_OP_SIZE(mins)
+IWMMXT_OP_SIZE(minu)
+IWMMXT_OP_SIZE(maxs)
+IWMMXT_OP_SIZE(maxu)
 
-IWMMXT_OP_ENV_SIZE(subn)
-IWMMXT_OP_ENV_SIZE(addn)
-IWMMXT_OP_ENV_SIZE(subu)
-IWMMXT_OP_ENV_SIZE(addu)
-IWMMXT_OP_ENV_SIZE(subs)
-IWMMXT_OP_ENV_SIZE(adds)
+IWMMXT_OP_SIZE(subn)
+IWMMXT_OP_SIZE(addn)
+IWMMXT_OP_SIZE(subu)
+IWMMXT_OP_SIZE(addu)
+IWMMXT_OP_SIZE(subs)
+IWMMXT_OP_SIZE(adds)
 
-IWMMXT_OP_ENV(avgb0)
-IWMMXT_OP_ENV(avgb1)
-IWMMXT_OP_ENV(avgw0)
-IWMMXT_OP_ENV(avgw1)
+IWMMXT_OP(avgb0)
+IWMMXT_OP(avgb1)
+IWMMXT_OP(avgw0)
+IWMMXT_OP(avgw1)
 
 IWMMXT_OP(msadb)
 
-IWMMXT_OP_ENV(packuw)
-IWMMXT_OP_ENV(packul)
-IWMMXT_OP_ENV(packuq)
-IWMMXT_OP_ENV(packsw)
-IWMMXT_OP_ENV(packsl)
-IWMMXT_OP_ENV(packsq)
+IWMMXT_OP(packuw)
+IWMMXT_OP(packul)
+IWMMXT_OP(packuq)
+IWMMXT_OP(packsw)
+IWMMXT_OP(packsl)
+IWMMXT_OP(packsq)
 
 static void gen_op_iwmmxt_set_mup(void)
 {
@@ -1966,13 +1959,13 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
         }
         switch ((insn >> 22) & 3) {
         case 1:
-            gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
+            gen_helper_iwmmxt_srlw(cpu_M0, cpu_M0, tmp);
             break;
         case 2:
-            gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
+            gen_helper_iwmmxt_srll(cpu_M0, cpu_M0, tmp);
             break;
         case 3:
-            gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
+            gen_helper_iwmmxt_srlq(cpu_M0, cpu_M0, tmp);
             break;
         }
         tcg_temp_free_i32(tmp);
@@ -1994,13 +1987,13 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
         }
         switch ((insn >> 22) & 3) {
         case 1:
-            gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
+            gen_helper_iwmmxt_sraw(cpu_M0, cpu_M0, tmp);
             break;
         case 2:
-            gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
+            gen_helper_iwmmxt_sral(cpu_M0, cpu_M0, tmp);
             break;
         case 3:
-            gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
+            gen_helper_iwmmxt_sraq(cpu_M0, cpu_M0, tmp);
             break;
         }
         tcg_temp_free_i32(tmp);
@@ -2022,13 +2015,13 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
         }
         switch ((insn >> 22) & 3) {
         case 1:
-            gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
+            gen_helper_iwmmxt_sllw(cpu_M0, cpu_M0, tmp);
             break;
         case 2:
-            gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
+            gen_helper_iwmmxt_slll(cpu_M0, cpu_M0, tmp);
             break;
         case 3:
-            gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
+            gen_helper_iwmmxt_sllq(cpu_M0, cpu_M0, tmp);
             break;
         }
         tcg_temp_free_i32(tmp);
@@ -2050,21 +2043,21 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
                 tcg_temp_free_i32(tmp);
                 return 1;
             }
-            gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
+            gen_helper_iwmmxt_rorw(cpu_M0, cpu_M0, tmp);
             break;
         case 2:
             if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
                 tcg_temp_free_i32(tmp);
                 return 1;
             }
-            gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
+            gen_helper_iwmmxt_rorl(cpu_M0, cpu_M0, tmp);
             break;
         case 3:
             if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
                 tcg_temp_free_i32(tmp);
                 return 1;
             }
-            gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
+            gen_helper_iwmmxt_rorq(cpu_M0, cpu_M0, tmp);
             break;
         }
         tcg_temp_free_i32(tmp);
@@ -2198,7 +2191,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
         rd0 = (insn >> 16) & 0xf;
         gen_op_iwmmxt_movq_M0_wRn(rd0);
         tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
-        gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
+        gen_helper_iwmmxt_shufh(cpu_M0, cpu_M0, tmp);
         tcg_temp_free(tmp);
         gen_op_iwmmxt_movq_wRn_M0(wrd);
         gen_op_iwmmxt_set_mup();

From cc49f2178041d5754368d4b62cb56b735aafbe9f Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 4 Apr 2011 11:46:35 +0100
Subject: [PATCH 098/386] target-arm: Make Neon helper routines use correct FP
 status

Make the Neon helper routines use the correct FP status from
the CPUEnv rather than using a dummy static one. This means
they will correctly handle denormals and NaNs and will set
FPSCR exception bits properly.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/neon_helper.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index 315e69337e..c3ac96a099 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -18,8 +18,7 @@
 
 #define SET_QC() env->vfp.xregs[ARM_VFP_FPSCR] = CPSR_Q
 
-static float_status neon_float_status;
-#define NFS &neon_float_status
+#define NFS (&env->vfp.standard_fp_status)
 
 #define NEON_TYPE1(name, type) \
 typedef struct \

From c8f930c0eeb696d638f4d4bf654e955fa44ff40f Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 4 Apr 2011 12:09:22 +0100
Subject: [PATCH 099/386] cpu-all.h: Remove unnecessary target-specific ifdef
 for CPU_QuadU

CPU_QuadU isn't used on all targets, but there's no harm in defining the
typedef anyway. It only needs to be guarded by CONFIG_SOFTFLOAT, because
softfloat-native doesn't have a float128 type. This avoids the need for
every new target which uses CPU_QuadU to add itself to an #ifdef in
what ought to be target-agnostic code.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 cpu-all.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/cpu-all.h b/cpu-all.h
index 4cc445ffc3..dc0f2f02ab 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -138,11 +138,10 @@ typedef union {
     uint64_t ll;
 } CPU_DoubleU;
 
-#if defined(TARGET_SPARC) || defined(TARGET_S390X)
+#if defined(CONFIG_SOFTFLOAT)
 typedef union {
     float128 q;
-#if defined(HOST_WORDS_BIGENDIAN) \
-    || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
+#if defined(HOST_WORDS_BIGENDIAN)
     struct {
         uint32_t upmost;
         uint32_t upper;

From 99123e139d698bee1531e8887e1a58207a52082b Mon Sep 17 00:00:00 2001
From: Mike Frysinger <vapier@gentoo.org>
Date: Thu, 7 Apr 2011 01:12:28 -0400
Subject: [PATCH 100/386] configure: add --version flag

Standard autoconf scripts include a --version flag so people can easily
query things.  Add this to qemu's configure so it too can integrate with
build systems that have standard autotool helpers.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 configure | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configure b/configure
index faaed60540..ae97e11a97 100755
--- a/configure
+++ b/configure
@@ -494,6 +494,8 @@ for opt do
   case "$opt" in
   --help|-h) show_help=yes
   ;;
+  --version|-V) exec cat $source_path/VERSION
+  ;;
   --prefix=*) prefix="$optarg"
   ;;
   --interp-prefix=*) interp_prefix="$optarg"

From 3b8e6a2db1946b5f21e69fde31b39f43367f1928 Mon Sep 17 00:00:00 2001
From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
Date: Tue, 5 Apr 2011 13:00:36 +0200
Subject: [PATCH 101/386] exec: Handle registrations of the entire address
 space

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 exec.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/exec.c b/exec.c
index 964ce318fb..983c0db3f7 100644
--- a/exec.c
+++ b/exec.c
@@ -2611,6 +2611,7 @@ void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
     ram_addr_t orig_size = size;
     subpage_t *subpage;
 
+    assert(size);
     cpu_notify_set_memory(start_addr, size, phys_offset);
 
     if (phys_offset == IO_MEM_UNASSIGNED) {
@@ -2619,7 +2620,9 @@ void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
     region_offset &= TARGET_PAGE_MASK;
     size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
     end_addr = start_addr + (target_phys_addr_t)size;
-    for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) {
+
+    addr = start_addr;
+    do {
         p = phys_page_find(addr >> TARGET_PAGE_BITS);
         if (p && p->phys_offset != IO_MEM_UNASSIGNED) {
             ram_addr_t orig_memory = p->phys_offset;
@@ -2671,7 +2674,8 @@ void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
             }
         }
         region_offset += TARGET_PAGE_SIZE;
-    }
+        addr += TARGET_PAGE_SIZE;
+    } while (addr != end_addr);
 
     /* since each CPU stores ram addresses in its TLB cache, we must
        reset the modified entries */

From f6ec953ca329d4509e5a1a1ff051365fccdbb6b7 Mon Sep 17 00:00:00 2001
From: Feiran Zheng <famcool@gmail.com>
Date: Tue, 29 Mar 2011 09:00:15 +0800
Subject: [PATCH 102/386] hw/xen_disk: ioreq not finished on error

Bug fix: routines 'ioreq_runio_qemu_sync' and 'ioreq_runio_qemu_aio'
won't call 'ioreq_unmap' or 'ioreq_finish' on errors, leaving ioreq in
the blkdev->inflight list and a leak.

Signed-off-by: Feiran Zheng <famcool@gmail.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/xen_disk.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index 445bf03aa0..558bf8ae25 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -310,7 +310,7 @@ static int ioreq_runio_qemu_sync(struct ioreq *ioreq)
     off_t pos;
 
     if (ioreq->req.nr_segments && ioreq_map(ioreq) == -1)
-	goto err;
+	goto err_no_map;
     if (ioreq->presync)
 	bdrv_flush(blkdev->bs);
 
@@ -364,6 +364,9 @@ static int ioreq_runio_qemu_sync(struct ioreq *ioreq)
     return 0;
 
 err:
+    ioreq_unmap(ioreq);
+err_no_map:
+    ioreq_finish(ioreq);
     ioreq->status = BLKIF_RSP_ERROR;
     return -1;
 }
@@ -393,7 +396,7 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
     struct XenBlkDev *blkdev = ioreq->blkdev;
 
     if (ioreq->req.nr_segments && ioreq_map(ioreq) == -1)
-	goto err;
+	goto err_no_map;
 
     ioreq->aio_inflight++;
     if (ioreq->presync)
@@ -427,6 +430,9 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
     return 0;
 
 err:
+    ioreq_unmap(ioreq);
+err_no_map:
+    ioreq_finish(ioreq);
     ioreq->status = BLKIF_RSP_ERROR;
     return -1;
 }

From d22b2f41c470067758b3636a01b452dfeda7069f Mon Sep 17 00:00:00 2001
From: Ryan Harper <ryanh@us.ibm.com>
Date: Tue, 29 Mar 2011 20:51:47 -0500
Subject: [PATCH 103/386] Do not delete BlockDriverState when deleting the
 drive

When removing a drive from the host-side via drive_del we currently have
the following path:

drive_del
qemu_aio_flush()
bdrv_close()    // zaps bs->drv, which makes any subsequent I/O get
                // dropped.  Works as designed
drive_uninit()
bdrv_delete()   // frees the bs.  Since the device is still connected to
                // bs, any subsequent I/O is a use-after-free.

The value of bs->drv becomes unpredictable on free.  As long as it
remains null, I/O still gets dropped, however it could become non-null
at any point after the free resulting SEGVs or other QEMU state
corruption.

To resolve this issue as simply as possible, we can chose to not
actually delete the BlockDriverState pointer.  Since bdrv_close()
handles setting the drv pointer to NULL, we just need to remove the
BlockDriverState from the QLIST that is used to enumerate the block
devices.  This is currently handled within bdrv_delete, so move this
into its own function, bdrv_make_anon().

The result is that we can now invoke drive_del, this closes the file
descriptors and sets BlockDriverState->drv to NULL which prevents futher
IO to the device, and since we do not free BlockDriverState, we don't
have to worry about the copy retained in the block devices.

We also don't attempt to remove the qdev property since we are no longer
deleting the BlockDriverState on drives with associated drives.  This
also allows for removing Drives with no devices associated either.

Reported-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c    | 14 +++++++++++---
 block.h    |  1 +
 blockdev.c | 25 ++++++++-----------------
 3 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/block.c b/block.c
index c8e2f97614..c93ec6d418 100644
--- a/block.c
+++ b/block.c
@@ -697,14 +697,22 @@ void bdrv_close_all(void)
     }
 }
 
+/* make a BlockDriverState anonymous by removing from bdrv_state list.
+   Also, NULL terminate the device_name to prevent double remove */
+void bdrv_make_anon(BlockDriverState *bs)
+{
+    if (bs->device_name[0] != '\0') {
+        QTAILQ_REMOVE(&bdrv_states, bs, list);
+    }
+    bs->device_name[0] = '\0';
+}
+
 void bdrv_delete(BlockDriverState *bs)
 {
     assert(!bs->peer);
 
     /* remove from list, if necessary */
-    if (bs->device_name[0] != '\0') {
-        QTAILQ_REMOVE(&bdrv_states, bs, list);
-    }
+    bdrv_make_anon(bs);
 
     bdrv_close(bs);
     if (bs->file != NULL) {
diff --git a/block.h b/block.h
index 5d78fc0ed7..52e9cad55c 100644
--- a/block.h
+++ b/block.h
@@ -66,6 +66,7 @@ int bdrv_create(BlockDriver *drv, const char* filename,
     QEMUOptionParameter *options);
 int bdrv_create_file(const char* filename, QEMUOptionParameter *options);
 BlockDriverState *bdrv_new(const char *device_name);
+void bdrv_make_anon(BlockDriverState *bs);
 void bdrv_delete(BlockDriverState *bs);
 int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags);
 int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
diff --git a/blockdev.c b/blockdev.c
index bbe92fe196..5429621f0c 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -737,8 +737,6 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
 {
     const char *id = qdict_get_str(qdict, "id");
     BlockDriverState *bs;
-    BlockDriverState **ptr;
-    Property *prop;
 
     bs = bdrv_find(id);
     if (!bs) {
@@ -755,24 +753,17 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
     bdrv_flush(bs);
     bdrv_close(bs);
 
-    /* clean up guest state from pointing to host resource by
-     * finding and removing DeviceState "drive" property */
+    /* if we have a device associated with this BlockDriverState (bs->peer)
+     * then we need to make the drive anonymous until the device
+     * can be removed.  If this is a drive with no device backing
+     * then we can just get rid of the block driver state right here.
+     */
     if (bs->peer) {
-        for (prop = bs->peer->info->props; prop && prop->name; prop++) {
-            if (prop->info->type == PROP_TYPE_DRIVE) {
-                ptr = qdev_get_prop_ptr(bs->peer, prop);
-                if (*ptr == bs) {
-                    bdrv_detach(bs, bs->peer);
-                    *ptr = NULL;
-                    break;
-                }
-            }
-        }
+        bdrv_make_anon(bs);
+    } else {
+        drive_uninit(drive_get_by_blockdev(bs));
     }
 
-    /* clean up host side */
-    drive_uninit(drive_get_by_blockdev(bs));
-
     return 0;
 }
 

From b8c6d0958943c96ca9401961a1200568c7ec0268 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Date: Tue, 29 Mar 2011 20:04:40 +0100
Subject: [PATCH 104/386] trace: Trace bdrv_set_locked()

It can be handy to know when the guest locks/unlocks the CD-ROM tray.
This trace event makes that possible.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c      | 2 ++
 trace-events | 1 +
 2 files changed, 3 insertions(+)

diff --git a/block.c b/block.c
index c93ec6d418..d8da3b09d3 100644
--- a/block.c
+++ b/block.c
@@ -2817,6 +2817,8 @@ void bdrv_set_locked(BlockDriverState *bs, int locked)
 {
     BlockDriver *drv = bs->drv;
 
+    trace_bdrv_set_locked(bs, locked);
+
     bs->locked = locked;
     if (drv && drv->bdrv_set_locked) {
         drv->bdrv_set_locked(bs, locked);
diff --git a/trace-events b/trace-events
index 06efdb7753..703b745bc4 100644
--- a/trace-events
+++ b/trace-events
@@ -54,6 +54,7 @@ disable bdrv_aio_multiwrite_latefail(void *mcb, int i) "mcb %p i %d"
 disable bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque %p"
 disable bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
 disable bdrv_aio_writev(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
+disable bdrv_set_locked(void *bs, int locked) "bs %p locked %d"
 
 # hw/virtio-blk.c
 disable virtio_blk_req_complete(void *req, int status) "req %p status %d"

From 46a4e4e6085c1e5ae498e350009ff6d321d9ee67 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Date: Tue, 29 Mar 2011 20:04:41 +0100
Subject: [PATCH 105/386] block: Do not cache device size for removable media

The block layer caches the device size to avoid doing lseek(fd, 0,
SEEK_END) every time this value is needed.  For removable media the
device size becomes stale if a new medium is inserted.  This patch
simply prevents device size caching for removable media.

A smarter solution is to update the cached device size when a new medium
is inserted.  Given that there are currently bugs with CD-ROM media
change I do not want to implement that approach until we've gotten
things correct first.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/block.c b/block.c
index d8da3b09d3..f731c7afbf 100644
--- a/block.c
+++ b/block.c
@@ -1161,14 +1161,12 @@ int64_t bdrv_getlength(BlockDriverState *bs)
     if (!drv)
         return -ENOMEDIUM;
 
-    /* Fixed size devices use the total_sectors value for speed instead of
-       issuing a length query (like lseek) on each call.  Also, legacy block
-       drivers don't provide a bdrv_getlength function and must use
-       total_sectors. */
-    if (!bs->growable || !drv->bdrv_getlength) {
-        return bs->total_sectors * BDRV_SECTOR_SIZE;
+    if (bs->growable || bs->removable) {
+        if (drv->bdrv_getlength) {
+            return drv->bdrv_getlength(bs);
+        }
     }
-    return drv->bdrv_getlength(bs);
+    return bs->total_sectors * BDRV_SECTOR_SIZE;
 }
 
 /* return 0 as number of sectors if no device present or error */

From 6b837bc4a4d81861027c74f882d8c1d43f4ec30c Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@redhat.com>
Date: Wed, 30 Mar 2011 14:16:25 +0200
Subject: [PATCH 106/386] qemu-img: Initial progress printing support

This adds the basic infrastructure for supporting progress output
on the command line, as well as progress support for qemu-img commands
'rebase' and 'convert'.

Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 Makefile.objs    |  2 +-
 qemu-common.h    |  4 +++
 qemu-img-cmds.hx |  4 +--
 qemu-img.c       | 38 +++++++++++++++++++--
 qemu-progress.c  | 89 ++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 132 insertions(+), 5 deletions(-)
 create mode 100644 qemu-progress.c

diff --git a/Makefile.objs b/Makefile.objs
index c05f5e59be..94587e1740 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -14,7 +14,7 @@ oslib-obj-$(CONFIG_POSIX) += oslib-posix.o
 # block-obj-y is code used by both qemu system emulation and qemu-img
 
 block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o async.o
-block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o
+block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o qemu-progress.o
 block-obj-$(CONFIG_POSIX) += posix-aio-compat.o
 block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
 
diff --git a/qemu-common.h b/qemu-common.h
index 8ecb48820a..82e27c18d3 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -334,6 +334,10 @@ void qemu_iovec_memset(QEMUIOVector *qiov, int c, size_t count);
 void qemu_iovec_memset_skip(QEMUIOVector *qiov, int c, size_t count,
                             size_t skip);
 
+void qemu_progress_init(int enabled, float min_skip);
+void qemu_progress_end(void);
+void qemu_progress_print(float percent, int max);
+
 /* Convert a byte between binary and BCD.  */
 static inline uint8_t to_bcd(uint8_t val)
 {
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 6c7176f8b4..3072d383cf 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -28,7 +28,7 @@ STEXI
 ETEXI
 
 DEF("convert", img_convert,
-    "convert [-c] [-f fmt] [-O output_fmt] [-o options] [-s snapshot_name] filename [filename2 [...]] output_filename")
+    "convert [-c] [-p] [-f fmt] [-O output_fmt] [-o options] [-s snapshot_name] filename [filename2 [...]] output_filename")
 STEXI
 @item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
@@ -46,7 +46,7 @@ STEXI
 ETEXI
 
 DEF("rebase", img_rebase,
-    "rebase [-f fmt] [-u] -b backing_file [-F backing_fmt] filename")
+    "rebase [-f fmt] [-p] [-u] -b backing_file [-F backing_fmt] filename")
 STEXI
 @item rebase [-f @var{fmt}] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
 ETEXI
diff --git a/qemu-img.c b/qemu-img.c
index 7e3cc4cbd5..074388ce89 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -77,6 +77,7 @@ static void help(void)
            "       match exactly. The image doesn't need a working backing file before\n"
            "       rebasing in this case (useful for renaming the backing file)\n"
            "  '-h' with or without a command shows this help and lists the supported formats\n"
+           "  '-p' show progress of command (only certain commands)\n"
            "\n"
            "Parameters to snapshot subcommand:\n"
            "  'snapshot' is the name of the snapshot to create, apply or delete\n"
@@ -567,6 +568,7 @@ static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n,
 static int img_convert(int argc, char **argv)
 {
     int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
+    int progress = 0;
     const char *fmt, *out_fmt, *out_baseimg, *out_filename;
     BlockDriver *drv, *proto_drv;
     BlockDriverState **bs = NULL, *out_bs = NULL;
@@ -579,13 +581,14 @@ static int img_convert(int argc, char **argv)
     QEMUOptionParameter *out_baseimg_param;
     char *options = NULL;
     const char *snapshot_name = NULL;
+    float local_progress;
 
     fmt = NULL;
     out_fmt = "raw";
     out_baseimg = NULL;
     compress = 0;
     for(;;) {
-        c = getopt(argc, argv, "f:O:B:s:hce6o:");
+        c = getopt(argc, argv, "f:O:B:s:hce6o:p");
         if (c == -1) {
             break;
         }
@@ -620,6 +623,9 @@ static int img_convert(int argc, char **argv)
         case 's':
             snapshot_name = optarg;
             break;
+        case 'p':
+            progress = 1;
+            break;
         }
     }
 
@@ -642,6 +648,9 @@ static int img_convert(int argc, char **argv)
         goto out;
     }
         
+    qemu_progress_init(progress, 2.0);
+    qemu_progress_print(0, 100);
+
     bs = qemu_mallocz(bs_n * sizeof(BlockDriverState *));
 
     total_sectors = 0;
@@ -773,6 +782,11 @@ static int img_convert(int argc, char **argv)
         }
         cluster_sectors = cluster_size >> 9;
         sector_num = 0;
+
+        nb_sectors = total_sectors;
+        local_progress = (float)100 /
+            (nb_sectors / MIN(nb_sectors, (cluster_sectors)));
+
         for(;;) {
             int64_t bs_num;
             int remainder;
@@ -832,6 +846,7 @@ static int img_convert(int argc, char **argv)
                 }
             }
             sector_num += n;
+            qemu_progress_print(local_progress, 100);
         }
         /* signal EOF to align */
         bdrv_write_compressed(out_bs, 0, NULL, 0);
@@ -839,6 +854,10 @@ static int img_convert(int argc, char **argv)
         int has_zero_init = bdrv_has_zero_init(out_bs);
 
         sector_num = 0; // total number of sectors converted so far
+        nb_sectors = total_sectors - sector_num;
+        local_progress = (float)100 /
+            (nb_sectors / MIN(nb_sectors, (IO_BUF_SIZE / 512)));
+
         for(;;) {
             nb_sectors = total_sectors - sector_num;
             if (nb_sectors <= 0) {
@@ -912,9 +931,11 @@ static int img_convert(int argc, char **argv)
                 n -= n1;
                 buf1 += n1 * 512;
             }
+            qemu_progress_print(local_progress, 100);
         }
     }
 out:
+    qemu_progress_end();
     free_option_parameters(create_options);
     free_option_parameters(param);
     qemu_free(buf);
@@ -1184,6 +1205,7 @@ static int img_rebase(int argc, char **argv)
     const char *fmt, *out_basefmt, *out_baseimg;
     int c, flags, ret;
     int unsafe = 0;
+    int progress = 0;
 
     /* Parse commandline parameters */
     fmt = NULL;
@@ -1191,7 +1213,7 @@ static int img_rebase(int argc, char **argv)
     out_basefmt = NULL;
 
     for(;;) {
-        c = getopt(argc, argv, "uhf:F:b:");
+        c = getopt(argc, argv, "uhf:F:b:p");
         if (c == -1) {
             break;
         }
@@ -1212,6 +1234,9 @@ static int img_rebase(int argc, char **argv)
         case 'u':
             unsafe = 1;
             break;
+        case 'p':
+            progress = 1;
+            break;
         }
     }
 
@@ -1220,6 +1245,9 @@ static int img_rebase(int argc, char **argv)
     }
     filename = argv[optind++];
 
+    qemu_progress_init(progress, 2.0);
+    qemu_progress_print(0, 100);
+
     /*
      * Open the images.
      *
@@ -1295,12 +1323,15 @@ static int img_rebase(int argc, char **argv)
         int n;
         uint8_t * buf_old;
         uint8_t * buf_new;
+        float local_progress;
 
         buf_old = qemu_malloc(IO_BUF_SIZE);
         buf_new = qemu_malloc(IO_BUF_SIZE);
 
         bdrv_get_geometry(bs, &num_sectors);
 
+        local_progress = (float)100 /
+            (num_sectors / MIN(num_sectors, (IO_BUF_SIZE / 512)));
         for (sector = 0; sector < num_sectors; sector += n) {
 
             /* How many sectors can we handle with the next read? */
@@ -1348,6 +1379,7 @@ static int img_rebase(int argc, char **argv)
 
                 written += pnum;
             }
+            qemu_progress_print(local_progress, 100);
         }
 
         qemu_free(buf_old);
@@ -1368,6 +1400,7 @@ static int img_rebase(int argc, char **argv)
             out_baseimg, strerror(-ret));
     }
 
+    qemu_progress_print(100, 0);
     /*
      * TODO At this point it is possible to check if any clusters that are
      * allocated in the COW file are the same in the backing file. If so, they
@@ -1375,6 +1408,7 @@ static int img_rebase(int argc, char **argv)
      * backing file, in case of a crash this would lead to corruption.
      */
 out:
+    qemu_progress_end();
     /* Cleanup */
     if (!unsafe) {
         bdrv_delete(bs_old_backing);
diff --git a/qemu-progress.c b/qemu-progress.c
new file mode 100644
index 0000000000..656e065b1d
--- /dev/null
+++ b/qemu-progress.c
@@ -0,0 +1,89 @@
+/*
+ * QEMU progress printing utility functions
+ *
+ * Copyright (C) 2011 Jes Sorensen <Jes.Sorensen@redhat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu-common.h"
+#include "osdep.h"
+#include "sysemu.h"
+#include <stdio.h>
+
+struct progress_state {
+    int enabled;
+    float current;
+    float last_print;
+    float min_skip;
+};
+
+static struct progress_state state;
+
+/*
+ * Simple progress print function.
+ * @percent relative percent of current operation
+ * @max percent of total operation
+ */
+static void progress_simple_print(void)
+{
+    if (state.enabled) {
+        printf("    (%3.2f/100%%)\r", state.current);
+        fflush(stdout);
+    }
+}
+
+static void progress_simple_end(void)
+{
+    if (state.enabled) {
+        printf("\n");
+    }
+}
+
+void qemu_progress_init(int enabled, float min_skip)
+{
+    state.enabled = enabled;
+    state.min_skip = min_skip;
+}
+
+void qemu_progress_end(void)
+{
+    progress_simple_end();
+}
+
+void qemu_progress_print(float percent, int max)
+{
+    float current;
+
+    if (max == 0) {
+        current = percent;
+    } else {
+        current = state.current + percent / 100 * max;
+    }
+    if (current > 100) {
+        current = 100;
+    }
+    state.current = current;
+
+    if (current > (state.last_print + state.min_skip) ||
+        (current == 100) || (current == 0)) {
+        state.last_print = state.current;
+        progress_simple_print();
+    }
+}

From eb863add0204210480d018a3298ca22e4eadf3ce Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Thu, 31 Mar 2011 12:39:51 +0200
Subject: [PATCH 107/386] qemu-img rebase: Fix segfault if backing file can't
 be opened

bdrv_delete must not be called for a NULL BlockDriverState.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 qemu-img.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 074388ce89..d9c2c12fa0 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1411,8 +1411,12 @@ out:
     qemu_progress_end();
     /* Cleanup */
     if (!unsafe) {
-        bdrv_delete(bs_old_backing);
-        bdrv_delete(bs_new_backing);
+        if (bs_old_backing != NULL) {
+            bdrv_delete(bs_old_backing);
+        }
+        if (bs_new_backing != NULL) {
+            bdrv_delete(bs_new_backing);
+        }
     }
 
     bdrv_delete(bs);

From e2982c3a27ab4c0879e61de3c9c57b838f7d0966 Mon Sep 17 00:00:00 2001
From: Michael Tokarev <mjt@tls.msk.ru>
Date: Wed, 30 Mar 2011 16:31:05 +0400
Subject: [PATCH 108/386] exit if -drive specified is invalid instead of
 ignoring the "wrong" -drive

This fixes the problem when qemu continues even if -drive specification
is somehow invalid, resulting in a mess.  Applicable for both current
master and for stable-0.14 (and the same issue exist 0.13 and 0.12 too).

The prob can actually be seriuos: when you start guest with two drives
and make an error in the specification of one of them, and the guest
has something like a raid array on the two drives, guest may start failing
that array or kick "missing" drives which may result in a mess - this is
what actually happened to me, I did't want a resync at all, and a resync
resulted in re-writing (and allocating) a 4TB virtual drive I used for
testing, which in turn resulted in my filesystem filling up and whole
thing failing badly.  Yes it was just testing VM, I experimented with
larger raid arrays, but the end result was quite, well, unexpected.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 vl.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/vl.c b/vl.c
index de232b75e6..68c3b532bc 100644
--- a/vl.c
+++ b/vl.c
@@ -2102,7 +2102,9 @@ int main(int argc, char **argv, char **envp)
                           HD_OPTS);
                 break;
             case QEMU_OPTION_drive:
-                drive_def(optarg);
+                if (drive_def(optarg) == NULL) {
+                    exit(1);
+                }
 	        break;
             case QEMU_OPTION_set:
                 if (qemu_set_option(optarg) != 0)

From 757179038c4884dc43c2ecd0f4da3facb24f262c Mon Sep 17 00:00:00 2001
From: Isaku Yamahata <yamahata@valinux.co.jp>
Date: Sun, 3 Apr 2011 20:32:46 +0900
Subject: [PATCH 109/386] ide: consolidate drive_get(IF_IDE)

factor out ide initialization to call drive_get(IF_IDE)

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide.h           |  3 +++
 hw/ide/core.c      | 14 ++++++++++++++
 hw/mips_fulong2e.c |  9 +--------
 hw/mips_malta.c    | 10 +---------
 hw/mips_r4k.c      | 10 +---------
 hw/pc_piix.c       | 10 +---------
 hw/ppc_newworld.c  | 11 ++---------
 hw/ppc_oldworld.c  | 11 +++--------
 hw/ppc_prep.c      | 10 +---------
 hw/sun4u.c         |  9 +--------
 10 files changed, 28 insertions(+), 69 deletions(-)

diff --git a/hw/ide.h b/hw/ide.h
index 73fb550574..34d9394bcc 100644
--- a/hw/ide.h
+++ b/hw/ide.h
@@ -28,4 +28,7 @@ void mmio_ide_init (target_phys_addr_t membase, target_phys_addr_t membase2,
 
 void ide_get_bs(BlockDriverState *bs[], BusState *qbus);
 
+/* ide/core.c */
+void ide_drive_get(DriveInfo **hd, int max_bus);
+
 #endif /* HW_IDE_H */
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 007a4ee0c9..c11d457b7a 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2826,3 +2826,17 @@ const VMStateDescription vmstate_ide_bus = {
         VMSTATE_END_OF_LIST()
     }
 };
+
+void ide_drive_get(DriveInfo **hd, int max_bus)
+{
+    int i;
+
+    if (drive_get_max_bus(IF_IDE) >= max_bus) {
+        fprintf(stderr, "qemu: too many IDE bus: %d\n", max_bus);
+        exit(1);
+    }
+
+    for(i = 0; i < max_bus * MAX_IDE_DEVS; i++) {
+        hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
+    }
+}
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
index f5ae63980c..0e90d684b4 100644
--- a/hw/mips_fulong2e.c
+++ b/hw/mips_fulong2e.c
@@ -338,14 +338,7 @@ static void mips_fulong2e_init(ram_addr_t ram_size, const char *boot_device,
     pci_bus = bonito_init((qemu_irq *)&(env->irq[2]));
 
     /* South bridge */
-    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
-        fprintf(stderr, "qemu: too many IDE bus\n");
-        exit(1);
-    }
-
-    for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
-        hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
-    }
+    ide_drive_get(hd, MAX_IDE_BUS);
 
     via_devfn = vt82c686b_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 0));
     if (via_devfn < 0) {
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index d8baa6d7e3..bf0d76d03d 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -905,15 +905,7 @@ void mips_malta_init (ram_addr_t ram_size,
     pci_bus = gt64120_register(i8259);
 
     /* Southbridge */
-
-    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
-        fprintf(stderr, "qemu: too many IDE bus\n");
-        exit(1);
-    }
-
-    for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
-        hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
-    }
+    ide_drive_get(hd, MAX_IDE_BUS);
 
     piix4_devfn = piix4_init(pci_bus, 80);
     isa_bus_irqs(i8259);
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 8feb46163f..2834a46d52 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -287,15 +287,7 @@ void mips_r4k_init (ram_addr_t ram_size,
     if (nd_table[0].vlan)
         isa_ne2000_init(0x300, 9, &nd_table[0]);
 
-    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
-        fprintf(stderr, "qemu: too many IDE bus\n");
-        exit(1);
-    }
-
-    for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
-        hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
-    }
-
+    ide_drive_get(hd, MAX_IDE_BUS);
     for(i = 0; i < MAX_IDE_BUS; i++)
         isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
                      hd[MAX_IDE_DEVS * i],
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index b3ede8941f..4d54ca1832 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -129,15 +129,7 @@ static void pc_init1(ram_addr_t ram_size,
             pci_nic_init_nofail(nd, "e1000", NULL);
     }
 
-    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
-        fprintf(stderr, "qemu: too many IDE bus\n");
-        exit(1);
-    }
-
-    for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
-        hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
-    }
-
+    ide_drive_get(hd, MAX_IDE_BUS);
     if (pci_enabled) {
         PCIDevice *dev;
         dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index b9245f066a..86f1cfbee9 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -325,20 +325,13 @@ static void ppc_core99_init (ram_addr_t ram_size,
     for(i = 0; i < nb_nics; i++)
         pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
 
-    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
-        fprintf(stderr, "qemu: too many IDE bus\n");
-        exit(1);
-    }
+    ide_drive_get(hd, MAX_IDE_BUS);
     dbdma = DBDMA_init(&dbdma_mem_index);
 
     /* We only emulate 2 out of 3 IDE controllers for now */
     ide_mem_index[0] = -1;
-    hd[0] = drive_get(IF_IDE, 0, 0);
-    hd[1] = drive_get(IF_IDE, 0, 1);
     ide_mem_index[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]);
-    hd[0] = drive_get(IF_IDE, 1, 0);
-    hd[1] = drive_get(IF_IDE, 1, 1);
-    ide_mem_index[2] = pmac_ide_init(hd, pic[0x0e], dbdma, 0x1a, pic[0x02]);
+    ide_mem_index[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]);
 
     /* cuda also initialize ADB */
     if (machine_arch == ARCH_MAC99_U3) {
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 8a4e088a38..75a312742e 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -236,21 +236,16 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
         pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
 
 
-    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
-        fprintf(stderr, "qemu: too many IDE bus\n");
-        exit(1);
-    }
+    ide_drive_get(hd, MAX_IDE_BUS);
 
     /* First IDE channel is a MAC IDE on the MacIO bus */
-    hd[0] = drive_get(IF_IDE, 0, 0);
-    hd[1] = drive_get(IF_IDE, 0, 1);
     dbdma = DBDMA_init(&dbdma_mem_index);
     ide_mem_index[0] = -1;
     ide_mem_index[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]);
 
     /* Second IDE channel is a CMD646 on the PCI bus */
-    hd[0] = drive_get(IF_IDE, 1, 0);
-    hd[1] = drive_get(IF_IDE, 1, 1);
+    hd[0] = hd[MAX_IDE_DEVS];
+    hd[1] = hd[MAX_IDE_DEVS + 1];
     hd[3] = hd[2] = NULL;
     pci_cmd646_ide_init(pci_bus, hd, 0);
 
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 5615ef9ad8..0e9cfc24cd 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -681,15 +681,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
         }
     }
 
-    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
-        fprintf(stderr, "qemu: too many IDE bus\n");
-        exit(1);
-    }
-
-    for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
-        hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
-    }
-
+    ide_drive_get(hd, MAX_IDE_BUS);
     for(i = 0; i < MAX_IDE_BUS; i++) {
         isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
                      hd[2 * i],
diff --git a/hw/sun4u.c b/hw/sun4u.c
index dbb5a15066..5eb38cf27d 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -793,14 +793,7 @@ static void sun4uv_init(ram_addr_t RAM_size,
     for(i = 0; i < nb_nics; i++)
         pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
 
-    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
-        fprintf(stderr, "qemu: too many IDE bus\n");
-        exit(1);
-    }
-    for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
-        hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS,
-                          i % MAX_IDE_DEVS);
-    }
+    ide_drive_get(hd, MAX_IDE_BUS);
 
     pci_cmd646_ide_init(pci_bus, hd, 1);
 

From b2e3d87f043d02f2fba03c8463c9ad3d0478c869 Mon Sep 17 00:00:00 2001
From: Nick Thomas <nick@bytemark.co.uk>
Date: Tue, 22 Feb 2011 15:44:51 +0000
Subject: [PATCH 110/386] NBD library: whitespace changes

Signed-off-by: Nick Thomas <nick@bytemark.co.uk>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 nbd.c | 725 +++++++++++++++++++++++++++++-----------------------------
 1 file changed, 363 insertions(+), 362 deletions(-)

diff --git a/nbd.c b/nbd.c
index d8ebc4298f..abe0ecb17e 100644
--- a/nbd.c
+++ b/nbd.c
@@ -49,7 +49,7 @@
 
 /* This is all part of the "official" NBD API */
 
-#define NBD_REPLY_SIZE		(4 + 4 + 8)
+#define NBD_REPLY_SIZE          (4 + 4 + 8)
 #define NBD_REQUEST_MAGIC       0x25609513
 #define NBD_REPLY_MAGIC         0x67446698
 
@@ -59,11 +59,11 @@
 #define NBD_DO_IT               _IO(0xab, 3)
 #define NBD_CLEAR_SOCK          _IO(0xab, 4)
 #define NBD_CLEAR_QUE           _IO(0xab, 5)
-#define NBD_PRINT_DEBUG	        _IO(0xab, 6)
-#define NBD_SET_SIZE_BLOCKS	_IO(0xab, 7)
+#define NBD_PRINT_DEBUG         _IO(0xab, 6)
+#define NBD_SET_SIZE_BLOCKS     _IO(0xab, 7)
 #define NBD_DISCONNECT          _IO(0xab, 8)
 
-#define NBD_OPT_EXPORT_NAME	(1 << 0)
+#define NBD_OPT_EXPORT_NAME     (1 << 0)
 
 /* That's all folks */
 
@@ -273,241 +273,241 @@ int unix_socket_outgoing(const char *path)
 
 int nbd_negotiate(int csock, off_t size)
 {
-	char buf[8 + 8 + 8 + 128];
+    char buf[8 + 8 + 8 + 128];
 
-	/* Negotiate
-	   [ 0 ..   7]   passwd   ("NBDMAGIC")
-	   [ 8 ..  15]   magic    (0x00420281861253)
-	   [16 ..  23]   size
-	   [24 .. 151]   reserved (0)
-	 */
+    /* Negotiate
+        [ 0 ..   7]   passwd   ("NBDMAGIC")
+        [ 8 ..  15]   magic    (0x00420281861253)
+        [16 ..  23]   size
+        [24 .. 151]   reserved (0)
+     */
 
-	TRACE("Beginning negotiation.");
-	memcpy(buf, "NBDMAGIC", 8);
-	cpu_to_be64w((uint64_t*)(buf + 8), 0x00420281861253LL);
-	cpu_to_be64w((uint64_t*)(buf + 16), size);
-	memset(buf + 24, 0, 128);
+    TRACE("Beginning negotiation.");
+    memcpy(buf, "NBDMAGIC", 8);
+    cpu_to_be64w((uint64_t*)(buf + 8), 0x00420281861253LL);
+    cpu_to_be64w((uint64_t*)(buf + 16), size);
+    memset(buf + 24, 0, 128);
 
-	if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
-		LOG("write failed");
-		errno = EINVAL;
-		return -1;
-	}
+    if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
+        LOG("write failed");
+        errno = EINVAL;
+        return -1;
+    }
 
-	TRACE("Negotation succeeded.");
+    TRACE("Negotation succeeded.");
 
-	return 0;
+    return 0;
 }
 
 int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags,
                           off_t *size, size_t *blocksize)
 {
-	char buf[256];
-	uint64_t magic, s;
-	uint16_t tmp;
+    char buf[256];
+    uint64_t magic, s;
+    uint16_t tmp;
 
-	TRACE("Receiving negotation.");
+    TRACE("Receiving negotation.");
 
-	if (read_sync(csock, buf, 8) != 8) {
-		LOG("read failed");
-		errno = EINVAL;
-		return -1;
-	}
+    if (read_sync(csock, buf, 8) != 8) {
+        LOG("read failed");
+        errno = EINVAL;
+        return -1;
+    }
 
-	buf[8] = '\0';
-	if (strlen(buf) == 0) {
-		LOG("server connection closed");
-		errno = EINVAL;
-		return -1;
-	}
+    buf[8] = '\0';
+    if (strlen(buf) == 0) {
+        LOG("server connection closed");
+        errno = EINVAL;
+        return -1;
+    }
 
-	TRACE("Magic is %c%c%c%c%c%c%c%c",
-	      qemu_isprint(buf[0]) ? buf[0] : '.',
-	      qemu_isprint(buf[1]) ? buf[1] : '.',
-	      qemu_isprint(buf[2]) ? buf[2] : '.',
-	      qemu_isprint(buf[3]) ? buf[3] : '.',
-	      qemu_isprint(buf[4]) ? buf[4] : '.',
-	      qemu_isprint(buf[5]) ? buf[5] : '.',
-	      qemu_isprint(buf[6]) ? buf[6] : '.',
-	      qemu_isprint(buf[7]) ? buf[7] : '.');
+    TRACE("Magic is %c%c%c%c%c%c%c%c",
+          qemu_isprint(buf[0]) ? buf[0] : '.',
+          qemu_isprint(buf[1]) ? buf[1] : '.',
+          qemu_isprint(buf[2]) ? buf[2] : '.',
+          qemu_isprint(buf[3]) ? buf[3] : '.',
+          qemu_isprint(buf[4]) ? buf[4] : '.',
+          qemu_isprint(buf[5]) ? buf[5] : '.',
+          qemu_isprint(buf[6]) ? buf[6] : '.',
+          qemu_isprint(buf[7]) ? buf[7] : '.');
 
-	if (memcmp(buf, "NBDMAGIC", 8) != 0) {
-		LOG("Invalid magic received");
-		errno = EINVAL;
-		return -1;
-	}
+    if (memcmp(buf, "NBDMAGIC", 8) != 0) {
+        LOG("Invalid magic received");
+        errno = EINVAL;
+        return -1;
+    }
 
-	if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
-		LOG("read failed");
-		errno = EINVAL;
-		return -1;
-	}
-	magic = be64_to_cpu(magic);
-	TRACE("Magic is 0x%" PRIx64, magic);
+    if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
+        LOG("read failed");
+        errno = EINVAL;
+        return -1;
+    }
+    magic = be64_to_cpu(magic);
+    TRACE("Magic is 0x%" PRIx64, magic);
 
-	if (name) {
-		uint32_t reserved = 0;
-		uint32_t opt;
-		uint32_t namesize;
+    if (name) {
+        uint32_t reserved = 0;
+        uint32_t opt;
+        uint32_t namesize;
 
-		TRACE("Checking magic (opts_magic)");
-		if (magic != 0x49484156454F5054LL) {
-			LOG("Bad magic received");
-			errno = EINVAL;
-			return -1;
-		}
-		if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
-			LOG("flags read failed");
-			errno = EINVAL;
-			return -1;
-		}
-		*flags = be16_to_cpu(tmp) << 16;
-		/* reserved for future use */
-		if (write_sync(csock, &reserved, sizeof(reserved)) !=
-		    sizeof(reserved)) {
-			LOG("write failed (reserved)");
-			errno = EINVAL;
-			return -1;
-		}
-		/* write the export name */
-		magic = cpu_to_be64(magic);
-		if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
-			LOG("write failed (magic)");
-			errno = EINVAL;
-			return -1;
-		}
-		opt = cpu_to_be32(NBD_OPT_EXPORT_NAME);
-		if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) {
-			LOG("write failed (opt)");
-			errno = EINVAL;
-			return -1;
-		}
-		namesize = cpu_to_be32(strlen(name));
-		if (write_sync(csock, &namesize, sizeof(namesize)) !=
-		    sizeof(namesize)) {
-			LOG("write failed (namesize)");
-			errno = EINVAL;
-			return -1;
-		}
-		if (write_sync(csock, (char*)name, strlen(name)) != strlen(name)) {
-			LOG("write failed (name)");
-			errno = EINVAL;
-			return -1;
-		}
-	} else {
-		TRACE("Checking magic (cli_magic)");
+        TRACE("Checking magic (opts_magic)");
+        if (magic != 0x49484156454F5054LL) {
+            LOG("Bad magic received");
+            errno = EINVAL;
+            return -1;
+        }
+        if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
+            LOG("flags read failed");
+            errno = EINVAL;
+            return -1;
+        }
+        *flags = be16_to_cpu(tmp) << 16;
+        /* reserved for future use */
+        if (write_sync(csock, &reserved, sizeof(reserved)) !=
+            sizeof(reserved)) {
+            LOG("write failed (reserved)");
+            errno = EINVAL;
+            return -1;
+        }
+        /* write the export name */
+        magic = cpu_to_be64(magic);
+        if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
+            LOG("write failed (magic)");
+            errno = EINVAL;
+            return -1;
+        }
+        opt = cpu_to_be32(NBD_OPT_EXPORT_NAME);
+        if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) {
+            LOG("write failed (opt)");
+            errno = EINVAL;
+            return -1;
+        }
+        namesize = cpu_to_be32(strlen(name));
+        if (write_sync(csock, &namesize, sizeof(namesize)) !=
+            sizeof(namesize)) {
+            LOG("write failed (namesize)");
+            errno = EINVAL;
+            return -1;
+        }
+        if (write_sync(csock, (char*)name, strlen(name)) != strlen(name)) {
+            LOG("write failed (name)");
+            errno = EINVAL;
+            return -1;
+        }
+    } else {
+        TRACE("Checking magic (cli_magic)");
 
-		if (magic != 0x00420281861253LL) {
-			LOG("Bad magic received");
-			errno = EINVAL;
-			return -1;
-		}
-	}
+        if (magic != 0x00420281861253LL) {
+            LOG("Bad magic received");
+            errno = EINVAL;
+            return -1;
+        }
+    }
 
-	if (read_sync(csock, &s, sizeof(s)) != sizeof(s)) {
-		LOG("read failed");
-		errno = EINVAL;
-		return -1;
-	}
-	*size = be64_to_cpu(s);
-	*blocksize = 1024;
-	TRACE("Size is %" PRIu64, *size);
+    if (read_sync(csock, &s, sizeof(s)) != sizeof(s)) {
+        LOG("read failed");
+        errno = EINVAL;
+        return -1;
+    }
+    *size = be64_to_cpu(s);
+    *blocksize = 1024;
+    TRACE("Size is %" PRIu64, *size);
 
-	if (!name) {
-		if (read_sync(csock, flags, sizeof(*flags)) != sizeof(*flags)) {
-			LOG("read failed (flags)");
-			errno = EINVAL;
-			return -1;
-		}
-		*flags = be32_to_cpup(flags);
-	} else {
-		if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
-			LOG("read failed (tmp)");
-			errno = EINVAL;
-			return -1;
-		}
-		*flags |= be32_to_cpu(tmp);
-	}
-	if (read_sync(csock, &buf, 124) != 124) {
-		LOG("read failed (buf)");
-		errno = EINVAL;
-		return -1;
-	}
+    if (!name) {
+        if (read_sync(csock, flags, sizeof(*flags)) != sizeof(*flags)) {
+            LOG("read failed (flags)");
+            errno = EINVAL;
+            return -1;
+        }
+        *flags = be32_to_cpup(flags);
+    } else {
+        if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
+            LOG("read failed (tmp)");
+            errno = EINVAL;
+            return -1;
+        }
+        *flags |= be32_to_cpu(tmp);
+    }
+    if (read_sync(csock, &buf, 124) != 124) {
+        LOG("read failed (buf)");
+        errno = EINVAL;
+        return -1;
+    }
         return 0;
 }
 
 #ifndef _WIN32
 int nbd_init(int fd, int csock, off_t size, size_t blocksize)
 {
-	TRACE("Setting block size to %lu", (unsigned long)blocksize);
+    TRACE("Setting block size to %lu", (unsigned long)blocksize);
 
-	if (ioctl(fd, NBD_SET_BLKSIZE, blocksize) == -1) {
-		int serrno = errno;
-		LOG("Failed setting NBD block size");
-		errno = serrno;
-		return -1;
-	}
+    if (ioctl(fd, NBD_SET_BLKSIZE, blocksize) == -1) {
+        int serrno = errno;
+        LOG("Failed setting NBD block size");
+        errno = serrno;
+        return -1;
+    }
 
         TRACE("Setting size to %zd block(s)", (size_t)(size / blocksize));
 
-	if (ioctl(fd, NBD_SET_SIZE_BLOCKS, size / blocksize) == -1) {
-		int serrno = errno;
-		LOG("Failed setting size (in blocks)");
-		errno = serrno;
-		return -1;
-	}
+    if (ioctl(fd, NBD_SET_SIZE_BLOCKS, size / blocksize) == -1) {
+        int serrno = errno;
+        LOG("Failed setting size (in blocks)");
+        errno = serrno;
+        return -1;
+    }
 
-	TRACE("Clearing NBD socket");
+    TRACE("Clearing NBD socket");
 
-	if (ioctl(fd, NBD_CLEAR_SOCK) == -1) {
-		int serrno = errno;
-		LOG("Failed clearing NBD socket");
-		errno = serrno;
-		return -1;
-	}
+    if (ioctl(fd, NBD_CLEAR_SOCK) == -1) {
+        int serrno = errno;
+        LOG("Failed clearing NBD socket");
+        errno = serrno;
+        return -1;
+    }
 
-	TRACE("Setting NBD socket");
+    TRACE("Setting NBD socket");
 
-	if (ioctl(fd, NBD_SET_SOCK, csock) == -1) {
-		int serrno = errno;
-		LOG("Failed to set NBD socket");
-		errno = serrno;
-		return -1;
-	}
+    if (ioctl(fd, NBD_SET_SOCK, csock) == -1) {
+        int serrno = errno;
+        LOG("Failed to set NBD socket");
+        errno = serrno;
+        return -1;
+    }
 
-	TRACE("Negotiation ended");
+    TRACE("Negotiation ended");
 
-	return 0;
+    return 0;
 }
 
 int nbd_disconnect(int fd)
 {
-	ioctl(fd, NBD_CLEAR_QUE);
-	ioctl(fd, NBD_DISCONNECT);
-	ioctl(fd, NBD_CLEAR_SOCK);
-	return 0;
+    ioctl(fd, NBD_CLEAR_QUE);
+    ioctl(fd, NBD_DISCONNECT);
+    ioctl(fd, NBD_CLEAR_SOCK);
+    return 0;
 }
 
 int nbd_client(int fd)
 {
-	int ret;
-	int serrno;
+    int ret;
+    int serrno;
 
-	TRACE("Doing NBD loop");
+    TRACE("Doing NBD loop");
 
-	ret = ioctl(fd, NBD_DO_IT);
-	serrno = errno;
+    ret = ioctl(fd, NBD_DO_IT);
+    serrno = errno;
 
-	TRACE("NBD loop returned %d: %s", ret, strerror(serrno));
+    TRACE("NBD loop returned %d: %s", ret, strerror(serrno));
 
-	TRACE("Clearing NBD queue");
-	ioctl(fd, NBD_CLEAR_QUE);
+    TRACE("Clearing NBD queue");
+    ioctl(fd, NBD_CLEAR_QUE);
 
-	TRACE("Clearing NBD socket");
-	ioctl(fd, NBD_CLEAR_SOCK);
+    TRACE("Clearing NBD socket");
+    ioctl(fd, NBD_CLEAR_SOCK);
 
-	errno = serrno;
-	return ret;
+    errno = serrno;
+    return ret;
 }
 #else
 int nbd_init(int fd, int csock, off_t size, size_t blocksize)
@@ -531,235 +531,236 @@ int nbd_client(int fd)
 
 int nbd_send_request(int csock, struct nbd_request *request)
 {
-	uint8_t buf[4 + 4 + 8 + 8 + 4];
+    uint8_t buf[4 + 4 + 8 + 8 + 4];
 
-	cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC);
-	cpu_to_be32w((uint32_t*)(buf + 4), request->type);
-	cpu_to_be64w((uint64_t*)(buf + 8), request->handle);
-	cpu_to_be64w((uint64_t*)(buf + 16), request->from);
-	cpu_to_be32w((uint32_t*)(buf + 24), request->len);
+    cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC);
+    cpu_to_be32w((uint32_t*)(buf + 4), request->type);
+    cpu_to_be64w((uint64_t*)(buf + 8), request->handle);
+    cpu_to_be64w((uint64_t*)(buf + 16), request->from);
+    cpu_to_be32w((uint32_t*)(buf + 24), request->len);
 
-	TRACE("Sending request to client");
+    TRACE("Sending request to client: "
+          "{ .from = %" PRIu64", .len = %u, .handle = %" PRIu64", .type=%i}",
+          request->from, request->len, request->handle, request->type);
 
-	if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
-		LOG("writing to socket failed");
-		errno = EINVAL;
-		return -1;
-	}
-	return 0;
+    if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
+        LOG("writing to socket failed");
+        errno = EINVAL;
+        return -1;
+    }
+    return 0;
 }
 
-
 static int nbd_receive_request(int csock, struct nbd_request *request)
 {
-	uint8_t buf[4 + 4 + 8 + 8 + 4];
-	uint32_t magic;
+    uint8_t buf[4 + 4 + 8 + 8 + 4];
+    uint32_t magic;
 
-	if (read_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
-		LOG("read failed");
-		errno = EINVAL;
-		return -1;
-	}
+    if (read_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
+        LOG("read failed");
+        errno = EINVAL;
+        return -1;
+    }
 
-	/* Request
-	   [ 0 ..  3]   magic   (NBD_REQUEST_MAGIC)
-	   [ 4 ..  7]   type    (0 == READ, 1 == WRITE)
-	   [ 8 .. 15]   handle
-	   [16 .. 23]   from
-	   [24 .. 27]   len
-	 */
+    /* Request
+       [ 0 ..  3]   magic   (NBD_REQUEST_MAGIC)
+       [ 4 ..  7]   type    (0 == READ, 1 == WRITE)
+       [ 8 .. 15]   handle
+       [16 .. 23]   from
+       [24 .. 27]   len
+     */
 
-	magic = be32_to_cpup((uint32_t*)buf);
-	request->type  = be32_to_cpup((uint32_t*)(buf + 4));
-	request->handle = be64_to_cpup((uint64_t*)(buf + 8));
-	request->from  = be64_to_cpup((uint64_t*)(buf + 16));
-	request->len   = be32_to_cpup((uint32_t*)(buf + 24));
+    magic = be32_to_cpup((uint32_t*)buf);
+    request->type  = be32_to_cpup((uint32_t*)(buf + 4));
+    request->handle = be64_to_cpup((uint64_t*)(buf + 8));
+    request->from  = be64_to_cpup((uint64_t*)(buf + 16));
+    request->len   = be32_to_cpup((uint32_t*)(buf + 24));
 
-	TRACE("Got request: "
-	      "{ magic = 0x%x, .type = %d, from = %" PRIu64" , len = %u }",
-	      magic, request->type, request->from, request->len);
+    TRACE("Got request: "
+          "{ magic = 0x%x, .type = %d, from = %" PRIu64" , len = %u }",
+          magic, request->type, request->from, request->len);
 
-	if (magic != NBD_REQUEST_MAGIC) {
-		LOG("invalid magic (got 0x%x)", magic);
-		errno = EINVAL;
-		return -1;
-	}
-	return 0;
+    if (magic != NBD_REQUEST_MAGIC) {
+        LOG("invalid magic (got 0x%x)", magic);
+        errno = EINVAL;
+        return -1;
+    }
+    return 0;
 }
 
 int nbd_receive_reply(int csock, struct nbd_reply *reply)
 {
-	uint8_t buf[NBD_REPLY_SIZE];
-	uint32_t magic;
+    uint8_t buf[NBD_REPLY_SIZE];
+    uint32_t magic;
 
-	memset(buf, 0xAA, sizeof(buf));
+    memset(buf, 0xAA, sizeof(buf));
 
-	if (read_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
-		LOG("read failed");
-		errno = EINVAL;
-		return -1;
-	}
+    if (read_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
+        LOG("read failed");
+        errno = EINVAL;
+        return -1;
+    }
 
-	/* Reply
-	   [ 0 ..  3]    magic   (NBD_REPLY_MAGIC)
-	   [ 4 ..  7]    error   (0 == no error)
-	   [ 7 .. 15]    handle
-	 */
+    /* Reply
+       [ 0 ..  3]    magic   (NBD_REPLY_MAGIC)
+       [ 4 ..  7]    error   (0 == no error)
+       [ 7 .. 15]    handle
+     */
 
-	magic = be32_to_cpup((uint32_t*)buf);
-	reply->error  = be32_to_cpup((uint32_t*)(buf + 4));
-	reply->handle = be64_to_cpup((uint64_t*)(buf + 8));
+    magic = be32_to_cpup((uint32_t*)buf);
+    reply->error  = be32_to_cpup((uint32_t*)(buf + 4));
+    reply->handle = be64_to_cpup((uint64_t*)(buf + 8));
 
-	TRACE("Got reply: "
-	      "{ magic = 0x%x, .error = %d, handle = %" PRIu64" }",
-	      magic, reply->error, reply->handle);
+    TRACE("Got reply: "
+          "{ magic = 0x%x, .error = %d, handle = %" PRIu64" }",
+          magic, reply->error, reply->handle);
 
-	if (magic != NBD_REPLY_MAGIC) {
-		LOG("invalid magic (got 0x%x)", magic);
-		errno = EINVAL;
-		return -1;
-	}
-	return 0;
+    if (magic != NBD_REPLY_MAGIC) {
+        LOG("invalid magic (got 0x%x)", magic);
+        errno = EINVAL;
+        return -1;
+    }
+    return 0;
 }
 
 static int nbd_send_reply(int csock, struct nbd_reply *reply)
 {
-	uint8_t buf[4 + 4 + 8];
+    uint8_t buf[4 + 4 + 8];
 
-	/* Reply
-	   [ 0 ..  3]    magic   (NBD_REPLY_MAGIC)
-	   [ 4 ..  7]    error   (0 == no error)
-	   [ 7 .. 15]    handle
-	 */
-	cpu_to_be32w((uint32_t*)buf, NBD_REPLY_MAGIC);
-	cpu_to_be32w((uint32_t*)(buf + 4), reply->error);
-	cpu_to_be64w((uint64_t*)(buf + 8), reply->handle);
+    /* Reply
+       [ 0 ..  3]    magic   (NBD_REPLY_MAGIC)
+       [ 4 ..  7]    error   (0 == no error)
+       [ 7 .. 15]    handle
+     */
+    cpu_to_be32w((uint32_t*)buf, NBD_REPLY_MAGIC);
+    cpu_to_be32w((uint32_t*)(buf + 4), reply->error);
+    cpu_to_be64w((uint64_t*)(buf + 8), reply->handle);
 
-	TRACE("Sending response to client");
+    TRACE("Sending response to client");
 
-	if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
-		LOG("writing to socket failed");
-		errno = EINVAL;
-		return -1;
-	}
-	return 0;
+    if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
+        LOG("writing to socket failed");
+        errno = EINVAL;
+        return -1;
+    }
+    return 0;
 }
 
 int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
              off_t *offset, bool readonly, uint8_t *data, int data_size)
 {
-	struct nbd_request request;
-	struct nbd_reply reply;
+    struct nbd_request request;
+    struct nbd_reply reply;
 
-	TRACE("Reading request.");
+    TRACE("Reading request.");
 
-	if (nbd_receive_request(csock, &request) == -1)
-		return -1;
+    if (nbd_receive_request(csock, &request) == -1)
+        return -1;
 
-	if (request.len + NBD_REPLY_SIZE > data_size) {
-		LOG("len (%u) is larger than max len (%u)",
-		    request.len + NBD_REPLY_SIZE, data_size);
-		errno = EINVAL;
-		return -1;
-	}
+    if (request.len + NBD_REPLY_SIZE > data_size) {
+        LOG("len (%u) is larger than max len (%u)",
+            request.len + NBD_REPLY_SIZE, data_size);
+        errno = EINVAL;
+        return -1;
+    }
 
-	if ((request.from + request.len) < request.from) {
-		LOG("integer overflow detected! "
-		    "you're probably being attacked");
-		errno = EINVAL;
-		return -1;
-	}
+    if ((request.from + request.len) < request.from) {
+        LOG("integer overflow detected! "
+            "you're probably being attacked");
+        errno = EINVAL;
+        return -1;
+    }
 
-	if ((request.from + request.len) > size) {
-	        LOG("From: %" PRIu64 ", Len: %u, Size: %" PRIu64
-		    ", Offset: %" PRIu64 "\n",
+    if ((request.from + request.len) > size) {
+            LOG("From: %" PRIu64 ", Len: %u, Size: %" PRIu64
+            ", Offset: %" PRIu64 "\n",
                     request.from, request.len, (uint64_t)size, dev_offset);
-		LOG("requested operation past EOF--bad client?");
-		errno = EINVAL;
-		return -1;
-	}
+        LOG("requested operation past EOF--bad client?");
+        errno = EINVAL;
+        return -1;
+    }
 
-	TRACE("Decoding type");
+    TRACE("Decoding type");
 
-	reply.handle = request.handle;
-	reply.error = 0;
+    reply.handle = request.handle;
+    reply.error = 0;
 
-	switch (request.type) {
-	case NBD_CMD_READ:
-		TRACE("Request type is READ");
+    switch (request.type) {
+    case NBD_CMD_READ:
+        TRACE("Request type is READ");
 
-		if (bdrv_read(bs, (request.from + dev_offset) / 512,
-			      data + NBD_REPLY_SIZE,
-			      request.len / 512) == -1) {
-			LOG("reading from file failed");
-			errno = EINVAL;
-			return -1;
-		}
-		*offset += request.len;
+        if (bdrv_read(bs, (request.from + dev_offset) / 512,
+                  data + NBD_REPLY_SIZE,
+                  request.len / 512) == -1) {
+            LOG("reading from file failed");
+            errno = EINVAL;
+            return -1;
+        }
+        *offset += request.len;
 
-		TRACE("Read %u byte(s)", request.len);
+        TRACE("Read %u byte(s)", request.len);
 
-		/* Reply
-		   [ 0 ..  3]    magic   (NBD_REPLY_MAGIC)
-		   [ 4 ..  7]    error   (0 == no error)
-		   [ 7 .. 15]    handle
-		 */
+        /* Reply
+           [ 0 ..  3]    magic   (NBD_REPLY_MAGIC)
+           [ 4 ..  7]    error   (0 == no error)
+           [ 7 .. 15]    handle
+         */
 
-		cpu_to_be32w((uint32_t*)data, NBD_REPLY_MAGIC);
-		cpu_to_be32w((uint32_t*)(data + 4), reply.error);
-		cpu_to_be64w((uint64_t*)(data + 8), reply.handle);
+        cpu_to_be32w((uint32_t*)data, NBD_REPLY_MAGIC);
+        cpu_to_be32w((uint32_t*)(data + 4), reply.error);
+        cpu_to_be64w((uint64_t*)(data + 8), reply.handle);
 
-		TRACE("Sending data to client");
+        TRACE("Sending data to client");
 
-		if (write_sync(csock, data,
-			       request.len + NBD_REPLY_SIZE) !=
-			       request.len + NBD_REPLY_SIZE) {
-			LOG("writing to socket failed");
-			errno = EINVAL;
-			return -1;
-		}
-		break;
-	case NBD_CMD_WRITE:
-		TRACE("Request type is WRITE");
+        if (write_sync(csock, data,
+                   request.len + NBD_REPLY_SIZE) !=
+                   request.len + NBD_REPLY_SIZE) {
+            LOG("writing to socket failed");
+            errno = EINVAL;
+            return -1;
+        }
+        break;
+    case NBD_CMD_WRITE:
+        TRACE("Request type is WRITE");
 
-		TRACE("Reading %u byte(s)", request.len);
+        TRACE("Reading %u byte(s)", request.len);
 
-		if (read_sync(csock, data, request.len) != request.len) {
-			LOG("reading from socket failed");
-			errno = EINVAL;
-			return -1;
-		}
+        if (read_sync(csock, data, request.len) != request.len) {
+            LOG("reading from socket failed");
+            errno = EINVAL;
+            return -1;
+        }
 
-		if (readonly) {
-			TRACE("Server is read-only, return error");
-			reply.error = 1;
-		} else {
-			TRACE("Writing to device");
+        if (readonly) {
+            TRACE("Server is read-only, return error");
+            reply.error = 1;
+        } else {
+            TRACE("Writing to device");
 
-			if (bdrv_write(bs, (request.from + dev_offset) / 512,
-				       data, request.len / 512) == -1) {
-				LOG("writing to file failed");
-				errno = EINVAL;
-				return -1;
-			}
+            if (bdrv_write(bs, (request.from + dev_offset) / 512,
+                       data, request.len / 512) == -1) {
+                LOG("writing to file failed");
+                errno = EINVAL;
+                return -1;
+            }
 
-			*offset += request.len;
-		}
+            *offset += request.len;
+        }
 
-		if (nbd_send_reply(csock, &reply) == -1)
-			return -1;
-		break;
-	case NBD_CMD_DISC:
-		TRACE("Request type is DISCONNECT");
-		errno = 0;
-		return 1;
-	default:
-		LOG("invalid request type (%u) received", request.type);
-		errno = EINVAL;
-		return -1;
-	}
+        if (nbd_send_reply(csock, &reply) == -1)
+            return -1;
+        break;
+    case NBD_CMD_DISC:
+        TRACE("Request type is DISCONNECT");
+        errno = 0;
+        return 1;
+    default:
+        LOG("invalid request type (%u) received", request.type);
+        errno = EINVAL;
+        return -1;
+    }
 
-	TRACE("Request/Reply complete");
+    TRACE("Request/Reply complete");
 
-	return 0;
+    return 0;
 }

From b82eac92ac69a22243d341dde0213b7d15d7ba24 Mon Sep 17 00:00:00 2001
From: Nick Thomas <nick@bytemark.co.uk>
Date: Tue, 22 Feb 2011 15:44:52 +0000
Subject: [PATCH 111/386] Set errno=ENOTSUP for attempts to use UNIX sockets on
 Windows platforms

Signed-off-by: Nick Thomas <nick@bytemark.co.uk>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qemu-sockets.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/qemu-sockets.c b/qemu-sockets.c
index c526324998..eda1850e9c 100644
--- a/qemu-sockets.c
+++ b/qemu-sockets.c
@@ -627,24 +627,28 @@ int unix_connect(const char *path)
 int unix_listen_opts(QemuOpts *opts)
 {
     fprintf(stderr, "unix sockets are not available on windows\n");
+    errno = ENOTSUP;
     return -1;
 }
 
 int unix_connect_opts(QemuOpts *opts)
 {
     fprintf(stderr, "unix sockets are not available on windows\n");
+    errno = ENOTSUP;
     return -1;
 }
 
 int unix_listen(const char *path, char *ostr, int olen)
 {
     fprintf(stderr, "unix sockets are not available on windows\n");
+    errno = ENOTSUP;
     return -1;
 }
 
 int unix_connect(const char *path)
 {
     fprintf(stderr, "unix sockets are not available on windows\n");
+    errno = ENOTSUP;
     return -1;
 }
 

From c12504ceef999c80b82c69c0154205ca23247fd5 Mon Sep 17 00:00:00 2001
From: Nick Thomas <nick@bytemark.co.uk>
Date: Tue, 22 Feb 2011 15:44:53 +0000
Subject: [PATCH 112/386] NBD: Use qemu_socket functions to open TCP and UNIX
 sockets

This commit has the side-effect of making the qemu-nbd binary
capable of binding to IPv6 addresses. ("-b ::1", for instance).
block/nbd.c fails to parse IPv6 IP addresses correctly at this
point, but will work over IPv6 when given a hostname. It still
works over IPv4 as before.

We move the qemu-sockets object from the 'common' to the 'block'
list in the Makefile. The common list includes the block list,
so this is effectively a no-op for the rest of the code.

We also add 32-bit 'magic' attributes to nbd_(request|reply) to
facilitate calculating maximum request/response sizes later.

Signed-off-by: Nick Thomas <nick@bytemark.co.uk>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 Makefile.objs |   4 +-
 nbd.c         | 164 ++++++++++----------------------------------------
 nbd.h         |   9 ++-
 3 files changed, 41 insertions(+), 136 deletions(-)

diff --git a/Makefile.objs b/Makefile.objs
index 94587e1740..44ce368d05 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -14,7 +14,7 @@ oslib-obj-$(CONFIG_POSIX) += oslib-posix.o
 # block-obj-y is code used by both qemu system emulation and qemu-img
 
 block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o async.o
-block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o qemu-progress.o
+block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o qemu-progress.o qemu-sockets.o
 block-obj-$(CONFIG_POSIX) += posix-aio-compat.o
 block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
 
@@ -94,7 +94,7 @@ common-obj-$(CONFIG_SSI_SD) += ssi-sd.o
 common-obj-$(CONFIG_SD) += sd.o
 common-obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o
 common-obj-y += bt-hci-csr.o
-common-obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o
+common-obj-y += buffered_file.o migration.o migration-tcp.o
 common-obj-y += qemu-char.o savevm.o #aio.o
 common-obj-y += msmouse.o ps2.o
 common-obj-y += qdev.o qdev-properties.o
diff --git a/nbd.c b/nbd.c
index abe0ecb17e..0dcd86b52f 100644
--- a/nbd.c
+++ b/nbd.c
@@ -107,155 +107,55 @@ size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read)
     return offset;
 }
 
+static void combine_addr(char *buf, size_t len, const char* address,
+                         uint16_t port)
+{
+    /* If the address-part contains a colon, it's an IPv6 IP so needs [] */
+    if (strstr(address, ":")) {
+        snprintf(buf, len, "[%s]:%u", address, port);
+    } else {
+        snprintf(buf, len, "%s:%u", address, port);
+    }
+}
+
 int tcp_socket_outgoing(const char *address, uint16_t port)
 {
-    int s;
-    struct in_addr in;
-    struct sockaddr_in addr;
+    char address_and_port[128];
+    combine_addr(address_and_port, 128, address, port);
+    return tcp_socket_outgoing_spec(address_and_port);
+}
 
-    s = socket(PF_INET, SOCK_STREAM, 0);
-    if (s == -1) {
-        return -1;
-    }
-
-    if (inet_aton(address, &in) == 0) {
-        struct hostent *ent;
-
-        ent = gethostbyname(address);
-        if (ent == NULL) {
-            goto error;
-        }
-
-        memcpy(&in, ent->h_addr, sizeof(in));
-    }
-
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(port);
-    memcpy(&addr.sin_addr.s_addr, &in, sizeof(in));
-
-    if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
-        goto error;
-    }
-
-    return s;
-error:
-    closesocket(s);
-    return -1;
+int tcp_socket_outgoing_spec(const char *address_and_port)
+{
+    return inet_connect(address_and_port, SOCK_STREAM);
 }
 
 int tcp_socket_incoming(const char *address, uint16_t port)
 {
-    int s;
-    struct in_addr in;
-    struct sockaddr_in addr;
-    int opt;
-
-    s = socket(PF_INET, SOCK_STREAM, 0);
-    if (s == -1) {
-        return -1;
-    }
-
-    if (inet_aton(address, &in) == 0) {
-        struct hostent *ent;
-
-        ent = gethostbyname(address);
-        if (ent == NULL) {
-            goto error;
-        }
-
-        memcpy(&in, ent->h_addr, sizeof(in));
-    }
-
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(port);
-    memcpy(&addr.sin_addr.s_addr, &in, sizeof(in));
-
-    opt = 1;
-    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
-                   (const void *) &opt, sizeof(opt)) == -1) {
-        goto error;
-    }
-
-    if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
-        goto error;
-    }
-
-    if (listen(s, 128) == -1) {
-        goto error;
-    }
-
-    return s;
-error:
-    closesocket(s);
-    return -1;
+    char address_and_port[128];
+    combine_addr(address_and_port, 128, address, port);
+    return tcp_socket_incoming_spec(address_and_port);
+}
+
+int tcp_socket_incoming_spec(const char *address_and_port)
+{
+    char *ostr  = NULL;
+    int olen = 0;
+    return inet_listen(address_and_port, ostr, olen, SOCK_STREAM, 0);
 }
 
-#ifndef _WIN32
 int unix_socket_incoming(const char *path)
 {
-    int s;
-    struct sockaddr_un addr;
+    char *ostr = NULL;
+    int olen = 0;
 
-    s = socket(PF_UNIX, SOCK_STREAM, 0);
-    if (s == -1) {
-        return -1;
-    }
-
-    memset(&addr, 0, sizeof(addr));
-    addr.sun_family = AF_UNIX;
-    pstrcpy(addr.sun_path, sizeof(addr.sun_path), path);
-
-    if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
-        goto error;
-    }
-
-    if (listen(s, 128) == -1) {
-        goto error;
-    }
-
-    return s;
-error:
-    closesocket(s);
-    return -1;
+    return unix_listen(path, ostr, olen);
 }
 
 int unix_socket_outgoing(const char *path)
 {
-    int s;
-    struct sockaddr_un addr;
-
-    s = socket(PF_UNIX, SOCK_STREAM, 0);
-    if (s == -1) {
-        return -1;
-    }
-
-    memset(&addr, 0, sizeof(addr));
-    addr.sun_family = AF_UNIX;
-    pstrcpy(addr.sun_path, sizeof(addr.sun_path), path);
-
-    if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
-        goto error;
-    }
-
-    return s;
-error:
-    closesocket(s);
-    return -1;
+    return unix_connect(path);
 }
-#else
-int unix_socket_incoming(const char *path)
-{
-    errno = ENOTSUP;
-    return -1;
-}
-
-int unix_socket_outgoing(const char *path)
-{
-    errno = ENOTSUP;
-    return -1;
-}
-#endif
-
 
 /* Basic flow
 
diff --git a/nbd.h b/nbd.h
index fc3a5944f4..b38d0d08de 100644
--- a/nbd.h
+++ b/nbd.h
@@ -22,19 +22,22 @@
 #include <sys/types.h>
 
 #include <qemu-common.h>
+
 #include "block_int.h"
 
 struct nbd_request {
+    uint32_t magic;
     uint32_t type;
     uint64_t handle;
     uint64_t from;
     uint32_t len;
-};
+} __attribute__ ((__packed__));
 
 struct nbd_reply {
+    uint32_t magic;
     uint32_t error;
     uint64_t handle;
-};
+} __attribute__ ((__packed__));
 
 enum {
     NBD_CMD_READ = 0,
@@ -47,6 +50,8 @@ enum {
 size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read);
 int tcp_socket_outgoing(const char *address, uint16_t port);
 int tcp_socket_incoming(const char *address, uint16_t port);
+int tcp_socket_outgoing_spec(const char *address_and_port);
+int tcp_socket_incoming_spec(const char *address_and_port);
 int unix_socket_outgoing(const char *path);
 int unix_socket_incoming(const char *path);
 

From 33897dc7d62970acb731aab2ef2a65c225a8d64c Mon Sep 17 00:00:00 2001
From: Nick Thomas <nick@bytemark.co.uk>
Date: Tue, 22 Feb 2011 15:44:54 +0000
Subject: [PATCH 113/386] NBD device: Separate out parsing configuration and
 opening sockets.

We also change the way the file parameter is parsed so IPv6 IP
addresses can be used, e.g.: "drive=nbd:[::1]:5000"

Signed-off-by: Nick Thomas <nick@bytemark.co.uk>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/nbd.c | 175 +++++++++++++++++++++++++++++++++-------------------
 1 file changed, 111 insertions(+), 64 deletions(-)

diff --git a/block/nbd.c b/block/nbd.c
index c8dc763c6b..1d6b22561b 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -29,98 +29,154 @@
 #include "qemu-common.h"
 #include "nbd.h"
 #include "module.h"
+#include "qemu_socket.h"
 
 #include <sys/types.h>
 #include <unistd.h>
 
 #define EN_OPTSTR ":exportname="
 
+/* #define DEBUG_NBD */
+
+#if defined(DEBUG_NBD)
+#define logout(fmt, ...) \
+                fprintf(stderr, "nbd\t%-24s" fmt, __func__, ##__VA_ARGS__)
+#else
+#define logout(fmt, ...) ((void)0)
+#endif
+
 typedef struct BDRVNBDState {
     int sock;
     off_t size;
     size_t blocksize;
+    char *export_name; /* An NBD server may export several devices */
+
+    /* If it begins with  '/', this is a UNIX domain socket. Otherwise,
+     * it's a string of the form <hostname|ip4|\[ip6\]>:port
+     */
+    char *host_spec;
 } BDRVNBDState;
 
-static int nbd_open(BlockDriverState *bs, const char* filename, int flags)
+static int nbd_config(BDRVNBDState *s, const char *filename, int flags)
 {
-    BDRVNBDState *s = bs->opaque;
-    uint32_t nbdflags;
-
     char *file;
-    char *name;
-    const char *host;
+    char *export_name;
+    const char *host_spec;
     const char *unixpath;
-    int sock;
-    off_t size;
-    size_t blocksize;
-    int ret;
     int err = -EINVAL;
 
     file = qemu_strdup(filename);
 
-    name = strstr(file, EN_OPTSTR);
-    if (name) {
-        if (name[strlen(EN_OPTSTR)] == 0) {
+    export_name = strstr(file, EN_OPTSTR);
+    if (export_name) {
+        if (export_name[strlen(EN_OPTSTR)] == 0) {
             goto out;
         }
-        name[0] = 0;
-        name += strlen(EN_OPTSTR);
+        export_name[0] = 0; /* truncate 'file' */
+        export_name += strlen(EN_OPTSTR);
+        s->export_name = qemu_strdup(export_name);
     }
 
-    if (!strstart(file, "nbd:", &host)) {
+    /* extract the host_spec - fail if it's not nbd:... */
+    if (!strstart(file, "nbd:", &host_spec)) {
         goto out;
     }
 
-    if (strstart(host, "unix:", &unixpath)) {
-
-        if (unixpath[0] != '/') {
+    /* are we a UNIX or TCP socket? */
+    if (strstart(host_spec, "unix:", &unixpath)) {
+        if (unixpath[0] != '/') { /* We demand  an absolute path*/
             goto out;
         }
-
-        sock = unix_socket_outgoing(unixpath);
-
+        s->host_spec = qemu_strdup(unixpath);
     } else {
-        uint16_t port = NBD_DEFAULT_PORT;
-        char *p, *r;
-        char hostname[128];
-
-        pstrcpy(hostname, 128, host);
-
-        p = strchr(hostname, ':');
-        if (p != NULL) {
-            *p = '\0';
-            p++;
-
-            port = strtol(p, &r, 0);
-            if (r == p) {
-                goto out;
-            }
-        }
-
-        sock = tcp_socket_outgoing(hostname, port);
+        s->host_spec = qemu_strdup(host_spec);
     }
 
-    if (sock == -1) {
-        err = -errno;
-        goto out;
-    }
-
-    ret = nbd_receive_negotiate(sock, name, &nbdflags, &size, &blocksize);
-    if (ret == -1) {
-        err = -errno;
-        goto out;
-    }
-
-    s->sock = sock;
-    s->size = size;
-    s->blocksize = blocksize;
     err = 0;
 
 out:
     qemu_free(file);
+    if (err != 0) {
+        qemu_free(s->export_name);
+        qemu_free(s->host_spec);
+    }
     return err;
 }
 
+static int nbd_establish_connection(BlockDriverState *bs)
+{
+    BDRVNBDState *s = bs->opaque;
+    int sock;
+    int ret;
+    off_t size;
+    size_t blocksize;
+    uint32_t nbdflags;
+
+    if (s->host_spec[0] == '/') {
+        sock = unix_socket_outgoing(s->host_spec);
+    } else {
+        sock = tcp_socket_outgoing_spec(s->host_spec);
+    }
+
+    /* Failed to establish connection */
+    if (sock == -1) {
+        logout("Failed to establish connection to NBD server\n");
+        return -errno;
+    }
+
+    /* NBD handshake */
+    ret = nbd_receive_negotiate(sock, s->export_name, &nbdflags, &size,
+                                &blocksize);
+    if (ret == -1) {
+        logout("Failed to negotiate with the NBD server\n");
+        closesocket(sock);
+        return -errno;
+    }
+
+    /* Now that we're connected, set the socket to be non-blocking */
+    socket_set_nonblock(sock);
+
+    s->sock = sock;
+    s->size = size;
+    s->blocksize = blocksize;
+
+    logout("Established connection with NBD server\n");
+    return 0;
+}
+
+static void nbd_teardown_connection(BlockDriverState *bs)
+{
+    BDRVNBDState *s = bs->opaque;
+    struct nbd_request request;
+
+    request.type = NBD_CMD_DISC;
+    request.handle = (uint64_t)(intptr_t)bs;
+    request.from = 0;
+    request.len = 0;
+    nbd_send_request(s->sock, &request);
+
+    closesocket(s->sock);
+}
+
+static int nbd_open(BlockDriverState *bs, const char* filename, int flags)
+{
+    BDRVNBDState *s = bs->opaque;
+    int result;
+
+    /* Pop the config into our state object. Exit if invalid. */
+    result = nbd_config(s, filename, flags);
+    if (result != 0) {
+        return result;
+    }
+
+    /* establish TCP connection, return error if it fails
+     * TODO: Configurable retry-until-timeout behaviour.
+     */
+    result = nbd_establish_connection(bs);
+
+    return result;
+}
+
 static int nbd_read(BlockDriverState *bs, int64_t sector_num,
                     uint8_t *buf, int nb_sectors)
 {
@@ -183,16 +239,7 @@ static int nbd_write(BlockDriverState *bs, int64_t sector_num,
 
 static void nbd_close(BlockDriverState *bs)
 {
-    BDRVNBDState *s = bs->opaque;
-    struct nbd_request request;
-
-    request.type = NBD_CMD_DISC;
-    request.handle = (uint64_t)(intptr_t)bs;
-    request.from = 0;
-    request.len = 0;
-    nbd_send_request(s->sock, &request);
-
-    close(s->sock);
+    nbd_teardown_connection(bs);
 }
 
 static int64_t nbd_getlength(BlockDriverState *bs)

From 7d905f716bea633f2836e1d661387983aacdc6d6 Mon Sep 17 00:00:00 2001
From: Jason Wang <jasowang@redhat.com>
Date: Wed, 6 Apr 2011 18:34:31 +0800
Subject: [PATCH 114/386] floppy: save and restore DIR register

We need to keep DIR register unchanged across migration, but currently it
depends on the media_changed flags from block layer. Since we do not
save/restore it and the bdrv_open() called in dest node may set the
media_changed flag when trying to open floppy image, guest driver may think the
floppy have changed after migration. To fix this, a new filed media_changed in
FDrive strcutre was introduced in order to save and restore the it from block
layer through pre_save/post_load callbacks.

Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/fdc.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 50 insertions(+), 1 deletion(-)

diff --git a/hw/fdc.c b/hw/fdc.c
index 9fdbc750b5..edf0360d1b 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -36,6 +36,7 @@
 #include "qdev-addr.h"
 #include "blockdev.h"
 #include "sysemu.h"
+#include "block_int.h"
 
 /********************************************************/
 /* debug Floppy devices */
@@ -82,6 +83,7 @@ typedef struct FDrive {
     uint8_t max_track;        /* Nb of tracks           */
     uint16_t bps;             /* Bytes per sector       */
     uint8_t ro;               /* Is read-only           */
+    uint8_t media_changed;    /* Is media changed       */
 } FDrive;
 
 static void fd_init(FDrive *drv)
@@ -533,16 +535,63 @@ static CPUWriteMemoryFunc * const fdctrl_mem_write_strict[3] = {
     NULL,
 };
 
+static void fdrive_media_changed_pre_save(void *opaque)
+{
+    FDrive *drive = opaque;
+
+    drive->media_changed = drive->bs->media_changed;
+}
+
+static int fdrive_media_changed_post_load(void *opaque, int version_id)
+{
+    FDrive *drive = opaque;
+
+    if (drive->bs != NULL) {
+        drive->bs->media_changed = drive->media_changed;
+    }
+
+    /* User ejected the floppy when drive->bs == NULL */
+    return 0;
+}
+
+static bool fdrive_media_changed_needed(void *opaque)
+{
+    FDrive *drive = opaque;
+
+    return (drive->bs != NULL && drive->bs->media_changed != 1);
+}
+
+static const VMStateDescription vmstate_fdrive_media_changed = {
+    .name = "fdrive/media_changed",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .pre_save = fdrive_media_changed_pre_save,
+    .post_load = fdrive_media_changed_post_load,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT8(media_changed, FDrive),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_fdrive = {
     .name = "fdrive",
     .version_id = 1,
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
-    .fields      = (VMStateField []) {
+    .fields      = (VMStateField[]) {
         VMSTATE_UINT8(head, FDrive),
         VMSTATE_UINT8(track, FDrive),
         VMSTATE_UINT8(sect, FDrive),
         VMSTATE_END_OF_LIST()
+    },
+    .subsections = (VMStateSubsection[]) {
+        {
+            .vmsd = &vmstate_fdrive_media_changed,
+            .needed = &fdrive_media_changed_needed,
+        } , {
+            /* empty */
+        }
     }
 };
 

From 155eb9aa09249874b4ff49e94c58595ad82d3abb Mon Sep 17 00:00:00 2001
From: Avishay Traeger <AVISHAY@il.ibm.com>
Date: Wed, 6 Apr 2011 10:45:36 +0300
Subject: [PATCH 115/386] Fix integer overflow in block migration bandwidth
 calculation

block_mig_state.reads is an int, and multiplying by BLOCK_SIZE yielded a
negative number, resulting in a negative bandwidth (running on a 32-bit
machine).  Change order to avoid.

Signed-off-by: Avishay Traeger <avishay@il.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block-migration.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/block-migration.c b/block-migration.c
index 8218bac09c..576e55a6a3 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -140,7 +140,7 @@ static inline void add_avg_read_time(int64_t time)
 static inline long double compute_read_bwidth(void)
 {
     assert(block_mig_state.total_time != 0);
-    return  (block_mig_state.reads * BLOCK_SIZE)/ block_mig_state.total_time;
+    return (block_mig_state.reads / block_mig_state.total_time) * BLOCK_SIZE;
 }
 
 static int bmds_aio_inflight(BlkMigDevState *bmds, int64_t sector)

From 62a2ab6aed53f30080c4151044c90945d16ac5fd Mon Sep 17 00:00:00 2001
From: Brad Hards <bradh@frogmouth.net>
Date: Tue, 5 Apr 2011 07:54:04 +1000
Subject: [PATCH 116/386] usb-ccid: Spelling fixes

While looking at David Gibson's build-fix for hw/usb-ccid.c, I noticed a spello
in a comment on the following (unchanged) line.

Signed-off-by: Brad Hards <bradh@frogmouth.net>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 hw/usb-ccid.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
index 44156cc1d8..079b4a2555 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -22,7 +22,7 @@
  *  "Universal Serial Bus, Device Class: Smart Card"
  *  Specification for Integrated Circuit(s) Cards Interface Devices
  *
- * Endianess note: from the spec (1.3)
+ * Endianness note: from the spec (1.3)
  *  "Fields that are larger than a byte are stored in little endian"
  *
  * KNOWN BUGS
@@ -172,7 +172,7 @@ enum {
     CLOCK_STATUS_RUNNING = 0,
     /*
      * 0 - Clock Running, 1 - Clock stopped in State L, 2 - H,
-     * 3 - unkonwn state. rest are RFU
+     * 3 - unknown state. rest are RFU
      */
 };
 
@@ -1200,7 +1200,7 @@ void ccid_card_card_error(CCIDCardState *card, uint64_t error)
     s->bmCommandStatus = COMMAND_STATUS_FAILED;
     s->last_answer_error = error;
     DPRINTF(s, 1, "VSC_Error: %" PRIX64 "\n", s->last_answer_error);
-    /* TODO: these error's should be more verbose and propogated to the guest.*/
+    /* TODO: these errors should be more verbose and propagated to the guest.*/
     /*
      * We flush all pending answers on CardRemove message in ccid-card-passthru,
      * so check that first to not trigger abort
@@ -1319,7 +1319,7 @@ static void ccid_pre_save(void *opaque)
     if (s->dev.attached) {
         /*
          * Migrating an open device, ignore reconnection CHR_EVENT to avoid an
-         * erronous detach.
+         * erroneous detach.
          */
         s->migration_state = MIGRATION_MIGRATED;
     }

From 3b29a1018457875a983bf10667cfe3a80c9d6dfd Mon Sep 17 00:00:00 2001
From: Michael Tokarev <mjt@tls.msk.ru>
Date: Wed, 6 Apr 2011 17:51:59 +0400
Subject: [PATCH 117/386] qdev: Fix comment around qdev_init_nofail()

In previous life qdev_init_nofail() used to call hw_error() which
did register dump and other scary things.  Now it calls
error_report() and does a regular exit(1).  Fix the comment
to match reality.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 hw/qdev.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 1aa1ea0e26..9519f5dd57 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -358,7 +358,8 @@ int qdev_simple_unplug_cb(DeviceState *dev)
     return 0;
 }
 
-/* Like qdev_init(), but terminate program via hw_error() instead of
+
+/* Like qdev_init(), but terminate program via error_report() instead of
    returning an error value.  This is okay during machine creation.
    Don't use for hotplug, because there callers need to recover from
    failure.  Exception: if you know the device's init() callback can't

From fa227023f044552ec48ca851411dba2f268a912c Mon Sep 17 00:00:00 2001
From: Alexey Kardashevskiy <aik@ozlabs.ru>
Date: Thu, 7 Apr 2011 13:02:02 +1000
Subject: [PATCH 118/386] spapr_llan: Fix warning when compiled with -dDEBUG

Compiling with the DEBUG macro causes leaves hw/spapr_llan.c with an
unused variable, which is treated as an error in the qemu build.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 hw/spapr_llan.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c
index 1d83fd58fd..ff3a78f729 100644
--- a/hw/spapr_llan.c
+++ b/hw/spapr_llan.c
@@ -274,9 +274,6 @@ static target_ulong h_register_logical_lan(CPUState *env,
     VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
     VIOsPAPRVLANDevice *dev = (VIOsPAPRVLANDevice *)sdev;
     vlan_bd_t filter_list_bd;
-#ifdef DEBUG
-    target_ulong mac_address = args[4];
-#endif
 
     if (!dev) {
         return H_PARAMETER;

From 4e37bfc1f0fcd17e48bfae233e0b45066830e126 Mon Sep 17 00:00:00 2001
From: Alexey Kardashevskiy <aik@ozlabs.ru>
Date: Thu, 7 Apr 2011 13:02:03 +1000
Subject: [PATCH 119/386] virtio-9p: fixed LE-to-host conversion bug when QEMU
 is called from guest

The 9p code already contains an attempt at the necessary endian
conversions, but it's broken.

The code which does conversion from host to guest does it correctly
and this code was copied to the function which does guest to host
conversion.  However the copied code hasn't been correctly updated, so
it first endian converts some garbage on the stack and then overwrites
it with a field from incoming packet without conversion.

The patch fixes the mistakes.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 hw/virtio-9p.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 7c59988a51..7e29535672 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -696,25 +696,22 @@ static size_t pdu_unmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...)
         case 'w': {
             uint16_t val, *valp;
             valp = va_arg(ap, uint16_t *);
-            val = le16_to_cpupu(valp);
             offset += pdu_unpack(&val, pdu, offset, sizeof(val));
-            *valp = val;
+            *valp = le16_to_cpu(val);
             break;
         }
         case 'd': {
             uint32_t val, *valp;
             valp = va_arg(ap, uint32_t *);
-            val = le32_to_cpupu(valp);
             offset += pdu_unpack(&val, pdu, offset, sizeof(val));
-            *valp = val;
+            *valp = le32_to_cpu(val);
             break;
         }
         case 'q': {
             uint64_t val, *valp;
             valp = va_arg(ap, uint64_t *);
-            val = le64_to_cpup(valp);
             offset += pdu_unpack(&val, pdu, offset, sizeof(val));
-            *valp = val;
+            *valp = le64_to_cpu(val);
             break;
         }
         case 'v': {

From e54f17713f638189e79dac5ba0aa0ce606788777 Mon Sep 17 00:00:00 2001
From: Alexey Kardashevskiy <aik@ozlabs.ru>
Date: Thu, 7 Apr 2011 13:02:04 +1000
Subject: [PATCH 120/386] virtio-balloon: fixed endianness bug in the config
 space

The specification for the virtio balloon device requres that the values
in the config space be encoded little-endian.  This differs from most
virtio things, where guest-native endian is the norm.

Currently, the qemu virtio-balloon code correctly makes the conversion
on get_config(), but doesn't on set_config for the 'actual' field.  The
kernel driver, on the other hand, correctly converts when setting the
actual field, but does not convert when reading the config space.  The
upshot is that virtio-balloon will only work correctly if both host and
guest are LE, making all the conversions nops.

This patch corrects the qemu side, correctly doing host-native <-> LE
conversions when accessing the config space.  This won't break any setups
that aren't already broken, and fixes the case of BE host, LE guest.
Fixing the BE guest case will require kernel fixes as well.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 hw/virtio-balloon.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
index 8adddeaa53..257baf8d4f 100644
--- a/hw/virtio-balloon.c
+++ b/hw/virtio-balloon.c
@@ -191,7 +191,7 @@ static void virtio_balloon_set_config(VirtIODevice *vdev,
     VirtIOBalloon *dev = to_virtio_balloon(vdev);
     struct virtio_balloon_config config;
     memcpy(&config, config_data, 8);
-    dev->actual = config.actual;
+    dev->actual = le32_to_cpu(config.actual);
 }
 
 static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f)

From 52c050236eaa4f0b5e1d160cd66dc18106445c4d Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <hch@lst.de>
Date: Wed, 6 Apr 2011 20:28:34 +0200
Subject: [PATCH 121/386] virtio-blk: fail unaligned requests

Like all block drivers virtio-blk should not allow small than block size
granularity access.  But given that the protocol specifies a
byte unit length field we currently accept such requests, which cause
qemu to abort() in lower layers.  Add checks to the main read and
write handlers to catch them early.

Reported-by: Conor Murphy <conor_murphy_virt@hotmail.com>
Tested-by: Conor Murphy <conor_murphy_virt@hotmail.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/virtio-blk.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index b14fb995e8..91e0394af9 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -290,6 +290,10 @@ static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb)
         virtio_blk_rw_complete(req, -EIO);
         return;
     }
+    if (req->qiov.size % req->dev->conf->logical_block_size) {
+        virtio_blk_rw_complete(req, -EIO);
+        return;
+    }
 
     if (mrb->num_writes == 32) {
         virtio_submit_multiwrite(req->dev->bs, mrb);
@@ -317,6 +321,10 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req)
         virtio_blk_rw_complete(req, -EIO);
         return;
     }
+    if (req->qiov.size % req->dev->conf->logical_block_size) {
+        virtio_blk_rw_complete(req, -EIO);
+        return;
+    }
 
     acb = bdrv_aio_readv(req->dev->bs, sector, &req->qiov,
                          req->qiov.size / BDRV_SECTOR_SIZE,

From 64a4d100b502f24d0116437b9e5678c032a233e6 Mon Sep 17 00:00:00 2001
From: Scott Wood <scottwood@freescale.com>
Date: Mon, 4 Oct 2010 11:15:58 +0000
Subject: [PATCH 122/386] Don't call cpu_synchronize_state() from machine init.

This will deadlock when the I/O thread is used, since the
CPU thread is blocked waiting for qemu_system_ready.

The synchronization is unnecessary since this is before
cpu_synchronize_all_post_init().

Signed-off-by: Scott Wood <scottwood@freescale.com>
Acked-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc440_bamboo.c     | 2 --
 hw/ppce500_mpc8544ds.c | 2 --
 2 files changed, 4 deletions(-)

diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index 34ddf45477..645e84fd36 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -156,8 +156,6 @@ static void bamboo_init(ram_addr_t ram_size,
             exit(1);
         }
 
-        cpu_synchronize_state(env);
-
         /* Set initial guest state. */
         env->gpr[1] = (16<<20) - 8;
         env->gpr[3] = FDT_ADDR;
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index b7670ae27c..e111dda5f4 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -268,8 +268,6 @@ static void mpc8544ds_init(ram_addr_t ram_size,
             exit(1);
         }
 
-        cpu_synchronize_state(env);
-
         /* Set initial guest state. */
         env->gpr[1] = (16<<20) - 8;
         env->gpr[3] = dt_base;

From 8804f57b531e4887ad9521c9abb9e0bbbcb1dd4e Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Sun, 3 Apr 2011 18:21:24 +0200
Subject: [PATCH 123/386] spapr_vscsi: Set uninitialized variable

cppcheck reports this error:

hw/spapr_vscsi.c:274: error: Uninitialized variable: rc

If llen == 0, rc was indeed used without being initialized.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/spapr_vscsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index e142dae624..992833450c 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -255,7 +255,7 @@ static int vscsi_srp_direct_data(VSCSIState *s, vscsi_req *req,
 {
     struct srp_direct_buf *md = req->cur_desc;
     uint32_t llen;
-    int rc;
+    int rc = 0;
 
     dprintf("VSCSI: direct segment 0x%x bytes, va=0x%llx desc len=0x%x\n",
             len, (unsigned long long)md->va, md->len);

From c7a5c0c9280c2ddaa875e3cafb3df16a96af809c Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Tue, 5 Apr 2011 15:12:09 +1000
Subject: [PATCH 124/386] pseries: Abolish envs array

Currently the pseries machine init code builds up an array, envs, of
CPUState pointers for all the cpus in the system.  This is kind of
pointless, given the generic code already has a perfectly good linked list
of the cpus.

In addition, there are a number of places which assume that the cpu's
cpu_index field is equal to its index in this array.  This is true in
practice, because cpu_index values are just assigned sequentially, but
it's conceptually incorrect and may not always be true.

Therefore, this patch abolishes the envs array, and explicitly uses the
generic cpu linked list and cpu_index values throughout.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/spapr.c | 49 ++++++++++++++++++++++++-------------------------
 hw/xics.c  | 32 +++++++++++++++++++++-----------
 hw/xics.h  |  3 +--
 3 files changed, 46 insertions(+), 38 deletions(-)

diff --git a/hw/spapr.c b/hw/spapr.c
index 1152a25b2e..f80873cfd2 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -57,7 +57,7 @@
 sPAPREnvironment *spapr;
 
 static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
-                              const char *cpu_model, CPUState *envs[],
+                              const char *cpu_model,
                               sPAPREnvironment *spapr,
                               target_phys_addr_t initrd_base,
                               target_phys_addr_t initrd_size,
@@ -68,6 +68,7 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
                               long hash_shift)
 {
     void *fdt;
+    CPUState *env;
     uint64_t mem_reg_property[] = { 0, cpu_to_be64(ramsize) };
     uint32_t start_prop = cpu_to_be32(initrd_base);
     uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
@@ -135,14 +136,14 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
         modelname[i] = toupper(modelname[i]);
     }
 
-    for (i = 0; i < smp_cpus; i++) {
-        CPUState *env = envs[i];
-        uint32_t gserver_prop[] = {cpu_to_be32(i), 0}; /* HACK! */
+    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        int index = env->cpu_index;
+        uint32_t gserver_prop[] = {cpu_to_be32(index), 0}; /* HACK! */
         char *nodename;
         uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
                            0xffffffff, 0xffffffff};
 
-        if (asprintf(&nodename, "%s@%x", modelname, i) < 0) {
+        if (asprintf(&nodename, "%s@%x", modelname, index) < 0) {
             fprintf(stderr, "Allocation failure\n");
             exit(1);
         }
@@ -151,7 +152,7 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
 
         free(nodename);
 
-        _FDT((fdt_property_cell(fdt, "reg", i)));
+        _FDT((fdt_property_cell(fdt, "reg", index)));
         _FDT((fdt_property_string(fdt, "device_type", "cpu")));
 
         _FDT((fdt_property_cell(fdt, "cpu-version", env->spr[SPR_PVR])));
@@ -168,11 +169,11 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
                            pft_size_prop, sizeof(pft_size_prop))));
         _FDT((fdt_property_string(fdt, "status", "okay")));
         _FDT((fdt_property(fdt, "64-bit", NULL, 0)));
-        _FDT((fdt_property_cell(fdt, "ibm,ppc-interrupt-server#s", i)));
+        _FDT((fdt_property_cell(fdt, "ibm,ppc-interrupt-server#s", index)));
         _FDT((fdt_property(fdt, "ibm,ppc-interrupt-gserver#s",
                            gserver_prop, sizeof(gserver_prop))));
 
-        if (envs[i]->mmu_model & POWERPC_MMU_1TSEG) {
+        if (env->mmu_model & POWERPC_MMU_1TSEG) {
             _FDT((fdt_property(fdt, "ibm,processor-segment-sizes",
                                segs, sizeof(segs))));
         }
@@ -261,8 +262,8 @@ static void ppc_spapr_init(ram_addr_t ram_size,
                            const char *initrd_filename,
                            const char *cpu_model)
 {
-    CPUState *envs[MAX_CPUS];
     void *fdt, *htab;
+    CPUState *env;
     int i;
     ram_addr_t ram_offset;
     target_phys_addr_t fdt_addr, rtas_addr;
@@ -288,7 +289,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
         cpu_model = "POWER7";
     }
     for (i = 0; i < smp_cpus; i++) {
-        CPUState *env = cpu_init(cpu_model);
+        env = cpu_init(cpu_model);
 
         if (!env) {
             fprintf(stderr, "Unable to find PowerPC CPU definition\n");
@@ -300,9 +301,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
 
         env->hreset_vector = 0x60;
         env->hreset_excp_prefix = 0;
-        env->gpr[3] = i;
-
-        envs[i] = env;
+        env->gpr[3] = env->cpu_index;
     }
 
     /* allocate RAM */
@@ -315,10 +314,10 @@ static void ppc_spapr_init(ram_addr_t ram_size,
     htab_size = 1ULL << (pteg_shift + 7);
     htab = qemu_mallocz(htab_size);
 
-    for (i = 0; i < smp_cpus; i++) {
-        envs[i]->external_htab = htab;
-        envs[i]->htab_base = -1;
-        envs[i]->htab_mask = htab_size - 1;
+    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        env->external_htab = htab;
+        env->htab_base = -1;
+        env->htab_mask = htab_size - 1;
     }
 
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");
@@ -330,7 +329,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
     qemu_free(filename);
 
     /* Set up Interrupt Controller */
-    spapr->icp = xics_system_init(smp_cpus, envs, XICS_IRQS);
+    spapr->icp = xics_system_init(XICS_IRQS);
 
     /* Set up VIO bus */
     spapr->vio_bus = spapr_vio_bus_init();
@@ -416,13 +415,13 @@ static void ppc_spapr_init(ram_addr_t ram_size,
 
         /* SLOF will startup the secondary CPUs using RTAS,
            rather than expecting a kexec() style entry */
-        for (i = 0; i < smp_cpus; i++) {
-            envs[i]->halted = 1;
+        for (env = first_cpu; env != NULL; env = env->next_cpu) {
+            env->halted = 1;
         }
     }
 
     /* Prepare the device tree */
-    fdt = spapr_create_fdt(&fdt_size, ram_size, cpu_model, envs, spapr,
+    fdt = spapr_create_fdt(&fdt_size, ram_size, cpu_model, spapr,
                            initrd_base, initrd_size,
                            boot_device, kernel_cmdline,
                            rtas_addr, rtas_size, pteg_shift + 7);
@@ -432,10 +431,10 @@ static void ppc_spapr_init(ram_addr_t ram_size,
 
     qemu_free(fdt);
 
-    envs[0]->gpr[3] = fdt_addr;
-    envs[0]->gpr[5] = 0;
-    envs[0]->hreset_vector = kernel_base;
-    envs[0]->halted = 0;
+    first_cpu->gpr[3] = fdt_addr;
+    first_cpu->gpr[5] = 0;
+    first_cpu->hreset_vector = kernel_base;
+    first_cpu->halted = 0;
 }
 
 static QEMUMachine spapr_machine = {
diff --git a/hw/xics.c b/hw/xics.c
index 66047a6c57..13a1d25944 100644
--- a/hw/xics.c
+++ b/hw/xics.c
@@ -425,27 +425,39 @@ static void rtas_int_on(sPAPREnvironment *spapr, uint32_t token,
     rtas_st(rets, 0, 0); /* Success */
 }
 
-struct icp_state *xics_system_init(int nr_servers, CPUState *servers[],
-                                   int nr_irqs)
+struct icp_state *xics_system_init(int nr_irqs)
 {
+    CPUState *env;
+    int max_server_num;
     int i;
     struct icp_state *icp;
     struct ics_state *ics;
 
+    max_server_num = -1;
+    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        if (env->cpu_index > max_server_num) {
+            max_server_num = env->cpu_index;
+        }
+    }
+
     icp = qemu_mallocz(sizeof(*icp));
-    icp->nr_servers = nr_servers;
-    icp->ss = qemu_mallocz(nr_servers * sizeof(struct icp_server_state));
+    icp->nr_servers = max_server_num + 1;
+    icp->ss = qemu_mallocz(icp->nr_servers*sizeof(struct icp_server_state));
 
-    for (i = 0; i < nr_servers; i++) {
-        servers[i]->cpu_index = i;
+    for (i = 0; i < icp->nr_servers; i++) {
+        icp->ss[i].mfrr = 0xff;
+    }
 
-        switch (PPC_INPUT(servers[i])) {
+    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        struct icp_server_state *ss = &icp->ss[env->cpu_index];
+
+        switch (PPC_INPUT(env)) {
         case PPC_FLAGS_INPUT_POWER7:
-            icp->ss[i].output = servers[i]->irq_inputs[POWER7_INPUT_INT];
+            ss->output = env->irq_inputs[POWER7_INPUT_INT];
             break;
 
         case PPC_FLAGS_INPUT_970:
-            icp->ss[i].output = servers[i]->irq_inputs[PPC970_INPUT_INT];
+            ss->output = env->irq_inputs[PPC970_INPUT_INT];
             break;
 
         default:
@@ -453,8 +465,6 @@ struct icp_state *xics_system_init(int nr_servers, CPUState *servers[],
                      "model\n");
             exit(1);
         }
-
-        icp->ss[i].mfrr = 0xff;
     }
 
     ics = qemu_mallocz(sizeof(*ics));
diff --git a/hw/xics.h b/hw/xics.h
index 096eeb346d..83c1182598 100644
--- a/hw/xics.h
+++ b/hw/xics.h
@@ -33,7 +33,6 @@ struct icp_state;
 
 qemu_irq xics_find_qirq(struct icp_state *icp, int irq);
 
-struct icp_state *xics_system_init(int nr_servers, CPUState *servers[],
-                                   int nr_irqs);
+struct icp_state *xics_system_init(int nr_irqs);
 
 #endif /* __XICS_H__ */

From a3467baa88c5bbb58834952980d2f2206aab4445 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Tue, 5 Apr 2011 15:12:10 +1000
Subject: [PATCH 125/386] Delay creation of pseries device tree until reset

At present, the 'pseries' machine creates a flattened device tree in the
machine->init function to pass to either the guest kernel or to firmware.

However, the machine->init function runs before processing of -device
command line options, which means that the device tree so created will
be (incorrectly) missing devices specified that way.

Supplying a correct device tree is, in any case, part of the required
platform entry conditions.  Therefore, this patch moves the creation and
loading of the device tree from machine->init to a reset callback.  The
setup of entry point address and initial register state moves with it,
which leads to a slight cleanup.

This is not, alas, quite enough to make a fully working reset for pseries.
For that we would need to reload the firmware images, which on this
machine are loaded into RAM.  It's a step in the right direction, though.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/spapr.c | 116 +++++++++++++++++++++++++++++++----------------------
 hw/spapr.h |   7 ++++
 2 files changed, 75 insertions(+), 48 deletions(-)

diff --git a/hw/spapr.c b/hw/spapr.c
index f80873cfd2..1782cc0a94 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -56,20 +56,16 @@
 
 sPAPREnvironment *spapr;
 
-static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
-                              const char *cpu_model,
-                              sPAPREnvironment *spapr,
-                              target_phys_addr_t initrd_base,
-                              target_phys_addr_t initrd_size,
-                              const char *boot_device,
-                              const char *kernel_cmdline,
-                              target_phys_addr_t rtas_addr,
-                              target_phys_addr_t rtas_size,
-                              long hash_shift)
+static void *spapr_create_fdt_skel(const char *cpu_model,
+                                   target_phys_addr_t initrd_base,
+                                   target_phys_addr_t initrd_size,
+                                   const char *boot_device,
+                                   const char *kernel_cmdline,
+                                   long hash_shift)
 {
     void *fdt;
     CPUState *env;
-    uint64_t mem_reg_property[] = { 0, cpu_to_be64(ramsize) };
+    uint64_t mem_reg_property[] = { 0, cpu_to_be64(ram_size) };
     uint32_t start_prop = cpu_to_be32(initrd_base);
     uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
     uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)};
@@ -78,7 +74,6 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
     uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
     int i;
     char *modelname;
-    int ret;
 
 #define _FDT(exp) \
     do { \
@@ -222,8 +217,21 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
     _FDT((fdt_end_node(fdt))); /* close root node */
     _FDT((fdt_finish(fdt)));
 
-    /* re-expand to allow for further tweaks */
-    _FDT((fdt_open_into(fdt, fdt, FDT_MAX_SIZE)));
+    return fdt;
+}
+
+static void spapr_finalize_fdt(sPAPREnvironment *spapr,
+                               target_phys_addr_t fdt_addr,
+                               target_phys_addr_t rtas_addr,
+                               target_phys_addr_t rtas_size)
+{
+    int ret;
+    void *fdt;
+
+    fdt = qemu_malloc(FDT_MAX_SIZE);
+
+    /* open out the base tree into a temp buffer for the final tweaks */
+    _FDT((fdt_open_into(spapr->fdt_skel, fdt, FDT_MAX_SIZE)));
 
     ret = spapr_populate_vdevice(spapr->vio_bus, fdt);
     if (ret < 0) {
@@ -239,9 +247,9 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
 
     _FDT((fdt_pack(fdt)));
 
-    *fdt_size = fdt_totalsize(fdt);
+    cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt));
 
-    return fdt;
+    qemu_free(fdt);
 }
 
 static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
@@ -254,6 +262,27 @@ static void emulate_spapr_hypercall(CPUState *env)
     env->gpr[3] = spapr_hypercall(env, env->gpr[3], &env->gpr[4]);
 }
 
+static void spapr_reset(void *opaque)
+{
+    sPAPREnvironment *spapr = (sPAPREnvironment *)opaque;
+
+    fprintf(stderr, "sPAPR reset\n");
+
+    /* flush out the hash table */
+    memset(spapr->htab, 0, spapr->htab_size);
+
+    /* Load the fdt */
+    spapr_finalize_fdt(spapr, spapr->fdt_addr, spapr->rtas_addr,
+                       spapr->rtas_size);
+
+    /* Set up the entry state */
+    first_cpu->gpr[3] = spapr->fdt_addr;
+    first_cpu->gpr[5] = 0;
+    first_cpu->halted = 0;
+    first_cpu->nip = spapr->entry_point;
+
+}
+
 /* pSeries LPAR / sPAPR hardware init */
 static void ppc_spapr_init(ram_addr_t ram_size,
                            const char *boot_device,
@@ -262,15 +291,12 @@ static void ppc_spapr_init(ram_addr_t ram_size,
                            const char *initrd_filename,
                            const char *cpu_model)
 {
-    void *fdt, *htab;
     CPUState *env;
     int i;
     ram_addr_t ram_offset;
-    target_phys_addr_t fdt_addr, rtas_addr;
-    uint32_t kernel_base, initrd_base;
-    long kernel_size, initrd_size, htab_size, rtas_size, fw_size;
+    uint32_t initrd_base;
+    long kernel_size, initrd_size, fw_size;
     long pteg_shift = 17;
-    int fdt_size;
     char *filename;
     int irq = 16;
 
@@ -280,9 +306,8 @@ static void ppc_spapr_init(ram_addr_t ram_size,
     /* We place the device tree just below either the top of RAM, or
      * 2GB, so that it can be processed with 32-bit code if
      * necessary */
-    fdt_addr = MIN(ram_size, 0x80000000) - FDT_MAX_SIZE;
-    /* RTAS goes just below that */
-    rtas_addr = fdt_addr - RTAS_MAX_SIZE;
+    spapr->fdt_addr = MIN(ram_size, 0x80000000) - FDT_MAX_SIZE;
+    spapr->rtas_addr = spapr->fdt_addr - RTAS_MAX_SIZE;
 
     /* init CPUs */
     if (cpu_model == NULL) {
@@ -311,18 +336,19 @@ static void ppc_spapr_init(ram_addr_t ram_size,
     /* allocate hash page table.  For now we always make this 16mb,
      * later we should probably make it scale to the size of guest
      * RAM */
-    htab_size = 1ULL << (pteg_shift + 7);
-    htab = qemu_mallocz(htab_size);
+    spapr->htab_size = 1ULL << (pteg_shift + 7);
+    spapr->htab = qemu_malloc(spapr->htab_size);
 
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        env->external_htab = htab;
+        env->external_htab = spapr->htab;
         env->htab_base = -1;
-        env->htab_mask = htab_size - 1;
+        env->htab_mask = spapr->htab_size - 1;
     }
 
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");
-    rtas_size = load_image_targphys(filename, rtas_addr, ram_size - rtas_addr);
-    if (rtas_size < 0) {
+    spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr,
+                                           ram_size - spapr->rtas_addr);
+    if (spapr->rtas_size < 0) {
         hw_error("qemu: could not load LPAR rtas '%s'\n", filename);
         exit(1);
     }
@@ -368,13 +394,12 @@ static void ppc_spapr_init(ram_addr_t ram_size,
     if (kernel_filename) {
         uint64_t lowaddr = 0;
 
-        kernel_base = KERNEL_LOAD_ADDR;
-
         kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
                                NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0);
         if (kernel_size < 0) {
-            kernel_size = load_image_targphys(kernel_filename, kernel_base,
-                                              ram_size - kernel_base);
+            kernel_size = load_image_targphys(kernel_filename,
+                                              KERNEL_LOAD_ADDR,
+                                              ram_size - KERNEL_LOAD_ADDR);
         }
         if (kernel_size < 0) {
             fprintf(stderr, "qemu: could not load kernel '%s'\n",
@@ -396,6 +421,8 @@ static void ppc_spapr_init(ram_addr_t ram_size,
             initrd_base = 0;
             initrd_size = 0;
         }
+
+        spapr->entry_point = KERNEL_LOAD_ADDR;
     } else {
         if (ram_size < (MIN_RAM_SLOF << 20)) {
             fprintf(stderr, "qemu: pSeries SLOF firmware requires >= "
@@ -409,7 +436,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
             exit(1);
         }
         qemu_free(filename);
-        kernel_base = 0x100;
+        spapr->entry_point = 0x100;
         initrd_base = 0;
         initrd_size = 0;
 
@@ -421,20 +448,13 @@ static void ppc_spapr_init(ram_addr_t ram_size,
     }
 
     /* Prepare the device tree */
-    fdt = spapr_create_fdt(&fdt_size, ram_size, cpu_model, spapr,
-                           initrd_base, initrd_size,
-                           boot_device, kernel_cmdline,
-                           rtas_addr, rtas_size, pteg_shift + 7);
-    assert(fdt != NULL);
+    spapr->fdt_skel = spapr_create_fdt_skel(cpu_model,
+                                            initrd_base, initrd_size,
+                                            boot_device, kernel_cmdline,
+                                            pteg_shift + 7);
+    assert(spapr->fdt_skel != NULL);
 
-    cpu_physical_memory_write(fdt_addr, fdt, fdt_size);
-
-    qemu_free(fdt);
-
-    first_cpu->gpr[3] = fdt_addr;
-    first_cpu->gpr[5] = 0;
-    first_cpu->hreset_vector = kernel_base;
-    first_cpu->halted = 0;
+    qemu_register_reset(spapr_reset, spapr);
 }
 
 static QEMUMachine spapr_machine = {
diff --git a/hw/spapr.h b/hw/spapr.h
index fae8e1351c..b52133a4aa 100644
--- a/hw/spapr.h
+++ b/hw/spapr.h
@@ -7,6 +7,13 @@ struct icp_state;
 typedef struct sPAPREnvironment {
     struct VIOsPAPRBus *vio_bus;
     struct icp_state *icp;
+
+    void *htab;
+    long htab_size;
+    target_phys_addr_t fdt_addr, rtas_addr;
+    long rtas_size;
+    void *fdt_skel;
+    target_ulong entry_point;
 } sPAPREnvironment;
 
 #define H_SUCCESS         0

From 3601ff11732160e42d3174d2821d873cfcd52a59 Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Tue, 5 Apr 2011 15:12:11 +1000
Subject: [PATCH 126/386] Use existing helper function to implement popcntd
 instruction

The recent patches adding partial support for POWER7 cpu emulation included
implementing the popcntd instruction.  The support for this was open coded,
but host-utils.h already included a function implementing an equivalent
population count function, which uses a gcc builtin (which can use special
host instructions) if available.

This patch makes the popcntd implementation use the existing, potentially
faster, implementation.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/op_helper.c | 14 +-------------
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index b1b883d0a7..5882becbc9 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -528,19 +528,7 @@ target_ulong helper_popcntw (target_ulong val)
 
 target_ulong helper_popcntd (target_ulong val)
 {
-    val = (val & 0x5555555555555555ULL) + ((val >>  1) &
-                                           0x5555555555555555ULL);
-    val = (val & 0x3333333333333333ULL) + ((val >>  2) &
-                                           0x3333333333333333ULL);
-    val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >>  4) &
-                                           0x0f0f0f0f0f0f0f0fULL);
-    val = (val & 0x00ff00ff00ff00ffULL) + ((val >>  8) &
-                                           0x00ff00ff00ff00ffULL);
-    val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) &
-                                           0x0000ffff0000ffffULL);
-    val = (val & 0x00000000ffffffffULL) + ((val >> 32) &
-                                           0x00000000ffffffffULL);
-    return val;
+    return ctpop64(val);
 }
 #else
 target_ulong helper_popcntb (target_ulong val)

From 6957785773e8a3cc8bd51f0e3172eaccbbaa5f3a Mon Sep 17 00:00:00 2001
From: David Gibson <david@gibson.dropbear.id.au>
Date: Fri, 8 Apr 2011 20:08:25 +1000
Subject: [PATCH 127/386] ppce500_mpc8544ds: Fix compile with --enable-debug
 and --disable-kvm

When configured with --enable-debug, we compile without optimization.
This means that the function mpc8544_copy_soc_cell() in ppce500_mpc8544ds.c
is not optimized out, even though it is never called without kvm.  That in
turn causes a link failure, because it calls the function
kvmppc_read_host_property() which is in kvm_ppc.o and therefore not
included in a --disable-kvm build.

This patch fixes the problem by providing a dummy stub for
kvmppc_read_host_property() in kvm_ppc.h when !CONFIG_KVM.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/kvm_ppc.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 5afb308477..45a1373b28 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -11,8 +11,17 @@
 
 void kvmppc_init(void);
 void kvmppc_fdt_update(void *fdt);
+#ifndef CONFIG_KVM
+static inline int kvmppc_read_host_property(const char *node_path, const char *prop,
+                                            void *val, size_t len)
+{
+    assert(0);
+    return -ENOSYS;
+}
+#else
 int kvmppc_read_host_property(const char *node_path, const char *prop,
                                      void *val, size_t len);
+#endif
 
 uint32_t kvmppc_get_tbfreq(void);
 int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len);

From 31a44434f7b3221d911d478de3d1665bde753c86 Mon Sep 17 00:00:00 2001
From: Alex Williamson <alex.williamson@redhat.com>
Date: Fri, 8 Apr 2011 13:03:34 -0600
Subject: [PATCH 128/386] Add ipxe submodule

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
---
 .gitmodules | 3 +++
 roms/ipxe   | 1 +
 2 files changed, 4 insertions(+)
 create mode 160000 roms/ipxe

diff --git a/.gitmodules b/.gitmodules
index 44fdd1a02d..788447189e 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -7,3 +7,6 @@
 [submodule "roms/SLOF"]
 	path = roms/SLOF
 	url = git://git.qemu.org/SLOF.git
+[submodule "roms/ipxe"]
+	path = roms/ipxe
+	url = git://git.qemu.org/ipxe.git
diff --git a/roms/ipxe b/roms/ipxe
new file mode 160000
index 0000000000..7aee315f61
--- /dev/null
+++ b/roms/ipxe
@@ -0,0 +1 @@
+Subproject commit 7aee315f61aaf1be6d2fff26339f28a1137231a5

From f95857b34d284895816f2091ef4fc6d9460ebf3b Mon Sep 17 00:00:00 2001
From: Adam Lackorzynski <adam@os.inf.tu-dresden.de>
Date: Fri, 8 Apr 2011 08:48:42 +0200
Subject: [PATCH 129/386] multiboot: Quote filename in error message

Quote filename in error message to spot possible whitespace character in
the filename and make error message more meaningful.

Signed-off-by: Adam Lackorzynski <adam@os.inf.tu-dresden.de>
Acked-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 hw/multiboot.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/multiboot.c b/hw/multiboot.c
index 0d2bfb4973..394ed0136e 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -272,7 +272,7 @@ int load_multiboot(void *fw_cfg,
             mb_debug("multiboot loading module: %s\n", initrd_filename);
             mb_mod_length = get_image_size(initrd_filename);
             if (mb_mod_length < 0) {
-                fprintf(stderr, "failed to get %s image size\n", initrd_filename);
+                fprintf(stderr, "Failed to open file '%s'\n", initrd_filename);
                 exit(1);
             }
 

From 97697373b41ec1d337d6826d981a0cb4e75c37f0 Mon Sep 17 00:00:00 2001
From: Brad Hards <bradh@frogmouth.net>
Date: Sat, 9 Apr 2011 12:11:36 +1000
Subject: [PATCH 130/386] event: trivial coding style fixes

Signed-off-by: Brad Hards <bradh@frogmouth.net>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 input.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/input.c b/input.c
index ec05548f7a..5664d3a1e3 100644
--- a/input.c
+++ b/input.c
@@ -161,15 +161,15 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
 
     if (mouse_event) {
         if (graphic_rotate) {
-            if (entry->qemu_put_mouse_event_absolute)
+            if (entry->qemu_put_mouse_event_absolute) {
                 width = 0x7fff;
-            else
+            } else {
                 width = graphic_width - 1;
-            mouse_event(mouse_event_opaque,
-                        width - dy, dx, dz, buttons_state);
-        } else
-            mouse_event(mouse_event_opaque,
-                        dx, dy, dz, buttons_state);
+            }
+            mouse_event(mouse_event_opaque, width - dy, dx, dz, buttons_state);
+        } else {
+            mouse_event(mouse_event_opaque, dx, dy, dz, buttons_state);
+        }
     }
 }
 

From 72b310e99a5752d520af82d641c6cafa5b1058ea Mon Sep 17 00:00:00 2001
From: Scott Wood <scottwood@freescale.com>
Date: Fri, 8 Apr 2011 17:06:37 -0500
Subject: [PATCH 131/386] mpc85xx_pci_map_irq: change "unknow" to "unknown"

Signed-off-by: Scott Wood <scottwood@freescale.com>
Acked-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 hw/ppce500_pci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 11edd03f16..2fc879236a 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -198,7 +198,7 @@ static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
             ret = (irq_num + devno - 0x10) % 4;
             break;
         default:
-            printf("Error:%s:unknow dev number\n", __func__);
+            printf("Error:%s:unknown dev number\n", __func__);
     }
 
     pci_debug("%s: devfn %x irq %d -> %d  devno:%x\n", __func__,

From 29e5badadffe2cc70a911a95e258d1fb01f2db71 Mon Sep 17 00:00:00 2001
From: Scott Wood <scottwood@freescale.com>
Date: Fri, 8 Apr 2011 14:15:50 -0500
Subject: [PATCH 132/386] configure: avoid basename usage message

basename prints a missing-argument error when sdlconfig is empty
and we're cross-compiling.

Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 configure | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure b/configure
index ae97e11a97..2bb3faa07e 100755
--- a/configure
+++ b/configure
@@ -1233,7 +1233,7 @@ else
   fi
   sdl=no
 fi
-if test -n "$cross_prefix" && test "`basename $sdlconfig`" = sdl-config; then
+if test -n "$cross_prefix" && test "$(basename "$sdlconfig")" = sdl-config; then
   echo warning: using "\"$sdlconfig\"" to detect cross-compiled sdl >&2
 fi
 

From 5145b3d1cc4dc77d82086d99b0690a76e1073071 Mon Sep 17 00:00:00 2001
From: Jordan Justen <jordan.l.justen@intel.com>
Date: Sun, 3 Apr 2011 13:16:26 -0700
Subject: [PATCH 133/386] hw/pflash_cfi02: Fix lazy reset of ROMD mode

When checking pfl->rom_mode for when to lazily reenter ROMD mode,
the value was check was the opposite of what it should have been.
This prevent the part from returning to ROMD mode after a write
was made to the CFI rom region.

Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/pflash_cfi02.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c
index 30c8aa4e4f..370c5eef7b 100644
--- a/hw/pflash_cfi02.c
+++ b/hw/pflash_cfi02.c
@@ -112,7 +112,7 @@ static uint32_t pflash_read (pflash_t *pfl, target_phys_addr_t offset,
 
     DPRINTF("%s: offset " TARGET_FMT_plx "\n", __func__, offset);
     ret = -1;
-    if (pfl->rom_mode) {
+    if (!pfl->rom_mode) {
         /* Lazy reset of to ROMD mode */
         if (pfl->wcycle == 0)
             pflash_register_memory(pfl, 1);

From a54d41a8b985cc7ff9d4bc52e6ca20a09216b394 Mon Sep 17 00:00:00 2001
From: Isaku Yamahata <yamahata@valinux.co.jp>
Date: Fri, 25 Mar 2011 19:54:38 +0900
Subject: [PATCH 134/386] acpi, acpi_piix, vt82c686: factor out PM_TMR logic

factor out PM_TMR logic. Later This will be used by ich9 acpi.
Also fixes the same bug in vt82c686.c that was fixed by the following
commits.

> commit 055479feab63607b8042bb8ebb2e0523f17cbc4e
> Author: aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
> Date:   Wed Jan 21 16:31:20 2009 +0000
>
>     Always return latest pmsts instead of the old one (Xiantao Zhang)
>
>     It may lead to the issue when booting windows guests with acpi=1
>     if return the old pmsts.
>
>     Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
>     Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

Cc: Blue Swirl <blauwirbel@gmail.com>
Cc: Huacai Chen <zltjiangshi@gmail.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/acpi.c       | 45 +++++++++++++++++++++++++++++++++++++++++++++
 hw/acpi.h       | 24 ++++++++++++++++++++++++
 hw/acpi_piix4.c | 45 ++++++++++++---------------------------------
 hw/vt82c686.c   | 47 +++++++++++++++--------------------------------
 4 files changed, 96 insertions(+), 65 deletions(-)

diff --git a/hw/acpi.c b/hw/acpi.c
index 8071e7beba..08cb12673b 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -197,3 +197,48 @@ out:
     }
     return -1;
 }
+
+/* ACPI PM_TMR */
+void acpi_pm_tmr_update(ACPIPMTimer *tmr, bool enable)
+{
+    int64_t expire_time;
+
+    /* schedule a timer interruption if needed */
+    if (enable) {
+        expire_time = muldiv64(tmr->overflow_time, get_ticks_per_sec(),
+                               PM_TIMER_FREQUENCY);
+        qemu_mod_timer(tmr->timer, expire_time);
+    } else {
+        qemu_del_timer(tmr->timer);
+    }
+}
+
+void acpi_pm_tmr_calc_overflow_time(ACPIPMTimer *tmr)
+{
+    int64_t d = acpi_pm_tmr_get_clock();
+    tmr->overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
+}
+
+uint32_t acpi_pm_tmr_get(ACPIPMTimer *tmr)
+{
+    uint32_t d = acpi_pm_tmr_get_clock();;
+    return d & 0xffffff;
+}
+
+static void acpi_pm_tmr_timer(void *opaque)
+{
+    ACPIPMTimer *tmr = opaque;
+    tmr->update_sci(tmr);
+}
+
+void acpi_pm_tmr_init(ACPIPMTimer *tmr, acpi_update_sci_fn update_sci)
+{
+    tmr->update_sci = update_sci;
+    tmr->timer = qemu_new_timer_ns(vm_clock, acpi_pm_tmr_timer, tmr);
+}
+
+void acpi_pm_tmr_reset(ACPIPMTimer *tmr)
+{
+    tmr->overflow_time = 0;
+    qemu_del_timer(tmr->timer);
+}
diff --git a/hw/acpi.h b/hw/acpi.h
index 5949958067..fc425012b3 100644
--- a/hw/acpi.h
+++ b/hw/acpi.h
@@ -74,5 +74,29 @@
 #define ACPI_BITMASK_ARB_DISABLE                0x0001
 
 /* PM_TMR */
+struct ACPIPMTimer;
+typedef struct ACPIPMTimer ACPIPMTimer;
+
+typedef void (*acpi_update_sci_fn)(ACPIPMTimer *tmr);
+
+struct ACPIPMTimer {
+    QEMUTimer *timer;
+    int64_t overflow_time;
+
+    acpi_update_sci_fn update_sci;
+};
+
+void acpi_pm_tmr_update(ACPIPMTimer *tmr, bool enable);
+void acpi_pm_tmr_calc_overflow_time(ACPIPMTimer *tmr);
+uint32_t acpi_pm_tmr_get(ACPIPMTimer *tmr);
+void acpi_pm_tmr_init(ACPIPMTimer *tmr, acpi_update_sci_fn update_sci);
+void acpi_pm_tmr_reset(ACPIPMTimer *tmr);
+
+#include "qemu-timer.h"
+static inline int64_t acpi_pm_tmr_get_clock(void)
+{
+    return muldiv64(qemu_get_clock_ns(vm_clock), PM_TIMER_FREQUENCY,
+                    get_ticks_per_sec());
+}
 
 #endif /* !QEMU_HW_ACPI_H */
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 74044ddd9b..e4ba8fc252 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -60,8 +60,7 @@ typedef struct PIIX4PMState {
 
     APMState apm;
 
-    QEMUTimer *tmr_timer;
-    int64_t tmr_overflow_time;
+    ACPIPMTimer tmr;
 
     PMSMBus smb;
     uint32_t smb_io_base;
@@ -82,20 +81,10 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s);
 #define ACPI_ENABLE 0xf1
 #define ACPI_DISABLE 0xf0
 
-static uint32_t get_pmtmr(PIIX4PMState *s)
-{
-    uint32_t d;
-    d = muldiv64(qemu_get_clock_ns(vm_clock), PM_TIMER_FREQUENCY, get_ticks_per_sec());
-    return d & 0xffffff;
-}
-
 static int get_pmsts(PIIX4PMState *s)
 {
-    int64_t d;
-
-    d = muldiv64(qemu_get_clock_ns(vm_clock), PM_TIMER_FREQUENCY,
-                 get_ticks_per_sec());
-    if (d >= s->tmr_overflow_time)
+    int64_t d = acpi_pm_tmr_get_clock();
+    if (d >= s->tmr.overflow_time)
         s->pmsts |= ACPI_BITMASK_TIMER_STATUS;
     return s->pmsts;
 }
@@ -103,7 +92,6 @@ static int get_pmsts(PIIX4PMState *s)
 static void pm_update_sci(PIIX4PMState *s)
 {
     int sci_level, pmsts;
-    int64_t expire_time;
 
     pmsts = get_pmsts(s);
     sci_level = (((pmsts & s->pmen) &
@@ -115,19 +103,13 @@ static void pm_update_sci(PIIX4PMState *s)
 
     qemu_set_irq(s->irq, sci_level);
     /* schedule a timer interruption if needed */
-    if ((s->pmen & ACPI_BITMASK_TIMER_ENABLE) &&
-        !(pmsts & ACPI_BITMASK_TIMER_STATUS)) {
-        expire_time = muldiv64(s->tmr_overflow_time, get_ticks_per_sec(),
-                               PM_TIMER_FREQUENCY);
-        qemu_mod_timer(s->tmr_timer, expire_time);
-    } else {
-        qemu_del_timer(s->tmr_timer);
-    }
+    acpi_pm_tmr_update(&s->tmr, (s->pmen & ACPI_BITMASK_TIMER_ENABLE) &&
+                       !(pmsts & ACPI_BITMASK_TIMER_STATUS));
 }
 
-static void pm_tmr_timer(void *opaque)
+static void pm_tmr_timer(ACPIPMTimer *tmr)
 {
-    PIIX4PMState *s = opaque;
+    PIIX4PMState *s = container_of(tmr, PIIX4PMState, tmr);
     pm_update_sci(s);
 }
 
@@ -144,14 +126,11 @@ static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width,
     switch(addr) {
     case 0x00:
         {
-            int64_t d;
             int pmsts;
             pmsts = get_pmsts(s);
             if (pmsts & val & ACPI_BITMASK_TIMER_STATUS) {
                 /* if TMRSTS is reset, then compute the new overflow time */
-                d = muldiv64(qemu_get_clock_ns(vm_clock), PM_TIMER_FREQUENCY,
-                             get_ticks_per_sec());
-                s->tmr_overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
+                acpi_pm_tmr_calc_overflow_time(&s->tmr);
             }
             s->pmsts &= ~val;
             pm_update_sci(s);
@@ -211,7 +190,7 @@ static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width,
         val = s->pmcntrl;
         break;
     case 0x08:
-        val = get_pmtmr(s);
+        val = acpi_pm_tmr_get(&s->tmr);
         break;
     default:
         val = 0;
@@ -316,8 +295,8 @@ static const VMStateDescription vmstate_acpi = {
         VMSTATE_UINT16(pmen, PIIX4PMState),
         VMSTATE_UINT16(pmcntrl, PIIX4PMState),
         VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState),
-        VMSTATE_TIMER(tmr_timer, PIIX4PMState),
-        VMSTATE_INT64(tmr_overflow_time, PIIX4PMState),
+        VMSTATE_TIMER(tmr.timer, PIIX4PMState),
+        VMSTATE_INT64(tmr.overflow_time, PIIX4PMState),
         VMSTATE_STRUCT(gpe, PIIX4PMState, 2, vmstate_gpe, struct gpe_regs),
         VMSTATE_STRUCT(pci0_status, PIIX4PMState, 2, vmstate_pci_status,
                        struct pci_status),
@@ -414,7 +393,7 @@ static int piix4_pm_initfn(PCIDevice *dev)
     register_ioport_write(s->smb_io_base, 64, 1, smb_ioport_writeb, &s->smb);
     register_ioport_read(s->smb_io_base, 64, 1, smb_ioport_readb, &s->smb);
 
-    s->tmr_timer = qemu_new_timer_ns(vm_clock, pm_tmr_timer, s);
+    acpi_pm_tmr_init(&s->tmr, pm_tmr_timer);
 
     qemu_system_powerdown = *qemu_allocate_irqs(piix4_powerdown, s, 1);
 
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 818460d716..6f9c3847cb 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -160,8 +160,7 @@ typedef struct VT686PMState {
     uint16_t pmen;
     uint16_t pmcntrl;
     APMState apm;
-    QEMUTimer *tmr_timer;
-    int64_t tmr_overflow_time;
+    ACPIPMTimer tmr;
     PMSMBus smb;
     uint32_t smb_io_base;
 } VT686PMState;
@@ -183,45 +182,31 @@ typedef struct VT686MC97State {
 #define ACPI_ENABLE  0xf1
 #define ACPI_DISABLE 0xf0
 
-static uint32_t get_pmtmr(VT686PMState *s)
-{
-    uint32_t d;
-    d = muldiv64(qemu_get_clock_ns(vm_clock), PM_TIMER_FREQUENCY, get_ticks_per_sec());
-    return d & 0xffffff;
-}
-
 static int get_pmsts(VT686PMState *s)
 {
-    int64_t d;
-    int pmsts;
-    pmsts = s->pmsts;
-    d = muldiv64(qemu_get_clock_ns(vm_clock), PM_TIMER_FREQUENCY, get_ticks_per_sec());
-    if (d >= s->tmr_overflow_time)
-        s->pmsts |= TMROF_EN;
-    return pmsts;
+    int64_t d = acpi_pm_tmr_get_clock();
+    if (d >= s->tmr.overflow_time) {
+        s->pmsts |= ACPI_BITMASK_TIMER_STATUS;
+    }
+    return s->pmsts;
 }
 
 static void pm_update_sci(VT686PMState *s)
 {
     int sci_level, pmsts;
-    int64_t expire_time;
 
     pmsts = get_pmsts(s);
     sci_level = (((pmsts & s->pmen) &
                   (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0);
     qemu_set_irq(s->dev.irq[0], sci_level);
     /* schedule a timer interruption if needed */
-    if ((s->pmen & TMROF_EN) && !(pmsts & TMROF_EN)) {
-        expire_time = muldiv64(s->tmr_overflow_time, get_ticks_per_sec(), PM_TIMER_FREQUENCY);
-        qemu_mod_timer(s->tmr_timer, expire_time);
-    } else {
-        qemu_del_timer(s->tmr_timer);
-    }
+    acpi_pm_tmr_update(&s->tmr, (s->pmen & ACPI_BITMASK_TIMER_ENABLE) &&
+                       !(pmsts & ACPI_BITMASK_TIMER_STATUS));
 }
 
-static void pm_tmr_timer(void *opaque)
+static void pm_tmr_timer(ACPIPMTimer *tmr)
 {
-    VT686PMState *s = opaque;
+    VT686PMState *s = container_of(tmr, VT686PMState, tmr);
     pm_update_sci(s);
 }
 
@@ -233,13 +218,11 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
     switch (addr) {
     case 0x00:
         {
-            int64_t d;
             int pmsts;
             pmsts = get_pmsts(s);
             if (pmsts & val & TMROF_EN) {
                 /* if TMRSTS is reset, then compute the new overflow time */
-                d = muldiv64(qemu_get_clock_ns(vm_clock), PM_TIMER_FREQUENCY, get_ticks_per_sec());
-                s->tmr_overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
+                acpi_pm_tmr_calc_overflow_time(&s->tmr);
             }
             s->pmsts &= ~val;
             pm_update_sci(s);
@@ -310,7 +293,7 @@ static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
     addr &= 0x0f;
     switch (addr) {
     case 0x08:
-        val = get_pmtmr(s);
+        val = acpi_pm_tmr_get(&s->tmr);
         break;
     default:
         val = 0;
@@ -365,8 +348,8 @@ static const VMStateDescription vmstate_acpi = {
         VMSTATE_UINT16(pmen, VT686PMState),
         VMSTATE_UINT16(pmcntrl, VT686PMState),
         VMSTATE_STRUCT(apm, VT686PMState, 0, vmstate_apm, APMState),
-        VMSTATE_TIMER(tmr_timer, VT686PMState),
-        VMSTATE_INT64(tmr_overflow_time, VT686PMState),
+        VMSTATE_TIMER(tmr.timer, VT686PMState),
+        VMSTATE_INT64(tmr.overflow_time, VT686PMState),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -486,7 +469,7 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
 
     apm_init(&s->apm, NULL, s);
 
-    s->tmr_timer = qemu_new_timer_ns(vm_clock, pm_tmr_timer, s);
+    acpi_pm_tmr_init(&s->tmr, pm_tmr_timer);
 
     pm_smbus_init(&s->dev.qdev, &s->smb);
 

From 04dc308f687d45dacc664251b266b6849f5a79d0 Mon Sep 17 00:00:00 2001
From: Isaku Yamahata <yamahata@valinux.co.jp>
Date: Fri, 25 Mar 2011 19:54:39 +0900
Subject: [PATCH 135/386] acpi, acpi_piix, vt82c686: factor out PM1a EVT logic

factor out ACPI PM1a EVT logic.
Later this will be used by ich9 acpi.

Cc: Blue Swirl <blauwirbel@gmail.com>
Cc: Huacai Chen <zltjiangshi@gmail.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/acpi.c       | 37 +++++++++++++++++++++++++++++++++
 hw/acpi.h       | 13 ++++++++++++
 hw/acpi_piix4.c | 52 +++++++++++++++--------------------------------
 hw/vt82c686.c   | 54 ++++++++++++++-----------------------------------
 4 files changed, 81 insertions(+), 75 deletions(-)

diff --git a/hw/acpi.c b/hw/acpi.c
index 08cb12673b..07283befce 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -15,6 +15,7 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>
  */
+#include "sysemu.h"
 #include "hw.h"
 #include "pc.h"
 #include "acpi.h"
@@ -198,6 +199,42 @@ out:
     return -1;
 }
 
+/* ACPI PM1a EVT */
+uint16_t acpi_pm1_evt_get_sts(ACPIPM1EVT *pm1, int64_t overflow_time)
+{
+    int64_t d = acpi_pm_tmr_get_clock();
+    if (d >= overflow_time) {
+        pm1->sts |= ACPI_BITMASK_TIMER_STATUS;
+    }
+    return pm1->sts;
+}
+
+void acpi_pm1_evt_write_sts(ACPIPM1EVT *pm1, ACPIPMTimer *tmr, uint16_t val)
+{
+    uint16_t pm1_sts = acpi_pm1_evt_get_sts(pm1, tmr->overflow_time);
+    if (pm1_sts & val & ACPI_BITMASK_TIMER_STATUS) {
+        /* if TMRSTS is reset, then compute the new overflow time */
+        acpi_pm_tmr_calc_overflow_time(tmr);
+    }
+    pm1->sts &= ~val;
+}
+
+void acpi_pm1_evt_power_down(ACPIPM1EVT *pm1, ACPIPMTimer *tmr)
+{
+    if (!pm1) {
+        qemu_system_shutdown_request();
+    } else if (pm1->en & ACPI_BITMASK_POWER_BUTTON_ENABLE) {
+        pm1->sts |= ACPI_BITMASK_POWER_BUTTON_STATUS;
+        tmr->update_sci(tmr);
+    }
+}
+
+void acpi_pm1_evt_reset(ACPIPM1EVT *pm1)
+{
+    pm1->sts = 0;
+    pm1->en = 0;
+}
+
 /* ACPI PM_TMR */
 void acpi_pm_tmr_update(ACPIPMTimer *tmr, bool enable)
 {
diff --git a/hw/acpi.h b/hw/acpi.h
index fc425012b3..c286d7d4e2 100644
--- a/hw/acpi.h
+++ b/hw/acpi.h
@@ -99,4 +99,17 @@ static inline int64_t acpi_pm_tmr_get_clock(void)
                     get_ticks_per_sec());
 }
 
+/* PM1a_EVT: piix and ich9 don't implement PM1b. */
+struct ACPIPM1EVT
+{
+    uint16_t sts;
+    uint16_t en;
+};
+typedef struct ACPIPM1EVT ACPIPM1EVT;
+
+uint16_t acpi_pm1_evt_get_sts(ACPIPM1EVT *pm1, int64_t overflow_time);
+void acpi_pm1_evt_write_sts(ACPIPM1EVT *pm1, ACPIPMTimer *tmr, uint16_t val);
+void acpi_pm1_evt_power_down(ACPIPM1EVT *pm1, ACPIPMTimer *tmr);
+void acpi_pm1_evt_reset(ACPIPM1EVT *pm1);
+
 #endif /* !QEMU_HW_ACPI_H */
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index e4ba8fc252..fa7c6a9702 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -54,8 +54,7 @@ struct pci_status {
 typedef struct PIIX4PMState {
     PCIDevice dev;
     IORange ioport;
-    uint16_t pmsts;
-    uint16_t pmen;
+    ACPIPM1EVT pm1a;
     uint16_t pmcntrl;
 
     APMState apm;
@@ -81,20 +80,12 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s);
 #define ACPI_ENABLE 0xf1
 #define ACPI_DISABLE 0xf0
 
-static int get_pmsts(PIIX4PMState *s)
-{
-    int64_t d = acpi_pm_tmr_get_clock();
-    if (d >= s->tmr.overflow_time)
-        s->pmsts |= ACPI_BITMASK_TIMER_STATUS;
-    return s->pmsts;
-}
-
 static void pm_update_sci(PIIX4PMState *s)
 {
     int sci_level, pmsts;
 
-    pmsts = get_pmsts(s);
-    sci_level = (((pmsts & s->pmen) &
+    pmsts = acpi_pm1_evt_get_sts(&s->pm1a, s->tmr.overflow_time);
+    sci_level = (((pmsts & s->pm1a.en) &
                   (ACPI_BITMASK_RT_CLOCK_ENABLE |
                    ACPI_BITMASK_POWER_BUTTON_ENABLE |
                    ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
@@ -103,7 +94,7 @@ static void pm_update_sci(PIIX4PMState *s)
 
     qemu_set_irq(s->irq, sci_level);
     /* schedule a timer interruption if needed */
-    acpi_pm_tmr_update(&s->tmr, (s->pmen & ACPI_BITMASK_TIMER_ENABLE) &&
+    acpi_pm_tmr_update(&s->tmr, (s->pm1a.en & ACPI_BITMASK_TIMER_ENABLE) &&
                        !(pmsts & ACPI_BITMASK_TIMER_STATUS));
 }
 
@@ -125,19 +116,11 @@ static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width,
 
     switch(addr) {
     case 0x00:
-        {
-            int pmsts;
-            pmsts = get_pmsts(s);
-            if (pmsts & val & ACPI_BITMASK_TIMER_STATUS) {
-                /* if TMRSTS is reset, then compute the new overflow time */
-                acpi_pm_tmr_calc_overflow_time(&s->tmr);
-            }
-            s->pmsts &= ~val;
-            pm_update_sci(s);
-        }
+        acpi_pm1_evt_write_sts(&s->pm1a, &s->tmr, val);
+        pm_update_sci(s);
         break;
     case 0x02:
-        s->pmen = val;
+        s->pm1a.en = val;
         pm_update_sci(s);
         break;
     case 0x04:
@@ -154,8 +137,8 @@ static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width,
                 case 1:
                     /* ACPI_BITMASK_WAKE_STATUS should be set on resume.
                        Pretend that resume was caused by power button */
-                    s->pmsts |= (ACPI_BITMASK_WAKE_STATUS |
-                                 ACPI_BITMASK_POWER_BUTTON_STATUS);
+                    s->pm1a.sts |= (ACPI_BITMASK_WAKE_STATUS |
+                                    ACPI_BITMASK_POWER_BUTTON_STATUS);
                     qemu_system_reset_request();
                     if (s->cmos_s3) {
                         qemu_irq_raise(s->cmos_s3);
@@ -181,10 +164,10 @@ static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width,
 
     switch(addr) {
     case 0x00:
-        val = get_pmsts(s);
+        val = acpi_pm1_evt_get_sts(&s->pm1a, s->tmr.overflow_time);
         break;
     case 0x02:
-        val = s->pmen;
+        val = s->pm1a.en;
         break;
     case 0x04:
         val = s->pmcntrl;
@@ -291,8 +274,8 @@ static const VMStateDescription vmstate_acpi = {
     .post_load = vmstate_acpi_post_load,
     .fields      = (VMStateField []) {
         VMSTATE_PCI_DEVICE(dev, PIIX4PMState),
-        VMSTATE_UINT16(pmsts, PIIX4PMState),
-        VMSTATE_UINT16(pmen, PIIX4PMState),
+        VMSTATE_UINT16(pm1a.sts, PIIX4PMState),
+        VMSTATE_UINT16(pm1a.en, PIIX4PMState),
         VMSTATE_UINT16(pmcntrl, PIIX4PMState),
         VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState),
         VMSTATE_TIMER(tmr.timer, PIIX4PMState),
@@ -343,13 +326,10 @@ static void piix4_reset(void *opaque)
 static void piix4_powerdown(void *opaque, int irq, int power_failing)
 {
     PIIX4PMState *s = opaque;
+    ACPIPM1EVT *pm1a = s? &s->pm1a: NULL;
+    ACPIPMTimer *tmr = s? &s->tmr: NULL;
 
-    if (!s) {
-        qemu_system_shutdown_request();
-    } else if (s->pmen & ACPI_BITMASK_POWER_BUTTON_ENABLE) {
-        s->pmsts |= ACPI_BITMASK_POWER_BUTTON_STATUS;
-        pm_update_sci(s);
-    }
+    acpi_pm1_evt_power_down(pm1a, tmr);
 }
 
 static int piix4_pm_initfn(PCIDevice *dev)
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 6f9c3847cb..10cbc74cf1 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -156,8 +156,7 @@ static void vt82c686b_write_config(PCIDevice * d, uint32_t address,
 
 typedef struct VT686PMState {
     PCIDevice dev;
-    uint16_t pmsts;
-    uint16_t pmen;
+    ACPIPM1EVT pm1a;
     uint16_t pmcntrl;
     APMState apm;
     ACPIPMTimer tmr;
@@ -173,34 +172,19 @@ typedef struct VT686MC97State {
     PCIDevice dev;
 } VT686MC97State;
 
-#define RTC_EN    (1 << 10)
-#define PWRBTN_EN (1 << 8)
-#define GBL_EN    (1 << 5)
-#define TMROF_EN  (1 << 0)
-#define SUS_EN    (1 << 13)
-
-#define ACPI_ENABLE  0xf1
-#define ACPI_DISABLE 0xf0
-
-static int get_pmsts(VT686PMState *s)
-{
-    int64_t d = acpi_pm_tmr_get_clock();
-    if (d >= s->tmr.overflow_time) {
-        s->pmsts |= ACPI_BITMASK_TIMER_STATUS;
-    }
-    return s->pmsts;
-}
-
 static void pm_update_sci(VT686PMState *s)
 {
     int sci_level, pmsts;
 
-    pmsts = get_pmsts(s);
-    sci_level = (((pmsts & s->pmen) &
-                  (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0);
+    pmsts = acpi_pm1_evt_get_sts(&s->pm1a, s->tmr.overflow_time);
+    sci_level = (((pmsts & s->pm1a.en) &
+                  (ACPI_BITMASK_RT_CLOCK_ENABLE |
+                   ACPI_BITMASK_POWER_BUTTON_ENABLE |
+                   ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
+                   ACPI_BITMASK_TIMER_ENABLE)) != 0);
     qemu_set_irq(s->dev.irq[0], sci_level);
     /* schedule a timer interruption if needed */
-    acpi_pm_tmr_update(&s->tmr, (s->pmen & ACPI_BITMASK_TIMER_ENABLE) &&
+    acpi_pm_tmr_update(&s->tmr, (s->pm1a.en & ACPI_BITMASK_TIMER_ENABLE) &&
                        !(pmsts & ACPI_BITMASK_TIMER_STATUS));
 }
 
@@ -217,19 +201,11 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
     addr &= 0x0f;
     switch (addr) {
     case 0x00:
-        {
-            int pmsts;
-            pmsts = get_pmsts(s);
-            if (pmsts & val & TMROF_EN) {
-                /* if TMRSTS is reset, then compute the new overflow time */
-                acpi_pm_tmr_calc_overflow_time(&s->tmr);
-            }
-            s->pmsts &= ~val;
-            pm_update_sci(s);
-        }
+        acpi_pm1_evt_write_sts(&s->pm1a, &s->tmr, val);
+        pm_update_sci(s);
         break;
     case 0x02:
-        s->pmen = val;
+        s->pm1a.en = val;
         pm_update_sci(s);
         break;
     case 0x04:
@@ -263,10 +239,10 @@ static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
     addr &= 0x0f;
     switch (addr) {
     case 0x00:
-        val = get_pmsts(s);
+        val = acpi_pm1_evt_get_sts(&s->pm1a, s->tmr.overflow_time);
         break;
     case 0x02:
-        val = s->pmen;
+        val = s->pm1a.en;
         break;
     case 0x04:
         val = s->pmcntrl;
@@ -344,8 +320,8 @@ static const VMStateDescription vmstate_acpi = {
     .post_load = vmstate_acpi_post_load,
     .fields      = (VMStateField []) {
         VMSTATE_PCI_DEVICE(dev, VT686PMState),
-        VMSTATE_UINT16(pmsts, VT686PMState),
-        VMSTATE_UINT16(pmen, VT686PMState),
+        VMSTATE_UINT16(pm1a.sts, VT686PMState),
+        VMSTATE_UINT16(pm1a.en, VT686PMState),
         VMSTATE_UINT16(pmcntrl, VT686PMState),
         VMSTATE_STRUCT(apm, VT686PMState, 0, vmstate_apm, APMState),
         VMSTATE_TIMER(tmr.timer, VT686PMState),

From eaba51c573afbdd45273eed9d61d9effda979b47 Mon Sep 17 00:00:00 2001
From: Isaku Yamahata <yamahata@valinux.co.jp>
Date: Fri, 25 Mar 2011 19:54:40 +0900
Subject: [PATCH 136/386] acpi, acpi_piix, vt82c686: factor out PM1_CNT logic

factor out ACPI PM1_CNT logic. This will be used by ich9 acpi.

Cc: Blue Swirl <blauwirbel@gmail.com>
Cc: Huacai Chen <zltjiangshi@gmail.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/acpi.c       | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 hw/acpi.h       | 14 ++++++++++++++
 hw/acpi_piix4.c | 40 ++++++----------------------------------
 hw/vt82c686.c   | 23 +++++------------------
 4 files changed, 74 insertions(+), 52 deletions(-)

diff --git a/hw/acpi.c b/hw/acpi.c
index 07283befce..2879eea406 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -279,3 +279,52 @@ void acpi_pm_tmr_reset(ACPIPMTimer *tmr)
     tmr->overflow_time = 0;
     qemu_del_timer(tmr->timer);
 }
+
+/* ACPI PM1aCNT */
+void acpi_pm1_cnt_init(ACPIPM1CNT *pm1_cnt, qemu_irq cmos_s3)
+{
+    pm1_cnt->cmos_s3 = cmos_s3;
+}
+
+void acpi_pm1_cnt_write(ACPIPM1EVT *pm1a, ACPIPM1CNT *pm1_cnt, uint16_t val)
+{
+    pm1_cnt->cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE);
+
+    if (val & ACPI_BITMASK_SLEEP_ENABLE) {
+        /* change suspend type */
+        uint16_t sus_typ = (val >> 10) & 7;
+        switch(sus_typ) {
+        case 0: /* soft power off */
+            qemu_system_shutdown_request();
+            break;
+        case 1:
+            /* ACPI_BITMASK_WAKE_STATUS should be set on resume.
+               Pretend that resume was caused by power button */
+            pm1a->sts |=
+                (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS);
+            qemu_system_reset_request();
+            qemu_irq_raise(pm1_cnt->cmos_s3);
+        default:
+            break;
+        }
+    }
+}
+
+void acpi_pm1_cnt_update(ACPIPM1CNT *pm1_cnt,
+                         bool sci_enable, bool sci_disable)
+{
+    /* ACPI specs 3.0, 4.7.2.5 */
+    if (sci_enable) {
+        pm1_cnt->cnt |= ACPI_BITMASK_SCI_ENABLE;
+    } else if (sci_disable) {
+        pm1_cnt->cnt &= ~ACPI_BITMASK_SCI_ENABLE;
+    }
+}
+
+void acpi_pm1_cnt_reset(ACPIPM1CNT *pm1_cnt)
+{
+    pm1_cnt->cnt = 0;
+    if (pm1_cnt->cmos_s3) {
+        qemu_irq_lower(pm1_cnt->cmos_s3);
+    }
+}
diff --git a/hw/acpi.h b/hw/acpi.h
index c286d7d4e2..836459e9c1 100644
--- a/hw/acpi.h
+++ b/hw/acpi.h
@@ -112,4 +112,18 @@ void acpi_pm1_evt_write_sts(ACPIPM1EVT *pm1, ACPIPMTimer *tmr, uint16_t val);
 void acpi_pm1_evt_power_down(ACPIPM1EVT *pm1, ACPIPMTimer *tmr);
 void acpi_pm1_evt_reset(ACPIPM1EVT *pm1);
 
+/* PM1a_CNT: piix and ich9 don't implement PM1b CNT. */
+struct ACPIPM1CNT {
+    uint16_t cnt;
+
+    qemu_irq cmos_s3;
+};
+typedef struct ACPIPM1CNT ACPIPM1CNT;
+
+void acpi_pm1_cnt_init(ACPIPM1CNT *pm1_cnt, qemu_irq cmos_s3);
+void acpi_pm1_cnt_write(ACPIPM1EVT *pm1a, ACPIPM1CNT *pm1_cnt, uint16_t val);
+void acpi_pm1_cnt_update(ACPIPM1CNT *pm1_cnt,
+                         bool sci_enable, bool sci_disable);
+void acpi_pm1_cnt_reset(ACPIPM1CNT *pm1_cnt);
+
 #endif /* !QEMU_HW_ACPI_H */
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index fa7c6a9702..412ace3849 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -55,7 +55,7 @@ typedef struct PIIX4PMState {
     PCIDevice dev;
     IORange ioport;
     ACPIPM1EVT pm1a;
-    uint16_t pmcntrl;
+    ACPIPM1CNT pm1_cnt;
 
     APMState apm;
 
@@ -65,7 +65,6 @@ typedef struct PIIX4PMState {
     uint32_t smb_io_base;
 
     qemu_irq irq;
-    qemu_irq cmos_s3;
     qemu_irq smi_irq;
     int kvm_enabled;
 
@@ -124,30 +123,7 @@ static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width,
         pm_update_sci(s);
         break;
     case 0x04:
-        {
-            int sus_typ;
-            s->pmcntrl = val & ~(ACPI_BITMASK_SLEEP_ENABLE);
-            if (val & ACPI_BITMASK_SLEEP_ENABLE) {
-                /* change suspend type */
-                sus_typ = (val >> 10) & 7;
-                switch(sus_typ) {
-                case 0: /* soft power off */
-                    qemu_system_shutdown_request();
-                    break;
-                case 1:
-                    /* ACPI_BITMASK_WAKE_STATUS should be set on resume.
-                       Pretend that resume was caused by power button */
-                    s->pm1a.sts |= (ACPI_BITMASK_WAKE_STATUS |
-                                    ACPI_BITMASK_POWER_BUTTON_STATUS);
-                    qemu_system_reset_request();
-                    if (s->cmos_s3) {
-                        qemu_irq_raise(s->cmos_s3);
-                    }
-                default:
-                    break;
-                }
-            }
-        }
+        acpi_pm1_cnt_write(&s->pm1a, &s->pm1_cnt, val);
         break;
     default:
         break;
@@ -170,7 +146,7 @@ static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width,
         val = s->pm1a.en;
         break;
     case 0x04:
-        val = s->pmcntrl;
+        val = s->pm1_cnt.cnt;
         break;
     case 0x08:
         val = acpi_pm_tmr_get(&s->tmr);
@@ -193,11 +169,7 @@ static void apm_ctrl_changed(uint32_t val, void *arg)
     PIIX4PMState *s = arg;
 
     /* ACPI specs 3.0, 4.7.2.5 */
-    if (val == ACPI_ENABLE) {
-        s->pmcntrl |= ACPI_BITMASK_SCI_ENABLE;
-    } else if (val == ACPI_DISABLE) {
-        s->pmcntrl &= ~ACPI_BITMASK_SCI_ENABLE;
-    }
+    acpi_pm1_cnt_update(&s->pm1_cnt, val == ACPI_ENABLE, val == ACPI_DISABLE);
 
     if (s->dev.config[0x5b] & (1 << 1)) {
         if (s->smi_irq) {
@@ -276,7 +248,7 @@ static const VMStateDescription vmstate_acpi = {
         VMSTATE_PCI_DEVICE(dev, PIIX4PMState),
         VMSTATE_UINT16(pm1a.sts, PIIX4PMState),
         VMSTATE_UINT16(pm1a.en, PIIX4PMState),
-        VMSTATE_UINT16(pmcntrl, PIIX4PMState),
+        VMSTATE_UINT16(pm1_cnt.cnt, PIIX4PMState),
         VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState),
         VMSTATE_TIMER(tmr.timer, PIIX4PMState),
         VMSTATE_INT64(tmr.overflow_time, PIIX4PMState),
@@ -396,7 +368,7 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
 
     s = DO_UPCAST(PIIX4PMState, dev, dev);
     s->irq = sci_irq;
-    s->cmos_s3 = cmos_s3;
+    acpi_pm1_cnt_init(&s->pm1_cnt, cmos_s3);
     s->smi_irq = smi_irq;
     s->kvm_enabled = kvm_enabled;
 
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 10cbc74cf1..ca8f826a07 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -157,7 +157,7 @@ static void vt82c686b_write_config(PCIDevice * d, uint32_t address,
 typedef struct VT686PMState {
     PCIDevice dev;
     ACPIPM1EVT pm1a;
-    uint16_t pmcntrl;
+    ACPIPM1CNT pm1_cnt;
     APMState apm;
     ACPIPMTimer tmr;
     PMSMBus smb;
@@ -209,21 +209,7 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
         pm_update_sci(s);
         break;
     case 0x04:
-        {
-            int sus_typ;
-            s->pmcntrl = val & ~(SUS_EN);
-            if (val & SUS_EN) {
-                /* change suspend type */
-                sus_typ = (val >> 10) & 3;
-                switch (sus_typ) {
-                case 0: /* soft power off */
-                    qemu_system_shutdown_request();
-                    break;
-                default:
-                    break;
-                }
-            }
-        }
+        acpi_pm1_cnt_write(&s->pm1a, &s->pm1_cnt, val);
         break;
     default:
         break;
@@ -245,7 +231,7 @@ static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
         val = s->pm1a.en;
         break;
     case 0x04:
-        val = s->pmcntrl;
+        val = s->pm1_cnt.cnt;
         break;
     default:
         val = 0;
@@ -322,7 +308,7 @@ static const VMStateDescription vmstate_acpi = {
         VMSTATE_PCI_DEVICE(dev, VT686PMState),
         VMSTATE_UINT16(pm1a.sts, VT686PMState),
         VMSTATE_UINT16(pm1a.en, VT686PMState),
-        VMSTATE_UINT16(pmcntrl, VT686PMState),
+        VMSTATE_UINT16(pm1_cnt.cnt, VT686PMState),
         VMSTATE_STRUCT(apm, VT686PMState, 0, vmstate_apm, APMState),
         VMSTATE_TIMER(tmr.timer, VT686PMState),
         VMSTATE_INT64(tmr.overflow_time, VT686PMState),
@@ -446,6 +432,7 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
     apm_init(&s->apm, NULL, s);
 
     acpi_pm_tmr_init(&s->tmr, pm_tmr_timer);
+    acpi_pm1_cnt_init(&s->pm1_cnt, NULL);
 
     pm_smbus_init(&s->dev.qdev, &s->smb);
 

From a0313c00fcd26530a025ff93edee32959917be8d Mon Sep 17 00:00:00 2001
From: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Date: Tue, 5 Apr 2011 23:34:04 +0900
Subject: [PATCH 137/386] lan9118: Ignore write to MAC_VLAN1 register

On Mon, 4 Apr 2011 20:15:30 +0200, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Is it really safe ignoring write to this register? If yes, it's probably
> a good idea to explain why in a comment. In any case, if supporting this
> register is easy to do, it would be the best option.

I think it is safe.  Please see an updated comment below.

And though implementing this register might be possible, I suppose it
is not worth to supporting FrameTooLong detection, for now at least.

Thank you for comments.

>8---------------------------------------------------------------------
From: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Date: Tue, 5 Apr 2011 23:12:07 +0900
Subject: [PATCH] lan9118: Ignore write to MAC_VLAN1 register

Since linux 2.6.38, smsc911x driver writes to VLAN1 registger.
Since this register only affects FrameTooLong detection, ignoring
write to this register should be safe.

Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/lan9118.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/hw/lan9118.c b/hw/lan9118.c
index af6949f1bc..2dc8d18549 100644
--- a/hw/lan9118.c
+++ b/hw/lan9118.c
@@ -785,6 +785,12 @@ static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
     case MAC_FLOW:
         s->mac_flow = val & 0xffff0000;
         break;
+    case MAC_VLAN1:
+        /* Writing to this register changes a condition for
+         * FrameTooLong bit in rx_status.  Since we do not set
+         * FrameTooLong anyway, just ignore write to this.
+         */
+        break;
     default:
         hw_error("lan9118: Unimplemented MAC register write: %d = 0x%x\n",
                  s->mac_cmd & 0xf, val);

From a88df0b9b517b76c1a0052fb1b0fe83080559197 Mon Sep 17 00:00:00 2001
From: Isaku Yamahata <yamahata@valinux.co.jp>
Date: Tue, 5 Apr 2011 11:07:06 +0900
Subject: [PATCH 138/386] smbus_eeprom: consolidate smbus eeprom creation oc
 pc_piix, mips_mapta, mips_fulong

consolidate smbus initialization for pc_piix, mips_malta and mips_fulong.

Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: Huacai Chen <zltjiangshi@gmail.com>
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/mips_fulong2e.c |  9 +--------
 hw/mips_malta.c    | 12 ++----------
 hw/pc_piix.c       | 10 ++--------
 hw/smbus.h         |  3 +++
 hw/smbus_eeprom.c  | 22 ++++++++++++++++++++--
 5 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
index 0e90d684b4..420fada25b 100644
--- a/hw/mips_fulong2e.c
+++ b/hw/mips_fulong2e.c
@@ -263,11 +263,9 @@ static void mips_fulong2e_init(ram_addr_t ram_size, const char *boot_device,
     qemu_irq *cpu_exit_irq;
     int via_devfn;
     PCIBus *pci_bus;
-    uint8_t *eeprom_buf;
     i2c_bus *smbus;
     int i;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
-    DeviceState *eeprom;
     CPUState *env;
 
     /* init CPUs */
@@ -353,13 +351,8 @@ static void mips_fulong2e_init(ram_addr_t ram_size, const char *boot_device,
 
     smbus = vt82c686b_pm_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 4),
                               0xeee1, NULL);
-    eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
-    memcpy(eeprom_buf, eeprom_spd, sizeof(eeprom_spd));
     /* TODO: Populate SPD eeprom data.  */
-    eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
-    qdev_prop_set_uint8(eeprom, "address", 0x50);
-    qdev_prop_set_ptr(eeprom, "data", eeprom_buf);
-    qdev_init_nofail(eeprom);
+    smbus_eeprom_init(smbus, 1, eeprom_spd, sizeof(eeprom_spd));
 
     /* init other devices */
     pit = pit_init(0x40, 0);
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index bf0d76d03d..ed2a483c9b 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -770,7 +770,6 @@ void mips_malta_init (ram_addr_t ram_size,
     qemu_irq *i8259;
     qemu_irq *cpu_exit_irq;
     int piix4_devfn;
-    uint8_t *eeprom_buf;
     i2c_bus *smbus;
     int i;
     DriveInfo *dinfo;
@@ -913,15 +912,8 @@ void mips_malta_init (ram_addr_t ram_size,
     usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
     smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, isa_get_irq(9),
                           NULL, NULL, 0);
-    eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
-    for (i = 0; i < 8; i++) {
-        /* TODO: Populate SPD eeprom data.  */
-        DeviceState *eeprom;
-        eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
-        qdev_prop_set_uint8(eeprom, "address", 0x50 + i);
-        qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));
-        qdev_init_nofail(eeprom);
-    }
+    /* TODO: Populate SPD eeprom data.  */
+    smbus_eeprom_init(smbus, 8, NULL, 0);
     pit = pit_init(0x40, 0);
     cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
     DMA_init(0, cpu_exit_irq);
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 4d54ca1832..a85214b7f1 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -37,6 +37,7 @@
 #include "sysbus.h"
 #include "arch_init.h"
 #include "blockdev.h"
+#include "smbus.h"
 
 #define MAX_IDE_BUS 2
 
@@ -154,7 +155,6 @@ static void pc_init1(ram_addr_t ram_size,
     }
 
     if (pci_enabled && acpi_enabled) {
-        uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
         i2c_bus *smbus;
 
         cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1);
@@ -163,13 +163,7 @@ static void pc_init1(ram_addr_t ram_size,
         smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
                               isa_get_irq(9), *cmos_s3, *smi_irq,
                               kvm_enabled());
-        for (i = 0; i < 8; i++) {
-            DeviceState *eeprom;
-            eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
-            qdev_prop_set_uint8(eeprom, "address", 0x50 + i);
-            qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));
-            qdev_init_nofail(eeprom);
-        }
+        smbus_eeprom_init(smbus, 8, NULL, 0);
     }
 
     if (i440fx_state) {
diff --git a/hw/smbus.h b/hw/smbus.h
index 571c52dfb1..a39871593b 100644
--- a/hw/smbus.h
+++ b/hw/smbus.h
@@ -66,3 +66,6 @@ void smbus_write_word(i2c_bus *bus, uint8_t addr, uint8_t command, uint16_t data
 int smbus_read_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data);
 void smbus_write_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data,
                        int len);
+
+void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom,
+                       const uint8_t *eeprom_spd, int size);
diff --git a/hw/smbus_eeprom.c b/hw/smbus_eeprom.c
index 52463e0f86..3634754891 100644
--- a/hw/smbus_eeprom.c
+++ b/hw/smbus_eeprom.c
@@ -96,7 +96,7 @@ static uint8_t eeprom_read_data(SMBusDevice *dev, uint8_t cmd, int n)
     return eeprom_receive_byte(dev);
 }
 
-static int smbus_eeprom_init(SMBusDevice *dev)
+static int smbus_eeprom_initfn(SMBusDevice *dev)
 {
     SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *)dev;
 
@@ -111,7 +111,7 @@ static SMBusDeviceInfo smbus_eeprom_info = {
         DEFINE_PROP_PTR("data", SMBusEEPROMDevice, data),
         DEFINE_PROP_END_OF_LIST(),
     },
-    .init = smbus_eeprom_init,
+    .init = smbus_eeprom_initfn,
     .quick_cmd = eeprom_quick_cmd,
     .send_byte = eeprom_send_byte,
     .receive_byte = eeprom_receive_byte,
@@ -125,3 +125,21 @@ static void smbus_eeprom_register_devices(void)
 }
 
 device_init(smbus_eeprom_register_devices)
+
+void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom,
+                       const uint8_t *eeprom_spd, int eeprom_spd_size)
+{
+    int i;
+    uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
+    if (eeprom_spd_size > 0) {
+        memcpy(eeprom_buf, eeprom_spd, eeprom_spd_size);
+    }
+
+    for (i = 0; i < nb_eeprom; i++) {
+        DeviceState *eeprom;
+        eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
+        qdev_prop_set_uint8(eeprom, "address", 0x50 + i);
+        qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));
+        qdev_init_nofail(eeprom);
+    }
+}

From 2caa9e9d2e0f356cc244bc41ce1d3e81663f6782 Mon Sep 17 00:00:00 2001
From: Michael Tokarev <mjt@tls.msk.ru>
Date: Mon, 21 Mar 2011 09:34:35 +0100
Subject: [PATCH 139/386] vnc: tight: Fix crash after 2GB of output

fix 2Gb integer overflow in in VNC tight and zlib encodings

As found by Roland Dreier <roland@purestorage.com> (excellent
catch!), when amount of VNC compressed data produced by zlib
and sent to client exceeds 2Gb, integer overflow occurs because
currently, we calculate amount of data produced at each step by
comparing saved total_out with new total_out, and total_out is
something which grows without bounds.  Compare it with previous
avail_out instead of total_out, and leave total_out alone.

The same code is used in vnc-enc-tight.c and vnc-enc-zlib.c,
so fix both cases.

There, there's no actual need to save previous_out value, since
capacity-offset (which is how that value is calculated) stays
the same so it can be recalculated again after call to deflate(),
but whole thing becomes less readable this way.

Reported-by: Roland Dreier <roland@purestorage.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Corentin Chary <corentin.chary@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 ui/vnc-enc-tight.c | 5 +++--
 ui/vnc-enc-zlib.c  | 4 ++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index 2522936193..87fdf35d3e 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -868,8 +868,8 @@ static int tight_compress_data(VncState *vs, int stream_id, size_t bytes,
     zstream->avail_in = vs->tight.tight.offset;
     zstream->next_out = vs->tight.zlib.buffer + vs->tight.zlib.offset;
     zstream->avail_out = vs->tight.zlib.capacity - vs->tight.zlib.offset;
+    previous_out = zstream->avail_out;
     zstream->data_type = Z_BINARY;
-    previous_out = zstream->total_out;
 
     /* start encoding */
     if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
@@ -878,7 +878,8 @@ static int tight_compress_data(VncState *vs, int stream_id, size_t bytes,
     }
 
     vs->tight.zlib.offset = vs->tight.zlib.capacity - zstream->avail_out;
-    bytes = zstream->total_out - previous_out;
+    /* ...how much data has actually been produced by deflate() */
+    bytes = previous_out - zstream->avail_out;
 
     tight_send_compact_size(vs, bytes);
     vnc_write(vs, vs->tight.zlib.buffer, bytes);
diff --git a/ui/vnc-enc-zlib.c b/ui/vnc-enc-zlib.c
index 3c6e6abf94..e32e4cd8a8 100644
--- a/ui/vnc-enc-zlib.c
+++ b/ui/vnc-enc-zlib.c
@@ -103,8 +103,8 @@ static int vnc_zlib_stop(VncState *vs)
     zstream->avail_in = vs->zlib.zlib.offset;
     zstream->next_out = vs->output.buffer + vs->output.offset;
     zstream->avail_out = vs->output.capacity - vs->output.offset;
+    previous_out = zstream->avail_out;
     zstream->data_type = Z_BINARY;
-    previous_out = zstream->total_out;
 
     // start encoding
     if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
@@ -113,7 +113,7 @@ static int vnc_zlib_stop(VncState *vs)
     }
 
     vs->output.offset = vs->output.capacity - zstream->avail_out;
-    return zstream->total_out - previous_out;
+    return previous_out - zstream->avail_out;
 }
 
 int vnc_zlib_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)

From 4b4a72e55660abf7efe85aca78762dcfea5519ad Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Sat, 2 Apr 2011 13:36:31 +0200
Subject: [PATCH 140/386] Fix conversions from pointer to tcg_target_long

tcg_gen_exit_tb takes a parameter of type tcg_target_long,
so the type casts of pointer to long should be replaced by
type casts of pointer to tcg_target_long (suggested by Blue Swirl).

These changes are needed for build environments where
sizeof(long) != sizeof(void *), especially for w64.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 gen-icount.h                  | 2 +-
 target-alpha/translate.c      | 6 +++---
 target-arm/translate.c        | 2 +-
 target-cris/translate.c       | 2 +-
 target-i386/translate.c       | 2 +-
 target-lm32/translate.c       | 2 +-
 target-m68k/translate.c       | 2 +-
 target-microblaze/translate.c | 2 +-
 target-mips/translate.c       | 2 +-
 target-ppc/translate.c        | 2 +-
 target-sh4/translate.c        | 2 +-
 target-sparc/translate.c      | 2 +-
 12 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/gen-icount.h b/gen-icount.h
index 8879da6335..5fb3829781 100644
--- a/gen-icount.h
+++ b/gen-icount.h
@@ -29,7 +29,7 @@ static void gen_icount_end(TranslationBlock *tb, int num_insns)
     if (use_icount) {
         *icount_arg = num_insns;
         gen_set_label(icount_label);
-        tcg_gen_exit_tb((long)tb + 2);
+        tcg_gen_exit_tb((tcg_target_long)tb + 2);
     }
 }
 
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 3a1c625f73..96e922b569 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -398,7 +398,7 @@ static ExitStatus gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
     } else if (use_goto_tb(ctx, dest)) {
         tcg_gen_goto_tb(0);
         tcg_gen_movi_i64(cpu_pc, dest);
-        tcg_gen_exit_tb((long)ctx->tb);
+        tcg_gen_exit_tb((tcg_target_long)ctx->tb);
         return EXIT_GOTO_TB;
     } else {
         tcg_gen_movi_i64(cpu_pc, dest);
@@ -417,12 +417,12 @@ static ExitStatus gen_bcond_internal(DisasContext *ctx, TCGCond cond,
 
         tcg_gen_goto_tb(0);
         tcg_gen_movi_i64(cpu_pc, ctx->pc);
-        tcg_gen_exit_tb((long)ctx->tb);
+        tcg_gen_exit_tb((tcg_target_long)ctx->tb);
 
         gen_set_label(lab_true);
         tcg_gen_goto_tb(1);
         tcg_gen_movi_i64(cpu_pc, dest);
-        tcg_gen_exit_tb((long)ctx->tb + 1);
+        tcg_gen_exit_tb((tcg_target_long)ctx->tb + 1);
 
         return EXIT_GOTO_TB;
     } else {
diff --git a/target-arm/translate.c b/target-arm/translate.c
index c6cb39ad2b..55d524ba13 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3387,7 +3387,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
         gen_set_pc_im(dest);
-        tcg_gen_exit_tb((long)tb + n);
+        tcg_gen_exit_tb((tcg_target_long)tb + n);
     } else {
         gen_set_pc_im(dest);
         tcg_gen_exit_tb(0);
diff --git a/target-cris/translate.c b/target-cris/translate.c
index b4648a01de..1c03fa5fb6 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -596,7 +596,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
 	if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
 		tcg_gen_goto_tb(n);
 		tcg_gen_movi_tl(env_pc, dest);
-		tcg_gen_exit_tb((long)tb + n);
+                tcg_gen_exit_tb((tcg_target_long)tb + n);
 	} else {
 		tcg_gen_movi_tl(env_pc, dest);
 		tcg_gen_exit_tb(0);
diff --git a/target-i386/translate.c b/target-i386/translate.c
index c00845038a..7d1340ed01 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -2274,7 +2274,7 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
         /* jump to same page: we can use a direct jump */
         tcg_gen_goto_tb(tb_num);
         gen_jmp_im(eip);
-        tcg_gen_exit_tb((long)tb + tb_num);
+        tcg_gen_exit_tb((tcg_target_long)tb + tb_num);
     } else {
         /* jump to another page: currently not optimized */
         gen_jmp_im(eip);
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 666d5f4dc3..efc9b5a856 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -138,7 +138,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
             likely(!dc->singlestep_enabled)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_tl(cpu_pc, dest);
-        tcg_gen_exit_tb((long)tb + n);
+        tcg_gen_exit_tb((tcg_target_long)tb + n);
     } else {
         tcg_gen_movi_tl(cpu_pc, dest);
         if (dc->singlestep_enabled) {
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 6f72a2bdd2..038c0af3ef 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -861,7 +861,7 @@ static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
                (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_i32(QREG_PC, dest);
-        tcg_gen_exit_tb((long)tb + n);
+        tcg_gen_exit_tb((tcg_target_long)tb + n);
     } else {
         gen_jmp_im(s, dest);
         tcg_gen_exit_tb(0);
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index b54b169b18..6f4eef1a69 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -146,7 +146,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_tl(cpu_SR[SR_PC], dest);
-        tcg_gen_exit_tb((long)tb + n);
+        tcg_gen_exit_tb((tcg_target_long)tb + n);
     } else {
         tcg_gen_movi_tl(cpu_SR[SR_PC], dest);
         tcg_gen_exit_tb(0);
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 0f93e2abb1..953c528068 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -2686,7 +2686,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
         likely(!ctx->singlestep_enabled)) {
         tcg_gen_goto_tb(n);
         gen_save_pc(dest);
-        tcg_gen_exit_tb((long)tb + n);
+        tcg_gen_exit_tb((tcg_target_long)tb + n);
     } else {
         gen_save_pc(dest);
         if (ctx->singlestep_enabled) {
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 090795b600..3c3ee24c95 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3347,7 +3347,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
         likely(!ctx->singlestep_enabled)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_tl(cpu_nip, dest & ~3);
-        tcg_gen_exit_tb((long)tb + n);
+        tcg_gen_exit_tb((tcg_target_long)tb + n);
     } else {
         tcg_gen_movi_tl(cpu_nip, dest & ~3);
         if (unlikely(ctx->singlestep_enabled)) {
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 58e9b8f93b..88098d7c23 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -302,7 +302,7 @@ static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
 	/* Use a direct jump if in same page and singlestep not enabled */
         tcg_gen_goto_tb(n);
         tcg_gen_movi_i32(cpu_pc, dest);
-        tcg_gen_exit_tb((long) tb + n);
+        tcg_gen_exit_tb((tcg_target_long)tb + n);
     } else {
         tcg_gen_movi_i32(cpu_pc, dest);
         if (ctx->singlestep_enabled)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index e26462eef5..883ecd2d2f 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -241,7 +241,7 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num,
         tcg_gen_goto_tb(tb_num);
         tcg_gen_movi_tl(cpu_pc, pc);
         tcg_gen_movi_tl(cpu_npc, npc);
-        tcg_gen_exit_tb((long)tb + tb_num);
+        tcg_gen_exit_tb((tcg_target_long)tb + tb_num);
     } else {
         /* jump to another page: currently not optimized */
         tcg_gen_movi_tl(cpu_pc, pc);

From be5e7a76010bd14d09f74504ed6368782e701888 Mon Sep 17 00:00:00 2001
From: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Date: Mon, 4 Apr 2011 17:38:44 +0400
Subject: [PATCH 141/386] arm: basic support for ARMv4/ARMv4T emulation

Currently target-arm/ assumes at least ARMv5 core. Add support for
handling also ARMv4/ARMv4T. This changes the following instructions:

BX(v4T and later)

BKPT, BLX, CDP2, CLZ, LDC2, LDRD, MCRR, MCRR2, MRRC, MCRR, MRC2, MRRC,
MRRC2, PLD QADD, QDADD, QDSUB, QSUB, STRD, SMLAxy, SMLALxy, SMLAWxy,
SMULxy, SMULWxy, STC2 (v5 and later)

All instructions that are "v5TE and later" are also bound to just v5, as
that's how it was before.

This patch doesn _not_ include disabling of cp15 access and base-updated
data abort model (that will be required to emulate chips based on a
ARM7TDMI), because:
* no ARM7TDMI chips are currently emulated (or planned)
* those features aren't strictly necessary for my purposes (SA-1 core
  emulation).

All v5 models are handled as they are v5T. Internally we still have a
check if the model is a v5(T) or v5TE, but as all emulated cores are
v5TE, those two cases are simply aliased (for now).

Patch is heavily based on patch by Filip Navara <filip.navara@gmail.com>
which in turn is based on work by Ulrich Hecht <uli@suse.de> and Vincent
Sanders <vince@kyllikki.org>.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/cpu.h       |  4 ++-
 target-arm/helper.c    | 29 ++++++++++++++++++++-
 target-arm/translate.c | 59 +++++++++++++++++++++++++++++++++++-------
 3 files changed, 80 insertions(+), 12 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 1ae7982c7f..e247a7ade0 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -360,7 +360,9 @@ enum arm_features {
     ARM_FEATURE_M, /* Microcontroller profile.  */
     ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling.  */
     ARM_FEATURE_THUMB2EE,
-    ARM_FEATURE_V7MP    /* v7 Multiprocessing Extensions */
+    ARM_FEATURE_V7MP,    /* v7 Multiprocessing Extensions */
+    ARM_FEATURE_V4T,
+    ARM_FEATURE_V5,
 };
 
 static inline int arm_feature(CPUARMState *env, int feature)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 6788a4c383..ce9a9d8fd2 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -48,17 +48,23 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
     env->cp15.c0_cpuid = id;
     switch (id) {
     case ARM_CPUID_ARM926:
+        set_feature(env, ARM_FEATURE_V4T);
+        set_feature(env, ARM_FEATURE_V5);
         set_feature(env, ARM_FEATURE_VFP);
         env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090;
         env->cp15.c0_cachetype = 0x1dd20d2;
         env->cp15.c1_sys = 0x00090078;
         break;
     case ARM_CPUID_ARM946:
+        set_feature(env, ARM_FEATURE_V4T);
+        set_feature(env, ARM_FEATURE_V5);
         set_feature(env, ARM_FEATURE_MPU);
         env->cp15.c0_cachetype = 0x0f004006;
         env->cp15.c1_sys = 0x00000078;
         break;
     case ARM_CPUID_ARM1026:
+        set_feature(env, ARM_FEATURE_V4T);
+        set_feature(env, ARM_FEATURE_V5);
         set_feature(env, ARM_FEATURE_VFP);
         set_feature(env, ARM_FEATURE_AUXCR);
         env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0;
@@ -67,6 +73,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
         break;
     case ARM_CPUID_ARM1136_R2:
     case ARM_CPUID_ARM1136:
+        set_feature(env, ARM_FEATURE_V4T);
+        set_feature(env, ARM_FEATURE_V5);
         set_feature(env, ARM_FEATURE_V6);
         set_feature(env, ARM_FEATURE_VFP);
         set_feature(env, ARM_FEATURE_AUXCR);
@@ -79,6 +87,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
         env->cp15.c1_sys = 0x00050078;
         break;
     case ARM_CPUID_ARM11MPCORE:
+        set_feature(env, ARM_FEATURE_V4T);
+        set_feature(env, ARM_FEATURE_V5);
         set_feature(env, ARM_FEATURE_V6);
         set_feature(env, ARM_FEATURE_V6K);
         set_feature(env, ARM_FEATURE_VFP);
@@ -91,6 +101,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
         env->cp15.c0_cachetype = 0x1dd20d2;
         break;
     case ARM_CPUID_CORTEXA8:
+        set_feature(env, ARM_FEATURE_V4T);
+        set_feature(env, ARM_FEATURE_V5);
         set_feature(env, ARM_FEATURE_V6);
         set_feature(env, ARM_FEATURE_V6K);
         set_feature(env, ARM_FEATURE_V7);
@@ -113,6 +125,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
         env->cp15.c1_sys = 0x00c50078;
         break;
     case ARM_CPUID_CORTEXA9:
+        set_feature(env, ARM_FEATURE_V4T);
+        set_feature(env, ARM_FEATURE_V5);
         set_feature(env, ARM_FEATURE_V6);
         set_feature(env, ARM_FEATURE_V6K);
         set_feature(env, ARM_FEATURE_V7);
@@ -140,6 +154,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
         env->cp15.c1_sys = 0x00c50078;
         break;
     case ARM_CPUID_CORTEXM3:
+        set_feature(env, ARM_FEATURE_V4T);
+        set_feature(env, ARM_FEATURE_V5);
         set_feature(env, ARM_FEATURE_V6);
         set_feature(env, ARM_FEATURE_THUMB2);
         set_feature(env, ARM_FEATURE_V7);
@@ -147,6 +163,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
         set_feature(env, ARM_FEATURE_DIV);
         break;
     case ARM_CPUID_ANY: /* For userspace emulation.  */
+        set_feature(env, ARM_FEATURE_V4T);
+        set_feature(env, ARM_FEATURE_V5);
         set_feature(env, ARM_FEATURE_V6);
         set_feature(env, ARM_FEATURE_V6K);
         set_feature(env, ARM_FEATURE_V7);
@@ -161,6 +179,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
         break;
     case ARM_CPUID_TI915T:
     case ARM_CPUID_TI925T:
+        set_feature(env, ARM_FEATURE_V4T);
         set_feature(env, ARM_FEATURE_OMAPCP);
         env->cp15.c0_cpuid = ARM_CPUID_TI925T; /* Depends on wiring.  */
         env->cp15.c0_cachetype = 0x5109149;
@@ -173,6 +192,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
     case ARM_CPUID_PXA260:
     case ARM_CPUID_PXA261:
     case ARM_CPUID_PXA262:
+        set_feature(env, ARM_FEATURE_V4T);
+        set_feature(env, ARM_FEATURE_V5);
         set_feature(env, ARM_FEATURE_XSCALE);
         /* JTAG_ID is ((id << 28) | 0x09265013) */
         env->cp15.c0_cachetype = 0xd172172;
@@ -184,6 +205,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
     case ARM_CPUID_PXA270_B1:
     case ARM_CPUID_PXA270_C0:
     case ARM_CPUID_PXA270_C5:
+        set_feature(env, ARM_FEATURE_V4T);
+        set_feature(env, ARM_FEATURE_V5);
         set_feature(env, ARM_FEATURE_XSCALE);
         /* JTAG_ID is ((id << 28) | 0x09265013) */
         set_feature(env, ARM_FEATURE_IWMMXT);
@@ -856,7 +879,11 @@ void do_interrupt(CPUARMState *env)
     /* Switch to the new mode, and to the correct instruction set.  */
     env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;
     env->uncached_cpsr |= mask;
-    env->thumb = (env->cp15.c1_sys & (1 << 30)) != 0;
+    /* this is a lie, as the was no c1_sys on V4T/V5, but who cares
+     * and we should just guard the thumb mode on V4 */
+    if (arm_feature(env, ARM_FEATURE_V4T)) {
+        env->thumb = (env->cp15.c1_sys & (1 << 30)) != 0;
+    }
     env->regs[14] = env->regs[15] + offset;
     env->regs[15] = addr;
     env->interrupt_request |= CPU_INTERRUPT_EXITTB;
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 55d524ba13..998cfd530c 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -34,6 +34,10 @@
 #define GEN_HELPER 1
 #include "helpers.h"
 
+#define ENABLE_ARCH_4T    arm_feature(env, ARM_FEATURE_V4T)
+#define ENABLE_ARCH_5     arm_feature(env, ARM_FEATURE_V5)
+/* currently all emulated v5 cores are also v5TE, so don't bother */
+#define ENABLE_ARCH_5TE   arm_feature(env, ARM_FEATURE_V5)
 #define ENABLE_ARCH_5J    0
 #define ENABLE_ARCH_6     arm_feature(env, ARM_FEATURE_V6)
 #define ENABLE_ARCH_6K   arm_feature(env, ARM_FEATURE_V6K)
@@ -750,6 +754,20 @@ static inline void store_reg_bx(CPUState *env, DisasContext *s,
     }
 }
 
+/* Variant of store_reg which uses branch&exchange logic when storing
+ * to r15 in ARM architecture v5T and above. This is used for storing
+ * the results of a LDR/LDM/POP into r15, and corresponds to the cases
+ * in the ARM ARM which use the LoadWritePC() pseudocode function. */
+static inline void store_reg_from_load(CPUState *env, DisasContext *s,
+                                int reg, TCGv var)
+{
+    if (reg == 15 && ENABLE_ARCH_5) {
+        gen_bx(s, var);
+    } else {
+        store_reg(s, reg, var);
+    }
+}
+
 static inline TCGv gen_ld8s(TCGv addr, int index)
 {
     TCGv tmp = tcg_temp_new_i32();
@@ -3436,6 +3454,10 @@ static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
 
     /* Mask out undefined bits.  */
     mask &= ~CPSR_RESERVED;
+    if (!arm_feature(env, ARM_FEATURE_V4T))
+        mask &= ~CPSR_T;
+    if (!arm_feature(env, ARM_FEATURE_V5))
+        mask &= ~CPSR_Q; /* V5TE in reality*/
     if (!arm_feature(env, ARM_FEATURE_V6))
         mask &= ~(CPSR_E | CPSR_GE);
     if (!arm_feature(env, ARM_FEATURE_THUMB2))
@@ -6127,6 +6149,12 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
         goto illegal_op;
     cond = insn >> 28;
     if (cond == 0xf){
+        /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
+         * choose to UNDEF. In ARMv5 and above the space is used
+         * for miscellaneous unconditional instructions.
+         */
+        ARCH(5);
+
         /* Unconditional instructions.  */
         if (((insn >> 25) & 7) == 1) {
             /* NEON Data processing.  */
@@ -6155,6 +6183,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
                 }
             }
             /* Otherwise PLD; v5TE+ */
+            ARCH(5TE);
             return;
         }
         if (((insn & 0x0f70f000) == 0x0450f000) ||
@@ -6291,6 +6320,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
             val += (offset << 2) | ((insn >> 23) & 2) | 1;
             /* pipeline offset */
             val += 4;
+            /* protected by ARCH(5); above, near the start of uncond block */
             gen_bx_im(s, val);
             return;
         } else if ((insn & 0x0e000f00) == 0x0c000100) {
@@ -6302,6 +6332,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
             }
         } else if ((insn & 0x0fe00000) == 0x0c400000) {
             /* Coprocessor double register transfer.  */
+            ARCH(5TE);
         } else if ((insn & 0x0f000010) == 0x0e000010) {
             /* Additional coprocessor register transfer.  */
         } else if ((insn & 0x0ff10020) == 0x01000000) {
@@ -6402,10 +6433,12 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
         case 0x1:
             if (op1 == 1) {
                 /* branch/exchange thumb (bx).  */
+                ARCH(4T);
                 tmp = load_reg(s, rm);
                 gen_bx(s, tmp);
             } else if (op1 == 3) {
                 /* clz */
+                ARCH(5);
                 rd = (insn >> 12) & 0xf;
                 tmp = load_reg(s, rm);
                 gen_helper_clz(tmp, tmp);
@@ -6428,6 +6461,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
             if (op1 != 1)
               goto illegal_op;
 
+            ARCH(5);
             /* branch link/exchange thumb (blx) */
             tmp = load_reg(s, rm);
             tmp2 = tcg_temp_new_i32();
@@ -6436,6 +6470,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
             gen_bx(s, tmp);
             break;
         case 0x5: /* saturating add/subtract */
+            ARCH(5TE);
             rd = (insn >> 12) & 0xf;
             rn = (insn >> 16) & 0xf;
             tmp = load_reg(s, rm);
@@ -6457,12 +6492,14 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
                 goto illegal_op;
             }
             /* bkpt */
+            ARCH(5);
             gen_exception_insn(s, 4, EXCP_BKPT);
             break;
         case 0x8: /* signed multiply */
         case 0xa:
         case 0xc:
         case 0xe:
+            ARCH(5TE);
             rs = (insn >> 8) & 0xf;
             rn = (insn >> 12) & 0xf;
             rd = (insn >> 16) & 0xf;
@@ -6858,6 +6895,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
                     }
                     load = 1;
                 } else if (sh & 2) {
+                    ARCH(5TE);
                     /* doubleword */
                     if (sh & 1) {
                         /* store */
@@ -7198,10 +7236,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
             }
             if (insn & (1 << 20)) {
                 /* Complete the load.  */
-                if (rd == 15)
-                    gen_bx(s, tmp);
-                else
-                    store_reg(s, rd, tmp);
+                store_reg_from_load(env, s, rd, tmp);
             }
             break;
         case 0x08:
@@ -7254,9 +7289,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
                         if (insn & (1 << 20)) {
                             /* load */
                             tmp = gen_ld32(addr, IS_USER(s));
-                            if (i == 15) {
-                                gen_bx(s, tmp);
-                            } else if (user) {
+                            if (user) {
                                 tmp2 = tcg_const_i32(i);
                                 gen_helper_set_user_reg(tmp2, tmp);
                                 tcg_temp_free_i32(tmp2);
@@ -7265,7 +7298,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
                                 loaded_var = tmp;
                                 loaded_base = 1;
                             } else {
-                                store_reg(s, i, tmp);
+                                store_reg_from_load(env, s, i, tmp);
                             }
                         } else {
                             /* store */
@@ -7465,6 +7498,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
            16-bit instructions to get correct prefetch abort behavior.  */
         insn = insn_hw1;
         if ((insn & (1 << 12)) == 0) {
+            ARCH(5);
             /* Second half of blx.  */
             offset = ((insn & 0x7ff) << 1);
             tmp = load_reg(s, 14);
@@ -8061,6 +8095,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
                 } else {
                     /* blx */
                     offset &= ~(uint32_t)2;
+                    /* thumb2 bx, no need to check */
                     gen_bx_im(s, offset);
                 }
             } else if (((insn >> 23) & 7) == 7) {
@@ -8642,11 +8677,13 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
             case 3:/* branch [and link] exchange thumb register */
                 tmp = load_reg(s, rm);
                 if (insn & (1 << 7)) {
+                    ARCH(5);
                     val = (uint32_t)s->pc | 1;
                     tmp2 = tcg_temp_new_i32();
                     tcg_gen_movi_i32(tmp2, val);
                     store_reg(s, 14, tmp2);
                 }
+                /* already thumb, no need to check */
                 gen_bx(s, tmp);
                 break;
             }
@@ -9006,8 +9043,9 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
             /* write back the new stack pointer */
             store_reg(s, 13, addr);
             /* set the new PC value */
-            if ((insn & 0x0900) == 0x0900)
-                gen_bx(s, tmp);
+            if ((insn & 0x0900) == 0x0900) {
+                store_reg_from_load(env, s, 15, tmp);
+            }
             break;
 
         case 1: case 3: case 9: case 11: /* czb */
@@ -9038,6 +9076,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
             break;
 
         case 0xe: /* bkpt */
+            ARCH(5);
             gen_exception_insn(s, 2, EXCP_BKPT);
             break;
 

From 23910d3f669d46073b403876e30a7314599633af Mon Sep 17 00:00:00 2001
From: Isaku Yamahata <yamahata@valinux.co.jp>
Date: Fri, 25 Mar 2011 19:54:41 +0900
Subject: [PATCH 142/386] acpi, acpi_piix: factor out GPE logic

factor out ACPI GPE logic. Later it will be used by ICH9 ACPI.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/acpi.c       | 66 ++++++++++++++++++++++++++++++++++
 hw/acpi.h       | 17 +++++++++
 hw/acpi_piix4.c | 95 +++++++++++++------------------------------------
 3 files changed, 108 insertions(+), 70 deletions(-)

diff --git a/hw/acpi.c b/hw/acpi.c
index 2879eea406..e372474399 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -328,3 +328,69 @@ void acpi_pm1_cnt_reset(ACPIPM1CNT *pm1_cnt)
         qemu_irq_lower(pm1_cnt->cmos_s3);
     }
 }
+
+/* ACPI GPE */
+void acpi_gpe_init(ACPIGPE *gpe, uint8_t len)
+{
+    gpe->len = len;
+    gpe->sts = qemu_mallocz(len / 2);
+    gpe->en = qemu_mallocz(len / 2);
+}
+
+void acpi_gpe_blk(ACPIGPE *gpe, uint32_t blk)
+{
+    gpe->blk = blk;
+}
+
+void acpi_gpe_reset(ACPIGPE *gpe)
+{
+    memset(gpe->sts, 0, gpe->len / 2);
+    memset(gpe->en, 0, gpe->len / 2);
+}
+
+static uint8_t *acpi_gpe_ioport_get_ptr(ACPIGPE *gpe, uint32_t addr)
+{
+    uint8_t *cur = NULL;
+
+    if (addr < gpe->len / 2) {
+        cur = gpe->sts + addr;
+    } else if (addr < gpe->len) {
+        cur = gpe->en + addr;
+    } else {
+        abort();
+    }
+
+    return cur;
+}
+
+void acpi_gpe_ioport_writeb(ACPIGPE *gpe, uint32_t addr, uint32_t val)
+{
+    uint8_t *cur;
+
+    addr -= gpe->blk;
+    cur = acpi_gpe_ioport_get_ptr(gpe, addr);
+    if (addr < gpe->len / 2) {
+        /* GPE_STS */
+        *cur = (*cur) & ~val;
+    } else if (addr < gpe->len) {
+        /* GPE_EN */
+        *cur = val;
+    } else {
+        abort();
+    }
+}
+
+uint32_t acpi_gpe_ioport_readb(ACPIGPE *gpe, uint32_t addr)
+{
+    uint8_t *cur;
+    uint32_t val;
+
+    addr -= gpe->blk;
+    cur = acpi_gpe_ioport_get_ptr(gpe, addr);
+    val = 0;
+    if (cur != NULL) {
+        val = *cur;
+    }
+
+    return val;
+}
diff --git a/hw/acpi.h b/hw/acpi.h
index 836459e9c1..c141e65f4f 100644
--- a/hw/acpi.h
+++ b/hw/acpi.h
@@ -126,4 +126,21 @@ void acpi_pm1_cnt_update(ACPIPM1CNT *pm1_cnt,
                          bool sci_enable, bool sci_disable);
 void acpi_pm1_cnt_reset(ACPIPM1CNT *pm1_cnt);
 
+/* GPE0 */
+struct ACPIGPE {
+    uint32_t blk;
+    uint8_t len;
+
+    uint8_t *sts;
+    uint8_t *en;
+};
+typedef struct ACPIGPE ACPIGPE;
+
+void acpi_gpe_init(ACPIGPE *gpe, uint8_t len);
+void acpi_gpe_blk(ACPIGPE *gpe, uint32_t blk);
+void acpi_gpe_reset(ACPIGPE *gpe);
+
+void acpi_gpe_ioport_writeb(ACPIGPE *gpe, uint32_t addr, uint32_t val);
+uint32_t acpi_gpe_ioport_readb(ACPIGPE *gpe, uint32_t addr);
+
 #endif /* !QEMU_HW_ACPI_H */
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 412ace3849..96f522233a 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -35,17 +35,13 @@
 #define ACPI_DBG_IO_ADDR  0xb044
 
 #define GPE_BASE 0xafe0
+#define GPE_LEN 4
 #define PCI_BASE 0xae00
 #define PCI_EJ_BASE 0xae08
 #define PCI_RMV_BASE 0xae0c
 
 #define PIIX4_PCI_HOTPLUG_STATUS 2
 
-struct gpe_regs {
-    uint16_t sts; /* status */
-    uint16_t en;  /* enabled */
-};
-
 struct pci_status {
     uint32_t up;
     uint32_t down;
@@ -69,7 +65,7 @@ typedef struct PIIX4PMState {
     int kvm_enabled;
 
     /* for pci hotplug */
-    struct gpe_regs gpe;
+    ACPIGPE gpe;
     struct pci_status pci0_status;
     uint32_t pci0_hotplug_enable;
 } PIIX4PMState;
@@ -89,7 +85,7 @@ static void pm_update_sci(PIIX4PMState *s)
                    ACPI_BITMASK_POWER_BUTTON_ENABLE |
                    ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
                    ACPI_BITMASK_TIMER_ENABLE)) != 0) ||
-        (((s->gpe.sts & s->gpe.en) & PIIX4_PCI_HOTPLUG_STATUS) != 0);
+        (((s->gpe.sts[0] & s->gpe.en[0]) & PIIX4_PCI_HOTPLUG_STATUS) != 0);
 
     qemu_set_irq(s->irq, sci_level);
     /* schedule a timer interruption if needed */
@@ -214,14 +210,25 @@ static int vmstate_acpi_post_load(void *opaque, int version_id)
     return 0;
 }
 
+#define VMSTATE_GPE_ARRAY(_field, _state)                            \
+ {                                                                   \
+     .name       = (stringify(_field)),                              \
+     .version_id = 0,                                                \
+     .num        = GPE_LEN,                                          \
+     .info       = &vmstate_info_uint16,                             \
+     .size       = sizeof(uint16_t),                                 \
+     .flags      = VMS_ARRAY | VMS_POINTER,                          \
+     .offset     = vmstate_offset_pointer(_state, _field, uint8_t),  \
+ }
+
 static const VMStateDescription vmstate_gpe = {
     .name = "gpe",
     .version_id = 1,
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
     .fields      = (VMStateField []) {
-        VMSTATE_UINT16(sts, struct gpe_regs),
-        VMSTATE_UINT16(en, struct gpe_regs),
+        VMSTATE_GPE_ARRAY(sts, ACPIGPE),
+        VMSTATE_GPE_ARRAY(en, ACPIGPE),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -252,7 +259,7 @@ static const VMStateDescription vmstate_acpi = {
         VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState),
         VMSTATE_TIMER(tmr.timer, PIIX4PMState),
         VMSTATE_INT64(tmr.overflow_time, PIIX4PMState),
-        VMSTATE_STRUCT(gpe, PIIX4PMState, 2, vmstate_gpe, struct gpe_regs),
+        VMSTATE_STRUCT(gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE),
         VMSTATE_STRUCT(pci0_status, PIIX4PMState, 2, vmstate_pci_status,
                        struct pci_status),
         VMSTATE_END_OF_LIST()
@@ -346,6 +353,7 @@ static int piix4_pm_initfn(PCIDevice *dev)
     register_ioport_read(s->smb_io_base, 64, 1, smb_ioport_readb, &s->smb);
 
     acpi_pm_tmr_init(&s->tmr, pm_tmr_timer);
+    acpi_gpe_init(&s->gpe, GPE_LEN);
 
     qemu_system_powerdown = *qemu_allocate_irqs(piix4_powerdown, s, 1);
 
@@ -399,74 +407,20 @@ static void piix4_pm_register(void)
 
 device_init(piix4_pm_register);
 
-static uint32_t gpe_read_val(uint16_t val, uint32_t addr)
-{
-    if (addr & 1)
-        return (val >> 8) & 0xff;
-    return val & 0xff;
-}
-
 static uint32_t gpe_readb(void *opaque, uint32_t addr)
 {
-    uint32_t val = 0;
     PIIX4PMState *s = opaque;
-    struct gpe_regs *g = &s->gpe;
-
-    switch (addr) {
-        case GPE_BASE:
-        case GPE_BASE + 1:
-            val = gpe_read_val(g->sts, addr);
-            break;
-        case GPE_BASE + 2:
-        case GPE_BASE + 3:
-            val = gpe_read_val(g->en, addr);
-            break;
-        default:
-            break;
-    }
+    uint32_t val = acpi_gpe_ioport_readb(&s->gpe, addr);
 
     PIIX4_DPRINTF("gpe read %x == %x\n", addr, val);
     return val;
 }
 
-static void gpe_write_val(uint16_t *cur, int addr, uint32_t val)
-{
-    if (addr & 1)
-        *cur = (*cur & 0xff) | (val << 8);
-    else
-        *cur = (*cur & 0xff00) | (val & 0xff);
-}
-
-static void gpe_reset_val(uint16_t *cur, int addr, uint32_t val)
-{
-    uint16_t x1, x0 = val & 0xff;
-    int shift = (addr & 1) ? 8 : 0;
-
-    x1 = (*cur >> shift) & 0xff;
-
-    x1 = x1 & ~x0;
-
-    *cur = (*cur & (0xff << (8 - shift))) | (x1 << shift);
-}
-
 static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
 {
     PIIX4PMState *s = opaque;
-    struct gpe_regs *g = &s->gpe;
-
-    switch (addr) {
-        case GPE_BASE:
-        case GPE_BASE + 1:
-            gpe_reset_val(&g->sts, addr, val);
-            break;
-        case GPE_BASE + 2:
-        case GPE_BASE + 3:
-            gpe_write_val(&g->en, addr, val);
-            break;
-        default:
-            break;
-    }
 
+    acpi_gpe_ioport_writeb(&s->gpe, addr, val);
     pm_update_sci(s);
 
     PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val);
@@ -549,8 +503,9 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
 {
     struct pci_status *pci0_status = &s->pci0_status;
 
-    register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, s);
-    register_ioport_read(GPE_BASE, 4, 1,  gpe_readb, s);
+    register_ioport_write(GPE_BASE, GPE_LEN, 1, gpe_writeb, s);
+    register_ioport_read(GPE_BASE, GPE_LEN, 1,  gpe_readb, s);
+    acpi_gpe_blk(&s->gpe, GPE_BASE);
 
     register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, pci0_status);
     register_ioport_read(PCI_BASE, 8, 4,  pcihotplug_read, pci0_status);
@@ -566,13 +521,13 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
 
 static void enable_device(PIIX4PMState *s, int slot)
 {
-    s->gpe.sts |= PIIX4_PCI_HOTPLUG_STATUS;
+    s->gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
     s->pci0_status.up |= (1 << slot);
 }
 
 static void disable_device(PIIX4PMState *s, int slot)
 {
-    s->gpe.sts |= PIIX4_PCI_HOTPLUG_STATUS;
+    s->gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
     s->pci0_status.down |= (1 << slot);
 }
 

From d04fba948fb945e467f263e820b1100d657c533d Mon Sep 17 00:00:00 2001
From: Jan Kiszka <jan.kiszka@web.de>
Date: Sun, 10 Apr 2011 09:35:42 +0200
Subject: [PATCH 143/386] musicpal: Fix registration of MMIO-less sysbus
 devices

The proper way to signal that a sysbus devices need no MMIO region is to
pass -1 to sysbus_create_simple.

Signed-off-by: Jan Kiszka <jan.kiszka@web.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/musicpal.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/musicpal.c b/hw/musicpal.c
index d98aa8d03c..52b2931d15 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1597,11 +1597,11 @@ static void musicpal_init(ram_addr_t ram_size,
     musicpal_misc_init();
 
     dev = sysbus_create_simple("musicpal_gpio", MP_GPIO_BASE, pic[MP_GPIO_IRQ]);
-    i2c_dev = sysbus_create_simple("gpio_i2c", 0, NULL);
+    i2c_dev = sysbus_create_simple("gpio_i2c", -1, NULL);
     i2c = (i2c_bus *)qdev_get_child_bus(i2c_dev, "i2c");
 
     lcd_dev = sysbus_create_simple("musicpal_lcd", MP_LCD_BASE, NULL);
-    key_dev = sysbus_create_simple("musicpal_key", 0, NULL);
+    key_dev = sysbus_create_simple("musicpal_key", -1, NULL);
 
     /* I2C read data */
     qdev_connect_gpio_out(i2c_dev, 0,

From 7b3da903041eae8e756d5dd29c492e5f043c9954 Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Mon, 4 Apr 2011 16:32:11 +0200
Subject: [PATCH 144/386] s390x: set alignment for long to 8

The alignment for longs on s390x is 8. That's the only place where it differs
from the default alignments found in configure already. The example alignment
program from Laurent printed the following on a real s390x:

  alignof(short) 2
  alignof(int) 4
  alignof(long) 8
  alignof(long long) 8

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 configure | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configure b/configure
index 2bb3faa07e..a4759ae817 100755
--- a/configure
+++ b/configure
@@ -3184,6 +3184,7 @@ case "$target_arch2" in
   s390x)
     target_nptl="yes"
     target_phys_bits=64
+    target_long_alignment=8
   ;;
   *)
     echo "Unsupported target CPU"

From 8f16753fd6b584f34d47e102d290dbf4d5c94d46 Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Mon, 4 Apr 2011 16:32:10 +0200
Subject: [PATCH 145/386] s390x: fix virtio feature bitmap

The feature bitmap in the s390 virtio machine is little endian. To
address for that, we need to bswap the values after reading them out.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/s390-virtio-bus.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index 58af164880..60e0135ed8 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -223,7 +223,7 @@ void s390_virtio_device_sync(VirtIOS390Device *dev)
     cur_offs += num_vq * VIRTIO_VQCONFIG_LEN;
 
     /* Sync feature bitmap */
-    stl_phys(cur_offs, dev->host_features);
+    stl_phys(cur_offs, bswap32(dev->host_features));
 
     dev->feat_offs = cur_offs + dev->feat_len;
     cur_offs += dev->feat_len * 2;
@@ -246,7 +246,7 @@ void s390_virtio_device_update_status(VirtIOS390Device *dev)
 
     /* Update guest supported feature bitmap */
 
-    features = ldl_phys(dev->feat_offs);
+    features = bswap32(ldl_phys(dev->feat_offs));
     if (vdev->set_features) {
         vdev->set_features(vdev, features);
     }

From 8b2715a01e5dee434fbe070c3c855133203b2845 Mon Sep 17 00:00:00 2001
From: Blue Swirl <blauwirbel@gmail.com>
Date: Sat, 9 Apr 2011 14:25:25 +0000
Subject: [PATCH 146/386] ppc: remove a write-only variable

Remove a write-only variable, spotted by GCC 4.6.0:
/src/qemu/hw/ppc.c: In function 'power7_set_irq':
/src/qemu/hw/ppc.c:255:9: error: variable 'cur_level' set but not used [-Werror=unused-but-set-variable]

Acked-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 hw/ppc.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/ppc.c b/hw/ppc.c
index dabb816510..18733289db 100644
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -252,11 +252,9 @@ void ppc970_irq_init (CPUState *env)
 static void power7_set_irq (void *opaque, int pin, int level)
 {
     CPUState *env = opaque;
-    int cur_level;
 
     LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
                 env, pin, level);
-    cur_level = (env->irq_input_state >> pin) & 1;
 
     switch (pin) {
     case POWER7_INPUT_INT:

From 7458a432f03bc9af031336af29fc6477de8c5e34 Mon Sep 17 00:00:00 2001
From: Alejandro Cabrera <aldaya@gmail.com>
Date: Mon, 11 Apr 2011 23:07:58 +0200
Subject: [PATCH 147/386] microblaze: Correct MMU_ZONES mask

Signed-off-by: Alejandro Cabrera <aldaya@gmail.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 target-microblaze/cpu.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index 14d4d42730..cc096474ff 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -194,7 +194,7 @@ struct CPUMBState;
 #define PVR11_MMU_ITLB_SIZE             0x38000000
 #define PVR11_MMU_DTLB_SIZE             0x07000000
 #define PVR11_MMU_TLB_ACCESS            0x00C00000
-#define PVR11_MMU_ZONES                 0x003C0000
+#define PVR11_MMU_ZONES                 0x003E0000
 /* MSR Reset value PVR mask */
 #define PVR11_MSR_RESET_VALUE_MASK      0x000007FF
 

From 3b584046aae87df3ac195cc85b89ff86c1a8db01 Mon Sep 17 00:00:00 2001
From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
Date: Mon, 11 Apr 2011 23:55:42 +0200
Subject: [PATCH 148/386] microblaze: Add constant for exception-code mask

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 target-microblaze/cpu.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index cc096474ff..d0aee190ba 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -91,6 +91,7 @@ struct CPUMBState;
 #define          ESR_EC_INSN_STORAGE    9
 #define          ESR_EC_DATA_TLB        10
 #define          ESR_EC_INSN_TLB        11
+#define          ESR_EC_MASK            31
 
 /* Floating Point Status Register (FSR) Bits */
 #define FSR_IO          (1<<4) /* Invalid operation */

From 2e42d52d95d613e38961727e6bac2028681340e3 Mon Sep 17 00:00:00 2001
From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
Date: Mon, 11 Apr 2011 23:57:07 +0200
Subject: [PATCH 149/386] microblaze: Correct ec mask in debug print

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 linux-user/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index e651bfdad8..91600877d2 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2258,7 +2258,7 @@ void cpu_loop (CPUState *env)
                     break;
                 default:
                     printf ("Unhandled hw-exception: 0x%x\n",
-                            env->sregs[SR_ESR] & 5);
+                            env->sregs[SR_ESR] & ESR_EC_MASK);
                     cpu_dump_state(env, stderr, fprintf, 0);
                     exit (1);
                     break;

From 8545364198da26f02f54343476947b8c11d17dfb Mon Sep 17 00:00:00 2001
From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
Date: Tue, 12 Apr 2011 00:42:28 +0200
Subject: [PATCH 150/386] microblaze: Add stream-insn related constants

Based on a patch from: Alejandro Cabrera <aldaya@gmail.com>

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 target-microblaze/cpu.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index d0aee190ba..536222e4b8 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -79,6 +79,8 @@ struct CPUMBState;
 #define          ESR_DIZ       (1<<11) /* Zone Protection */
 #define          ESR_S         (1<<10) /* Store instruction */
 
+#define          ESR_ESS_FSL_OFFSET     5
+
 #define          ESR_EC_FSL             0
 #define          ESR_EC_UNALIGNED_DATA  1
 #define          ESR_EC_ILLEGAL_OP      2
@@ -212,6 +214,13 @@ struct CPUMBState;
 #define CC_EQ  0
 
 #define NB_MMU_MODES    3
+
+#define STREAM_EXCEPTION (1 << 0)
+#define STREAM_ATOMIC    (1 << 1)
+#define STREAM_TEST      (1 << 2)
+#define STREAM_CONTROL   (1 << 3)
+#define STREAM_NONBLOCK  (1 << 4)
+
 typedef struct CPUMBState {
     uint32_t debug;
     uint32_t btaken;

From 6d76d23e82d0ce8a7874b13f5951aa763e059908 Mon Sep 17 00:00:00 2001
From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
Date: Tue, 12 Apr 2011 00:48:33 +0200
Subject: [PATCH 151/386] microblaze: Add partial decoding of stream insns

Based on a patch from: Alejandro Cabrera <aldaya@gmail.com>

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 target-microblaze/helper.h            |  3 +++
 target-microblaze/microblaze-decode.h |  3 +++
 target-microblaze/op_helper.c         | 35 +++++++++++++++++++++++++
 target-microblaze/translate.c         | 37 +++++++++++++++++++++++++++
 4 files changed, 78 insertions(+)

diff --git a/target-microblaze/helper.h b/target-microblaze/helper.h
index 1696b885b6..b92aa34d05 100644
--- a/target-microblaze/helper.h
+++ b/target-microblaze/helper.h
@@ -33,4 +33,7 @@ DEF_HELPER_2(mmu_write, void, i32, i32)
 
 DEF_HELPER_4(memalign, void, i32, i32, i32, i32)
 
+DEF_HELPER_2(get, i32, i32, i32)
+DEF_HELPER_3(put, void, i32, i32, i32)
+
 #include "def-helper.h"
diff --git a/target-microblaze/microblaze-decode.h b/target-microblaze/microblaze-decode.h
index 4a274768d3..401319ed46 100644
--- a/target-microblaze/microblaze-decode.h
+++ b/target-microblaze/microblaze-decode.h
@@ -50,3 +50,6 @@
 #define DEC_BR      {B8(00100110), B8(00110111)}
 #define DEC_BCC     {B8(00100111), B8(00110111)}
 #define DEC_RTS     {B8(00101101), B8(00111111)}
+
+#define DEC_STREAM  {B8(00010011), B8(00110111)}
+
diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
index d75a53cc54..39b8ec1e15 100644
--- a/target-microblaze/op_helper.c
+++ b/target-microblaze/op_helper.c
@@ -69,6 +69,41 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 }
 #endif
 
+void helper_put(uint32_t id, uint32_t ctrl, uint32_t data)
+{
+    int test = ctrl & STREAM_TEST;
+    int atomic = ctrl & STREAM_ATOMIC;
+    int control = ctrl & STREAM_CONTROL;
+    int nonblock = ctrl & STREAM_NONBLOCK;
+    int exception = ctrl & STREAM_EXCEPTION;
+
+    qemu_log("Unhandled stream put to stream-id=%d data=%x %s%s%s%s%s\n",
+             id, data,
+             test ? "t" : "",
+             nonblock ? "n" : "",
+             exception ? "e" : "",
+             control ? "c" : "",
+             atomic ? "a" : "");
+}
+
+uint32_t helper_get(uint32_t id, uint32_t ctrl)
+{
+    int test = ctrl & STREAM_TEST;
+    int atomic = ctrl & STREAM_ATOMIC;
+    int control = ctrl & STREAM_CONTROL;
+    int nonblock = ctrl & STREAM_NONBLOCK;
+    int exception = ctrl & STREAM_EXCEPTION;
+
+    qemu_log("Unhandled stream get from stream-id=%d %s%s%s%s%s\n",
+             id,
+             test ? "t" : "",
+             nonblock ? "n" : "",
+             exception ? "e" : "",
+             control ? "c" : "",
+             atomic ? "a" : "");
+    return 0xdead0000 | id;
+}
+
 void helper_raise_exception(uint32_t index)
 {
     env->exception_index = index;
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 6f4eef1a69..bff3a11bc8 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1476,6 +1476,42 @@ static void dec_null(DisasContext *dc)
     dc->abort_at_next_insn = 1;
 }
 
+/* Insns connected to FSL or AXI stream attached devices.  */
+static void dec_stream(DisasContext *dc)
+{
+    int mem_index = cpu_mmu_index(dc->env);
+    TCGv_i32 t_id, t_ctrl;
+    int ctrl;
+
+    LOG_DIS("%s%s imm=%x\n", dc->rd ? "get" : "put",
+            dc->type_b ? "" : "d", dc->imm);
+
+    if ((dc->tb_flags & MSR_EE_FLAG) && (mem_index == MMU_USER_IDX)) {
+        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+        t_gen_raise_exception(dc, EXCP_HW_EXCP);
+        return;
+    }
+
+    t_id = tcg_temp_new();
+    if (dc->type_b) {
+        tcg_gen_movi_tl(t_id, dc->imm & 0xf);
+        ctrl = dc->imm >> 10;
+    } else {
+        tcg_gen_andi_tl(t_id, cpu_R[dc->rb], 0xf);
+        ctrl = dc->imm >> 5;
+    }
+
+    t_ctrl = tcg_const_tl(ctrl);
+
+    if (dc->rd == 0) {
+        gen_helper_put(t_id, t_ctrl, cpu_R[dc->ra]);
+    } else {
+        gen_helper_get(cpu_R[dc->rd], t_id, t_ctrl);
+    }
+    tcg_temp_free(t_id);
+    tcg_temp_free(t_ctrl);
+}
+
 static struct decoder_info {
     struct {
         uint32_t bits;
@@ -1500,6 +1536,7 @@ static struct decoder_info {
     {DEC_MUL, dec_mul},
     {DEC_DIV, dec_div},
     {DEC_MSR, dec_msr},
+    {DEC_STREAM, dec_stream},
     {{0, 0}, dec_null}
 };
 

From 6e64da3cd6890181fbeaaae7c08cfb779f138d82 Mon Sep 17 00:00:00 2001
From: Guan Xuetao <gxt@mprc.pku.edu.cn>
Date: Tue, 12 Apr 2011 16:25:59 +0800
Subject: [PATCH 152/386] unicore32: add target-unicore32 directory for
 unicore32-linux-user support

Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 target-unicore32/cpu.h       |  182 +++
 target-unicore32/exec.h      |   50 +
 target-unicore32/helper.c    |  487 ++++++++
 target-unicore32/helper.h    |   70 ++
 target-unicore32/op_helper.c |  248 ++++
 target-unicore32/translate.c | 2105 ++++++++++++++++++++++++++++++++++
 6 files changed, 3142 insertions(+)
 create mode 100644 target-unicore32/cpu.h
 create mode 100644 target-unicore32/exec.h
 create mode 100644 target-unicore32/helper.c
 create mode 100644 target-unicore32/helper.h
 create mode 100644 target-unicore32/op_helper.c
 create mode 100644 target-unicore32/translate.c

diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
new file mode 100644
index 0000000000..1e10049f89
--- /dev/null
+++ b/target-unicore32/cpu.h
@@ -0,0 +1,182 @@
+/*
+ * UniCore32 virtual CPU header
+ *
+ * Copyright (C) 2010-2011 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __CPU_UC32_H__
+#define __CPU_UC32_H__
+
+#define TARGET_LONG_BITS                32
+#define TARGET_PAGE_BITS                12
+
+#define TARGET_PHYS_ADDR_SPACE_BITS     32
+#define TARGET_VIRT_ADDR_SPACE_BITS     32
+
+#define ELF_MACHINE             EM_UNICORE32
+
+#define CPUState                struct CPUState_UniCore32
+
+#include "cpu-defs.h"
+#include "softfloat.h"
+
+#define NB_MMU_MODES            2
+
+typedef struct CPUState_UniCore32 {
+    /* Regs for current mode.  */
+    uint32_t regs[32];
+    /* Frequently accessed ASR bits are stored separately for efficiently.
+       This contains all the other bits.  Use asr_{read,write} to access
+       the whole ASR.  */
+    uint32_t uncached_asr;
+    uint32_t bsr;
+
+    /* Banked registers.  */
+    uint32_t banked_bsr[6];
+    uint32_t banked_r29[6];
+    uint32_t banked_r30[6];
+
+    /* asr flag cache for faster execution */
+    uint32_t CF; /* 0 or 1 */
+    uint32_t VF; /* V is the bit 31. All other bits are undefined */
+    uint32_t NF; /* N is bit 31. All other bits are undefined.  */
+    uint32_t ZF; /* Z set if zero.  */
+
+    /* System control coprocessor (cp0) */
+    struct {
+        uint32_t c0_cpuid;
+        uint32_t c0_cachetype;
+        uint32_t c1_sys; /* System control register.  */
+        uint32_t c2_base; /* MMU translation table base.  */
+        uint32_t c3_faultstatus; /* Fault status registers.  */
+        uint32_t c4_faultaddr; /* Fault address registers.  */
+        uint32_t c5_cacheop; /* Cache operation registers.  */
+        uint32_t c6_tlbop; /* TLB operation registers. */
+    } cp0;
+
+    /* UniCore-F64 coprocessor state.  */
+    struct {
+        float64 regs[16];
+        uint32_t xregs[32];
+        float_status fp_status;
+    } ucf64;
+
+    CPU_COMMON
+
+    /* Internal CPU feature flags.  */
+    uint32_t features;
+
+} CPUState_UniCore32;
+
+#define ASR_M                   (0x1f)
+#define ASR_MODE_USER           (0x10)
+#define ASR_MODE_INTR           (0x12)
+#define ASR_MODE_PRIV           (0x13)
+#define ASR_MODE_TRAP           (0x17)
+#define ASR_MODE_EXTN           (0x1b)
+#define ASR_MODE_SUSR           (0x1f)
+#define ASR_I                   (1 << 7)
+#define ASR_V                   (1 << 28)
+#define ASR_C                   (1 << 29)
+#define ASR_Z                   (1 << 30)
+#define ASR_N                   (1 << 31)
+#define ASR_NZCV                (ASR_N | ASR_Z | ASR_C | ASR_V)
+#define ASR_RESERVED            (~(ASR_M | ASR_I | ASR_NZCV))
+
+#define UC32_EXCP_PRIV          (ASR_MODE_PRIV)
+#define UC32_EXCP_TRAP          (ASR_MODE_TRAP)
+
+/* Return the current ASR value.  */
+target_ulong cpu_asr_read(CPUState *env1);
+/* Set the ASR.  Note that some bits of mask must be all-set or all-clear.  */
+void cpu_asr_write(CPUState *env1, target_ulong val, target_ulong mask);
+
+/* UniCore-F64 system registers.  */
+#define UC32_UCF64_FPSCR                (31)
+#define UCF64_FPSCR_MASK                (0x27ffffff)
+#define UCF64_FPSCR_RND_MASK            (0x7)
+#define UCF64_FPSCR_RND(r)              (((r) >>  0) & UCF64_FPSCR_RND_MASK)
+#define UCF64_FPSCR_TRAPEN_MASK         (0x7f)
+#define UCF64_FPSCR_TRAPEN(r)           (((r) >> 10) & UCF64_FPSCR_TRAPEN_MASK)
+#define UCF64_FPSCR_FLAG_MASK           (0x3ff)
+#define UCF64_FPSCR_FLAG(r)             (((r) >> 17) & UCF64_FPSCR_FLAG_MASK)
+#define UCF64_FPSCR_FLAG_ZERO           (1 << 17)
+#define UCF64_FPSCR_FLAG_INFINITY       (1 << 18)
+#define UCF64_FPSCR_FLAG_INVALID        (1 << 19)
+#define UCF64_FPSCR_FLAG_UNDERFLOW      (1 << 20)
+#define UCF64_FPSCR_FLAG_OVERFLOW       (1 << 21)
+#define UCF64_FPSCR_FLAG_INEXACT        (1 << 22)
+#define UCF64_FPSCR_FLAG_HUGEINT        (1 << 23)
+#define UCF64_FPSCR_FLAG_DENORMAL       (1 << 24)
+#define UCF64_FPSCR_FLAG_UNIMP          (1 << 25)
+#define UCF64_FPSCR_FLAG_DIVZERO        (1 << 26)
+
+#define UC32_HWCAP_CMOV                 4 /* 1 << 2 */
+#define UC32_HWCAP_UCF64                8 /* 1 << 3 */
+
+#define UC32_CPUID(env)                 (env->cp0.c0_cpuid)
+#define UC32_CPUID_UCV2                 0x40010863
+#define UC32_CPUID_ANY                  0xffffffff
+
+#define cpu_init                        uc32_cpu_init
+#define cpu_exec                        uc32_cpu_exec
+#define cpu_signal_handler              uc32_cpu_signal_handler
+#define cpu_handle_mmu_fault            uc32_cpu_handle_mmu_fault
+
+CPUState *uc32_cpu_init(const char *cpu_model);
+int uc32_cpu_exec(CPUState *s);
+int uc32_cpu_signal_handler(int host_signum, void *pinfo, void *puc);
+int uc32_cpu_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
+                              int mmu_idx, int is_softmuu);
+
+#define CPU_SAVE_VERSION 2
+
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_USER_IDX 1
+static inline int cpu_mmu_index(CPUState *env)
+{
+    return (env->uncached_asr & ASR_M) == ASR_MODE_USER ? 1 : 0;
+}
+
+static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->regs[29] = newsp;
+    }
+    env->regs[0] = 0;
+}
+
+static inline void cpu_set_tls(CPUState *env, target_ulong newtls)
+{
+    env->regs[16] = newtls;
+}
+
+#include "cpu-all.h"
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->regs[31] = tb->pc;
+}
+
+static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
+                                        target_ulong *cs_base, int *flags)
+{
+    *pc = env->regs[31];
+    *cs_base = 0;
+    *flags = 0;
+    if ((env->uncached_asr & ASR_M) != ASR_MODE_USER) {
+        *flags |= (1 << 6);
+    }
+}
+
+void uc32_translate_init(void);
+void do_interrupt(CPUState *);
+void switch_mode(CPUState_UniCore32 *, int);
+
+#endif /* __CPU_UC32_H__ */
diff --git a/target-unicore32/exec.h b/target-unicore32/exec.h
new file mode 100644
index 0000000000..4ab55f42cf
--- /dev/null
+++ b/target-unicore32/exec.h
@@ -0,0 +1,50 @@
+/*
+ *  UniCore32 execution defines
+ *
+ * Copyright (C) 2010-2011 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __UC32_EXEC_H__
+#define __UC32_EXEC_H__
+
+#include "config.h"
+#include "dyngen-exec.h"
+
+register struct CPUState_UniCore32 *env asm(AREG0);
+
+#include "cpu.h"
+#include "exec-all.h"
+
+static inline void env_to_regs(void)
+{
+}
+
+static inline void regs_to_env(void)
+{
+}
+
+static inline int cpu_has_work(CPUState *env)
+{
+    return env->interrupt_request &
+        (CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
+}
+
+static inline int cpu_halted(CPUState *env)
+{
+    if (!env->halted) {
+        return 0;
+    }
+    /* An interrupt wakes the CPU even if the I and R ASR bits are
+       set.  We use EXITTB to silently wake CPU without causing an
+       actual interrupt.  */
+    if (cpu_has_work(env)) {
+        env->halted = 0;
+        return 0;
+    }
+    return EXCP_HALTED;
+}
+
+#endif /* __UC32_EXEC_H__ */
diff --git a/target-unicore32/helper.c b/target-unicore32/helper.c
new file mode 100644
index 0000000000..483aeaeb14
--- /dev/null
+++ b/target-unicore32/helper.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright (C) 2010-2011 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "cpu.h"
+#include "exec-all.h"
+#include "gdbstub.h"
+#include "helper.h"
+#include "qemu-common.h"
+#include "host-utils.h"
+
+static inline void set_feature(CPUState *env, int feature)
+{
+    env->features |= feature;
+}
+
+struct uc32_cpu_t {
+    uint32_t id;
+    const char *name;
+};
+
+static const struct uc32_cpu_t uc32_cpu_names[] = {
+    { UC32_CPUID_UCV2, "UniCore-II"},
+    { UC32_CPUID_ANY, "any"},
+    { 0, NULL}
+};
+
+/* return 0 if not found */
+static uint32_t uc32_cpu_find_by_name(const char *name)
+{
+    int i;
+    uint32_t id;
+
+    id = 0;
+    for (i = 0; uc32_cpu_names[i].name; i++) {
+        if (strcmp(name, uc32_cpu_names[i].name) == 0) {
+            id = uc32_cpu_names[i].id;
+            break;
+        }
+    }
+    return id;
+}
+
+CPUState *uc32_cpu_init(const char *cpu_model)
+{
+    CPUState *env;
+    uint32_t id;
+    static int inited = 1;
+
+    env = qemu_mallocz(sizeof(CPUState));
+    cpu_exec_init(env);
+
+    id = uc32_cpu_find_by_name(cpu_model);
+    switch (id) {
+    case UC32_CPUID_UCV2:
+        set_feature(env, UC32_HWCAP_CMOV);
+        set_feature(env, UC32_HWCAP_UCF64);
+        env->ucf64.xregs[UC32_UCF64_FPSCR] = 0;
+        env->cp0.c0_cachetype = 0x1dd20d2;
+        env->cp0.c1_sys = 0x00090078;
+        break;
+    case UC32_CPUID_ANY: /* For userspace emulation.  */
+        set_feature(env, UC32_HWCAP_CMOV);
+        set_feature(env, UC32_HWCAP_UCF64);
+        break;
+    default:
+        cpu_abort(env, "Bad CPU ID: %x\n", id);
+    }
+
+    env->cpu_model_str = cpu_model;
+    env->cp0.c0_cpuid = id;
+    env->uncached_asr = ASR_MODE_USER;
+    env->regs[31] = 0;
+
+    if (inited) {
+        inited = 0;
+        uc32_translate_init();
+    }
+
+    tlb_flush(env, 1);
+    qemu_init_vcpu(env);
+    return env;
+}
+
+uint32_t HELPER(clo)(uint32_t x)
+{
+    return clo32(x);
+}
+
+uint32_t HELPER(clz)(uint32_t x)
+{
+    return clz32(x);
+}
+
+void do_interrupt(CPUState *env)
+{
+    env->exception_index = -1;
+}
+
+int uc32_cpu_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
+                              int mmu_idx, int is_softmmu)
+{
+    env->exception_index = UC32_EXCP_TRAP;
+    env->cp0.c4_faultaddr = address;
+    return 1;
+}
+
+/* These should probably raise undefined insn exceptions.  */
+void HELPER(set_cp)(CPUState *env, uint32_t insn, uint32_t val)
+{
+    int op1 = (insn >> 8) & 0xf;
+    cpu_abort(env, "cp%i insn %08x\n", op1, insn);
+    return;
+}
+
+uint32_t HELPER(get_cp)(CPUState *env, uint32_t insn)
+{
+    int op1 = (insn >> 8) & 0xf;
+    cpu_abort(env, "cp%i insn %08x\n", op1, insn);
+    return 0;
+}
+
+void HELPER(set_cp0)(CPUState *env, uint32_t insn, uint32_t val)
+{
+    cpu_abort(env, "cp0 insn %08x\n", insn);
+}
+
+uint32_t HELPER(get_cp0)(CPUState *env, uint32_t insn)
+{
+    cpu_abort(env, "cp0 insn %08x\n", insn);
+    return 0;
+}
+
+void switch_mode(CPUState *env, int mode)
+{
+    if (mode != ASR_MODE_USER) {
+        cpu_abort(env, "Tried to switch out of user mode\n");
+    }
+}
+
+void HELPER(set_r29_banked)(CPUState *env, uint32_t mode, uint32_t val)
+{
+    cpu_abort(env, "banked r29 write\n");
+}
+
+uint32_t HELPER(get_r29_banked)(CPUState *env, uint32_t mode)
+{
+    cpu_abort(env, "banked r29 read\n");
+    return 0;
+}
+
+/* UniCore-F64 support.  We follow the convention used for F64 instrunctions:
+   Single precition routines have a "s" suffix, double precision a
+   "d" suffix.  */
+
+/* Convert host exception flags to f64 form.  */
+static inline int ucf64_exceptbits_from_host(int host_bits)
+{
+    int target_bits = 0;
+
+    if (host_bits & float_flag_invalid) {
+        target_bits |= UCF64_FPSCR_FLAG_INVALID;
+    }
+    if (host_bits & float_flag_divbyzero) {
+        target_bits |= UCF64_FPSCR_FLAG_DIVZERO;
+    }
+    if (host_bits & float_flag_overflow) {
+        target_bits |= UCF64_FPSCR_FLAG_OVERFLOW;
+    }
+    if (host_bits & float_flag_underflow) {
+        target_bits |= UCF64_FPSCR_FLAG_UNDERFLOW;
+    }
+    if (host_bits & float_flag_inexact) {
+        target_bits |= UCF64_FPSCR_FLAG_INEXACT;
+    }
+    return target_bits;
+}
+
+uint32_t HELPER(ucf64_get_fpscr)(CPUState *env)
+{
+    int i;
+    uint32_t fpscr;
+
+    fpscr = (env->ucf64.xregs[UC32_UCF64_FPSCR] & UCF64_FPSCR_MASK);
+    i = get_float_exception_flags(&env->ucf64.fp_status);
+    fpscr |= ucf64_exceptbits_from_host(i);
+    return fpscr;
+}
+
+/* Convert ucf64 exception flags to target form.  */
+static inline int ucf64_exceptbits_to_host(int target_bits)
+{
+    int host_bits = 0;
+
+    if (target_bits & UCF64_FPSCR_FLAG_INVALID) {
+        host_bits |= float_flag_invalid;
+    }
+    if (target_bits & UCF64_FPSCR_FLAG_DIVZERO) {
+        host_bits |= float_flag_divbyzero;
+    }
+    if (target_bits & UCF64_FPSCR_FLAG_OVERFLOW) {
+        host_bits |= float_flag_overflow;
+    }
+    if (target_bits & UCF64_FPSCR_FLAG_UNDERFLOW) {
+        host_bits |= float_flag_underflow;
+    }
+    if (target_bits & UCF64_FPSCR_FLAG_INEXACT) {
+        host_bits |= float_flag_inexact;
+    }
+    return host_bits;
+}
+
+void HELPER(ucf64_set_fpscr)(CPUState *env, uint32_t val)
+{
+    int i;
+    uint32_t changed;
+
+    changed = env->ucf64.xregs[UC32_UCF64_FPSCR];
+    env->ucf64.xregs[UC32_UCF64_FPSCR] = (val & UCF64_FPSCR_MASK);
+
+    changed ^= val;
+    if (changed & (UCF64_FPSCR_RND_MASK)) {
+        i = UCF64_FPSCR_RND(val);
+        switch (i) {
+        case 0:
+            i = float_round_nearest_even;
+            break;
+        case 1:
+            i = float_round_to_zero;
+            break;
+        case 2:
+            i = float_round_up;
+            break;
+        case 3:
+            i = float_round_down;
+            break;
+        default: /* 100 and 101 not implement */
+            cpu_abort(env, "Unsupported UniCore-F64 round mode");
+        }
+        set_float_rounding_mode(i, &env->ucf64.fp_status);
+    }
+
+    i = ucf64_exceptbits_to_host(UCF64_FPSCR_TRAPEN(val));
+    set_float_exception_flags(i, &env->ucf64.fp_status);
+}
+
+float32 HELPER(ucf64_adds)(float32 a, float32 b, CPUState *env)
+{
+    return float32_add(a, b, &env->ucf64.fp_status);
+}
+
+float64 HELPER(ucf64_addd)(float64 a, float64 b, CPUState *env)
+{
+    return float64_add(a, b, &env->ucf64.fp_status);
+}
+
+float32 HELPER(ucf64_subs)(float32 a, float32 b, CPUState *env)
+{
+    return float32_sub(a, b, &env->ucf64.fp_status);
+}
+
+float64 HELPER(ucf64_subd)(float64 a, float64 b, CPUState *env)
+{
+    return float64_sub(a, b, &env->ucf64.fp_status);
+}
+
+float32 HELPER(ucf64_muls)(float32 a, float32 b, CPUState *env)
+{
+    return float32_mul(a, b, &env->ucf64.fp_status);
+}
+
+float64 HELPER(ucf64_muld)(float64 a, float64 b, CPUState *env)
+{
+    return float64_mul(a, b, &env->ucf64.fp_status);
+}
+
+float32 HELPER(ucf64_divs)(float32 a, float32 b, CPUState *env)
+{
+    return float32_div(a, b, &env->ucf64.fp_status);
+}
+
+float64 HELPER(ucf64_divd)(float64 a, float64 b, CPUState *env)
+{
+    return float64_div(a, b, &env->ucf64.fp_status);
+}
+
+float32 HELPER(ucf64_negs)(float32 a)
+{
+    return float32_chs(a);
+}
+
+float64 HELPER(ucf64_negd)(float64 a)
+{
+    return float64_chs(a);
+}
+
+float32 HELPER(ucf64_abss)(float32 a)
+{
+    return float32_abs(a);
+}
+
+float64 HELPER(ucf64_absd)(float64 a)
+{
+    return float64_abs(a);
+}
+
+/* XXX: check quiet/signaling case */
+void HELPER(ucf64_cmps)(float32 a, float32 b, uint32_t c, CPUState *env)
+{
+    int flag;
+    flag = float32_compare_quiet(a, b, &env->ucf64.fp_status);
+    env->CF = 0;
+    switch (c & 0x7) {
+    case 0: /* F */
+        break;
+    case 1: /* UN */
+        if (flag == 2) {
+            env->CF = 1;
+        }
+        break;
+    case 2: /* EQ */
+        if (flag == 0) {
+            env->CF = 1;
+        }
+        break;
+    case 3: /* UEQ */
+        if ((flag == 0) || (flag == 2)) {
+            env->CF = 1;
+        }
+        break;
+    case 4: /* OLT */
+        if (flag == -1) {
+            env->CF = 1;
+        }
+        break;
+    case 5: /* ULT */
+        if ((flag == -1) || (flag == 2)) {
+            env->CF = 1;
+        }
+        break;
+    case 6: /* OLE */
+        if ((flag == -1) || (flag == 0)) {
+            env->CF = 1;
+        }
+        break;
+    case 7: /* ULE */
+        if (flag != 1) {
+            env->CF = 1;
+        }
+        break;
+    }
+    env->ucf64.xregs[UC32_UCF64_FPSCR] = (env->CF << 29)
+                    | (env->ucf64.xregs[UC32_UCF64_FPSCR] & 0x0fffffff);
+}
+
+void HELPER(ucf64_cmpd)(float64 a, float64 b, uint32_t c, CPUState *env)
+{
+    int flag;
+    flag = float64_compare_quiet(a, b, &env->ucf64.fp_status);
+    env->CF = 0;
+    switch (c & 0x7) {
+    case 0: /* F */
+        break;
+    case 1: /* UN */
+        if (flag == 2) {
+            env->CF = 1;
+        }
+        break;
+    case 2: /* EQ */
+        if (flag == 0) {
+            env->CF = 1;
+        }
+        break;
+    case 3: /* UEQ */
+        if ((flag == 0) || (flag == 2)) {
+            env->CF = 1;
+        }
+        break;
+    case 4: /* OLT */
+        if (flag == -1) {
+            env->CF = 1;
+        }
+        break;
+    case 5: /* ULT */
+        if ((flag == -1) || (flag == 2)) {
+            env->CF = 1;
+        }
+        break;
+    case 6: /* OLE */
+        if ((flag == -1) || (flag == 0)) {
+            env->CF = 1;
+        }
+        break;
+    case 7: /* ULE */
+        if (flag != 1) {
+            env->CF = 1;
+        }
+        break;
+    }
+    env->ucf64.xregs[UC32_UCF64_FPSCR] = (env->CF << 29)
+                    | (env->ucf64.xregs[UC32_UCF64_FPSCR] & 0x0fffffff);
+}
+
+/* Helper routines to perform bitwise copies between float and int.  */
+static inline float32 ucf64_itos(uint32_t i)
+{
+    union {
+        uint32_t i;
+        float32 s;
+    } v;
+
+    v.i = i;
+    return v.s;
+}
+
+static inline uint32_t ucf64_stoi(float32 s)
+{
+    union {
+        uint32_t i;
+        float32 s;
+    } v;
+
+    v.s = s;
+    return v.i;
+}
+
+static inline float64 ucf64_itod(uint64_t i)
+{
+    union {
+        uint64_t i;
+        float64 d;
+    } v;
+
+    v.i = i;
+    return v.d;
+}
+
+static inline uint64_t ucf64_dtoi(float64 d)
+{
+    union {
+        uint64_t i;
+        float64 d;
+    } v;
+
+    v.d = d;
+    return v.i;
+}
+
+/* Integer to float conversion.  */
+float32 HELPER(ucf64_si2sf)(float32 x, CPUState *env)
+{
+    return int32_to_float32(ucf64_stoi(x), &env->ucf64.fp_status);
+}
+
+float64 HELPER(ucf64_si2df)(float32 x, CPUState *env)
+{
+    return int32_to_float64(ucf64_stoi(x), &env->ucf64.fp_status);
+}
+
+/* Float to integer conversion.  */
+float32 HELPER(ucf64_sf2si)(float32 x, CPUState *env)
+{
+    return ucf64_itos(float32_to_int32(x, &env->ucf64.fp_status));
+}
+
+float32 HELPER(ucf64_df2si)(float64 x, CPUState *env)
+{
+    return ucf64_itos(float64_to_int32(x, &env->ucf64.fp_status));
+}
+
+/* floating point conversion */
+float64 HELPER(ucf64_sf2df)(float32 x, CPUState *env)
+{
+    return float32_to_float64(x, &env->ucf64.fp_status);
+}
+
+float32 HELPER(ucf64_df2sf)(float64 x, CPUState *env)
+{
+    return float64_to_float32(x, &env->ucf64.fp_status);
+}
diff --git a/target-unicore32/helper.h b/target-unicore32/helper.h
new file mode 100644
index 0000000000..615de2add9
--- /dev/null
+++ b/target-unicore32/helper.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2010-2011 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include "def-helper.h"
+
+DEF_HELPER_1(clz, i32, i32)
+DEF_HELPER_1(clo, i32, i32)
+
+DEF_HELPER_1(exception, void, i32)
+
+DEF_HELPER_2(asr_write, void, i32, i32)
+DEF_HELPER_0(asr_read, i32)
+
+DEF_HELPER_3(set_cp0, void, env, i32, i32)
+DEF_HELPER_2(get_cp0, i32, env, i32)
+
+DEF_HELPER_3(set_cp, void, env, i32, i32)
+DEF_HELPER_2(get_cp, i32, env, i32)
+
+DEF_HELPER_1(get_user_reg, i32, i32)
+DEF_HELPER_2(set_user_reg, void, i32, i32)
+
+DEF_HELPER_2(add_cc, i32, i32, i32)
+DEF_HELPER_2(adc_cc, i32, i32, i32)
+DEF_HELPER_2(sub_cc, i32, i32, i32)
+DEF_HELPER_2(sbc_cc, i32, i32, i32)
+
+DEF_HELPER_2(shl, i32, i32, i32)
+DEF_HELPER_2(shr, i32, i32, i32)
+DEF_HELPER_2(sar, i32, i32, i32)
+DEF_HELPER_2(shl_cc, i32, i32, i32)
+DEF_HELPER_2(shr_cc, i32, i32, i32)
+DEF_HELPER_2(sar_cc, i32, i32, i32)
+DEF_HELPER_2(ror_cc, i32, i32, i32)
+
+DEF_HELPER_2(get_r29_banked, i32, env, i32)
+DEF_HELPER_3(set_r29_banked, void, env, i32, i32)
+
+DEF_HELPER_1(ucf64_get_fpscr, i32, env)
+DEF_HELPER_2(ucf64_set_fpscr, void, env, i32)
+
+DEF_HELPER_3(ucf64_adds, f32, f32, f32, env)
+DEF_HELPER_3(ucf64_addd, f64, f64, f64, env)
+DEF_HELPER_3(ucf64_subs, f32, f32, f32, env)
+DEF_HELPER_3(ucf64_subd, f64, f64, f64, env)
+DEF_HELPER_3(ucf64_muls, f32, f32, f32, env)
+DEF_HELPER_3(ucf64_muld, f64, f64, f64, env)
+DEF_HELPER_3(ucf64_divs, f32, f32, f32, env)
+DEF_HELPER_3(ucf64_divd, f64, f64, f64, env)
+DEF_HELPER_1(ucf64_negs, f32, f32)
+DEF_HELPER_1(ucf64_negd, f64, f64)
+DEF_HELPER_1(ucf64_abss, f32, f32)
+DEF_HELPER_1(ucf64_absd, f64, f64)
+DEF_HELPER_4(ucf64_cmps, void, f32, f32, i32, env)
+DEF_HELPER_4(ucf64_cmpd, void, f64, f64, i32, env)
+
+DEF_HELPER_2(ucf64_sf2df, f64, f32, env)
+DEF_HELPER_2(ucf64_df2sf, f32, f64, env)
+
+DEF_HELPER_2(ucf64_si2sf, f32, f32, env)
+DEF_HELPER_2(ucf64_si2df, f64, f32, env)
+
+DEF_HELPER_2(ucf64_sf2si, f32, f32, env)
+DEF_HELPER_2(ucf64_df2si, f32, f64, env)
+
+#include "def-helper.h"
diff --git a/target-unicore32/op_helper.c b/target-unicore32/op_helper.c
new file mode 100644
index 0000000000..31e4b11e43
--- /dev/null
+++ b/target-unicore32/op_helper.c
@@ -0,0 +1,248 @@
+/*
+ *  UniCore32 helper routines
+ *
+ * Copyright (C) 2010-2011 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include "exec.h"
+#include "helper.h"
+
+#define SIGNBIT (uint32_t)0x80000000
+#define SIGNBIT64 ((uint64_t)1 << 63)
+
+void HELPER(exception)(uint32_t excp)
+{
+    env->exception_index = excp;
+    cpu_loop_exit();
+}
+
+static target_ulong asr_read(void)
+{
+    int ZF;
+    ZF = (env->ZF == 0);
+    return env->uncached_asr | (env->NF & 0x80000000) | (ZF << 30) |
+        (env->CF << 29) | ((env->VF & 0x80000000) >> 3);
+}
+
+target_ulong cpu_asr_read(CPUState *env1)
+{
+    CPUState *saved_env;
+    target_ulong ret;
+
+    saved_env = env;
+    env = env1;
+    ret = asr_read();
+    env = saved_env;
+    return ret;
+}
+
+target_ulong HELPER(asr_read)(void)
+{
+    return asr_read();
+}
+
+static void asr_write(target_ulong val, target_ulong mask)
+{
+    if (mask & ASR_NZCV) {
+        env->ZF = (~val) & ASR_Z;
+        env->NF = val;
+        env->CF = (val >> 29) & 1;
+        env->VF = (val << 3) & 0x80000000;
+    }
+
+    if ((env->uncached_asr ^ val) & mask & ASR_M) {
+        switch_mode(env, val & ASR_M);
+    }
+    mask &= ~ASR_NZCV;
+    env->uncached_asr = (env->uncached_asr & ~mask) | (val & mask);
+}
+
+void cpu_asr_write(CPUState *env1, target_ulong val, target_ulong mask)
+{
+    CPUState *saved_env;
+
+    saved_env = env;
+    env = env1;
+    asr_write(val, mask);
+    env = saved_env;
+}
+
+void HELPER(asr_write)(target_ulong val, target_ulong mask)
+{
+    asr_write(val, mask);
+}
+
+/* Access to user mode registers from privileged modes.  */
+uint32_t HELPER(get_user_reg)(uint32_t regno)
+{
+    uint32_t val;
+
+    if (regno == 29) {
+        val = env->banked_r29[0];
+    } else if (regno == 30) {
+        val = env->banked_r30[0];
+    } else {
+        val = env->regs[regno];
+    }
+    return val;
+}
+
+void HELPER(set_user_reg)(uint32_t regno, uint32_t val)
+{
+    if (regno == 29) {
+        env->banked_r29[0] = val;
+    } else if (regno == 30) {
+        env->banked_r30[0] = val;
+    } else {
+        env->regs[regno] = val;
+    }
+}
+
+/* ??? Flag setting arithmetic is awkward because we need to do comparisons.
+   The only way to do that in TCG is a conditional branch, which clobbers
+   all our temporaries.  For now implement these as helper functions.  */
+
+uint32_t HELPER(add_cc)(uint32_t a, uint32_t b)
+{
+    uint32_t result;
+    result = a + b;
+    env->NF = env->ZF = result;
+    env->CF = result < a;
+    env->VF = (a ^ b ^ -1) & (a ^ result);
+    return result;
+}
+
+uint32_t HELPER(adc_cc)(uint32_t a, uint32_t b)
+{
+    uint32_t result;
+    if (!env->CF) {
+        result = a + b;
+        env->CF = result < a;
+    } else {
+        result = a + b + 1;
+        env->CF = result <= a;
+    }
+    env->VF = (a ^ b ^ -1) & (a ^ result);
+    env->NF = env->ZF = result;
+    return result;
+}
+
+uint32_t HELPER(sub_cc)(uint32_t a, uint32_t b)
+{
+    uint32_t result;
+    result = a - b;
+    env->NF = env->ZF = result;
+    env->CF = a >= b;
+    env->VF = (a ^ b) & (a ^ result);
+    return result;
+}
+
+uint32_t HELPER(sbc_cc)(uint32_t a, uint32_t b)
+{
+    uint32_t result;
+    if (!env->CF) {
+        result = a - b - 1;
+        env->CF = a > b;
+    } else {
+        result = a - b;
+        env->CF = a >= b;
+    }
+    env->VF = (a ^ b) & (a ^ result);
+    env->NF = env->ZF = result;
+    return result;
+}
+
+/* Similarly for variable shift instructions.  */
+
+uint32_t HELPER(shl)(uint32_t x, uint32_t i)
+{
+    int shift = i & 0xff;
+    if (shift >= 32) {
+        return 0;
+    }
+    return x << shift;
+}
+
+uint32_t HELPER(shr)(uint32_t x, uint32_t i)
+{
+    int shift = i & 0xff;
+    if (shift >= 32) {
+        return 0;
+    }
+    return (uint32_t)x >> shift;
+}
+
+uint32_t HELPER(sar)(uint32_t x, uint32_t i)
+{
+    int shift = i & 0xff;
+    if (shift >= 32) {
+        shift = 31;
+    }
+    return (int32_t)x >> shift;
+}
+
+uint32_t HELPER(shl_cc)(uint32_t x, uint32_t i)
+{
+    int shift = i & 0xff;
+    if (shift >= 32) {
+        if (shift == 32) {
+            env->CF = x & 1;
+        } else {
+            env->CF = 0;
+        }
+        return 0;
+    } else if (shift != 0) {
+        env->CF = (x >> (32 - shift)) & 1;
+        return x << shift;
+    }
+    return x;
+}
+
+uint32_t HELPER(shr_cc)(uint32_t x, uint32_t i)
+{
+    int shift = i & 0xff;
+    if (shift >= 32) {
+        if (shift == 32) {
+            env->CF = (x >> 31) & 1;
+        } else {
+            env->CF = 0;
+        }
+        return 0;
+    } else if (shift != 0) {
+        env->CF = (x >> (shift - 1)) & 1;
+        return x >> shift;
+    }
+    return x;
+}
+
+uint32_t HELPER(sar_cc)(uint32_t x, uint32_t i)
+{
+    int shift = i & 0xff;
+    if (shift >= 32) {
+        env->CF = (x >> 31) & 1;
+        return (int32_t)x >> 31;
+    } else if (shift != 0) {
+        env->CF = (x >> (shift - 1)) & 1;
+        return (int32_t)x >> shift;
+    }
+    return x;
+}
+
+uint32_t HELPER(ror_cc)(uint32_t x, uint32_t i)
+{
+    int shift1, shift;
+    shift1 = i & 0xff;
+    shift = shift1 & 0x1f;
+    if (shift == 0) {
+        if (shift1 != 0) {
+            env->CF = (x >> 31) & 1;
+        }
+        return x;
+    } else {
+        env->CF = (x >> (shift - 1)) & 1;
+        return ((uint32_t)x >> shift) | (x << (32 - shift));
+    }
+}
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
new file mode 100644
index 0000000000..a6ba991e92
--- /dev/null
+++ b/target-unicore32/translate.c
@@ -0,0 +1,2105 @@
+/*
+ *  UniCore32 translation
+ *
+ * Copyright (C) 2010-2011 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "cpu.h"
+#include "exec-all.h"
+#include "disas.h"
+#include "tcg-op.h"
+#include "qemu-log.h"
+
+#include "helper.h"
+#define GEN_HELPER 1
+#include "helper.h"
+
+/* internal defines */
+typedef struct DisasContext {
+    target_ulong pc;
+    int is_jmp;
+    /* Nonzero if this instruction has been conditionally skipped.  */
+    int condjmp;
+    /* The label that will be jumped to when the instruction is skipped.  */
+    int condlabel;
+    struct TranslationBlock *tb;
+    int singlestep_enabled;
+} DisasContext;
+
+#define IS_USER(s) 1
+
+/* These instructions trap after executing, so defer them until after the
+   conditional executions state has been updated.  */
+#define DISAS_SYSCALL 5
+
+static TCGv_ptr cpu_env;
+static TCGv_i32 cpu_R[32];
+
+/* FIXME:  These should be removed.  */
+static TCGv cpu_F0s, cpu_F1s;
+static TCGv_i64 cpu_F0d, cpu_F1d;
+
+#include "gen-icount.h"
+
+static const char *regnames[] = {
+      "r00", "r01", "r02", "r03", "r04", "r05", "r06", "r07",
+      "r08", "r09", "r10", "r11", "r12", "r13", "r14", "r15",
+      "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+      "r24", "r25", "r26", "r27", "r28", "r29", "r30", "pc" };
+
+/* initialize TCG globals.  */
+void uc32_translate_init(void)
+{
+    int i;
+
+    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+
+    for (i = 0; i < 32; i++) {
+        cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
+                                offsetof(CPUState, regs[i]), regnames[i]);
+    }
+
+#define GEN_HELPER 2
+#include "helper.h"
+}
+
+static int num_temps;
+
+/* Allocate a temporary variable.  */
+static TCGv_i32 new_tmp(void)
+{
+    num_temps++;
+    return tcg_temp_new_i32();
+}
+
+/* Release a temporary variable.  */
+static void dead_tmp(TCGv tmp)
+{
+    tcg_temp_free(tmp);
+    num_temps--;
+}
+
+static inline TCGv load_cpu_offset(int offset)
+{
+    TCGv tmp = new_tmp();
+    tcg_gen_ld_i32(tmp, cpu_env, offset);
+    return tmp;
+}
+
+#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
+
+static inline void store_cpu_offset(TCGv var, int offset)
+{
+    tcg_gen_st_i32(var, cpu_env, offset);
+    dead_tmp(var);
+}
+
+#define store_cpu_field(var, name) \
+    store_cpu_offset(var, offsetof(CPUState, name))
+
+/* Set a variable to the value of a CPU register.  */
+static void load_reg_var(DisasContext *s, TCGv var, int reg)
+{
+    if (reg == 31) {
+        uint32_t addr;
+        /* normaly, since we updated PC */
+        addr = (long)s->pc;
+        tcg_gen_movi_i32(var, addr);
+    } else {
+        tcg_gen_mov_i32(var, cpu_R[reg]);
+    }
+}
+
+/* Create a new temporary and set it to the value of a CPU register.  */
+static inline TCGv load_reg(DisasContext *s, int reg)
+{
+    TCGv tmp = new_tmp();
+    load_reg_var(s, tmp, reg);
+    return tmp;
+}
+
+/* Set a CPU register.  The source must be a temporary and will be
+   marked as dead.  */
+static void store_reg(DisasContext *s, int reg, TCGv var)
+{
+    if (reg == 31) {
+        tcg_gen_andi_i32(var, var, ~3);
+        s->is_jmp = DISAS_JUMP;
+    }
+    tcg_gen_mov_i32(cpu_R[reg], var);
+    dead_tmp(var);
+}
+
+/* Value extensions.  */
+#define gen_uxtb(var)           tcg_gen_ext8u_i32(var, var)
+#define gen_uxth(var)           tcg_gen_ext16u_i32(var, var)
+#define gen_sxtb(var)           tcg_gen_ext8s_i32(var, var)
+#define gen_sxth(var)           tcg_gen_ext16s_i32(var, var)
+
+#define UCOP_REG_M              (((insn) >>  0) & 0x1f)
+#define UCOP_REG_N              (((insn) >> 19) & 0x1f)
+#define UCOP_REG_D              (((insn) >> 14) & 0x1f)
+#define UCOP_REG_S              (((insn) >>  9) & 0x1f)
+#define UCOP_REG_LO             (((insn) >> 14) & 0x1f)
+#define UCOP_REG_HI             (((insn) >>  9) & 0x1f)
+#define UCOP_SH_OP              (((insn) >>  6) & 0x03)
+#define UCOP_SH_IM              (((insn) >>  9) & 0x1f)
+#define UCOP_OPCODES            (((insn) >> 25) & 0x0f)
+#define UCOP_IMM_9              (((insn) >>  0) & 0x1ff)
+#define UCOP_IMM10              (((insn) >>  0) & 0x3ff)
+#define UCOP_IMM14              (((insn) >>  0) & 0x3fff)
+#define UCOP_COND               (((insn) >> 25) & 0x0f)
+#define UCOP_CMOV_COND          (((insn) >> 19) & 0x0f)
+#define UCOP_CPNUM              (((insn) >> 10) & 0x0f)
+#define UCOP_UCF64_FMT          (((insn) >> 24) & 0x03)
+#define UCOP_UCF64_FUNC         (((insn) >>  6) & 0x0f)
+#define UCOP_UCF64_COND         (((insn) >>  6) & 0x0f)
+
+#define UCOP_SET(i)             ((insn) & (1 << (i)))
+#define UCOP_SET_P              UCOP_SET(28)
+#define UCOP_SET_U              UCOP_SET(27)
+#define UCOP_SET_B              UCOP_SET(26)
+#define UCOP_SET_W              UCOP_SET(25)
+#define UCOP_SET_L              UCOP_SET(24)
+#define UCOP_SET_S              UCOP_SET(24)
+
+#define ILLEGAL         cpu_abort(env,                                  \
+                        "Illegal UniCore32 instruction %x at line %d!", \
+                        insn, __LINE__)
+
+static inline void gen_set_asr(TCGv var, uint32_t mask)
+{
+    TCGv tmp_mask = tcg_const_i32(mask);
+    gen_helper_asr_write(var, tmp_mask);
+    tcg_temp_free_i32(tmp_mask);
+}
+/* Set NZCV flags from the high 4 bits of var.  */
+#define gen_set_nzcv(var) gen_set_asr(var, ASR_NZCV)
+
+static void gen_exception(int excp)
+{
+    TCGv tmp = new_tmp();
+    tcg_gen_movi_i32(tmp, excp);
+    gen_helper_exception(tmp);
+    dead_tmp(tmp);
+}
+
+/* FIXME: Most targets have native widening multiplication.
+   It would be good to use that instead of a full wide multiply.  */
+/* 32x32->64 multiply.  Marks inputs as dead.  */
+static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
+{
+    TCGv_i64 tmp1 = tcg_temp_new_i64();
+    TCGv_i64 tmp2 = tcg_temp_new_i64();
+
+    tcg_gen_extu_i32_i64(tmp1, a);
+    dead_tmp(a);
+    tcg_gen_extu_i32_i64(tmp2, b);
+    dead_tmp(b);
+    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
+    tcg_temp_free_i64(tmp2);
+    return tmp1;
+}
+
+static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
+{
+    TCGv_i64 tmp1 = tcg_temp_new_i64();
+    TCGv_i64 tmp2 = tcg_temp_new_i64();
+
+    tcg_gen_ext_i32_i64(tmp1, a);
+    dead_tmp(a);
+    tcg_gen_ext_i32_i64(tmp2, b);
+    dead_tmp(b);
+    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
+    tcg_temp_free_i64(tmp2);
+    return tmp1;
+}
+
+#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
+
+/* Set CF to the top bit of var.  */
+static void gen_set_CF_bit31(TCGv var)
+{
+    TCGv tmp = new_tmp();
+    tcg_gen_shri_i32(tmp, var, 31);
+    gen_set_CF(tmp);
+    dead_tmp(tmp);
+}
+
+/* Set N and Z flags from var.  */
+static inline void gen_logic_CC(TCGv var)
+{
+    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
+    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
+}
+
+/* dest = T0 + T1 + CF. */
+static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
+{
+    TCGv tmp;
+    tcg_gen_add_i32(dest, t0, t1);
+    tmp = load_cpu_field(CF);
+    tcg_gen_add_i32(dest, dest, tmp);
+    dead_tmp(tmp);
+}
+
+/* dest = T0 - T1 + CF - 1.  */
+static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
+{
+    TCGv tmp;
+    tcg_gen_sub_i32(dest, t0, t1);
+    tmp = load_cpu_field(CF);
+    tcg_gen_add_i32(dest, dest, tmp);
+    tcg_gen_subi_i32(dest, dest, 1);
+    dead_tmp(tmp);
+}
+
+static void shifter_out_im(TCGv var, int shift)
+{
+    TCGv tmp = new_tmp();
+    if (shift == 0) {
+        tcg_gen_andi_i32(tmp, var, 1);
+    } else {
+        tcg_gen_shri_i32(tmp, var, shift);
+        if (shift != 31) {
+            tcg_gen_andi_i32(tmp, tmp, 1);
+        }
+    }
+    gen_set_CF(tmp);
+    dead_tmp(tmp);
+}
+
+/* Shift by immediate.  Includes special handling for shift == 0.  */
+static inline void gen_uc32_shift_im(TCGv var, int shiftop, int shift,
+        int flags)
+{
+    switch (shiftop) {
+    case 0: /* LSL */
+        if (shift != 0) {
+            if (flags) {
+                shifter_out_im(var, 32 - shift);
+            }
+            tcg_gen_shli_i32(var, var, shift);
+        }
+        break;
+    case 1: /* LSR */
+        if (shift == 0) {
+            if (flags) {
+                tcg_gen_shri_i32(var, var, 31);
+                gen_set_CF(var);
+            }
+            tcg_gen_movi_i32(var, 0);
+        } else {
+            if (flags) {
+                shifter_out_im(var, shift - 1);
+            }
+            tcg_gen_shri_i32(var, var, shift);
+        }
+        break;
+    case 2: /* ASR */
+        if (shift == 0) {
+            shift = 32;
+        }
+        if (flags) {
+            shifter_out_im(var, shift - 1);
+        }
+        if (shift == 32) {
+            shift = 31;
+        }
+        tcg_gen_sari_i32(var, var, shift);
+        break;
+    case 3: /* ROR/RRX */
+        if (shift != 0) {
+            if (flags) {
+                shifter_out_im(var, shift - 1);
+            }
+            tcg_gen_rotri_i32(var, var, shift); break;
+        } else {
+            TCGv tmp = load_cpu_field(CF);
+            if (flags) {
+                shifter_out_im(var, 0);
+            }
+            tcg_gen_shri_i32(var, var, 1);
+            tcg_gen_shli_i32(tmp, tmp, 31);
+            tcg_gen_or_i32(var, var, tmp);
+            dead_tmp(tmp);
+        }
+    }
+};
+
+static inline void gen_uc32_shift_reg(TCGv var, int shiftop,
+                                     TCGv shift, int flags)
+{
+    if (flags) {
+        switch (shiftop) {
+        case 0:
+            gen_helper_shl_cc(var, var, shift);
+            break;
+        case 1:
+            gen_helper_shr_cc(var, var, shift);
+            break;
+        case 2:
+            gen_helper_sar_cc(var, var, shift);
+            break;
+        case 3:
+            gen_helper_ror_cc(var, var, shift);
+            break;
+        }
+    } else {
+        switch (shiftop) {
+        case 0:
+            gen_helper_shl(var, var, shift);
+            break;
+        case 1:
+            gen_helper_shr(var, var, shift);
+            break;
+        case 2:
+            gen_helper_sar(var, var, shift);
+            break;
+        case 3:
+            tcg_gen_andi_i32(shift, shift, 0x1f);
+            tcg_gen_rotr_i32(var, var, shift);
+            break;
+        }
+    }
+    dead_tmp(shift);
+}
+
+static void gen_test_cc(int cc, int label)
+{
+    TCGv tmp;
+    TCGv tmp2;
+    int inv;
+
+    switch (cc) {
+    case 0: /* eq: Z */
+        tmp = load_cpu_field(ZF);
+        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
+        break;
+    case 1: /* ne: !Z */
+        tmp = load_cpu_field(ZF);
+        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
+        break;
+    case 2: /* cs: C */
+        tmp = load_cpu_field(CF);
+        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
+        break;
+    case 3: /* cc: !C */
+        tmp = load_cpu_field(CF);
+        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
+        break;
+    case 4: /* mi: N */
+        tmp = load_cpu_field(NF);
+        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
+        break;
+    case 5: /* pl: !N */
+        tmp = load_cpu_field(NF);
+        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
+        break;
+    case 6: /* vs: V */
+        tmp = load_cpu_field(VF);
+        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
+        break;
+    case 7: /* vc: !V */
+        tmp = load_cpu_field(VF);
+        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
+        break;
+    case 8: /* hi: C && !Z */
+        inv = gen_new_label();
+        tmp = load_cpu_field(CF);
+        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
+        dead_tmp(tmp);
+        tmp = load_cpu_field(ZF);
+        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
+        gen_set_label(inv);
+        break;
+    case 9: /* ls: !C || Z */
+        tmp = load_cpu_field(CF);
+        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
+        dead_tmp(tmp);
+        tmp = load_cpu_field(ZF);
+        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
+        break;
+    case 10: /* ge: N == V -> N ^ V == 0 */
+        tmp = load_cpu_field(VF);
+        tmp2 = load_cpu_field(NF);
+        tcg_gen_xor_i32(tmp, tmp, tmp2);
+        dead_tmp(tmp2);
+        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
+        break;
+    case 11: /* lt: N != V -> N ^ V != 0 */
+        tmp = load_cpu_field(VF);
+        tmp2 = load_cpu_field(NF);
+        tcg_gen_xor_i32(tmp, tmp, tmp2);
+        dead_tmp(tmp2);
+        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
+        break;
+    case 12: /* gt: !Z && N == V */
+        inv = gen_new_label();
+        tmp = load_cpu_field(ZF);
+        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
+        dead_tmp(tmp);
+        tmp = load_cpu_field(VF);
+        tmp2 = load_cpu_field(NF);
+        tcg_gen_xor_i32(tmp, tmp, tmp2);
+        dead_tmp(tmp2);
+        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
+        gen_set_label(inv);
+        break;
+    case 13: /* le: Z || N != V */
+        tmp = load_cpu_field(ZF);
+        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
+        dead_tmp(tmp);
+        tmp = load_cpu_field(VF);
+        tmp2 = load_cpu_field(NF);
+        tcg_gen_xor_i32(tmp, tmp, tmp2);
+        dead_tmp(tmp2);
+        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
+        break;
+    default:
+        fprintf(stderr, "Bad condition code 0x%x\n", cc);
+        abort();
+    }
+    dead_tmp(tmp);
+}
+
+static const uint8_t table_logic_cc[16] = {
+    1, /* and */    1, /* xor */    0, /* sub */    0, /* rsb */
+    0, /* add */    0, /* adc */    0, /* sbc */    0, /* rsc */
+    1, /* andl */   1, /* xorl */   0, /* cmp */    0, /* cmn */
+    1, /* orr */    1, /* mov */    1, /* bic */    1, /* mvn */
+};
+
+/* Set PC state from an immediate address.  */
+static inline void gen_bx_im(DisasContext *s, uint32_t addr)
+{
+    s->is_jmp = DISAS_UPDATE;
+    tcg_gen_movi_i32(cpu_R[31], addr & ~3);
+}
+
+/* Set PC state from var.  var is marked as dead.  */
+static inline void gen_bx(DisasContext *s, TCGv var)
+{
+    s->is_jmp = DISAS_UPDATE;
+    tcg_gen_andi_i32(cpu_R[31], var, ~3);
+    dead_tmp(var);
+}
+
+static inline void store_reg_bx(DisasContext *s, int reg, TCGv var)
+{
+    store_reg(s, reg, var);
+}
+
+static inline TCGv gen_ld8s(TCGv addr, int index)
+{
+    TCGv tmp = new_tmp();
+    tcg_gen_qemu_ld8s(tmp, addr, index);
+    return tmp;
+}
+
+static inline TCGv gen_ld8u(TCGv addr, int index)
+{
+    TCGv tmp = new_tmp();
+    tcg_gen_qemu_ld8u(tmp, addr, index);
+    return tmp;
+}
+
+static inline TCGv gen_ld16s(TCGv addr, int index)
+{
+    TCGv tmp = new_tmp();
+    tcg_gen_qemu_ld16s(tmp, addr, index);
+    return tmp;
+}
+
+static inline TCGv gen_ld16u(TCGv addr, int index)
+{
+    TCGv tmp = new_tmp();
+    tcg_gen_qemu_ld16u(tmp, addr, index);
+    return tmp;
+}
+
+static inline TCGv gen_ld32(TCGv addr, int index)
+{
+    TCGv tmp = new_tmp();
+    tcg_gen_qemu_ld32u(tmp, addr, index);
+    return tmp;
+}
+
+static inline TCGv_i64 gen_ld64(TCGv addr, int index)
+{
+    TCGv_i64 tmp = tcg_temp_new_i64();
+    tcg_gen_qemu_ld64(tmp, addr, index);
+    return tmp;
+}
+
+static inline void gen_st8(TCGv val, TCGv addr, int index)
+{
+    tcg_gen_qemu_st8(val, addr, index);
+    dead_tmp(val);
+}
+
+static inline void gen_st16(TCGv val, TCGv addr, int index)
+{
+    tcg_gen_qemu_st16(val, addr, index);
+    dead_tmp(val);
+}
+
+static inline void gen_st32(TCGv val, TCGv addr, int index)
+{
+    tcg_gen_qemu_st32(val, addr, index);
+    dead_tmp(val);
+}
+
+static inline void gen_st64(TCGv_i64 val, TCGv addr, int index)
+{
+    tcg_gen_qemu_st64(val, addr, index);
+    tcg_temp_free_i64(val);
+}
+
+static inline void gen_set_pc_im(uint32_t val)
+{
+    tcg_gen_movi_i32(cpu_R[31], val);
+}
+
+/* Force a TB lookup after an instruction that changes the CPU state.  */
+static inline void gen_lookup_tb(DisasContext *s)
+{
+    tcg_gen_movi_i32(cpu_R[31], s->pc & ~1);
+    s->is_jmp = DISAS_UPDATE;
+}
+
+static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
+        TCGv var)
+{
+    int val;
+    TCGv offset;
+
+    if (UCOP_SET(29)) {
+        /* immediate */
+        val = UCOP_IMM14;
+        if (!UCOP_SET_U) {
+            val = -val;
+        }
+        if (val != 0) {
+            tcg_gen_addi_i32(var, var, val);
+        }
+    } else {
+        /* shift/register */
+        offset = load_reg(s, UCOP_REG_M);
+        gen_uc32_shift_im(offset, UCOP_SH_OP, UCOP_SH_IM, 0);
+        if (!UCOP_SET_U) {
+            tcg_gen_sub_i32(var, var, offset);
+        } else {
+            tcg_gen_add_i32(var, var, offset);
+        }
+        dead_tmp(offset);
+    }
+}
+
+static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
+        TCGv var)
+{
+    int val;
+    TCGv offset;
+
+    if (UCOP_SET(26)) {
+        /* immediate */
+        val = (insn & 0x1f) | ((insn >> 4) & 0x3e0);
+        if (!UCOP_SET_U) {
+            val = -val;
+        }
+        if (val != 0) {
+            tcg_gen_addi_i32(var, var, val);
+        }
+    } else {
+        /* register */
+        offset = load_reg(s, UCOP_REG_M);
+        if (!UCOP_SET_U) {
+            tcg_gen_sub_i32(var, var, offset);
+        } else {
+            tcg_gen_add_i32(var, var, offset);
+        }
+        dead_tmp(offset);
+    }
+}
+
+static inline long ucf64_reg_offset(int reg)
+{
+    if (reg & 1) {
+        return offsetof(CPUState, ucf64.regs[reg >> 1])
+          + offsetof(CPU_DoubleU, l.upper);
+    } else {
+        return offsetof(CPUState, ucf64.regs[reg >> 1])
+          + offsetof(CPU_DoubleU, l.lower);
+    }
+}
+
+#define ucf64_gen_ld32(reg)      load_cpu_offset(ucf64_reg_offset(reg))
+#define ucf64_gen_st32(var, reg) store_cpu_offset(var, ucf64_reg_offset(reg))
+
+/* UniCore-F64 single load/store I_offset */
+static void do_ucf64_ldst_i(CPUState *env, DisasContext *s, uint32_t insn)
+{
+    int offset;
+    TCGv tmp;
+    TCGv addr;
+
+    addr = load_reg(s, UCOP_REG_N);
+    if (!UCOP_SET_P && !UCOP_SET_W) {
+        ILLEGAL;
+    }
+
+    if (UCOP_SET_P) {
+        offset = UCOP_IMM10 << 2;
+        if (!UCOP_SET_U) {
+            offset = -offset;
+        }
+        if (offset != 0) {
+            tcg_gen_addi_i32(addr, addr, offset);
+        }
+    }
+
+    if (UCOP_SET_L) { /* load */
+        tmp = gen_ld32(addr, IS_USER(s));
+        ucf64_gen_st32(tmp, UCOP_REG_D);
+    } else { /* store */
+        tmp = ucf64_gen_ld32(UCOP_REG_D);
+        gen_st32(tmp, addr, IS_USER(s));
+    }
+
+    if (!UCOP_SET_P) {
+        offset = UCOP_IMM10 << 2;
+        if (!UCOP_SET_U) {
+            offset = -offset;
+        }
+        if (offset != 0) {
+            tcg_gen_addi_i32(addr, addr, offset);
+        }
+    }
+    if (UCOP_SET_W) {
+        store_reg(s, UCOP_REG_N, addr);
+    } else {
+        dead_tmp(addr);
+    }
+}
+
+/* UniCore-F64 load/store multiple words */
+static void do_ucf64_ldst_m(CPUState *env, DisasContext *s, uint32_t insn)
+{
+    unsigned int i;
+    int j, n, freg;
+    TCGv tmp;
+    TCGv addr;
+
+    if (UCOP_REG_D != 0) {
+        ILLEGAL;
+    }
+    if (UCOP_REG_N == 31) {
+        ILLEGAL;
+    }
+    if ((insn << 24) == 0) {
+        ILLEGAL;
+    }
+
+    addr = load_reg(s, UCOP_REG_N);
+
+    n = 0;
+    for (i = 0; i < 8; i++) {
+        if (UCOP_SET(i)) {
+            n++;
+        }
+    }
+
+    if (UCOP_SET_U) {
+        if (UCOP_SET_P) { /* pre increment */
+            tcg_gen_addi_i32(addr, addr, 4);
+        } /* unnecessary to do anything when post increment */
+    } else {
+        if (UCOP_SET_P) { /* pre decrement */
+            tcg_gen_addi_i32(addr, addr, -(n * 4));
+        } else { /* post decrement */
+            if (n != 1) {
+                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
+            }
+        }
+    }
+
+    freg = ((insn >> 8) & 3) << 3; /* freg should be 0, 8, 16, 24 */
+
+    for (i = 0, j = 0; i < 8; i++, freg++) {
+        if (!UCOP_SET(i)) {
+            continue;
+        }
+
+        if (UCOP_SET_L) { /* load */
+            tmp = gen_ld32(addr, IS_USER(s));
+            ucf64_gen_st32(tmp, freg);
+        } else { /* store */
+            tmp = ucf64_gen_ld32(freg);
+            gen_st32(tmp, addr, IS_USER(s));
+        }
+
+        j++;
+        /* unnecessary to add after the last transfer */
+        if (j != n) {
+            tcg_gen_addi_i32(addr, addr, 4);
+        }
+    }
+
+    if (UCOP_SET_W) { /* write back */
+        if (UCOP_SET_U) {
+            if (!UCOP_SET_P) { /* post increment */
+                tcg_gen_addi_i32(addr, addr, 4);
+            } /* unnecessary to do anything when pre increment */
+        } else {
+            if (UCOP_SET_P) {
+                /* pre decrement */
+                if (n != 1) {
+                    tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
+                }
+            } else {
+                /* post decrement */
+                tcg_gen_addi_i32(addr, addr, -(n * 4));
+            }
+        }
+        store_reg(s, UCOP_REG_N, addr);
+    } else {
+        dead_tmp(addr);
+    }
+}
+
+/* UniCore-F64 mrc/mcr */
+static void do_ucf64_trans(CPUState *env, DisasContext *s, uint32_t insn)
+{
+    TCGv tmp;
+
+    if ((insn & 0xfe0003ff) == 0xe2000000) {
+        /* control register */
+        if ((UCOP_REG_N != UC32_UCF64_FPSCR) || (UCOP_REG_D == 31)) {
+            ILLEGAL;
+        }
+        if (UCOP_SET(24)) {
+            /* CFF */
+            tmp = new_tmp();
+            gen_helper_ucf64_get_fpscr(tmp, cpu_env);
+            store_reg(s, UCOP_REG_D, tmp);
+        } else {
+            /* CTF */
+            tmp = load_reg(s, UCOP_REG_D);
+            gen_helper_ucf64_set_fpscr(cpu_env, tmp);
+            dead_tmp(tmp);
+            gen_lookup_tb(s);
+        }
+        return;
+    }
+    if ((insn & 0xfe0003ff) == 0xe0000000) {
+        /* general register */
+        if (UCOP_REG_D == 31) {
+            ILLEGAL;
+        }
+        if (UCOP_SET(24)) { /* MFF */
+            tmp = ucf64_gen_ld32(UCOP_REG_N);
+            store_reg(s, UCOP_REG_D, tmp);
+        } else { /* MTF */
+            tmp = load_reg(s, UCOP_REG_D);
+            ucf64_gen_st32(tmp, UCOP_REG_N);
+        }
+        return;
+    }
+    if ((insn & 0xfb000000) == 0xe9000000) {
+        /* MFFC */
+        if (UCOP_REG_D != 31) {
+            ILLEGAL;
+        }
+        if (UCOP_UCF64_COND & 0x8) {
+            ILLEGAL;
+        }
+
+        tmp = new_tmp();
+        tcg_gen_movi_i32(tmp, UCOP_UCF64_COND);
+        if (UCOP_SET(26)) {
+            tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_N));
+            tcg_gen_ld_i64(cpu_F1d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
+            gen_helper_ucf64_cmpd(cpu_F0d, cpu_F1d, tmp, cpu_env);
+        } else {
+            tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_N));
+            tcg_gen_ld_i32(cpu_F1s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
+            gen_helper_ucf64_cmps(cpu_F0s, cpu_F1s, tmp, cpu_env);
+        }
+        dead_tmp(tmp);
+        return;
+    }
+    ILLEGAL;
+}
+
+/* UniCore-F64 convert instructions */
+static void do_ucf64_fcvt(CPUState *env, DisasContext *s, uint32_t insn)
+{
+    if (UCOP_UCF64_FMT == 3) {
+        ILLEGAL;
+    }
+    if (UCOP_REG_N != 0) {
+        ILLEGAL;
+    }
+    switch (UCOP_UCF64_FUNC) {
+    case 0: /* cvt.s */
+        switch (UCOP_UCF64_FMT) {
+        case 1 /* d */:
+            tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
+            gen_helper_ucf64_df2sf(cpu_F0s, cpu_F0d, cpu_env);
+            tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
+            break;
+        case 2 /* w */:
+            tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
+            gen_helper_ucf64_si2sf(cpu_F0s, cpu_F0s, cpu_env);
+            tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
+            break;
+        default /* s */:
+            ILLEGAL;
+            break;
+        }
+        break;
+    case 1: /* cvt.d */
+        switch (UCOP_UCF64_FMT) {
+        case 0 /* s */:
+            tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
+            gen_helper_ucf64_sf2df(cpu_F0d, cpu_F0s, cpu_env);
+            tcg_gen_st_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_D));
+            break;
+        case 2 /* w */:
+            tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
+            gen_helper_ucf64_si2df(cpu_F0d, cpu_F0s, cpu_env);
+            tcg_gen_st_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_D));
+            break;
+        default /* d */:
+            ILLEGAL;
+            break;
+        }
+        break;
+    case 4: /* cvt.w */
+        switch (UCOP_UCF64_FMT) {
+        case 0 /* s */:
+            tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
+            gen_helper_ucf64_sf2si(cpu_F0s, cpu_F0s, cpu_env);
+            tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
+            break;
+        case 1 /* d */:
+            tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
+            gen_helper_ucf64_df2si(cpu_F0s, cpu_F0d, cpu_env);
+            tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
+            break;
+    default /* w */:
+            ILLEGAL;
+            break;
+        }
+        break;
+    default:
+        ILLEGAL;
+    }
+}
+
+/* UniCore-F64 compare instructions */
+static void do_ucf64_fcmp(CPUState *env, DisasContext *s, uint32_t insn)
+{
+    if (UCOP_SET(25)) {
+        ILLEGAL;
+    }
+    if (UCOP_REG_D != 0) {
+        ILLEGAL;
+    }
+
+    ILLEGAL; /* TODO */
+    if (UCOP_SET(24)) {
+        tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_N));
+        tcg_gen_ld_i64(cpu_F1d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
+        /* gen_helper_ucf64_cmpd(cpu_F0d, cpu_F1d, cpu_env); */
+    } else {
+        tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_N));
+        tcg_gen_ld_i32(cpu_F1s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
+        /* gen_helper_ucf64_cmps(cpu_F0s, cpu_F1s, cpu_env); */
+    }
+}
+
+#define gen_helper_ucf64_movs(x, y)      do { } while (0)
+#define gen_helper_ucf64_movd(x, y)      do { } while (0)
+
+#define UCF64_OP1(name)    do {                           \
+        if (UCOP_REG_N != 0) {                            \
+            ILLEGAL;                                      \
+        }                                                 \
+        switch (UCOP_UCF64_FMT) {                         \
+        case 0 /* s */:                                   \
+            tcg_gen_ld_i32(cpu_F0s, cpu_env,              \
+                           ucf64_reg_offset(UCOP_REG_M)); \
+            gen_helper_ucf64_##name##s(cpu_F0s, cpu_F0s); \
+            tcg_gen_st_i32(cpu_F0s, cpu_env,              \
+                           ucf64_reg_offset(UCOP_REG_D)); \
+            break;                                        \
+        case 1 /* d */:                                   \
+            tcg_gen_ld_i64(cpu_F0d, cpu_env,              \
+                           ucf64_reg_offset(UCOP_REG_M)); \
+            gen_helper_ucf64_##name##d(cpu_F0d, cpu_F0d); \
+            tcg_gen_st_i64(cpu_F0d, cpu_env,              \
+                           ucf64_reg_offset(UCOP_REG_D)); \
+            break;                                        \
+        case 2 /* w */:                                   \
+            ILLEGAL;                                      \
+            break;                                        \
+        }                                                 \
+    } while (0)
+
+#define UCF64_OP2(name)    do {                           \
+        switch (UCOP_UCF64_FMT) {                         \
+        case 0 /* s */:                                   \
+            tcg_gen_ld_i32(cpu_F0s, cpu_env,              \
+                           ucf64_reg_offset(UCOP_REG_N)); \
+            tcg_gen_ld_i32(cpu_F1s, cpu_env,              \
+                           ucf64_reg_offset(UCOP_REG_M)); \
+            gen_helper_ucf64_##name##s(cpu_F0s,           \
+                           cpu_F0s, cpu_F1s, cpu_env);    \
+            tcg_gen_st_i32(cpu_F0s, cpu_env,              \
+                           ucf64_reg_offset(UCOP_REG_D)); \
+            break;                                        \
+        case 1 /* d */:                                   \
+            tcg_gen_ld_i64(cpu_F0d, cpu_env,              \
+                           ucf64_reg_offset(UCOP_REG_N)); \
+            tcg_gen_ld_i64(cpu_F1d, cpu_env,              \
+                           ucf64_reg_offset(UCOP_REG_M)); \
+            gen_helper_ucf64_##name##d(cpu_F0d,           \
+                           cpu_F0d, cpu_F1d, cpu_env);    \
+            tcg_gen_st_i64(cpu_F0d, cpu_env,              \
+                           ucf64_reg_offset(UCOP_REG_D)); \
+            break;                                        \
+        case 2 /* w */:                                   \
+            ILLEGAL;                                      \
+            break;                                        \
+        }                                                 \
+    } while (0)
+
+/* UniCore-F64 data processing */
+static void do_ucf64_datap(CPUState *env, DisasContext *s, uint32_t insn)
+{
+    if (UCOP_UCF64_FMT == 3) {
+        ILLEGAL;
+    }
+    switch (UCOP_UCF64_FUNC) {
+    case 0: /* add */
+        UCF64_OP2(add);
+        break;
+    case 1: /* sub */
+        UCF64_OP2(sub);
+        break;
+    case 2: /* mul */
+        UCF64_OP2(mul);
+        break;
+    case 4: /* div */
+        UCF64_OP2(div);
+        break;
+    case 5: /* abs */
+        UCF64_OP1(abs);
+        break;
+    case 6: /* mov */
+        UCF64_OP1(mov);
+        break;
+    case 7: /* neg */
+        UCF64_OP1(neg);
+        break;
+    default:
+        ILLEGAL;
+    }
+}
+
+/* Disassemble an F64 instruction */
+static void disas_ucf64_insn(CPUState *env, DisasContext *s, uint32_t insn)
+{
+    if (!UCOP_SET(29)) {
+        if (UCOP_SET(26)) {
+            do_ucf64_ldst_m(env, s, insn);
+        } else {
+            do_ucf64_ldst_i(env, s, insn);
+        }
+    } else {
+        if (UCOP_SET(5)) {
+            switch ((insn >> 26) & 0x3) {
+            case 0:
+                do_ucf64_datap(env, s, insn);
+                break;
+            case 1:
+                ILLEGAL;
+                break;
+            case 2:
+                do_ucf64_fcvt(env, s, insn);
+                break;
+            case 3:
+                do_ucf64_fcmp(env, s, insn);
+                break;
+            }
+        } else {
+            do_ucf64_trans(env, s, insn);
+        }
+    }
+}
+
+static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
+{
+    TranslationBlock *tb;
+
+    tb = s->tb;
+    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
+        tcg_gen_goto_tb(n);
+        gen_set_pc_im(dest);
+        tcg_gen_exit_tb((long)tb + n);
+    } else {
+        gen_set_pc_im(dest);
+        tcg_gen_exit_tb(0);
+    }
+}
+
+static inline void gen_jmp(DisasContext *s, uint32_t dest)
+{
+    if (unlikely(s->singlestep_enabled)) {
+        /* An indirect jump so that we still trigger the debug exception.  */
+        gen_bx_im(s, dest);
+    } else {
+        gen_goto_tb(s, 0, dest);
+        s->is_jmp = DISAS_TB_JUMP;
+    }
+}
+
+static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
+{
+    if (x) {
+        tcg_gen_sari_i32(t0, t0, 16);
+    } else {
+        gen_sxth(t0);
+    }
+    if (y) {
+        tcg_gen_sari_i32(t1, t1, 16);
+    } else {
+        gen_sxth(t1);
+    }
+    tcg_gen_mul_i32(t0, t0, t1);
+}
+
+/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
+static int gen_set_psr(DisasContext *s, uint32_t mask, int bsr, TCGv t0)
+{
+    TCGv tmp;
+    if (bsr) {
+        /* ??? This is also undefined in system mode.  */
+        if (IS_USER(s)) {
+            return 1;
+        }
+
+        tmp = load_cpu_field(bsr);
+        tcg_gen_andi_i32(tmp, tmp, ~mask);
+        tcg_gen_andi_i32(t0, t0, mask);
+        tcg_gen_or_i32(tmp, tmp, t0);
+        store_cpu_field(tmp, bsr);
+    } else {
+        gen_set_asr(t0, mask);
+    }
+    dead_tmp(t0);
+    gen_lookup_tb(s);
+    return 0;
+}
+
+/* Generate an old-style exception return. Marks pc as dead. */
+static void gen_exception_return(DisasContext *s, TCGv pc)
+{
+    TCGv tmp;
+    store_reg(s, 31, pc);
+    tmp = load_cpu_field(bsr);
+    gen_set_asr(tmp, 0xffffffff);
+    dead_tmp(tmp);
+    s->is_jmp = DISAS_UPDATE;
+}
+
+static void disas_coproc_insn(CPUState *env, DisasContext *s, uint32_t insn)
+{
+    switch (UCOP_CPNUM) {
+    case 2:
+        disas_ucf64_insn(env, s, insn);
+        break;
+    default:
+        /* Unknown coprocessor. */
+        cpu_abort(env, "Unknown coprocessor!");
+    }
+}
+
+
+/* Store a 64-bit value to a register pair.  Clobbers val.  */
+static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
+{
+    TCGv tmp;
+    tmp = new_tmp();
+    tcg_gen_trunc_i64_i32(tmp, val);
+    store_reg(s, rlow, tmp);
+    tmp = new_tmp();
+    tcg_gen_shri_i64(val, val, 32);
+    tcg_gen_trunc_i64_i32(tmp, val);
+    store_reg(s, rhigh, tmp);
+}
+
+/* load and add a 64-bit value from a register pair.  */
+static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
+{
+    TCGv_i64 tmp;
+    TCGv tmpl;
+    TCGv tmph;
+
+    /* Load 64-bit value rd:rn.  */
+    tmpl = load_reg(s, rlow);
+    tmph = load_reg(s, rhigh);
+    tmp = tcg_temp_new_i64();
+    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
+    dead_tmp(tmpl);
+    dead_tmp(tmph);
+    tcg_gen_add_i64(val, val, tmp);
+    tcg_temp_free_i64(tmp);
+}
+
+/* data processing instructions */
+static void do_datap(CPUState *env, DisasContext *s, uint32_t insn)
+{
+    TCGv tmp;
+    TCGv tmp2;
+    int logic_cc;
+
+    if (UCOP_OPCODES == 0x0f || UCOP_OPCODES == 0x0d) {
+        if (UCOP_SET(23)) { /* CMOV instructions */
+            if ((UCOP_CMOV_COND == 0xe) || (UCOP_CMOV_COND == 0xf)) {
+                ILLEGAL;
+            }
+            /* if not always execute, we generate a conditional jump to
+               next instruction */
+            s->condlabel = gen_new_label();
+            gen_test_cc(UCOP_CMOV_COND ^ 1, s->condlabel);
+            s->condjmp = 1;
+        }
+    }
+
+    logic_cc = table_logic_cc[UCOP_OPCODES] & (UCOP_SET_S >> 24);
+
+    if (UCOP_SET(29)) {
+        unsigned int val;
+        /* immediate operand */
+        val = UCOP_IMM_9;
+        if (UCOP_SH_IM) {
+            val = (val >> UCOP_SH_IM) | (val << (32 - UCOP_SH_IM));
+        }
+        tmp2 = new_tmp();
+        tcg_gen_movi_i32(tmp2, val);
+        if (logic_cc && UCOP_SH_IM) {
+            gen_set_CF_bit31(tmp2);
+        }
+   } else {
+        /* register */
+        tmp2 = load_reg(s, UCOP_REG_M);
+        if (UCOP_SET(5)) {
+            tmp = load_reg(s, UCOP_REG_S);
+            gen_uc32_shift_reg(tmp2, UCOP_SH_OP, tmp, logic_cc);
+        } else {
+            gen_uc32_shift_im(tmp2, UCOP_SH_OP, UCOP_SH_IM, logic_cc);
+        }
+    }
+
+    if (UCOP_OPCODES != 0x0f && UCOP_OPCODES != 0x0d) {
+        tmp = load_reg(s, UCOP_REG_N);
+    } else {
+        TCGV_UNUSED(tmp);
+    }
+
+    switch (UCOP_OPCODES) {
+    case 0x00:
+        tcg_gen_and_i32(tmp, tmp, tmp2);
+        if (logic_cc) {
+            gen_logic_CC(tmp);
+        }
+        store_reg_bx(s, UCOP_REG_D, tmp);
+        break;
+    case 0x01:
+        tcg_gen_xor_i32(tmp, tmp, tmp2);
+        if (logic_cc) {
+            gen_logic_CC(tmp);
+        }
+        store_reg_bx(s, UCOP_REG_D, tmp);
+        break;
+    case 0x02:
+        if (UCOP_SET_S && UCOP_REG_D == 31) {
+            /* SUBS r31, ... is used for exception return.  */
+            if (IS_USER(s)) {
+                ILLEGAL;
+            }
+            gen_helper_sub_cc(tmp, tmp, tmp2);
+            gen_exception_return(s, tmp);
+        } else {
+            if (UCOP_SET_S) {
+                gen_helper_sub_cc(tmp, tmp, tmp2);
+            } else {
+                tcg_gen_sub_i32(tmp, tmp, tmp2);
+            }
+            store_reg_bx(s, UCOP_REG_D, tmp);
+        }
+        break;
+    case 0x03:
+        if (UCOP_SET_S) {
+            gen_helper_sub_cc(tmp, tmp2, tmp);
+        } else {
+            tcg_gen_sub_i32(tmp, tmp2, tmp);
+        }
+        store_reg_bx(s, UCOP_REG_D, tmp);
+        break;
+    case 0x04:
+        if (UCOP_SET_S) {
+            gen_helper_add_cc(tmp, tmp, tmp2);
+        } else {
+            tcg_gen_add_i32(tmp, tmp, tmp2);
+        }
+        store_reg_bx(s, UCOP_REG_D, tmp);
+        break;
+    case 0x05:
+        if (UCOP_SET_S) {
+            gen_helper_adc_cc(tmp, tmp, tmp2);
+        } else {
+            gen_add_carry(tmp, tmp, tmp2);
+        }
+        store_reg_bx(s, UCOP_REG_D, tmp);
+        break;
+    case 0x06:
+        if (UCOP_SET_S) {
+            gen_helper_sbc_cc(tmp, tmp, tmp2);
+        } else {
+            gen_sub_carry(tmp, tmp, tmp2);
+        }
+        store_reg_bx(s, UCOP_REG_D, tmp);
+        break;
+    case 0x07:
+        if (UCOP_SET_S) {
+            gen_helper_sbc_cc(tmp, tmp2, tmp);
+        } else {
+            gen_sub_carry(tmp, tmp2, tmp);
+        }
+        store_reg_bx(s, UCOP_REG_D, tmp);
+        break;
+    case 0x08:
+        if (UCOP_SET_S) {
+            tcg_gen_and_i32(tmp, tmp, tmp2);
+            gen_logic_CC(tmp);
+        }
+        dead_tmp(tmp);
+        break;
+    case 0x09:
+        if (UCOP_SET_S) {
+            tcg_gen_xor_i32(tmp, tmp, tmp2);
+            gen_logic_CC(tmp);
+        }
+        dead_tmp(tmp);
+        break;
+    case 0x0a:
+        if (UCOP_SET_S) {
+            gen_helper_sub_cc(tmp, tmp, tmp2);
+        }
+        dead_tmp(tmp);
+        break;
+    case 0x0b:
+        if (UCOP_SET_S) {
+            gen_helper_add_cc(tmp, tmp, tmp2);
+        }
+        dead_tmp(tmp);
+        break;
+    case 0x0c:
+        tcg_gen_or_i32(tmp, tmp, tmp2);
+        if (logic_cc) {
+            gen_logic_CC(tmp);
+        }
+        store_reg_bx(s, UCOP_REG_D, tmp);
+        break;
+    case 0x0d:
+        if (logic_cc && UCOP_REG_D == 31) {
+            /* MOVS r31, ... is used for exception return.  */
+            if (IS_USER(s)) {
+                ILLEGAL;
+            }
+            gen_exception_return(s, tmp2);
+        } else {
+            if (logic_cc) {
+                gen_logic_CC(tmp2);
+            }
+            store_reg_bx(s, UCOP_REG_D, tmp2);
+        }
+        break;
+    case 0x0e:
+        tcg_gen_andc_i32(tmp, tmp, tmp2);
+        if (logic_cc) {
+            gen_logic_CC(tmp);
+        }
+        store_reg_bx(s, UCOP_REG_D, tmp);
+        break;
+    default:
+    case 0x0f:
+        tcg_gen_not_i32(tmp2, tmp2);
+        if (logic_cc) {
+            gen_logic_CC(tmp2);
+        }
+        store_reg_bx(s, UCOP_REG_D, tmp2);
+        break;
+    }
+    if (UCOP_OPCODES != 0x0f && UCOP_OPCODES != 0x0d) {
+        dead_tmp(tmp2);
+    }
+}
+
+/* multiply */
+static void do_mult(CPUState *env, DisasContext *s, uint32_t insn)
+{
+    TCGv tmp;
+    TCGv tmp2;
+    TCGv_i64 tmp64;
+
+    if (UCOP_SET(27)) {
+        /* 64 bit mul */
+        tmp = load_reg(s, UCOP_REG_M);
+        tmp2 = load_reg(s, UCOP_REG_N);
+        if (UCOP_SET(26)) {
+            tmp64 = gen_muls_i64_i32(tmp, tmp2);
+        } else {
+            tmp64 = gen_mulu_i64_i32(tmp, tmp2);
+        }
+        if (UCOP_SET(25)) { /* mult accumulate */
+            gen_addq(s, tmp64, UCOP_REG_LO, UCOP_REG_HI);
+        }
+        gen_storeq_reg(s, UCOP_REG_LO, UCOP_REG_HI, tmp64);
+        tcg_temp_free_i64(tmp64);
+    } else {
+        /* 32 bit mul */
+        tmp = load_reg(s, UCOP_REG_M);
+        tmp2 = load_reg(s, UCOP_REG_N);
+        tcg_gen_mul_i32(tmp, tmp, tmp2);
+        dead_tmp(tmp2);
+        if (UCOP_SET(25)) {
+            /* Add */
+            tmp2 = load_reg(s, UCOP_REG_S);
+            tcg_gen_add_i32(tmp, tmp, tmp2);
+            dead_tmp(tmp2);
+        }
+        if (UCOP_SET_S) {
+            gen_logic_CC(tmp);
+        }
+        store_reg(s, UCOP_REG_D, tmp);
+    }
+}
+
+/* miscellaneous instructions */
+static void do_misc(CPUState *env, DisasContext *s, uint32_t insn)
+{
+    unsigned int val;
+    TCGv tmp;
+
+    if ((insn & 0xffffffe0) == 0x10ffc120) {
+        /* Trivial implementation equivalent to bx.  */
+        tmp = load_reg(s, UCOP_REG_M);
+        gen_bx(s, tmp);
+        return;
+    }
+
+    if ((insn & 0xfbffc000) == 0x30ffc000) {
+        /* PSR = immediate */
+        val = UCOP_IMM_9;
+        if (UCOP_SH_IM) {
+            val = (val >> UCOP_SH_IM) | (val << (32 - UCOP_SH_IM));
+        }
+        tmp = new_tmp();
+        tcg_gen_movi_i32(tmp, val);
+        if (gen_set_psr(s, ~ASR_RESERVED, UCOP_SET_B, tmp)) {
+            ILLEGAL;
+        }
+        return;
+    }
+
+    if ((insn & 0xfbffffe0) == 0x12ffc020) {
+        /* PSR.flag = reg */
+        tmp = load_reg(s, UCOP_REG_M);
+        if (gen_set_psr(s, ASR_NZCV, UCOP_SET_B, tmp)) {
+            ILLEGAL;
+        }
+        return;
+    }
+
+    if ((insn & 0xfbffffe0) == 0x10ffc020) {
+        /* PSR = reg */
+        tmp = load_reg(s, UCOP_REG_M);
+        if (gen_set_psr(s, ~ASR_RESERVED, UCOP_SET_B, tmp)) {
+            ILLEGAL;
+        }
+        return;
+    }
+
+    if ((insn & 0xfbf83fff) == 0x10f80000) {
+        /* reg = PSR */
+        if (UCOP_SET_B) {
+            if (IS_USER(s)) {
+                ILLEGAL;
+            }
+            tmp = load_cpu_field(bsr);
+        } else {
+            tmp = new_tmp();
+            gen_helper_asr_read(tmp);
+        }
+        store_reg(s, UCOP_REG_D, tmp);
+        return;
+    }
+
+    if ((insn & 0xfbf83fe0) == 0x12f80120) {
+        /* clz */
+        tmp = load_reg(s, UCOP_REG_M);
+        if (UCOP_SET(26)) {
+            gen_helper_clo(tmp, tmp);
+        } else {
+            gen_helper_clz(tmp, tmp);
+        }
+        store_reg(s, UCOP_REG_D, tmp);
+        return;
+    }
+
+    /* otherwise */
+    ILLEGAL;
+}
+
+/* load/store I_offset and R_offset */
+static void do_ldst_ir(CPUState *env, DisasContext *s, uint32_t insn)
+{
+    unsigned int i;
+    TCGv tmp;
+    TCGv tmp2;
+
+    tmp2 = load_reg(s, UCOP_REG_N);
+    i = (IS_USER(s) || (!UCOP_SET_P && UCOP_SET_W));
+
+    /* immediate */
+    if (UCOP_SET_P) {
+        gen_add_data_offset(s, insn, tmp2);
+    }
+
+    if (UCOP_SET_L) {
+        /* load */
+        if (UCOP_SET_B) {
+            tmp = gen_ld8u(tmp2, i);
+        } else {
+            tmp = gen_ld32(tmp2, i);
+        }
+    } else {
+        /* store */
+        tmp = load_reg(s, UCOP_REG_D);
+        if (UCOP_SET_B) {
+            gen_st8(tmp, tmp2, i);
+        } else {
+            gen_st32(tmp, tmp2, i);
+        }
+    }
+    if (!UCOP_SET_P) {
+        gen_add_data_offset(s, insn, tmp2);
+        store_reg(s, UCOP_REG_N, tmp2);
+    } else if (UCOP_SET_W) {
+        store_reg(s, UCOP_REG_N, tmp2);
+    } else {
+        dead_tmp(tmp2);
+    }
+    if (UCOP_SET_L) {
+        /* Complete the load.  */
+        if (UCOP_REG_D == 31) {
+            gen_bx(s, tmp);
+        } else {
+            store_reg(s, UCOP_REG_D, tmp);
+        }
+    }
+}
+
+/* SWP instruction */
+static void do_swap(CPUState *env, DisasContext *s, uint32_t insn)
+{
+    TCGv addr;
+    TCGv tmp;
+    TCGv tmp2;
+
+    if ((insn & 0xff003fe0) != 0x40000120) {
+        ILLEGAL;
+    }
+
+    /* ??? This is not really atomic.  However we know
+       we never have multiple CPUs running in parallel,
+       so it is good enough.  */
+    addr = load_reg(s, UCOP_REG_N);
+    tmp = load_reg(s, UCOP_REG_M);
+    if (UCOP_SET_B) {
+        tmp2 = gen_ld8u(addr, IS_USER(s));
+        gen_st8(tmp, addr, IS_USER(s));
+    } else {
+        tmp2 = gen_ld32(addr, IS_USER(s));
+        gen_st32(tmp, addr, IS_USER(s));
+    }
+    dead_tmp(addr);
+    store_reg(s, UCOP_REG_D, tmp2);
+}
+
+/* load/store hw/sb */
+static void do_ldst_hwsb(CPUState *env, DisasContext *s, uint32_t insn)
+{
+    TCGv addr;
+    TCGv tmp;
+
+    if (UCOP_SH_OP == 0) {
+        do_swap(env, s, insn);
+        return;
+    }
+
+    addr = load_reg(s, UCOP_REG_N);
+    if (UCOP_SET_P) {
+        gen_add_datah_offset(s, insn, addr);
+    }
+
+    if (UCOP_SET_L) { /* load */
+        switch (UCOP_SH_OP) {
+        case 1:
+            tmp = gen_ld16u(addr, IS_USER(s));
+            break;
+        case 2:
+            tmp = gen_ld8s(addr, IS_USER(s));
+            break;
+        default: /* see do_swap */
+        case 3:
+            tmp = gen_ld16s(addr, IS_USER(s));
+            break;
+        }
+    } else { /* store */
+        if (UCOP_SH_OP != 1) {
+            ILLEGAL;
+        }
+        tmp = load_reg(s, UCOP_REG_D);
+        gen_st16(tmp, addr, IS_USER(s));
+    }
+    /* Perform base writeback before the loaded value to
+       ensure correct behavior with overlapping index registers. */
+    if (!UCOP_SET_P) {
+        gen_add_datah_offset(s, insn, addr);
+        store_reg(s, UCOP_REG_N, addr);
+    } else if (UCOP_SET_W) {
+        store_reg(s, UCOP_REG_N, addr);
+    } else {
+        dead_tmp(addr);
+    }
+    if (UCOP_SET_L) {
+        /* Complete the load.  */
+        store_reg(s, UCOP_REG_D, tmp);
+    }
+}
+
+/* load/store multiple words */
+static void do_ldst_m(CPUState *env, DisasContext *s, uint32_t insn)
+{
+    unsigned int val, i;
+    int j, n, reg, user, loaded_base;
+    TCGv tmp;
+    TCGv tmp2;
+    TCGv addr;
+    TCGv loaded_var;
+
+    if (UCOP_SET(7)) {
+        ILLEGAL;
+    }
+    /* XXX: store correct base if write back */
+    user = 0;
+    if (UCOP_SET_B) { /* S bit in instruction table */
+        if (IS_USER(s)) {
+            ILLEGAL; /* only usable in supervisor mode */
+        }
+        if (UCOP_SET(18) == 0) { /* pc reg */
+            user = 1;
+        }
+    }
+
+    addr = load_reg(s, UCOP_REG_N);
+
+    /* compute total size */
+    loaded_base = 0;
+    TCGV_UNUSED(loaded_var);
+    n = 0;
+    for (i = 0; i < 6; i++) {
+        if (UCOP_SET(i)) {
+            n++;
+        }
+    }
+    for (i = 9; i < 19; i++) {
+        if (UCOP_SET(i)) {
+            n++;
+        }
+    }
+    /* XXX: test invalid n == 0 case ? */
+    if (UCOP_SET_U) {
+        if (UCOP_SET_P) {
+            /* pre increment */
+            tcg_gen_addi_i32(addr, addr, 4);
+        } else {
+            /* post increment */
+        }
+    } else {
+        if (UCOP_SET_P) {
+            /* pre decrement */
+            tcg_gen_addi_i32(addr, addr, -(n * 4));
+        } else {
+            /* post decrement */
+            if (n != 1) {
+                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
+            }
+        }
+    }
+
+    j = 0;
+    reg = UCOP_SET(6) ? 16 : 0;
+    for (i = 0; i < 19; i++, reg++) {
+        if (i == 6) {
+            i = i + 3;
+        }
+        if (UCOP_SET(i)) {
+            if (UCOP_SET_L) { /* load */
+                tmp = gen_ld32(addr, IS_USER(s));
+                if (reg == 31) {
+                    gen_bx(s, tmp);
+                } else if (user) {
+                    tmp2 = tcg_const_i32(reg);
+                    gen_helper_set_user_reg(tmp2, tmp);
+                    tcg_temp_free_i32(tmp2);
+                    dead_tmp(tmp);
+                } else if (reg == UCOP_REG_N) {
+                    loaded_var = tmp;
+                    loaded_base = 1;
+                } else {
+                    store_reg(s, reg, tmp);
+                }
+            } else { /* store */
+                if (reg == 31) {
+                    /* special case: r31 = PC + 4 */
+                    val = (long)s->pc;
+                    tmp = new_tmp();
+                    tcg_gen_movi_i32(tmp, val);
+                } else if (user) {
+                    tmp = new_tmp();
+                    tmp2 = tcg_const_i32(reg);
+                    gen_helper_get_user_reg(tmp, tmp2);
+                    tcg_temp_free_i32(tmp2);
+                } else {
+                    tmp = load_reg(s, reg);
+                }
+                gen_st32(tmp, addr, IS_USER(s));
+            }
+            j++;
+            /* no need to add after the last transfer */
+            if (j != n) {
+                tcg_gen_addi_i32(addr, addr, 4);
+            }
+        }
+    }
+    if (UCOP_SET_W) { /* write back */
+        if (UCOP_SET_U) {
+            if (UCOP_SET_P) {
+                /* pre increment */
+            } else {
+                /* post increment */
+                tcg_gen_addi_i32(addr, addr, 4);
+            }
+        } else {
+            if (UCOP_SET_P) {
+                /* pre decrement */
+                if (n != 1) {
+                    tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
+                }
+            } else {
+                /* post decrement */
+                tcg_gen_addi_i32(addr, addr, -(n * 4));
+            }
+        }
+        store_reg(s, UCOP_REG_N, addr);
+    } else {
+        dead_tmp(addr);
+    }
+    if (loaded_base) {
+        store_reg(s, UCOP_REG_N, loaded_var);
+    }
+    if (UCOP_SET_B && !user) {
+        /* Restore ASR from BSR.  */
+        tmp = load_cpu_field(bsr);
+        gen_set_asr(tmp, 0xffffffff);
+        dead_tmp(tmp);
+        s->is_jmp = DISAS_UPDATE;
+    }
+}
+
+/* branch (and link) */
+static void do_branch(CPUState *env, DisasContext *s, uint32_t insn)
+{
+    unsigned int val;
+    int32_t offset;
+    TCGv tmp;
+
+    if (UCOP_COND == 0xf) {
+        ILLEGAL;
+    }
+
+    if (UCOP_COND != 0xe) {
+        /* if not always execute, we generate a conditional jump to
+           next instruction */
+        s->condlabel = gen_new_label();
+        gen_test_cc(UCOP_COND ^ 1, s->condlabel);
+        s->condjmp = 1;
+    }
+
+    val = (int32_t)s->pc;
+    if (UCOP_SET_L) {
+        tmp = new_tmp();
+        tcg_gen_movi_i32(tmp, val);
+        store_reg(s, 30, tmp);
+    }
+    offset = (((int32_t)insn << 8) >> 8);
+    val += (offset << 2); /* unicore is pc+4 */
+    gen_jmp(s, val);
+}
+
+static void disas_uc32_insn(CPUState *env, DisasContext *s)
+{
+    unsigned int insn;
+
+    insn = ldl_code(s->pc);
+    s->pc += 4;
+
+    /* UniCore instructions class:
+     * AAAB BBBC xxxx xxxx xxxx xxxD xxEx xxxx
+     * AAA  : see switch case
+     * BBBB : opcodes or cond or PUBW
+     * C    : S OR L
+     * D    : 8
+     * E    : 5
+     */
+    switch (insn >> 29) {
+    case 0b000:
+        if (UCOP_SET(5) && UCOP_SET(8) && !UCOP_SET(28)) {
+            do_mult(env, s, insn);
+            break;
+        }
+
+        if (UCOP_SET(8)) {
+            do_misc(env, s, insn);
+            break;
+        }
+    case 0b001:
+        if (((UCOP_OPCODES >> 2) == 2) && !UCOP_SET_S) {
+            do_misc(env, s, insn);
+            break;
+        }
+        do_datap(env, s, insn);
+        break;
+
+    case 0b010:
+        if (UCOP_SET(8) && UCOP_SET(5)) {
+            do_ldst_hwsb(env, s, insn);
+            break;
+        }
+        if (UCOP_SET(8) || UCOP_SET(5)) {
+            ILLEGAL;
+        }
+    case 0b011:
+        do_ldst_ir(env, s, insn);
+        break;
+
+    case 0b100:
+        if (UCOP_SET(8)) {
+            ILLEGAL; /* extended instructions */
+        }
+        do_ldst_m(env, s, insn);
+        break;
+    case 0b101:
+        do_branch(env, s, insn);
+        break;
+    case 0b110:
+        /* Coprocessor.  */
+        disas_coproc_insn(env, s, insn);
+        break;
+    case 0b111:
+        if (!UCOP_SET(28)) {
+            disas_coproc_insn(env, s, insn);
+            break;
+        }
+        if ((insn & 0xff000000) == 0xff000000) { /* syscall */
+            gen_set_pc_im(s->pc);
+            s->is_jmp = DISAS_SYSCALL;
+            break;
+        }
+        ILLEGAL;
+    }
+
+    return;
+}
+
+/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
+   basic block 'tb'. If search_pc is TRUE, also generate PC
+   information for each intermediate instruction. */
+static inline void gen_intermediate_code_internal(CPUState *env,
+        TranslationBlock *tb, int search_pc)
+{
+    DisasContext dc1, *dc = &dc1;
+    CPUBreakpoint *bp;
+    uint16_t *gen_opc_end;
+    int j, lj;
+    target_ulong pc_start;
+    uint32_t next_page_start;
+    int num_insns;
+    int max_insns;
+
+    /* generate intermediate code */
+    num_temps = 0;
+
+    pc_start = tb->pc;
+
+    dc->tb = tb;
+
+    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+
+    dc->is_jmp = DISAS_NEXT;
+    dc->pc = pc_start;
+    dc->singlestep_enabled = env->singlestep_enabled;
+    dc->condjmp = 0;
+    cpu_F0s = tcg_temp_new_i32();
+    cpu_F1s = tcg_temp_new_i32();
+    cpu_F0d = tcg_temp_new_i64();
+    cpu_F1d = tcg_temp_new_i64();
+    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
+    lj = -1;
+    num_insns = 0;
+    max_insns = tb->cflags & CF_COUNT_MASK;
+    if (max_insns == 0) {
+        max_insns = CF_COUNT_MASK;
+    }
+
+    gen_icount_start();
+    do {
+        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
+            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
+                if (bp->pc == dc->pc) {
+                    gen_set_pc_im(dc->pc);
+                    gen_exception(EXCP_DEBUG);
+                    dc->is_jmp = DISAS_JUMP;
+                    /* Advance PC so that clearing the breakpoint will
+                       invalidate this TB.  */
+                    dc->pc += 2; /* FIXME */
+                    goto done_generating;
+                    break;
+                }
+            }
+        }
+        if (search_pc) {
+            j = gen_opc_ptr - gen_opc_buf;
+            if (lj < j) {
+                lj++;
+                while (lj < j) {
+                    gen_opc_instr_start[lj++] = 0;
+                }
+            }
+            gen_opc_pc[lj] = dc->pc;
+            gen_opc_instr_start[lj] = 1;
+            gen_opc_icount[lj] = num_insns;
+        }
+
+        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
+            gen_io_start();
+        }
+
+        disas_uc32_insn(env, dc);
+
+        if (num_temps) {
+            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
+            num_temps = 0;
+        }
+
+        if (dc->condjmp && !dc->is_jmp) {
+            gen_set_label(dc->condlabel);
+            dc->condjmp = 0;
+        }
+        /* Translation stops when a conditional branch is encountered.
+         * Otherwise the subsequent code could get translated several times.
+         * Also stop translation when a page boundary is reached.  This
+         * ensures prefetch aborts occur at the right place.  */
+        num_insns++;
+    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
+             !env->singlestep_enabled &&
+             !singlestep &&
+             dc->pc < next_page_start &&
+             num_insns < max_insns);
+
+    if (tb->cflags & CF_LAST_IO) {
+        if (dc->condjmp) {
+            /* FIXME:  This can theoretically happen with self-modifying
+               code.  */
+            cpu_abort(env, "IO on conditional branch instruction");
+        }
+        gen_io_end();
+    }
+
+    /* At this stage dc->condjmp will only be set when the skipped
+       instruction was a conditional branch or trap, and the PC has
+       already been written.  */
+    if (unlikely(env->singlestep_enabled)) {
+        /* Make sure the pc is updated, and raise a debug exception.  */
+        if (dc->condjmp) {
+            if (dc->is_jmp == DISAS_SYSCALL) {
+                gen_exception(UC32_EXCP_PRIV);
+            } else {
+                gen_exception(EXCP_DEBUG);
+            }
+            gen_set_label(dc->condlabel);
+        }
+        if (dc->condjmp || !dc->is_jmp) {
+            gen_set_pc_im(dc->pc);
+            dc->condjmp = 0;
+        }
+        if (dc->is_jmp == DISAS_SYSCALL && !dc->condjmp) {
+            gen_exception(UC32_EXCP_PRIV);
+        } else {
+            gen_exception(EXCP_DEBUG);
+        }
+    } else {
+        /* While branches must always occur at the end of an IT block,
+           there are a few other things that can cause us to terminate
+           the TB in the middel of an IT block:
+            - Exception generating instructions (bkpt, swi, undefined).
+            - Page boundaries.
+            - Hardware watchpoints.
+           Hardware breakpoints have already been handled and skip this code.
+         */
+        switch (dc->is_jmp) {
+        case DISAS_NEXT:
+            gen_goto_tb(dc, 1, dc->pc);
+            break;
+        default:
+        case DISAS_JUMP:
+        case DISAS_UPDATE:
+            /* indicate that the hash table must be used to find the next TB */
+            tcg_gen_exit_tb(0);
+            break;
+        case DISAS_TB_JUMP:
+            /* nothing more to generate */
+            break;
+        case DISAS_SYSCALL:
+            gen_exception(UC32_EXCP_PRIV);
+            break;
+        }
+        if (dc->condjmp) {
+            gen_set_label(dc->condlabel);
+            gen_goto_tb(dc, 1, dc->pc);
+            dc->condjmp = 0;
+        }
+    }
+
+done_generating:
+    gen_icount_end(tb, num_insns);
+    *gen_opc_ptr = INDEX_op_end;
+
+#ifdef DEBUG_DISAS
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
+        qemu_log("----------------\n");
+        qemu_log("IN: %s\n", lookup_symbol(pc_start));
+        log_target_disas(pc_start, dc->pc - pc_start, 0);
+        qemu_log("\n");
+    }
+#endif
+    if (search_pc) {
+        j = gen_opc_ptr - gen_opc_buf;
+        lj++;
+        while (lj <= j) {
+            gen_opc_instr_start[lj++] = 0;
+        }
+    } else {
+        tb->size = dc->pc - pc_start;
+        tb->icount = num_insns;
+    }
+}
+
+void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
+{
+    gen_intermediate_code_internal(env, tb, 0);
+}
+
+void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
+{
+    gen_intermediate_code_internal(env, tb, 1);
+}
+
+static const char *cpu_mode_names[16] = {
+    "USER", "REAL", "INTR", "PRIV", "UM14", "UM15", "UM16", "TRAP",
+    "UM18", "UM19", "UM1A", "EXTN", "UM1C", "UM1D", "UM1E", "SUSR"
+};
+
+#define UCF64_DUMP_STATE
+void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
+        int flags)
+{
+    int i;
+#ifdef UCF64_DUMP_STATE
+    union {
+        uint32_t i;
+        float s;
+    } s0, s1;
+    CPU_DoubleU d;
+    /* ??? This assumes float64 and double have the same layout.
+       Oh well, it's only debug dumps.  */
+    union {
+        float64 f64;
+        double d;
+    } d0;
+#endif
+    uint32_t psr;
+
+    for (i = 0; i < 32; i++) {
+        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
+        if ((i % 4) == 3) {
+            cpu_fprintf(f, "\n");
+        } else {
+            cpu_fprintf(f, " ");
+        }
+    }
+    psr = cpu_asr_read(env);
+    cpu_fprintf(f, "PSR=%08x %c%c%c%c %s\n",
+                psr,
+                psr & (1 << 31) ? 'N' : '-',
+                psr & (1 << 30) ? 'Z' : '-',
+                psr & (1 << 29) ? 'C' : '-',
+                psr & (1 << 28) ? 'V' : '-',
+                cpu_mode_names[psr & 0xf]);
+
+#ifdef UCF64_DUMP_STATE
+    for (i = 0; i < 16; i++) {
+        d.d = env->ucf64.regs[i];
+        s0.i = d.l.lower;
+        s1.i = d.l.upper;
+        d0.f64 = d.d;
+        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%" PRIx64 "(%8g)\n",
+                    i * 2, (int)s0.i, s0.s,
+                    i * 2 + 1, (int)s1.i, s1.s,
+                    i, (uint64_t)d0.f64, d0.d);
+    }
+    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->ucf64.xregs[UC32_UCF64_FPSCR]);
+#endif
+}
+
+void gen_pc_load(CPUState *env, TranslationBlock *tb,
+        unsigned long searched_pc, int pc_pos, void *puc)
+{
+    env->regs[31] = gen_opc_pc[pc_pos];
+}

From 8b5d487d4d35a1a18c3ac48f3dd367fb769592b2 Mon Sep 17 00:00:00 2001
From: Guan Xuetao <gxt@mprc.pku.edu.cn>
Date: Tue, 12 Apr 2011 16:26:27 +0800
Subject: [PATCH 153/386] unicore32: add necessry headers in
 linux-user/unicore32 for unicore32 support

Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 linux-user/unicore32/syscall.h       |  55 ++++
 linux-user/unicore32/syscall_nr.h    | 371 +++++++++++++++++++++++++++
 linux-user/unicore32/target_signal.h |  26 ++
 linux-user/unicore32/termbits.h      |   2 +
 4 files changed, 454 insertions(+)
 create mode 100644 linux-user/unicore32/syscall.h
 create mode 100644 linux-user/unicore32/syscall_nr.h
 create mode 100644 linux-user/unicore32/target_signal.h
 create mode 100644 linux-user/unicore32/termbits.h

diff --git a/linux-user/unicore32/syscall.h b/linux-user/unicore32/syscall.h
new file mode 100644
index 0000000000..010cdd896e
--- /dev/null
+++ b/linux-user/unicore32/syscall.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010-2011 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __UC32_SYSCALL_H__
+#define __UC32_SYSCALL_H__
+struct target_pt_regs {
+    abi_ulong uregs[34];
+};
+
+#define UC32_REG_pc             uregs[31]
+#define UC32_REG_lr             uregs[30]
+#define UC32_REG_sp             uregs[29]
+#define UC32_REG_ip             uregs[28]
+#define UC32_REG_fp             uregs[27]
+#define UC32_REG_26             uregs[26]
+#define UC32_REG_25             uregs[25]
+#define UC32_REG_24             uregs[24]
+#define UC32_REG_23             uregs[23]
+#define UC32_REG_22             uregs[22]
+#define UC32_REG_21             uregs[21]
+#define UC32_REG_20             uregs[20]
+#define UC32_REG_19             uregs[19]
+#define UC32_REG_18             uregs[18]
+#define UC32_REG_17             uregs[17]
+#define UC32_REG_16             uregs[16]
+#define UC32_REG_15             uregs[15]
+#define UC32_REG_14             uregs[14]
+#define UC32_REG_13             uregs[13]
+#define UC32_REG_12             uregs[12]
+#define UC32_REG_11             uregs[11]
+#define UC32_REG_10             uregs[10]
+#define UC32_REG_09             uregs[9]
+#define UC32_REG_08             uregs[8]
+#define UC32_REG_07             uregs[7]
+#define UC32_REG_06             uregs[6]
+#define UC32_REG_05             uregs[5]
+#define UC32_REG_04             uregs[4]
+#define UC32_REG_03             uregs[3]
+#define UC32_REG_02             uregs[2]
+#define UC32_REG_01             uregs[1]
+#define UC32_REG_00             uregs[0]
+#define UC32_REG_asr            uregs[32]
+#define UC32_REG_ORIG_00        uregs[33]
+
+#define UC32_SYSCALL_BASE               0x900000
+#define UC32_SYSCALL_ARCH_BASE          0xf0000
+#define UC32_SYSCALL_NR_set_tls         (UC32_SYSCALL_ARCH_BASE + 5)
+
+#define UNAME_MACHINE "UniCore-II"
+
+#endif /* __UC32_SYSCALL_H__ */
diff --git a/linux-user/unicore32/syscall_nr.h b/linux-user/unicore32/syscall_nr.h
new file mode 100644
index 0000000000..9c72d84d80
--- /dev/null
+++ b/linux-user/unicore32/syscall_nr.h
@@ -0,0 +1,371 @@
+/*
+ * This file contains the system call numbers for UniCore32 oldabi.
+ *
+ * Copyright (C) 2010-2011 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define TARGET_NR_restart_syscall               0
+#define TARGET_NR_exit                          1
+#define TARGET_NR_fork                          2
+#define TARGET_NR_read                          3
+#define TARGET_NR_write                         4
+#define TARGET_NR_open                          5
+#define TARGET_NR_close                         6
+#define TARGET_NR_waitpid                       7
+#define TARGET_NR_creat                         8
+#define TARGET_NR_link                          9
+#define TARGET_NR_unlink                        10
+#define TARGET_NR_execve                        11
+#define TARGET_NR_chdir                         12
+#define TARGET_NR_time                          13
+#define TARGET_NR_mknod                         14
+#define TARGET_NR_chmod                         15
+#define TARGET_NR_lchown                        16
+#define TARGET_NR_break                         17
+                                                /* 18 */
+#define TARGET_NR_lseek                         19
+#define TARGET_NR_getpid                        20
+#define TARGET_NR_mount                         21
+#define TARGET_NR_umount                        22
+#define TARGET_NR_setuid                        23
+#define TARGET_NR_getuid                        24
+#define TARGET_NR_stime                         25
+#define TARGET_NR_ptrace                        26
+#define TARGET_NR_alarm                         27
+                                                /* 28 */
+#define TARGET_NR_pause                         29
+#define TARGET_NR_utime                         30
+#define TARGET_NR_stty                          31
+#define TARGET_NR_gtty                          32
+#define TARGET_NR_access                        33
+#define TARGET_NR_nice                          34
+#define TARGET_NR_ftime                         35
+#define TARGET_NR_sync                          36
+#define TARGET_NR_kill                          37
+#define TARGET_NR_rename                        38
+#define TARGET_NR_mkdir                         39
+#define TARGET_NR_rmdir                         40
+#define TARGET_NR_dup                           41
+#define TARGET_NR_pipe                          42
+#define TARGET_NR_times                         43
+#define TARGET_NR_prof                          44
+#define TARGET_NR_brk                           45
+#define TARGET_NR_setgid                        46
+#define TARGET_NR_getgid                        47
+#define TARGET_NR_signal                        48
+#define TARGET_NR_geteuid                       49
+#define TARGET_NR_getegid                       50
+#define TARGET_NR_acct                          51
+#define TARGET_NR_umount2                       52
+#define TARGET_NR_lock                          53
+#define TARGET_NR_ioctl                         54
+#define TARGET_NR_fcntl                         55
+#define TARGET_NR_mpx                           56
+#define TARGET_NR_setpgid                       57
+#define TARGET_NR_ulimit                        58
+                                                /* 59 */
+#define TARGET_NR_umask                         60
+#define TARGET_NR_chroot                        61
+#define TARGET_NR_ustat                         62
+#define TARGET_NR_dup2                          63
+#define TARGET_NR_getppid                       64
+#define TARGET_NR_getpgrp                       65
+#define TARGET_NR_setsid                        66
+#define TARGET_NR_sigaction                     67
+#define TARGET_NR_sgetmask                      68
+#define TARGET_NR_ssetmask                      69
+#define TARGET_NR_setreuid                      70
+#define TARGET_NR_setregid                      71
+#define TARGET_NR_sigsuspend                    72
+#define TARGET_NR_sigpending                    73
+#define TARGET_NR_sethostname                   74
+#define TARGET_NR_setrlimit                     75
+#define TARGET_NR_getrlimit                     76
+#define TARGET_NR_getrusage                     77
+#define TARGET_NR_gettimeofday                  78
+#define TARGET_NR_settimeofday                  79
+#define TARGET_NR_getgroups                     80
+#define TARGET_NR_setgroups                     81
+#define TARGET_NR_select                        82
+#define TARGET_NR_symlink                       83
+                                                /* 84 */
+#define TARGET_NR_readlink                      85
+#define TARGET_NR_uselib                        86
+#define TARGET_NR_swapon                        87
+#define TARGET_NR_reboot                        88
+#define TARGET_NR_readdir                       89
+#define TARGET_NR_mmap                          90
+#define TARGET_NR_munmap                        91
+#define TARGET_NR_truncate                      92
+#define TARGET_NR_ftruncate                     93
+#define TARGET_NR_fchmod                        94
+#define TARGET_NR_fchown                        95
+#define TARGET_NR_getpriority                   96
+#define TARGET_NR_setpriority                   97
+#define TARGET_NR_profil                        98
+#define TARGET_NR_statfs                        99
+#define TARGET_NR_fstatfs                       100
+#define TARGET_NR_ioperm                        101
+#define TARGET_NR_socketcall                    102
+#define TARGET_NR_syslog                        103
+#define TARGET_NR_setitimer                     104
+#define TARGET_NR_getitimer                     105
+#define TARGET_NR_stat                          106
+#define TARGET_NR_lstat                         107
+#define TARGET_NR_fstat                         108
+                                                /* 109 */
+                                                /* 110 */
+#define TARGET_NR_vhangup                       111
+#define TARGET_NR_idle                          112
+#define TARGET_NR_syscall                       113
+#define TARGET_NR_wait4                         114
+#define TARGET_NR_swapoff                       115
+#define TARGET_NR_sysinfo                       116
+#define TARGET_NR_ipc                           117
+#define TARGET_NR_fsync                         118
+#define TARGET_NR_sigreturn                     119
+#define TARGET_NR_clone                         120
+#define TARGET_NR_setdomainname                 121
+#define TARGET_NR_uname                         122
+#define TARGET_NR_modify_ldt                    123
+#define TARGET_NR_adjtimex                      124
+#define TARGET_NR_mprotect                      125
+#define TARGET_NR_sigprocmask                   126
+#define TARGET_NR_create_module                 127
+#define TARGET_NR_init_module                   128
+#define TARGET_NR_delete_module                 129
+#define TARGET_NR_get_kernel_syms               130
+#define TARGET_NR_quotactl                      131
+#define TARGET_NR_getpgid                       132
+#define TARGET_NR_fchdir                        133
+#define TARGET_NR_bdflush                       134
+#define TARGET_NR_sysfs                         135
+#define TARGET_NR_personality                   136
+#define TARGET_NR_afs_syscall                   137
+#define TARGET_NR_setfsuid                      138
+#define TARGET_NR_setfsgid                      139
+#define TARGET_NR__llseek                       140
+#define TARGET_NR_getdents                      141
+#define TARGET_NR__newselect                    142
+#define TARGET_NR_flock                         143
+#define TARGET_NR_msync                         144
+#define TARGET_NR_readv                         145
+#define TARGET_NR_writev                        146
+#define TARGET_NR_getsid                        147
+#define TARGET_NR_fdatasync                     148
+#define TARGET_NR__sysctl                       149
+#define TARGET_NR_mlock                         150
+#define TARGET_NR_munlock                       151
+#define TARGET_NR_mlockall                      152
+#define TARGET_NR_munlockall                    153
+#define TARGET_NR_sched_setparam                154
+#define TARGET_NR_sched_getparam                155
+#define TARGET_NR_sched_setscheduler            156
+#define TARGET_NR_sched_getscheduler            157
+#define TARGET_NR_sched_yield                   158
+#define TARGET_NR_sched_get_priority_max        159
+#define TARGET_NR_sched_get_priority_min        160
+#define TARGET_NR_sched_rr_get_interval         161
+#define TARGET_NR_nanosleep                     162
+#define TARGET_NR_mremap                        163
+#define TARGET_NR_setresuid                     164
+#define TARGET_NR_getresuid                     165
+#define TARGET_NR_vm86                          166
+#define TARGET_NR_query_module                  167
+#define TARGET_NR_poll                          168
+#define TARGET_NR_nfsservctl                    169
+#define TARGET_NR_setresgid                     170
+#define TARGET_NR_getresgid                     171
+#define TARGET_NR_prctl                         172
+#define TARGET_NR_rt_sigreturn                  173
+#define TARGET_NR_rt_sigaction                  174
+#define TARGET_NR_rt_sigprocmask                175
+#define TARGET_NR_rt_sigpending                 176
+#define TARGET_NR_rt_sigtimedwait               177
+#define TARGET_NR_rt_sigqueueinfo               178
+#define TARGET_NR_rt_sigsuspend                 179
+#define TARGET_NR_pread                         180
+#define TARGET_NR_pwrite                        181
+#define TARGET_NR_chown                         182
+#define TARGET_NR_getcwd                        183
+#define TARGET_NR_capget                        184
+#define TARGET_NR_capset                        185
+#define TARGET_NR_sigaltstack                   186
+#define TARGET_NR_sendfile                      187
+                                                /* 188 */
+                                                /* 189 */
+#define TARGET_NR_vfork                         190
+#define TARGET_NR_ugetrlimit                    191
+#define TARGET_NR_mmap2                         192
+#define TARGET_NR_truncate64                    193
+#define TARGET_NR_ftruncate64                   194
+#define TARGET_NR_stat64                        195
+#define TARGET_NR_lstat64                       196
+#define TARGET_NR_fstat64                       197
+#define TARGET_NR_lchown32                      198
+#define TARGET_NR_getuid32                      199
+#define TARGET_NR_getgid32                      200
+#define TARGET_NR_geteuid32                     201
+#define TARGET_NR_getegid32                     202
+#define TARGET_NR_setreuid32                    203
+#define TARGET_NR_setregid32                    204
+#define TARGET_NR_getgroups32                   205
+#define TARGET_NR_setgroups32                   206
+#define TARGET_NR_fchown32                      207
+#define TARGET_NR_setresuid32                   208
+#define TARGET_NR_getresuid32                   209
+#define TARGET_NR_setresgid32                   210
+#define TARGET_NR_getresgid32                   211
+#define TARGET_NR_chown32                       212
+#define TARGET_NR_setuid32                      213
+#define TARGET_NR_setgid32                      214
+#define TARGET_NR_setfsuid32                    215
+#define TARGET_NR_setfsgid32                    216
+#define TARGET_NR_getdents64                    217
+#define TARGET_NR_pivot_root                    218
+#define TARGET_NR_mincore                       219
+#define TARGET_NR_madvise                       220
+#define TARGET_NR_fcntl64                       221
+                                                /* 222 */
+                                                /* 223 */
+#define TARGET_NR_gettid                        224
+#define TARGET_NR_readahead                     225
+#define TARGET_NR_setxattr                      226
+#define TARGET_NR_lsetxattr                     227
+#define TARGET_NR_fsetxattr                     228
+#define TARGET_NR_getxattr                      229
+#define TARGET_NR_lgetxattr                     230
+#define TARGET_NR_fgetxattr                     231
+#define TARGET_NR_listxattr                     232
+#define TARGET_NR_llistxattr                    233
+#define TARGET_NR_flistxattr                    234
+#define TARGET_NR_removexattr                   235
+#define TARGET_NR_lremovexattr                  236
+#define TARGET_NR_fremovexattr                  237
+#define TARGET_NR_tkill                         238
+#define TARGET_NR_sendfile64                    239
+#define TARGET_NR_futex                         240
+#define TARGET_NR_sched_setaffinity             241
+#define TARGET_NR_sched_getaffinity             242
+#define TARGET_NR_io_setup                      243
+#define TARGET_NR_io_destroy                    244
+#define TARGET_NR_io_getevents                  245
+#define TARGET_NR_io_submit                     246
+#define TARGET_NR_io_cancel                     247
+#define TARGET_NR_exit_group                    248
+#define TARGET_NR_lookup_dcookie                249
+#define TARGET_NR_epoll_create                  250
+#define TARGET_NR_epoll_ctl                     251
+#define TARGET_NR_epoll_wait                    252
+#define TARGET_NR_remap_file_pages              253
+                                                /* 254 */
+                                                /* 255 */
+                                                /* 256 */
+#define TARGET_NR_set_tid_address               256
+#define TARGET_NR_timer_create                  257
+#define TARGET_NR_timer_settime                 258
+#define TARGET_NR_timer_gettime                 259
+#define TARGET_NR_timer_getoverrun              260
+#define TARGET_NR_timer_delete                  261
+#define TARGET_NR_clock_settime                 262
+#define TARGET_NR_clock_gettime                 263
+#define TARGET_NR_clock_getres                  264
+#define TARGET_NR_clock_nanosleep               265
+#define TARGET_NR_statfs64                      266
+#define TARGET_NR_fstatfs64                     267
+#define TARGET_NR_tgkill                        268
+#define TARGET_NR_utimes                        269
+#define TARGET_NR_fadvise64_64                  270
+#define TARGET_NR_pciconfig_iobase              271
+#define TARGET_NR_pciconfig_read                272
+#define TARGET_NR_pciconfig_write               273
+#define TARGET_NR_mq_open                       274
+#define TARGET_NR_mq_unlink                     275
+#define TARGET_NR_mq_timedsend                  276
+#define TARGET_NR_mq_timedreceive               277
+#define TARGET_NR_mq_notify                     278
+#define TARGET_NR_mq_getsetattr                 279
+#define TARGET_NR_waitid                        280
+#define TARGET_NR_socket                        281
+#define TARGET_NR_bind                          282
+#define TARGET_NR_connect                       283
+#define TARGET_NR_listen                        284
+#define TARGET_NR_accept                        285
+#define TARGET_NR_getsockname                   286
+#define TARGET_NR_getpeername                   287
+#define TARGET_NR_socketpair                    288
+#define TARGET_NR_send                          289
+#define TARGET_NR_sendto                        290
+#define TARGET_NR_recv                          291
+#define TARGET_NR_recvfrom                      292
+#define TARGET_NR_shutdown                      293
+#define TARGET_NR_setsockopt                    294
+#define TARGET_NR_getsockopt                    295
+#define TARGET_NR_sendmsg                       296
+#define TARGET_NR_recvmsg                       297
+#define TARGET_NR_semop                         298
+#define TARGET_NR_semget                        299
+#define TARGET_NR_semctl                        300
+#define TARGET_NR_msgsnd                        301
+#define TARGET_NR_msgrcv                        302
+#define TARGET_NR_msgget                        303
+#define TARGET_NR_msgctl                        304
+#define TARGET_NR_shmat                         305
+#define TARGET_NR_shmdt                         306
+#define TARGET_NR_shmget                        307
+#define TARGET_NR_shmctl                        308
+#define TARGET_NR_add_key                       309
+#define TARGET_NR_request_key                   310
+#define TARGET_NR_keyctl                        311
+#define TARGET_NR_semtimedop                    312
+#define TARGET_NR_vserver                       313
+#define TARGET_NR_ioprio_set                    314
+#define TARGET_NR_ioprio_get                    315
+#define TARGET_NR_inotify_init                  316
+#define TARGET_NR_inotify_add_watch             317
+#define TARGET_NR_inotify_rm_watch              318
+#define TARGET_NR_mbind                         319
+#define TARGET_NR_get_mempolicy                 320
+#define TARGET_NR_set_mempolicy                 321
+#define TARGET_NR_openat                        322
+#define TARGET_NR_mkdirat                       323
+#define TARGET_NR_mknodat                       324
+#define TARGET_NR_fchownat                      325
+#define TARGET_NR_futimesat                     326
+#define TARGET_NR_fstatat64                     327
+#define TARGET_NR_unlinkat                      328
+#define TARGET_NR_renameat                      329
+#define TARGET_NR_linkat                        330
+#define TARGET_NR_symlinkat                     331
+#define TARGET_NR_readlinkat                    332
+#define TARGET_NR_fchmodat                      333
+#define TARGET_NR_faccessat                     334
+                                                /* 335 */
+                                                /* 336 */
+#define TARGET_NR_unshare                       337
+#define TARGET_NR_set_robust_list               338
+#define TARGET_NR_get_robust_list               339
+#define TARGET_NR_splice                        340
+#define TARGET_NR_sync_file_range2              341
+#define TARGET_NR_tee                           342
+#define TARGET_NR_vmsplice                      343
+#define TARGET_NR_move_pages                    344
+#define TARGET_NR_getcpu                        345
+                                                /* 346 */
+#define TARGET_NR_kexec_load                    347
+#define TARGET_NR_utimensat                     348
+#define TARGET_NR_signalfd                      349
+#define TARGET_NR_timerfd                       350
+#define TARGET_NR_eventfd                       351
+#define TARGET_NR_fallocate                     352
+#define TARGET_NR_timerfd_settime               353
+#define TARGET_NR_timerfd_gettime               354
+#define TARGET_NR_signalfd4                     355
+#define TARGET_NR_eventfd2                      356
+#define TARGET_NR_epoll_create1                 357
+#define TARGET_NR_dup3                          358
+#define TARGET_NR_pipe2                         359
+#define TARGET_NR_inotify_init1                 360
diff --git a/linux-user/unicore32/target_signal.h b/linux-user/unicore32/target_signal.h
new file mode 100644
index 0000000000..8b255c4550
--- /dev/null
+++ b/linux-user/unicore32/target_signal.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2010-2011 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef TARGET_SIGNAL_H
+#define TARGET_SIGNAL_H
+
+/* this struct defines a stack used during syscall handling */
+typedef struct target_sigaltstack {
+    abi_ulong ss_sp;
+    abi_ulong ss_flags;
+    abi_ulong ss_size;
+} target_stack_t;
+
+/*
+ * sigaltstack controls
+ */
+#define TARGET_SS_ONSTACK               1
+#define TARGET_SS_DISABLE               2
+
+#define get_sp_from_cpustate(cpustate)  (cpustate->regs[29])
+
+#endif /* TARGET_SIGNAL_H */
diff --git a/linux-user/unicore32/termbits.h b/linux-user/unicore32/termbits.h
new file mode 100644
index 0000000000..a5fcd64abf
--- /dev/null
+++ b/linux-user/unicore32/termbits.h
@@ -0,0 +1,2 @@
+/* NOTE: exactly the same as i386 */
+#include "../i386/termbits.h"

From d2fbca94223ef573a67d4eb2f27509a9bbb85ca1 Mon Sep 17 00:00:00 2001
From: Guan Xuetao <gxt@mprc.pku.edu.cn>
Date: Tue, 12 Apr 2011 16:27:03 +0800
Subject: [PATCH 154/386] unicore32: necessary modifications for other files to
 support unicore32

Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 configure                                | 11 ++-
 cpu-exec.c                               | 12 +++-
 default-configs/unicore32-linux-user.mak |  1 +
 elf.h                                    |  2 +
 fpu/softfloat-specialize.h               | 10 +--
 fpu/softfloat.h                          |  2 +-
 linux-user/elfload.c                     | 74 ++++++++++++++++++++
 linux-user/main.c                        | 89 +++++++++++++++++++++++-
 linux-user/qemu.h                        |  5 +-
 linux-user/syscall_defs.h                | 10 ++-
 10 files changed, 202 insertions(+), 14 deletions(-)
 create mode 100644 default-configs/unicore32-linux-user.mak

diff --git a/configure b/configure
index a4759ae817..ed4d951ce9 100755
--- a/configure
+++ b/configure
@@ -283,7 +283,7 @@ else
 fi
 
 case "$cpu" in
-  alpha|cris|ia64|lm32|m68k|microblaze|ppc|ppc64|sparc64)
+  alpha|cris|ia64|lm32|m68k|microblaze|ppc|ppc64|sparc64|unicore32)
     cpu="$cpu"
   ;;
   i386|i486|i586|i686|i86pc|BePC)
@@ -814,6 +814,9 @@ case "$cpu" in
     hppa*)
            host_guest_base="yes"
            ;;
+    unicore32*)
+           host_guest_base="yes"
+           ;;
 esac
 
 [ -z "$guest_base" ] && guest_base="$host_guest_base"
@@ -1048,6 +1051,7 @@ sh4eb-linux-user \
 sparc-linux-user \
 sparc64-linux-user \
 sparc32plus-linux-user \
+unicore32-linux-user \
 "
     fi
 # the following are Darwin specific
@@ -2633,7 +2637,7 @@ echo "docdir=$docdir" >> $config_host_mak
 echo "confdir=$confdir" >> $config_host_mak
 
 case "$cpu" in
-  i386|x86_64|alpha|cris|hppa|ia64|lm32|m68k|microblaze|mips|mips64|ppc|ppc64|s390|s390x|sparc|sparc64)
+  i386|x86_64|alpha|cris|hppa|ia64|lm32|m68k|microblaze|mips|mips64|ppc|ppc64|s390|s390x|sparc|sparc64|unicore32)
     ARCH=$cpu
   ;;
   armv4b|armv4l)
@@ -3186,6 +3190,9 @@ case "$target_arch2" in
     target_phys_bits=64
     target_long_alignment=8
   ;;
+  unicore32)
+    target_phys_bits=32
+  ;;
   *)
     echo "Unsupported target CPU"
     exit 1
diff --git a/cpu-exec.c b/cpu-exec.c
index 5cc937904a..5d6c9a8a1c 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -267,6 +267,7 @@ int cpu_exec(CPUState *env1)
     env->cc_x = (env->sr >> 4) & 1;
 #elif defined(TARGET_ALPHA)
 #elif defined(TARGET_ARM)
+#elif defined(TARGET_UNICORE32)
 #elif defined(TARGET_PPC)
 #elif defined(TARGET_LM32)
 #elif defined(TARGET_MICROBLAZE)
@@ -335,6 +336,8 @@ int cpu_exec(CPUState *env1)
                     do_interrupt(env);
 #elif defined(TARGET_ARM)
                     do_interrupt(env);
+#elif defined(TARGET_UNICORE32)
+                    do_interrupt(env);
 #elif defined(TARGET_SH4)
 		    do_interrupt(env);
 #elif defined(TARGET_ALPHA)
@@ -367,7 +370,7 @@ int cpu_exec(CPUState *env1)
                     }
 #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
     defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
-    defined(TARGET_MICROBLAZE) || defined(TARGET_LM32)
+    defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || defined(TARGET_UNICORE32)
                     if (interrupt_request & CPU_INTERRUPT_HALT) {
                         env->interrupt_request &= ~CPU_INTERRUPT_HALT;
                         env->halted = 1;
@@ -514,6 +517,12 @@ int cpu_exec(CPUState *env1)
                         do_interrupt(env);
                         next_tb = 0;
                     }
+#elif defined(TARGET_UNICORE32)
+                    if (interrupt_request & CPU_INTERRUPT_HARD
+                        && !(env->uncached_asr & ASR_I)) {
+                        do_interrupt(env);
+                        next_tb = 0;
+                    }
 #elif defined(TARGET_SH4)
                     if (interrupt_request & CPU_INTERRUPT_HARD) {
                         do_interrupt(env);
@@ -664,6 +673,7 @@ int cpu_exec(CPUState *env1)
     env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
 #elif defined(TARGET_ARM)
     /* XXX: Save/restore host fpu exception state?.  */
+#elif defined(TARGET_UNICORE32)
 #elif defined(TARGET_SPARC)
 #elif defined(TARGET_PPC)
 #elif defined(TARGET_LM32)
diff --git a/default-configs/unicore32-linux-user.mak b/default-configs/unicore32-linux-user.mak
new file mode 100644
index 0000000000..6aafd21494
--- /dev/null
+++ b/default-configs/unicore32-linux-user.mak
@@ -0,0 +1 @@
+# Default configuration for unicore32-linux-user
diff --git a/elf.h b/elf.h
index 523c972a6b..ffcac7e0b0 100644
--- a/elf.h
+++ b/elf.h
@@ -106,6 +106,8 @@ typedef int64_t  Elf64_Sxword;
 #define EM_H8S          48      /* Hitachi H8S     */
 #define EM_LATTICEMICO32 138    /* LatticeMico32 */
 
+#define EM_UNICORE32    110     /* UniCore32 */
+
 /*
  * This is an interim value that we will use until the committee comes
  * up with a final number.
diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index 4b65de64a8..b1101872af 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -93,7 +93,7 @@ float16 float16_maybe_silence_nan(float16 a_)
 {
     if (float16_is_signaling_nan(a_)) {
 #if SNAN_BIT_IS_ONE
-#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
+#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
         return float16_default_nan;
 #  else
 #    error Rules for silencing a signaling NaN are target-specific
@@ -184,7 +184,7 @@ float32 float32_maybe_silence_nan( float32 a_ )
 {
     if (float32_is_signaling_nan(a_)) {
 #if SNAN_BIT_IS_ONE
-#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
+#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
         return float32_default_nan;
 #  else
 #    error Rules for silencing a signaling NaN are target-specific
@@ -430,7 +430,7 @@ float64 float64_maybe_silence_nan( float64 a_ )
 {
     if (float64_is_signaling_nan(a_)) {
 #if SNAN_BIT_IS_ONE
-#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
+#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
         return float64_default_nan;
 #  else
 #    error Rules for silencing a signaling NaN are target-specific
@@ -578,7 +578,7 @@ floatx80 floatx80_maybe_silence_nan( floatx80 a )
 {
     if (floatx80_is_signaling_nan(a)) {
 #if SNAN_BIT_IS_ONE
-#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
+#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
         a.low = floatx80_default_nan_low;
         a.high = floatx80_default_nan_high;
 #  else
@@ -721,7 +721,7 @@ float128 float128_maybe_silence_nan( float128 a )
 {
     if (float128_is_signaling_nan(a)) {
 #if SNAN_BIT_IS_ONE
-#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
+#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
         a.low = float128_default_nan_low;
         a.high = float128_default_nan_high;
 #  else
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 90f4250173..7abcbe899e 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -68,7 +68,7 @@ typedef int64_t int64;
 #define LIT64( a ) a##LL
 #define INLINE static inline
 
-#if defined(TARGET_MIPS) || defined(TARGET_SH4)
+#if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
 #define SNAN_BIT_IS_ONE		1
 #else
 #define SNAN_BIT_IS_ONE		0
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index fe5410e6f9..4c399f8e33 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -339,6 +339,80 @@ enum
 
 #endif
 
+#ifdef TARGET_UNICORE32
+
+#define ELF_START_MMAP          0x80000000
+
+#define elf_check_arch(x)       ((x) == EM_UNICORE32)
+
+#define ELF_CLASS               ELFCLASS32
+#define ELF_DATA                ELFDATA2LSB
+#define ELF_ARCH                EM_UNICORE32
+
+static inline void init_thread(struct target_pt_regs *regs,
+        struct image_info *infop)
+{
+    abi_long stack = infop->start_stack;
+    memset(regs, 0, sizeof(*regs));
+    regs->UC32_REG_asr = 0x10;
+    regs->UC32_REG_pc = infop->entry & 0xfffffffe;
+    regs->UC32_REG_sp = infop->start_stack;
+    /* FIXME - what to for failure of get_user()? */
+    get_user_ual(regs->UC32_REG_02, stack + 8); /* envp */
+    get_user_ual(regs->UC32_REG_01, stack + 4); /* envp */
+    /* XXX: it seems that r0 is zeroed after ! */
+    regs->UC32_REG_00 = 0;
+}
+
+#define ELF_NREG    34
+typedef target_elf_greg_t  target_elf_gregset_t[ELF_NREG];
+
+static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
+{
+    (*regs)[0] = env->regs[0];
+    (*regs)[1] = env->regs[1];
+    (*regs)[2] = env->regs[2];
+    (*regs)[3] = env->regs[3];
+    (*regs)[4] = env->regs[4];
+    (*regs)[5] = env->regs[5];
+    (*regs)[6] = env->regs[6];
+    (*regs)[7] = env->regs[7];
+    (*regs)[8] = env->regs[8];
+    (*regs)[9] = env->regs[9];
+    (*regs)[10] = env->regs[10];
+    (*regs)[11] = env->regs[11];
+    (*regs)[12] = env->regs[12];
+    (*regs)[13] = env->regs[13];
+    (*regs)[14] = env->regs[14];
+    (*regs)[15] = env->regs[15];
+    (*regs)[16] = env->regs[16];
+    (*regs)[17] = env->regs[17];
+    (*regs)[18] = env->regs[18];
+    (*regs)[19] = env->regs[19];
+    (*regs)[20] = env->regs[20];
+    (*regs)[21] = env->regs[21];
+    (*regs)[22] = env->regs[22];
+    (*regs)[23] = env->regs[23];
+    (*regs)[24] = env->regs[24];
+    (*regs)[25] = env->regs[25];
+    (*regs)[26] = env->regs[26];
+    (*regs)[27] = env->regs[27];
+    (*regs)[28] = env->regs[28];
+    (*regs)[29] = env->regs[29];
+    (*regs)[30] = env->regs[30];
+    (*regs)[31] = env->regs[31];
+
+    (*regs)[32] = cpu_asr_read((CPUState *)env);
+    (*regs)[33] = env->regs[0]; /* XXX */
+}
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE               4096
+
+#define ELF_HWCAP                       (UC32_HWCAP_CMOV | UC32_HWCAP_UCF64)
+
+#endif
+
 #ifdef TARGET_SPARC
 #ifdef TARGET_SPARC64
 
diff --git a/linux-user/main.c b/linux-user/main.c
index 91600877d2..a1e37e4948 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -816,6 +816,83 @@ void cpu_loop(CPUARMState *env)
 
 #endif
 
+#ifdef TARGET_UNICORE32
+
+void cpu_loop(CPUState *env)
+{
+    int trapnr;
+    unsigned int n, insn;
+    target_siginfo_t info;
+
+    for (;;) {
+        cpu_exec_start(env);
+        trapnr = uc32_cpu_exec(env);
+        cpu_exec_end(env);
+        switch (trapnr) {
+        case UC32_EXCP_PRIV:
+            {
+                /* system call */
+                get_user_u32(insn, env->regs[31] - 4);
+                n = insn & 0xffffff;
+
+                if (n >= UC32_SYSCALL_BASE) {
+                    /* linux syscall */
+                    n -= UC32_SYSCALL_BASE;
+                    if (n == UC32_SYSCALL_NR_set_tls) {
+                            cpu_set_tls(env, env->regs[0]);
+                            env->regs[0] = 0;
+                    } else {
+                        env->regs[0] = do_syscall(env,
+                                                  n,
+                                                  env->regs[0],
+                                                  env->regs[1],
+                                                  env->regs[2],
+                                                  env->regs[3],
+                                                  env->regs[4],
+                                                  env->regs[5]);
+                    }
+                } else {
+                    goto error;
+                }
+            }
+            break;
+        case UC32_EXCP_TRAP:
+            info.si_signo = SIGSEGV;
+            info.si_errno = 0;
+            /* XXX: check env->error_code */
+            info.si_code = TARGET_SEGV_MAPERR;
+            info._sifields._sigfault._addr = env->cp0.c4_faultaddr;
+            queue_signal(env, info.si_signo, &info);
+            break;
+        case EXCP_INTERRUPT:
+            /* just indicate that signals should be handled asap */
+            break;
+        case EXCP_DEBUG:
+            {
+                int sig;
+
+                sig = gdb_handlesig(env, TARGET_SIGTRAP);
+                if (sig) {
+                    info.si_signo = sig;
+                    info.si_errno = 0;
+                    info.si_code = TARGET_TRAP_BRKPT;
+                    queue_signal(env, info.si_signo, &info);
+                }
+            }
+            break;
+        default:
+            goto error;
+        }
+        process_pending_signals(env);
+    }
+
+error:
+    fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
+    cpu_dump_state(env, stderr, fprintf, 0);
+    abort();
+}
+#endif
+
 #ifdef TARGET_SPARC
 #define SPARC64_STACK_BIAS 2047
 
@@ -2925,6 +3002,8 @@ int main(int argc, char **argv, char **envp)
 #endif
 #elif defined(TARGET_ARM)
         cpu_model = "any";
+#elif defined(TARGET_UNICORE32)
+        cpu_model = "any";
 #elif defined(TARGET_M68K)
         cpu_model = "any";
 #elif defined(TARGET_SPARC)
@@ -3227,6 +3306,14 @@ int main(int argc, char **argv, char **envp)
             env->regs[i] = regs->uregs[i];
         }
     }
+#elif defined(TARGET_UNICORE32)
+    {
+        int i;
+        cpu_asr_write(env, regs->uregs[32], 0xffffffff);
+        for (i = 0; i < 32; i++) {
+            env->regs[i] = regs->uregs[i];
+        }
+    }
 #elif defined(TARGET_SPARC)
     {
         int i;
@@ -3367,7 +3454,7 @@ int main(int argc, char **argv, char **envp)
 #error unsupported target CPU
 #endif
 
-#if defined(TARGET_ARM) || defined(TARGET_M68K)
+#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
     ts->stack_base = info->start_stack;
     ts->heap_base = info->brk;
     /* This will be filled in on the first SYS_HEAPINFO call.  */
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 250814d9f7..f522f5e64a 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -105,6 +105,9 @@ typedef struct TaskState {
     FPA11 fpa;
     int swi_errno;
 #endif
+#ifdef TARGET_UNICORE32
+    int swi_errno;
+#endif
 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
     abi_ulong target_v86;
     struct vm86_saved_state vm86_saved_regs;
@@ -118,7 +121,7 @@ typedef struct TaskState {
 #ifdef TARGET_M68K
     int sim_syscalls;
 #endif
-#if defined(TARGET_ARM) || defined(TARGET_M68K)
+#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
     /* Extra fields for semihosted binaries.  */
     uint32_t stack_base;
     uint32_t heap_base;
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 702652cb9e..bde89213de 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -55,7 +55,7 @@
 #endif
 
 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \
-    || defined(TARGET_M68K) || defined(TARGET_CRIS)
+    || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_UNICORE32)
 
 #define TARGET_IOC_SIZEBITS	14
 #define TARGET_IOC_DIRBITS	2
@@ -315,7 +315,10 @@ struct target_sigaction;
 int do_sigaction(int sig, const struct target_sigaction *act,
                  struct target_sigaction *oact);
 
-#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
+    || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined(TARGET_SH4) \
+    || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) \
+    || defined(TARGET_MICROBLAZE) || defined(TARGET_UNICORE32)
 
 #if defined(TARGET_SPARC)
 #define TARGET_SA_NOCLDSTOP    8u
@@ -1002,7 +1005,8 @@ struct target_winsize {
 #define TARGET_MAP_UNINITIALIZED 0x4000000	/* for anonymous mmap, memory could be uninitialized */
 #endif
 
-#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_CRIS)
+#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) \
+    || defined(TARGET_CRIS) || defined(TARGET_UNICORE32)
 struct target_stat {
 	unsigned short st_dev;
 	unsigned short __pad1;

From d6c424c56e0e9064448d04c271625c8ac696ae50 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Sun, 10 Apr 2011 21:09:12 +0200
Subject: [PATCH 155/386] target-sh4: get rid of CPU_{Float,Double}U

SH4 is always using softfloat, so it's possible to have helpers directly
taking float32 or float64 value. This allow to get rid of conversions
through CPU_{Float,Double}U.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-sh4/helper.h    |  48 +++---
 target-sh4/op_helper.c | 342 +++++++++++++++++------------------------
 2 files changed, 162 insertions(+), 228 deletions(-)

diff --git a/target-sh4/helper.h b/target-sh4/helper.h
index 2e52768414..95e3c7c8f7 100644
--- a/target-sh4/helper.h
+++ b/target-sh4/helper.h
@@ -23,31 +23,31 @@ DEF_HELPER_2(macw, void, i32, i32)
 
 DEF_HELPER_1(ld_fpscr, void, i32)
 
-DEF_HELPER_1(fabs_FT, i32, i32)
-DEF_HELPER_1(fabs_DT, i64, i64)
-DEF_HELPER_2(fadd_FT, i32, i32, i32)
-DEF_HELPER_2(fadd_DT, i64, i64, i64)
-DEF_HELPER_1(fcnvsd_FT_DT, i64, i32)
-DEF_HELPER_1(fcnvds_DT_FT, i32, i64)
+DEF_HELPER_1(fabs_FT, f32, f32)
+DEF_HELPER_1(fabs_DT, f64, f64)
+DEF_HELPER_2(fadd_FT, f32, f32, f32)
+DEF_HELPER_2(fadd_DT, f64, f64, f64)
+DEF_HELPER_1(fcnvsd_FT_DT, f64, f32)
+DEF_HELPER_1(fcnvds_DT_FT, f32, f64)
 
-DEF_HELPER_2(fcmp_eq_FT, void, i32, i32)
-DEF_HELPER_2(fcmp_eq_DT, void, i64, i64)
-DEF_HELPER_2(fcmp_gt_FT, void, i32, i32)
-DEF_HELPER_2(fcmp_gt_DT, void, i64, i64)
-DEF_HELPER_2(fdiv_FT, i32, i32, i32)
-DEF_HELPER_2(fdiv_DT, i64, i64, i64)
-DEF_HELPER_1(float_FT, i32, i32)
-DEF_HELPER_1(float_DT, i64, i32)
-DEF_HELPER_3(fmac_FT, i32, i32, i32, i32)
-DEF_HELPER_2(fmul_FT, i32, i32, i32)
-DEF_HELPER_2(fmul_DT, i64, i64, i64)
-DEF_HELPER_1(fneg_T, i32, i32)
-DEF_HELPER_2(fsub_FT, i32, i32, i32)
-DEF_HELPER_2(fsub_DT, i64, i64, i64)
-DEF_HELPER_1(fsqrt_FT, i32, i32)
-DEF_HELPER_1(fsqrt_DT, i64, i64)
-DEF_HELPER_1(ftrc_FT, i32, i32)
-DEF_HELPER_1(ftrc_DT, i32, i64)
+DEF_HELPER_2(fcmp_eq_FT, void, f32, f32)
+DEF_HELPER_2(fcmp_eq_DT, void, f64, f64)
+DEF_HELPER_2(fcmp_gt_FT, void, f32, f32)
+DEF_HELPER_2(fcmp_gt_DT, void, f64, f64)
+DEF_HELPER_2(fdiv_FT, f32, f32, f32)
+DEF_HELPER_2(fdiv_DT, f64, f64, f64)
+DEF_HELPER_1(float_FT, f32, i32)
+DEF_HELPER_1(float_DT, f64, i32)
+DEF_HELPER_3(fmac_FT, f32, f32, f32, f32)
+DEF_HELPER_2(fmul_FT, f32, f32, f32)
+DEF_HELPER_2(fmul_DT, f64, f64, f64)
+DEF_HELPER_1(fneg_T, f32, f32)
+DEF_HELPER_2(fsub_FT, f32, f32, f32)
+DEF_HELPER_2(fsub_DT, f64, f64, f64)
+DEF_HELPER_1(fsqrt_FT, f32, f32)
+DEF_HELPER_1(fsqrt_DT, f64, f64)
+DEF_HELPER_1(ftrc_FT, i32, f32)
+DEF_HELPER_1(ftrc_DT, i32, f64)
 DEF_HELPER_2(fipr, void, i32, i32)
 DEF_HELPER_1(ftrv, void, i32)
 
diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
index b8f4ca28ed..c127860cd9 100644
--- a/target-sh4/op_helper.c
+++ b/target-sh4/op_helper.c
@@ -487,53 +487,38 @@ static void update_fpscr(void *retaddr)
     }
 }
 
-uint32_t helper_fabs_FT(uint32_t t0)
+float32 helper_fabs_FT(float32 t0)
 {
-    CPU_FloatU f;
-    f.l = t0;
-    f.f = float32_abs(f.f);
-    return f.l;
+    return float32_abs(t0);
 }
 
-uint64_t helper_fabs_DT(uint64_t t0)
+float64 helper_fabs_DT(float64 t0)
 {
-    CPU_DoubleU d;
-    d.ll = t0;
-    d.d = float64_abs(d.d);
-    return d.ll;
+    return float64_abs(t0);
 }
 
-uint32_t helper_fadd_FT(uint32_t t0, uint32_t t1)
+float32 helper_fadd_FT(float32 t0, float32 t1)
 {
-    CPU_FloatU f0, f1;
-    f0.l = t0;
-    f1.l = t1;
     set_float_exception_flags(0, &env->fp_status);
-    f0.f = float32_add(f0.f, f1.f, &env->fp_status);
+    t0 = float32_add(t0, t1, &env->fp_status);
     update_fpscr(GETPC());
-    return f0.l;
+    return t0;
 }
 
-uint64_t helper_fadd_DT(uint64_t t0, uint64_t t1)
+float64 helper_fadd_DT(float64 t0, float64 t1)
 {
-    CPU_DoubleU d0, d1;
-    d0.ll = t0;
-    d1.ll = t1;
     set_float_exception_flags(0, &env->fp_status);
-    d0.d = float64_add(d0.d, d1.d, &env->fp_status);
+    t0 = float64_add(t0, t1, &env->fp_status);
     update_fpscr(GETPC());
-    return d0.ll;
+    return t0;
 }
 
-void helper_fcmp_eq_FT(uint32_t t0, uint32_t t1)
+void helper_fcmp_eq_FT(float32 t0, float32 t1)
 {
-    CPU_FloatU f0, f1;
     int relation;
-    f0.l = t0;
-    f1.l = t1;
 
     set_float_exception_flags(0, &env->fp_status);
-    relation = float32_compare(f0.f, f1.f, &env->fp_status);
+    relation = float32_compare(t0, t1, &env->fp_status);
     if (unlikely(relation == float_relation_unordered)) {
         update_fpscr(GETPC());
     } else if (relation == float_relation_equal) {
@@ -543,15 +528,12 @@ void helper_fcmp_eq_FT(uint32_t t0, uint32_t t1)
     }
 }
 
-void helper_fcmp_eq_DT(uint64_t t0, uint64_t t1)
+void helper_fcmp_eq_DT(float64 t0, float64 t1)
 {
-    CPU_DoubleU d0, d1;
     int relation;
-    d0.ll = t0;
-    d1.ll = t1;
 
     set_float_exception_flags(0, &env->fp_status);
-    relation = float64_compare(d0.d, d1.d, &env->fp_status);
+    relation = float64_compare(t0, t1, &env->fp_status);
     if (unlikely(relation == float_relation_unordered)) {
         update_fpscr(GETPC());
     } else if (relation == float_relation_equal) {
@@ -561,15 +543,12 @@ void helper_fcmp_eq_DT(uint64_t t0, uint64_t t1)
     }
 }
 
-void helper_fcmp_gt_FT(uint32_t t0, uint32_t t1)
+void helper_fcmp_gt_FT(float32 t0, float32 t1)
 {
-    CPU_FloatU f0, f1;
     int relation;
-    f0.l = t0;
-    f1.l = t1;
 
     set_float_exception_flags(0, &env->fp_status);
-    relation = float32_compare(f0.f, f1.f, &env->fp_status);
+    relation = float32_compare(t0, t1, &env->fp_status);
     if (unlikely(relation == float_relation_unordered)) {
         update_fpscr(GETPC());
     } else if (relation == float_relation_greater) {
@@ -579,15 +558,12 @@ void helper_fcmp_gt_FT(uint32_t t0, uint32_t t1)
     }
 }
 
-void helper_fcmp_gt_DT(uint64_t t0, uint64_t t1)
+void helper_fcmp_gt_DT(float64 t0, float64 t1)
 {
-    CPU_DoubleU d0, d1;
     int relation;
-    d0.ll = t0;
-    d1.ll = t1;
 
     set_float_exception_flags(0, &env->fp_status);
-    relation = float64_compare(d0.d, d1.d, &env->fp_status);
+    relation = float64_compare(t0, t1, &env->fp_status);
     if (unlikely(relation == float_relation_unordered)) {
         update_fpscr(GETPC());
     } else if (relation == float_relation_greater) {
@@ -597,176 +573,134 @@ void helper_fcmp_gt_DT(uint64_t t0, uint64_t t1)
     }
 }
 
-uint64_t helper_fcnvsd_FT_DT(uint32_t t0)
+float64 helper_fcnvsd_FT_DT(float32 t0)
 {
-    CPU_DoubleU d;
-    CPU_FloatU f;
-    f.l = t0;
+    float64 ret;
     set_float_exception_flags(0, &env->fp_status);
-    d.d = float32_to_float64(f.f, &env->fp_status);
-    update_fpscr(GETPC());
-    return d.ll;
-}
-
-uint32_t helper_fcnvds_DT_FT(uint64_t t0)
-{
-    CPU_DoubleU d;
-    CPU_FloatU f;
-    d.ll = t0;
-    set_float_exception_flags(0, &env->fp_status);
-    f.f = float64_to_float32(d.d, &env->fp_status);
-    update_fpscr(GETPC());
-    return f.l;
-}
-
-uint32_t helper_fdiv_FT(uint32_t t0, uint32_t t1)
-{
-    CPU_FloatU f0, f1;
-    f0.l = t0;
-    f1.l = t1;
-    set_float_exception_flags(0, &env->fp_status);
-    f0.f = float32_div(f0.f, f1.f, &env->fp_status);
-    update_fpscr(GETPC());
-    return f0.l;
-}
-
-uint64_t helper_fdiv_DT(uint64_t t0, uint64_t t1)
-{
-    CPU_DoubleU d0, d1;
-    d0.ll = t0;
-    d1.ll = t1;
-    set_float_exception_flags(0, &env->fp_status);
-    d0.d = float64_div(d0.d, d1.d, &env->fp_status);
-    update_fpscr(GETPC());
-    return d0.ll;
-}
-
-uint32_t helper_float_FT(uint32_t t0)
-{
-    CPU_FloatU f;
-
-    set_float_exception_flags(0, &env->fp_status);
-    f.f = int32_to_float32(t0, &env->fp_status);
-    update_fpscr(GETPC());
-
-    return f.l;
-}
-
-uint64_t helper_float_DT(uint32_t t0)
-{
-    CPU_DoubleU d;
-    set_float_exception_flags(0, &env->fp_status);
-    d.d = int32_to_float64(t0, &env->fp_status);
-    update_fpscr(GETPC());
-    return d.ll;
-}
-
-uint32_t helper_fmac_FT(uint32_t t0, uint32_t t1, uint32_t t2)
-{
-    CPU_FloatU f0, f1, f2;
-    f0.l = t0;
-    f1.l = t1;
-    f2.l = t2;
-    set_float_exception_flags(0, &env->fp_status);
-    f0.f = float32_mul(f0.f, f1.f, &env->fp_status);
-    f0.f = float32_add(f0.f, f2.f, &env->fp_status);
-    update_fpscr(GETPC());
-
-    return f0.l;
-}
-
-uint32_t helper_fmul_FT(uint32_t t0, uint32_t t1)
-{
-    CPU_FloatU f0, f1;
-    f0.l = t0;
-    f1.l = t1;
-    set_float_exception_flags(0, &env->fp_status);
-    f0.f = float32_mul(f0.f, f1.f, &env->fp_status);
-    update_fpscr(GETPC());
-    return f0.l;
-}
-
-uint64_t helper_fmul_DT(uint64_t t0, uint64_t t1)
-{
-    CPU_DoubleU d0, d1;
-    d0.ll = t0;
-    d1.ll = t1;
-    set_float_exception_flags(0, &env->fp_status);
-    d0.d = float64_mul(d0.d, d1.d, &env->fp_status);
-    update_fpscr(GETPC());
-
-    return d0.ll;
-}
-
-uint32_t helper_fneg_T(uint32_t t0)
-{
-    CPU_FloatU f;
-    f.l = t0;
-    f.f = float32_chs(f.f);
-    return f.l;
-}
-
-uint32_t helper_fsqrt_FT(uint32_t t0)
-{
-    CPU_FloatU f;
-    f.l = t0;
-    set_float_exception_flags(0, &env->fp_status);
-    f.f = float32_sqrt(f.f, &env->fp_status);
-    update_fpscr(GETPC());
-    return f.l;
-}
-
-uint64_t helper_fsqrt_DT(uint64_t t0)
-{
-    CPU_DoubleU d;
-    d.ll = t0;
-    set_float_exception_flags(0, &env->fp_status);
-    d.d = float64_sqrt(d.d, &env->fp_status);
-    update_fpscr(GETPC());
-    return d.ll;
-}
-
-uint32_t helper_fsub_FT(uint32_t t0, uint32_t t1)
-{
-    CPU_FloatU f0, f1;
-    f0.l = t0;
-    f1.l = t1;
-    set_float_exception_flags(0, &env->fp_status);
-    f0.f = float32_sub(f0.f, f1.f, &env->fp_status);
-    update_fpscr(GETPC());
-    return f0.l;
-}
-
-uint64_t helper_fsub_DT(uint64_t t0, uint64_t t1)
-{
-    CPU_DoubleU d0, d1;
-
-    d0.ll = t0;
-    d1.ll = t1;
-    set_float_exception_flags(0, &env->fp_status);
-    d0.d = float64_sub(d0.d, d1.d, &env->fp_status);
-    update_fpscr(GETPC());
-    return d0.ll;
-}
-
-uint32_t helper_ftrc_FT(uint32_t t0)
-{
-    CPU_FloatU f;
-    uint32_t ret;
-    f.l = t0;
-    set_float_exception_flags(0, &env->fp_status);
-    ret = float32_to_int32_round_to_zero(f.f, &env->fp_status);
+    ret = float32_to_float64(t0, &env->fp_status);
     update_fpscr(GETPC());
     return ret;
 }
 
-uint32_t helper_ftrc_DT(uint64_t t0)
+float32 helper_fcnvds_DT_FT(float64 t0)
 {
-    CPU_DoubleU d;
-    uint32_t ret;
-    d.ll = t0;
+    float32 ret;
     set_float_exception_flags(0, &env->fp_status);
-    ret = float64_to_int32_round_to_zero(d.d, &env->fp_status);
+    ret = float64_to_float32(t0, &env->fp_status);
+    update_fpscr(GETPC());
+    return ret;
+}
+
+float32 helper_fdiv_FT(float32 t0, float32 t1)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    t0 = float32_div(t0, t1, &env->fp_status);
+    update_fpscr(GETPC());
+    return t0;
+}
+
+float64 helper_fdiv_DT(float64 t0, float64 t1)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    t0 = float64_div(t0, t1, &env->fp_status);
+    update_fpscr(GETPC());
+    return t0;
+}
+
+float32 helper_float_FT(uint32_t t0)
+{
+    float32 ret;
+    set_float_exception_flags(0, &env->fp_status);
+    ret = int32_to_float32(t0, &env->fp_status);
+    update_fpscr(GETPC());
+    return ret;
+}
+
+float64 helper_float_DT(uint32_t t0)
+{
+    float64 ret;
+    set_float_exception_flags(0, &env->fp_status);
+    ret = int32_to_float64(t0, &env->fp_status);
+    update_fpscr(GETPC());
+    return ret;
+}
+
+float32 helper_fmac_FT(float32 t0, float32 t1, float32 t2)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    t0 = float32_mul(t0, t1, &env->fp_status);
+    t0 = float32_add(t0, t2, &env->fp_status);
+    update_fpscr(GETPC());
+    return t0;
+}
+
+float32 helper_fmul_FT(float32 t0, float32 t1)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    t0 = float32_mul(t0, t1, &env->fp_status);
+    update_fpscr(GETPC());
+    return t0;
+}
+
+float64 helper_fmul_DT(float64 t0, float64 t1)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    t0 = float64_mul(t0, t1, &env->fp_status);
+    update_fpscr(GETPC());
+    return t0;
+}
+
+float32 helper_fneg_T(float32 t0)
+{
+    return float32_chs(t0);
+}
+
+float32 helper_fsqrt_FT(float32 t0)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    t0 = float32_sqrt(t0, &env->fp_status);
+    update_fpscr(GETPC());
+    return t0;
+}
+
+float64 helper_fsqrt_DT(float64 t0)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    t0 = float64_sqrt(t0, &env->fp_status);
+    update_fpscr(GETPC());
+    return t0;
+}
+
+float32 helper_fsub_FT(float32 t0, float32 t1)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    t0 = float32_sub(t0, t1, &env->fp_status);
+    update_fpscr(GETPC());
+    return t0;
+}
+
+float64 helper_fsub_DT(float64 t0, float64 t1)
+{
+    set_float_exception_flags(0, &env->fp_status);
+    t0 = float64_sub(t0, t1, &env->fp_status);
+    update_fpscr(GETPC());
+    return t0;
+}
+
+uint32_t helper_ftrc_FT(float32 t0)
+{
+    uint32_t ret;
+    set_float_exception_flags(0, &env->fp_status);
+    ret = float32_to_int32_round_to_zero(t0, &env->fp_status);
+    update_fpscr(GETPC());
+    return ret;
+}
+
+uint32_t helper_ftrc_DT(float64 t0)
+{
+    uint32_t ret;
+    set_float_exception_flags(0, &env->fp_status);
+    ret = float64_to_int32_round_to_zero(t0, &env->fp_status);
     update_fpscr(GETPC());
     return ret;
 }

From 7dae117a58dc89af15e3832fe435a4037c83d3d2 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Sun, 10 Apr 2011 21:09:12 +0200
Subject: [PATCH 156/386] target-ppc: remove #ifdef FLOAT128

Now that PPC defaults to softfloat which always provides float128
support, there is no need to keep two version of the code, depending if
float128 support is available or not. Suggested by Peter Maydell.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-ppc/op_helper.c | 20 --------------------
 1 file changed, 20 deletions(-)

diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 5882becbc9..8c993a1cf5 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -1287,7 +1287,6 @@ uint64_t helper_fmadd (uint64_t arg1, uint64_t arg2, uint64_t arg3)
             /* sNaN operation */
             fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
         }
-#ifdef FLOAT128
         /* This is the way the PowerPC specification defines it */
         float128 ft0_128, ft1_128;
 
@@ -1303,10 +1302,6 @@ uint64_t helper_fmadd (uint64_t arg1, uint64_t arg2, uint64_t arg3)
             ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status);
             farg1.d = float128_to_float64(ft0_128, &env->fp_status);
         }
-#else
-        /* This is OK on x86 hosts */
-        farg1.d = (farg1.d * farg2.d) + farg3.d;
-#endif
     }
 
     return farg1.ll;
@@ -1332,7 +1327,6 @@ uint64_t helper_fmsub (uint64_t arg1, uint64_t arg2, uint64_t arg3)
             /* sNaN operation */
             fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
         }
-#ifdef FLOAT128
         /* This is the way the PowerPC specification defines it */
         float128 ft0_128, ft1_128;
 
@@ -1348,10 +1342,6 @@ uint64_t helper_fmsub (uint64_t arg1, uint64_t arg2, uint64_t arg3)
             ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status);
             farg1.d = float128_to_float64(ft0_128, &env->fp_status);
         }
-#else
-        /* This is OK on x86 hosts */
-        farg1.d = (farg1.d * farg2.d) - farg3.d;
-#endif
     }
     return farg1.ll;
 }
@@ -1376,7 +1366,6 @@ uint64_t helper_fnmadd (uint64_t arg1, uint64_t arg2, uint64_t arg3)
             /* sNaN operation */
             fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
         }
-#ifdef FLOAT128
         /* This is the way the PowerPC specification defines it */
         float128 ft0_128, ft1_128;
 
@@ -1392,10 +1381,6 @@ uint64_t helper_fnmadd (uint64_t arg1, uint64_t arg2, uint64_t arg3)
             ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status);
             farg1.d = float128_to_float64(ft0_128, &env->fp_status);
         }
-#else
-        /* This is OK on x86 hosts */
-        farg1.d = (farg1.d * farg2.d) + farg3.d;
-#endif
         if (likely(!float64_is_any_nan(farg1.d))) {
             farg1.d = float64_chs(farg1.d);
         }
@@ -1423,7 +1408,6 @@ uint64_t helper_fnmsub (uint64_t arg1, uint64_t arg2, uint64_t arg3)
             /* sNaN operation */
             fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);
         }
-#ifdef FLOAT128
         /* This is the way the PowerPC specification defines it */
         float128 ft0_128, ft1_128;
 
@@ -1439,10 +1423,6 @@ uint64_t helper_fnmsub (uint64_t arg1, uint64_t arg2, uint64_t arg3)
             ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status);
             farg1.d = float128_to_float64(ft0_128, &env->fp_status);
         }
-#else
-        /* This is OK on x86 hosts */
-        farg1.d = (farg1.d * farg2.d) - farg3.d;
-#endif
         if (likely(!float64_is_any_nan(farg1.d))) {
             farg1.d = float64_chs(farg1.d);
         }

From f50ee4e0749604373bfd3bf3bb1d94c28787a378 Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Sat, 9 Apr 2011 23:13:20 +0200
Subject: [PATCH 157/386] configure: disable opengl per default

There is a bug in nvidia's binary GPU driver, which causes a segmentation
fault if linked to libGL.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 configure | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configure b/configure
index ed4d951ce9..da2da04059 100755
--- a/configure
+++ b/configure
@@ -177,6 +177,7 @@ spice=""
 rbd=""
 smartcard=""
 smartcard_nss=""
+opengl="no"
 
 # parse CC options first
 for opt do

From 3bad98147f84f2606afe2afb9d80ea15d3e1c39f Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Sun, 10 Apr 2011 17:28:56 +0200
Subject: [PATCH 158/386] cpu-common: Modify cpu_physical_memory_read and
 cpu_physical_memory_write

A lot of calls don't operate on bytes but on words or on structured data.
So instead of a pointer to uint8_t, a void pointer is the better choice.

This allows removing many type casts.

(Some very early implementations of memcpy used char pointers
which were replaced by void pointers for the same reason).

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 cpu-common.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/cpu-common.h b/cpu-common.h
index ef4e8dab7a..96c02aeb64 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -68,14 +68,14 @@ void cpu_unregister_io_memory(int table_address);
 void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
                             int len, int is_write);
 static inline void cpu_physical_memory_read(target_phys_addr_t addr,
-                                            uint8_t *buf, int len)
+                                            void *buf, int len)
 {
     cpu_physical_memory_rw(addr, buf, len, 0);
 }
 static inline void cpu_physical_memory_write(target_phys_addr_t addr,
-                                             const uint8_t *buf, int len)
+                                             const void *buf, int len)
 {
-    cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1);
+    cpu_physical_memory_rw(addr, (void *)buf, len, 1);
 }
 void *cpu_physical_memory_map(target_phys_addr_t addr,
                               target_phys_addr_t *plen,

From 71d2b725e1f38162872b198992a61fa460978d77 Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Sat, 26 Mar 2011 21:06:56 +0100
Subject: [PATCH 159/386] exec: Remove a type cast which is no longer needed

All other type casts in calls of cpu_physical_memory_write are
used by hardware emulations and will be fixed by separate patches.

Cc: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 exec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/exec.c b/exec.c
index 983c0db3f7..e8f1eeb750 100644
--- a/exec.c
+++ b/exec.c
@@ -4253,7 +4253,7 @@ void stw_phys(target_phys_addr_t addr, uint32_t val)
 void stq_phys(target_phys_addr_t addr, uint64_t val)
 {
     val = tswap64(val);
-    cpu_physical_memory_write(addr, (const uint8_t *)&val, 8);
+    cpu_physical_memory_write(addr, &val, 8);
 }
 
 /* virtual memory access for debug (includes writing to ROM) */

From b8b79323d0f26959237fdb80053cd48a750e3482 Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Sat, 26 Mar 2011 21:11:05 +0100
Subject: [PATCH 160/386] monitor: Remove some type casts which are no longer
 needed

All other type casts in calls of cpu_physical_memory_read are
used by hardware emulations and will be fixed by separate patches.

Cc: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 monitor.c | 48 ++++++++++++++++++------------------------------
 1 file changed, 18 insertions(+), 30 deletions(-)

diff --git a/monitor.c b/monitor.c
index f1a08dc486..07186ca028 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2026,7 +2026,7 @@ static void tlb_info_32(Monitor *mon, CPUState *env)
 
     pgd = env->cr[3] & ~0xfff;
     for(l1 = 0; l1 < 1024; l1++) {
-        cpu_physical_memory_read(pgd + l1 * 4, (uint8_t *)&pde, 4);
+        cpu_physical_memory_read(pgd + l1 * 4, &pde, 4);
         pde = le32_to_cpu(pde);
         if (pde & PG_PRESENT_MASK) {
             if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
@@ -2034,8 +2034,7 @@ static void tlb_info_32(Monitor *mon, CPUState *env)
                 print_pte(mon, (l1 << 22), pde, ~((1 << 21) - 1));
             } else {
                 for(l2 = 0; l2 < 1024; l2++) {
-                    cpu_physical_memory_read((pde & ~0xfff) + l2 * 4,
-                                             (uint8_t *)&pte, 4);
+                    cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4);
                     pte = le32_to_cpu(pte);
                     if (pte & PG_PRESENT_MASK) {
                         print_pte(mon, (l1 << 22) + (l2 << 12),
@@ -2056,13 +2055,12 @@ static void tlb_info_pae32(Monitor *mon, CPUState *env)
 
     pdp_addr = env->cr[3] & ~0x1f;
     for (l1 = 0; l1 < 4; l1++) {
-        cpu_physical_memory_read(pdp_addr + l1 * 8, (uint8_t *)&pdpe, 8);
+        cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8);
         pdpe = le64_to_cpu(pdpe);
         if (pdpe & PG_PRESENT_MASK) {
             pd_addr = pdpe & 0x3fffffffff000ULL;
             for (l2 = 0; l2 < 512; l2++) {
-                cpu_physical_memory_read(pd_addr + l2 * 8,
-                                         (uint8_t *)&pde, 8);
+                cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8);
                 pde = le64_to_cpu(pde);
                 if (pde & PG_PRESENT_MASK) {
                     if (pde & PG_PSE_MASK) {
@@ -2072,8 +2070,7 @@ static void tlb_info_pae32(Monitor *mon, CPUState *env)
                     } else {
                         pt_addr = pde & 0x3fffffffff000ULL;
                         for (l3 = 0; l3 < 512; l3++) {
-                            cpu_physical_memory_read(pt_addr + l3 * 8,
-                                                     (uint8_t *)&pte, 8);
+                            cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8);
                             pte = le64_to_cpu(pte);
                             if (pte & PG_PRESENT_MASK) {
                                 print_pte(mon, (l1 << 30 ) + (l2 << 21)
@@ -2098,13 +2095,12 @@ static void tlb_info_64(Monitor *mon, CPUState *env)
 
     pml4_addr = env->cr[3] & 0x3fffffffff000ULL;
     for (l1 = 0; l1 < 512; l1++) {
-        cpu_physical_memory_read(pml4_addr + l1 * 8, (uint8_t *)&pml4e, 8);
+        cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
         pml4e = le64_to_cpu(pml4e);
         if (pml4e & PG_PRESENT_MASK) {
             pdp_addr = pml4e & 0x3fffffffff000ULL;
             for (l2 = 0; l2 < 512; l2++) {
-                cpu_physical_memory_read(pdp_addr + l2 * 8, (uint8_t *)&pdpe,
-                                         8);
+                cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
                 pdpe = le64_to_cpu(pdpe);
                 if (pdpe & PG_PRESENT_MASK) {
                     if (pdpe & PG_PSE_MASK) {
@@ -2114,8 +2110,7 @@ static void tlb_info_64(Monitor *mon, CPUState *env)
                     } else {
                         pd_addr = pdpe & 0x3fffffffff000ULL;
                         for (l3 = 0; l3 < 512; l3++) {
-                            cpu_physical_memory_read(pd_addr + l3 * 8,
-                                                     (uint8_t *)&pde, 8);
+                            cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
                             pde = le64_to_cpu(pde);
                             if (pde & PG_PRESENT_MASK) {
                                 if (pde & PG_PSE_MASK) {
@@ -2128,8 +2123,7 @@ static void tlb_info_64(Monitor *mon, CPUState *env)
                                     for (l4 = 0; l4 < 512; l4++) {
                                         cpu_physical_memory_read(pt_addr
                                                                  + l4 * 8,
-                                                                 (uint8_t *)&pte,
-                                                                 8);
+                                                                 &pte, 8);
                                         pte = le64_to_cpu(pte);
                                         if (pte & PG_PRESENT_MASK) {
                                             print_pte(mon, (l1 << 39) +
@@ -2207,7 +2201,7 @@ static void mem_info_32(Monitor *mon, CPUState *env)
     last_prot = 0;
     start = -1;
     for(l1 = 0; l1 < 1024; l1++) {
-        cpu_physical_memory_read(pgd + l1 * 4, (uint8_t *)&pde, 4);
+        cpu_physical_memory_read(pgd + l1 * 4, &pde, 4);
         pde = le32_to_cpu(pde);
         end = l1 << 22;
         if (pde & PG_PRESENT_MASK) {
@@ -2216,8 +2210,7 @@ static void mem_info_32(Monitor *mon, CPUState *env)
                 mem_print(mon, &start, &last_prot, end, prot);
             } else {
                 for(l2 = 0; l2 < 1024; l2++) {
-                    cpu_physical_memory_read((pde & ~0xfff) + l2 * 4,
-                                             (uint8_t *)&pte, 4);
+                    cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4);
                     pte = le32_to_cpu(pte);
                     end = (l1 << 22) + (l2 << 12);
                     if (pte & PG_PRESENT_MASK) {
@@ -2246,14 +2239,13 @@ static void mem_info_pae32(Monitor *mon, CPUState *env)
     last_prot = 0;
     start = -1;
     for (l1 = 0; l1 < 4; l1++) {
-        cpu_physical_memory_read(pdp_addr + l1 * 8, (uint8_t *)&pdpe, 8);
+        cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8);
         pdpe = le64_to_cpu(pdpe);
         end = l1 << 30;
         if (pdpe & PG_PRESENT_MASK) {
             pd_addr = pdpe & 0x3fffffffff000ULL;
             for (l2 = 0; l2 < 512; l2++) {
-                cpu_physical_memory_read(pd_addr + l2 * 8,
-                                         (uint8_t *)&pde, 8);
+                cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8);
                 pde = le64_to_cpu(pde);
                 end = (l1 << 30) + (l2 << 21);
                 if (pde & PG_PRESENT_MASK) {
@@ -2264,8 +2256,7 @@ static void mem_info_pae32(Monitor *mon, CPUState *env)
                     } else {
                         pt_addr = pde & 0x3fffffffff000ULL;
                         for (l3 = 0; l3 < 512; l3++) {
-                            cpu_physical_memory_read(pt_addr + l3 * 8,
-                                                     (uint8_t *)&pte, 8);
+                            cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8);
                             pte = le64_to_cpu(pte);
                             end = (l1 << 30) + (l2 << 21) + (l3 << 12);
                             if (pte & PG_PRESENT_MASK) {
@@ -2302,14 +2293,13 @@ static void mem_info_64(Monitor *mon, CPUState *env)
     last_prot = 0;
     start = -1;
     for (l1 = 0; l1 < 512; l1++) {
-        cpu_physical_memory_read(pml4_addr + l1 * 8, (uint8_t *)&pml4e, 8);
+        cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
         pml4e = le64_to_cpu(pml4e);
         end = l1 << 39;
         if (pml4e & PG_PRESENT_MASK) {
             pdp_addr = pml4e & 0x3fffffffff000ULL;
             for (l2 = 0; l2 < 512; l2++) {
-                cpu_physical_memory_read(pdp_addr + l2 * 8, (uint8_t *)&pdpe,
-                                         8);
+                cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
                 pdpe = le64_to_cpu(pdpe);
                 end = (l1 << 39) + (l2 << 30);
                 if (pdpe & PG_PRESENT_MASK) {
@@ -2320,8 +2310,7 @@ static void mem_info_64(Monitor *mon, CPUState *env)
                     } else {
                         pd_addr = pdpe & 0x3fffffffff000ULL;
                         for (l3 = 0; l3 < 512; l3++) {
-                            cpu_physical_memory_read(pd_addr + l3 * 8,
-                                                     (uint8_t *)&pde, 8);
+                            cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
                             pde = le64_to_cpu(pde);
                             end = (l1 << 39) + (l2 << 30) + (l3 << 21);
                             if (pde & PG_PRESENT_MASK) {
@@ -2334,8 +2323,7 @@ static void mem_info_64(Monitor *mon, CPUState *env)
                                     for (l4 = 0; l4 < 512; l4++) {
                                         cpu_physical_memory_read(pt_addr
                                                                  + l4 * 8,
-                                                                 (uint8_t *)&pte,
-                                                                 8);
+                                                                 &pte, 8);
                                         pte = le64_to_cpu(pte);
                                         end = (l1 << 39) + (l2 << 30) +
                                             (l3 << 21) + (l4 << 12);

From 54f7b4a396d00522d99c685562a54725a1b52e40 Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Sun, 10 Apr 2011 18:23:39 +0200
Subject: [PATCH 161/386] Replace cpu_physical_memory_rw were possible

Using cpu_physical_memory_read, cpu_physical_memory_write and ldub_phys
improves readability and allows removing some type casts.

lduw_phys and ldl_phys were not used because both require aligned
addresses. Therefore it is not possible to simply replace existing
calls by one of these functions.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 disas.c              |  2 +-
 exec.c               |  2 +-
 hw/rc4030.c          |  4 ++--
 hw/s390-virtio-bus.c |  3 ++-
 hw/s390-virtio.c     |  4 ++--
 hw/sm501_template.h  |  2 +-
 hw/usb-ohci.c        | 14 ++++++--------
 monitor.c            |  9 ++++-----
 8 files changed, 19 insertions(+), 21 deletions(-)

diff --git a/disas.c b/disas.c
index 17b4ce47b2..223606cc50 100644
--- a/disas.c
+++ b/disas.c
@@ -345,7 +345,7 @@ monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
                      struct disassemble_info *info)
 {
     if (monitor_disas_is_physical) {
-        cpu_physical_memory_rw(memaddr, myaddr, length, 0);
+        cpu_physical_memory_read(memaddr, myaddr, length);
     } else {
         cpu_memory_rw_debug(monitor_disas_env, memaddr,myaddr, length, 0);
     }
diff --git a/exec.c b/exec.c
index e8f1eeb750..b1ee52a4d0 100644
--- a/exec.c
+++ b/exec.c
@@ -3932,7 +3932,7 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
             bounce.addr = addr;
             bounce.len = l;
             if (!is_write) {
-                cpu_physical_memory_rw(addr, bounce.buffer, l, 0);
+                cpu_physical_memory_read(addr, bounce.buffer, l);
             }
             ptr = bounce.buffer;
         } else {
diff --git a/hw/rc4030.c b/hw/rc4030.c
index d30230a859..6563336dd0 100644
--- a/hw/rc4030.c
+++ b/hw/rc4030.c
@@ -307,7 +307,7 @@ static void rc4030_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
         if (s->cache_ltag == 0x80000001 && s->cache_bmask == 0xf0f0f0f) {
             target_phys_addr_t dest = s->cache_ptag & ~0x1;
             dest += (s->cache_maint & 0x3) << 3;
-            cpu_physical_memory_rw(dest, (uint8_t*)&val, 4, 1);
+            cpu_physical_memory_write(dest, &val, 4);
         }
         break;
     /* Remote Speed Registers */
@@ -704,7 +704,7 @@ void rc4030_dma_memory_rw(void *opaque, target_phys_addr_t addr, uint8_t *buf, i
         entry_addr = s->dma_tl_base + index * sizeof(dma_pagetable_entry);
         /* XXX: not sure. should we really use only lowest bits? */
         entry_addr &= 0x7fffffff;
-        cpu_physical_memory_rw(entry_addr, (uint8_t *)&entry, sizeof(entry), 0);
+        cpu_physical_memory_read(entry_addr, &entry, sizeof(entry));
 
         /* Read/write data at right place */
         phys_addr = entry.frame + (addr & (DMA_PAGESIZE - 1));
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index 60e0135ed8..175e5cb3a0 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -233,7 +233,8 @@ void s390_virtio_device_sync(VirtIOS390Device *dev)
         dev->vdev->get_config(dev->vdev, dev->vdev->config);
     }
 
-    cpu_physical_memory_rw(cur_offs, dev->vdev->config, dev->vdev->config_len, 1);
+    cpu_physical_memory_write(cur_offs,
+                              dev->vdev->config, dev->vdev->config_len);
     cur_offs += dev->vdev->config_len;
 }
 
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 850422fee0..d429f10d56 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -230,8 +230,8 @@ static void s390_init(ram_addr_t ram_size,
     }
 
     if (kernel_cmdline) {
-        cpu_physical_memory_rw(KERN_PARM_AREA, (uint8_t *)kernel_cmdline,
-                               strlen(kernel_cmdline), 1);
+        cpu_physical_memory_write(KERN_PARM_AREA, kernel_cmdline,
+                                  strlen(kernel_cmdline));
     }
 
     /* Create VirtIO network adapters */
diff --git a/hw/sm501_template.h b/hw/sm501_template.h
index d1ceef9cb6..2d4a3d8b48 100644
--- a/hw/sm501_template.h
+++ b/hw/sm501_template.h
@@ -120,7 +120,7 @@ static void glue(draw_hwc_line_, PIXEL_NAME)(SM501State * s, int crt,
 
         /* get pixel value */
         if (i % 4 == 0) {
-            cpu_physical_memory_rw(cursor_addr, &bitset, 1, 0);
+            bitset = ldub_phys(cursor_addr);
             cursor_addr++;
         }
         v = bitset & 3;
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index d2b14f7b4f..0ad4f555d0 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -427,7 +427,7 @@ static inline int get_dwords(OHCIState *ohci,
     addr += ohci->localmem_base;
 
     for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
-        cpu_physical_memory_rw(addr, (uint8_t *)buf, sizeof(*buf), 0);
+        cpu_physical_memory_read(addr, buf, sizeof(*buf));
         *buf = le32_to_cpu(*buf);
     }
 
@@ -444,7 +444,7 @@ static inline int put_dwords(OHCIState *ohci,
 
     for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
         uint32_t tmp = cpu_to_le32(*buf);
-        cpu_physical_memory_rw(addr, (uint8_t *)&tmp, sizeof(tmp), 1);
+        cpu_physical_memory_write(addr, &tmp, sizeof(tmp));
     }
 
     return 1;
@@ -459,7 +459,7 @@ static inline int get_words(OHCIState *ohci,
     addr += ohci->localmem_base;
 
     for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
-        cpu_physical_memory_rw(addr, (uint8_t *)buf, sizeof(*buf), 0);
+        cpu_physical_memory_read(addr, buf, sizeof(*buf));
         *buf = le16_to_cpu(*buf);
     }
 
@@ -476,7 +476,7 @@ static inline int put_words(OHCIState *ohci,
 
     for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
         uint16_t tmp = cpu_to_le16(*buf);
-        cpu_physical_memory_rw(addr, (uint8_t *)&tmp, sizeof(tmp), 1);
+        cpu_physical_memory_write(addr, &tmp, sizeof(tmp));
     }
 
     return 1;
@@ -504,8 +504,7 @@ static inline int ohci_read_iso_td(OHCIState *ohci,
 static inline int ohci_read_hcca(OHCIState *ohci,
                                  uint32_t addr, struct ohci_hcca *hcca)
 {
-    cpu_physical_memory_rw(addr + ohci->localmem_base,
-                           (uint8_t *)hcca, sizeof(*hcca), 0);
+    cpu_physical_memory_read(addr + ohci->localmem_base, hcca, sizeof(*hcca));
     return 1;
 }
 
@@ -531,8 +530,7 @@ static inline int ohci_put_iso_td(OHCIState *ohci,
 static inline int ohci_put_hcca(OHCIState *ohci,
                                 uint32_t addr, struct ohci_hcca *hcca)
 {
-    cpu_physical_memory_rw(addr + ohci->localmem_base,
-                           (uint8_t *)hcca, sizeof(*hcca), 1);
+    cpu_physical_memory_write(addr + ohci->localmem_base, hcca, sizeof(*hcca));
     return 1;
 }
 
diff --git a/monitor.c b/monitor.c
index 07186ca028..5f3bc726bd 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1429,7 +1429,7 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
         if (l > line_size)
             l = line_size;
         if (is_physical) {
-            cpu_physical_memory_rw(addr, buf, l, 0);
+            cpu_physical_memory_read(addr, buf, l);
         } else {
             env = mon_get_cpu();
             if (cpu_memory_rw_debug(env, addr, buf, l, 0) < 0) {
@@ -1605,7 +1605,7 @@ static int do_physical_memory_save(Monitor *mon, const QDict *qdict,
         l = sizeof(buf);
         if (l > size)
             l = size;
-        cpu_physical_memory_rw(addr, buf, l, 0);
+        cpu_physical_memory_read(addr, buf, l);
         if (fwrite(buf, 1, l, f) != l) {
             monitor_printf(mon, "fwrite() error in do_physical_memory_save\n");
             goto exit;
@@ -1625,17 +1625,16 @@ exit:
 static void do_sum(Monitor *mon, const QDict *qdict)
 {
     uint32_t addr;
-    uint8_t buf[1];
     uint16_t sum;
     uint32_t start = qdict_get_int(qdict, "start");
     uint32_t size = qdict_get_int(qdict, "size");
 
     sum = 0;
     for(addr = start; addr < (start + size); addr++) {
-        cpu_physical_memory_rw(addr, buf, 1, 0);
+        uint8_t val = ldub_phys(addr);
         /* BSD sum algorithm ('sum' Unix command) */
         sum = (sum >> 1) | (sum << 15);
-        sum += buf[0];
+        sum += val;
     }
     monitor_printf(mon, "%05d\n", sum);
 }

From 54f8e61d5bf8c80c407d8d6ea46ead816c029512 Mon Sep 17 00:00:00 2001
From: Wen Congyang <wency@cn.fujitsu.com>
Date: Tue, 12 Apr 2011 17:27:44 +0800
Subject: [PATCH 162/386] fix acpi regression

This bug is introduced by commit 23910d3f.

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/acpi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/acpi.c b/hw/acpi.c
index e372474399..ad40fb4c3c 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -355,7 +355,7 @@ static uint8_t *acpi_gpe_ioport_get_ptr(ACPIGPE *gpe, uint32_t addr)
     if (addr < gpe->len / 2) {
         cur = gpe->sts + addr;
     } else if (addr < gpe->len) {
-        cur = gpe->en + addr;
+        cur = gpe->en + addr - gpe->len / 2;
     } else {
         abort();
     }

From 62698be3bac2e4c969205f3849c48922e0e76e88 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 11 Apr 2011 16:26:11 +0100
Subject: [PATCH 163/386] target-arm: Use lookup table for size check on Neon
 3-reg-same insns

Simplify the checks for invalid size values for the Neon "three registers
of the same size" instruction forms (and add them where they were missing)
by using a lookup table.

This includes adding symbolic constants for the op values in this space,
since we now use them in multiple places.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 197 ++++++++++++++++++++++++++++-------------
 1 file changed, 133 insertions(+), 64 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 998cfd530c..3fa27e145b 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3558,15 +3558,14 @@ static void gen_nop_hint(DisasContext *s, int val)
 
 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
 
-static inline int gen_neon_add(int size, TCGv t0, TCGv t1)
+static inline void gen_neon_add(int size, TCGv t0, TCGv t1)
 {
     switch (size) {
     case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
     case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
     case 2: tcg_gen_add_i32(t0, t0, t1); break;
-    default: return 1;
+    default: abort();
     }
-    return 0;
 }
 
 static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
@@ -4245,6 +4244,74 @@ static void gen_neon_narrow_op(int op, int u, int size, TCGv dest, TCGv_i64 src)
     }
 }
 
+/* Symbolic constants for op fields for Neon 3-register same-length.
+ * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
+ * table A7-9.
+ */
+#define NEON_3R_VHADD 0
+#define NEON_3R_VQADD 1
+#define NEON_3R_VRHADD 2
+#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
+#define NEON_3R_VHSUB 4
+#define NEON_3R_VQSUB 5
+#define NEON_3R_VCGT 6
+#define NEON_3R_VCGE 7
+#define NEON_3R_VSHL 8
+#define NEON_3R_VQSHL 9
+#define NEON_3R_VRSHL 10
+#define NEON_3R_VQRSHL 11
+#define NEON_3R_VMAX 12
+#define NEON_3R_VMIN 13
+#define NEON_3R_VABD 14
+#define NEON_3R_VABA 15
+#define NEON_3R_VADD_VSUB 16
+#define NEON_3R_VTST_VCEQ 17
+#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
+#define NEON_3R_VMUL 19
+#define NEON_3R_VPMAX 20
+#define NEON_3R_VPMIN 21
+#define NEON_3R_VQDMULH_VQRDMULH 22
+#define NEON_3R_VPADD 23
+#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
+#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
+#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
+#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
+#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
+#define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
+
+static const uint8_t neon_3r_sizes[] = {
+    [NEON_3R_VHADD] = 0x7,
+    [NEON_3R_VQADD] = 0xf,
+    [NEON_3R_VRHADD] = 0x7,
+    [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
+    [NEON_3R_VHSUB] = 0x7,
+    [NEON_3R_VQSUB] = 0xf,
+    [NEON_3R_VCGT] = 0x7,
+    [NEON_3R_VCGE] = 0x7,
+    [NEON_3R_VSHL] = 0xf,
+    [NEON_3R_VQSHL] = 0xf,
+    [NEON_3R_VRSHL] = 0xf,
+    [NEON_3R_VQRSHL] = 0xf,
+    [NEON_3R_VMAX] = 0x7,
+    [NEON_3R_VMIN] = 0x7,
+    [NEON_3R_VABD] = 0x7,
+    [NEON_3R_VABA] = 0x7,
+    [NEON_3R_VADD_VSUB] = 0xf,
+    [NEON_3R_VTST_VCEQ] = 0x7,
+    [NEON_3R_VML] = 0x7,
+    [NEON_3R_VMUL] = 0x7,
+    [NEON_3R_VPMAX] = 0x7,
+    [NEON_3R_VPMIN] = 0x7,
+    [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
+    [NEON_3R_VPADD] = 0x7,
+    [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
+    [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
+    [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
+    [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
+    [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
+    [NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */
+};
+
 /* Translate a NEON data processing instruction.  Return nonzero if the
    instruction is invalid.
    We process data in a mixture of 32-bit and 64-bit chunks.
@@ -4277,56 +4344,59 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
     if ((insn & (1 << 23)) == 0) {
         /* Three register same length.  */
         op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
-        if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
-                          || op == 10 || op  == 11 || op == 16)) {
-            /* 64-bit element instructions.  */
+        /* Catch invalid op and bad size combinations: UNDEF */
+        if ((neon_3r_sizes[op] & (1 << size)) == 0) {
+            return 1;
+        }
+        if (size == 3 && op != NEON_3R_LOGIC) {
+            /* 64-bit element instructions. */
             for (pass = 0; pass < (q ? 2 : 1); pass++) {
                 neon_load_reg64(cpu_V0, rn + pass);
                 neon_load_reg64(cpu_V1, rm + pass);
                 switch (op) {
-                case 1: /* VQADD */
+                case NEON_3R_VQADD:
                     if (u) {
                         gen_helper_neon_qadd_u64(cpu_V0, cpu_V0, cpu_V1);
                     } else {
                         gen_helper_neon_qadd_s64(cpu_V0, cpu_V0, cpu_V1);
                     }
                     break;
-                case 5: /* VQSUB */
+                case NEON_3R_VQSUB:
                     if (u) {
                         gen_helper_neon_qsub_u64(cpu_V0, cpu_V0, cpu_V1);
                     } else {
                         gen_helper_neon_qsub_s64(cpu_V0, cpu_V0, cpu_V1);
                     }
                     break;
-                case 8: /* VSHL */
+                case NEON_3R_VSHL:
                     if (u) {
                         gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
                     } else {
                         gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
                     }
                     break;
-                case 9: /* VQSHL */
+                case NEON_3R_VQSHL:
                     if (u) {
                         gen_helper_neon_qshl_u64(cpu_V0, cpu_V1, cpu_V0);
                     } else {
                         gen_helper_neon_qshl_s64(cpu_V0, cpu_V1, cpu_V0);
                     }
                     break;
-                case 10: /* VRSHL */
+                case NEON_3R_VRSHL:
                     if (u) {
                         gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
                     } else {
                         gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
                     }
                     break;
-                case 11: /* VQRSHL */
+                case NEON_3R_VQRSHL:
                     if (u) {
                         gen_helper_neon_qrshl_u64(cpu_V0, cpu_V1, cpu_V0);
                     } else {
                         gen_helper_neon_qrshl_s64(cpu_V0, cpu_V1, cpu_V0);
                     }
                     break;
-                case 16:
+                case NEON_3R_VADD_VSUB:
                     if (u) {
                         tcg_gen_sub_i64(CPU_V001);
                     } else {
@@ -4341,10 +4411,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
             return 0;
         }
         switch (op) {
-        case 8: /* VSHL */
-        case 9: /* VQSHL */
-        case 10: /* VRSHL */
-        case 11: /* VQRSHL */
+        case NEON_3R_VSHL:
+        case NEON_3R_VQSHL:
+        case NEON_3R_VRSHL:
+        case NEON_3R_VQRSHL:
             {
                 int rtmp;
                 /* Shift instruction operands are reversed.  */
@@ -4354,15 +4424,15 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 pairwise = 0;
             }
             break;
-        case 20: /* VPMAX */
-        case 21: /* VPMIN */
-        case 23: /* VPADD */
+        case NEON_3R_VPMAX:
+        case NEON_3R_VPMIN:
+        case NEON_3R_VPADD:
             pairwise = 1;
             break;
-        case 26: /* VPADD (float) */
+        case NEON_3R_FLOAT_ARITH: /* VADD, VSUB, VPADD, VABD (float) */
             pairwise = (u && size < 2);
             break;
-        case 30: /* VPMIN/VPMAX (float) */
+        case NEON_3R_FLOAT_MINMAX: /* VPMIN/VPMAX (float) */
             pairwise = u;
             break;
         default:
@@ -4391,16 +4461,16 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
             tmp2 = neon_load_reg(rm, pass);
         }
         switch (op) {
-        case 0: /* VHADD */
+        case NEON_3R_VHADD:
             GEN_NEON_INTEGER_OP(hadd);
             break;
-        case 1: /* VQADD */
+        case NEON_3R_VQADD:
             GEN_NEON_INTEGER_OP(qadd);
             break;
-        case 2: /* VRHADD */
+        case NEON_3R_VRHADD:
             GEN_NEON_INTEGER_OP(rhadd);
             break;
-        case 3: /* Logic ops.  */
+        case NEON_3R_LOGIC: /* Logic ops.  */
             switch ((u << 2) | size) {
             case 0: /* VAND */
                 tcg_gen_and_i32(tmp, tmp, tmp2);
@@ -4434,81 +4504,80 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 break;
             }
             break;
-        case 4: /* VHSUB */
+        case NEON_3R_VHSUB:
             GEN_NEON_INTEGER_OP(hsub);
             break;
-        case 5: /* VQSUB */
+        case NEON_3R_VQSUB:
             GEN_NEON_INTEGER_OP(qsub);
             break;
-        case 6: /* VCGT */
+        case NEON_3R_VCGT:
             GEN_NEON_INTEGER_OP(cgt);
             break;
-        case 7: /* VCGE */
+        case NEON_3R_VCGE:
             GEN_NEON_INTEGER_OP(cge);
             break;
-        case 8: /* VSHL */
+        case NEON_3R_VSHL:
             GEN_NEON_INTEGER_OP(shl);
             break;
-        case 9: /* VQSHL */
+        case NEON_3R_VQSHL:
             GEN_NEON_INTEGER_OP(qshl);
             break;
-        case 10: /* VRSHL */
+        case NEON_3R_VRSHL:
             GEN_NEON_INTEGER_OP(rshl);
             break;
-        case 11: /* VQRSHL */
+        case NEON_3R_VQRSHL:
             GEN_NEON_INTEGER_OP(qrshl);
             break;
-        case 12: /* VMAX */
+        case NEON_3R_VMAX:
             GEN_NEON_INTEGER_OP(max);
             break;
-        case 13: /* VMIN */
+        case NEON_3R_VMIN:
             GEN_NEON_INTEGER_OP(min);
             break;
-        case 14: /* VABD */
+        case NEON_3R_VABD:
             GEN_NEON_INTEGER_OP(abd);
             break;
-        case 15: /* VABA */
+        case NEON_3R_VABA:
             GEN_NEON_INTEGER_OP(abd);
             tcg_temp_free_i32(tmp2);
             tmp2 = neon_load_reg(rd, pass);
             gen_neon_add(size, tmp, tmp2);
             break;
-        case 16:
+        case NEON_3R_VADD_VSUB:
             if (!u) { /* VADD */
-                if (gen_neon_add(size, tmp, tmp2))
-                    return 1;
+                gen_neon_add(size, tmp, tmp2);
             } else { /* VSUB */
                 switch (size) {
                 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
                 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
                 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
-                default: return 1;
+                default: abort();
                 }
             }
             break;
-        case 17:
+        case NEON_3R_VTST_VCEQ:
             if (!u) { /* VTST */
                 switch (size) {
                 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
                 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
                 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
-                default: return 1;
+                default: abort();
                 }
             } else { /* VCEQ */
                 switch (size) {
                 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
                 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
                 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
-                default: return 1;
+                default: abort();
                 }
             }
             break;
-        case 18: /* Multiply.  */
+        case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
             switch (size) {
             case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
             case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
             case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
-            default: return 1;
+            default: abort();
             }
             tcg_temp_free_i32(tmp2);
             tmp2 = neon_load_reg(rd, pass);
@@ -4518,7 +4587,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 gen_neon_add(size, tmp, tmp2);
             }
             break;
-        case 19: /* VMUL */
+        case NEON_3R_VMUL:
             if (u) { /* polynomial */
                 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
             } else { /* Integer */
@@ -4526,42 +4595,42 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
                 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
                 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
-                default: return 1;
+                default: abort();
                 }
             }
             break;
-        case 20: /* VPMAX */
+        case NEON_3R_VPMAX:
             GEN_NEON_INTEGER_OP(pmax);
             break;
-        case 21: /* VPMIN */
+        case NEON_3R_VPMIN:
             GEN_NEON_INTEGER_OP(pmin);
             break;
-        case 22: /* Hultiply high.  */
+        case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high.  */
             if (!u) { /* VQDMULH */
                 switch (size) {
                 case 1: gen_helper_neon_qdmulh_s16(tmp, tmp, tmp2); break;
                 case 2: gen_helper_neon_qdmulh_s32(tmp, tmp, tmp2); break;
-                default: return 1;
+                default: abort();
                 }
-            } else { /* VQRDHMUL */
+            } else { /* VQRDMULH */
                 switch (size) {
                 case 1: gen_helper_neon_qrdmulh_s16(tmp, tmp, tmp2); break;
                 case 2: gen_helper_neon_qrdmulh_s32(tmp, tmp, tmp2); break;
-                default: return 1;
+                default: abort();
                 }
             }
             break;
-        case 23: /* VPADD */
+        case NEON_3R_VPADD:
             if (u)
                 return 1;
             switch (size) {
             case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
             case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
             case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
-            default: return 1;
+            default: abort();
             }
             break;
-        case 26: /* Floating point arithnetic.  */
+        case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
             switch ((u << 2) | size) {
             case 0: /* VADD */
                 gen_helper_neon_add_f32(tmp, tmp, tmp2);
@@ -4576,10 +4645,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 gen_helper_neon_abd_f32(tmp, tmp, tmp2);
                 break;
             default:
-                return 1;
+                abort();
             }
             break;
-        case 27: /* Float multiply.  */
+        case NEON_3R_FLOAT_MULTIPLY:
             gen_helper_neon_mul_f32(tmp, tmp, tmp2);
             if (!u) {
                 tcg_temp_free_i32(tmp2);
@@ -4591,7 +4660,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 }
             }
             break;
-        case 28: /* Float compare.  */
+        case NEON_3R_FLOAT_CMP:
             if (!u) {
                 gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
             } else {
@@ -4601,7 +4670,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                     gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
             }
             break;
-        case 29: /* Float compare absolute.  */
+        case NEON_3R_FLOAT_ACMP:
             if (!u)
                 return 1;
             if (size == 0)
@@ -4609,13 +4678,13 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
             else
                 gen_helper_neon_acgt_f32(tmp, tmp, tmp2);
             break;
-        case 30: /* Float min/max.  */
+        case NEON_3R_FLOAT_MINMAX:
             if (size == 0)
                 gen_helper_neon_max_f32(tmp, tmp, tmp2);
             else
                 gen_helper_neon_min_f32(tmp, tmp, tmp2);
             break;
-        case 31:
+        case NEON_3R_VRECPS_VRSQRTS:
             if (size == 0)
                 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
             else

From 25f84f79481db5363c638dd95d5c2a0a0e430cee Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 11 Apr 2011 16:26:12 +0100
Subject: [PATCH 164/386] target-arm: Handle UNDEF cases for Neon 3-regs-same
 insns

Correct the handling of UNDEF cases for the NEON "3 registers same
size" forms, by adding missing checks and rationalising some others
so they are done early enough to avoid leaking TCG temporaries.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 54 +++++++++++++++++++++++++++++++++---------
 1 file changed, 43 insertions(+), 11 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 3fa27e145b..5ffbace5ae 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4348,6 +4348,12 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
         if ((neon_3r_sizes[op] & (1 << size)) == 0) {
             return 1;
         }
+        /* All insns of this form UNDEF for either this condition or the
+         * superset of cases "Q==1"; we catch the latter later.
+         */
+        if (q && ((rd | rn | rm) & 1)) {
+            return 1;
+        }
         if (size == 3 && op != NEON_3R_LOGIC) {
             /* 64-bit element instructions. */
             for (pass = 0; pass < (q ? 2 : 1); pass++) {
@@ -4410,6 +4416,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
             }
             return 0;
         }
+        pairwise = 0;
         switch (op) {
         case NEON_3R_VSHL:
         case NEON_3R_VQSHL:
@@ -4421,25 +4428,54 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 rtmp = rn;
                 rn = rm;
                 rm = rtmp;
-                pairwise = 0;
             }
             break;
+        case NEON_3R_VPADD:
+            if (u) {
+                return 1;
+            }
+            /* Fall through */
         case NEON_3R_VPMAX:
         case NEON_3R_VPMIN:
-        case NEON_3R_VPADD:
             pairwise = 1;
             break;
-        case NEON_3R_FLOAT_ARITH: /* VADD, VSUB, VPADD, VABD (float) */
-            pairwise = (u && size < 2);
+        case NEON_3R_FLOAT_ARITH:
+            pairwise = (u && size < 2); /* if VPADD (float) */
             break;
-        case NEON_3R_FLOAT_MINMAX: /* VPMIN/VPMAX (float) */
-            pairwise = u;
+        case NEON_3R_FLOAT_MINMAX:
+            pairwise = u; /* if VPMIN/VPMAX (float) */
+            break;
+        case NEON_3R_FLOAT_CMP:
+            if (!u && size) {
+                /* no encoding for U=0 C=1x */
+                return 1;
+            }
+            break;
+        case NEON_3R_FLOAT_ACMP:
+            if (!u) {
+                return 1;
+            }
+            break;
+        case NEON_3R_VRECPS_VRSQRTS:
+            if (u) {
+                return 1;
+            }
+            break;
+        case NEON_3R_VMUL:
+            if (u && (size != 0)) {
+                /* UNDEF on invalid size for polynomial subcase */
+                return 1;
+            }
             break;
         default:
-            pairwise = 0;
             break;
         }
 
+        if (pairwise && q) {
+            /* All the pairwise insns UNDEF if Q is set */
+            return 1;
+        }
+
         for (pass = 0; pass < (q ? 4 : 2); pass++) {
 
         if (pairwise) {
@@ -4621,8 +4657,6 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
             }
             break;
         case NEON_3R_VPADD:
-            if (u)
-                return 1;
             switch (size) {
             case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
             case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
@@ -4671,8 +4705,6 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
             }
             break;
         case NEON_3R_FLOAT_ACMP:
-            if (!u)
-                return 1;
             if (size == 0)
                 gen_helper_neon_acge_f32(tmp, tmp, tmp2);
             else

From a5a14945da2c9ea8903c69af22274c33ad9488f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juha=20Riihim=C3=A4ki?= <juha.riihimaki@nokia.com>
Date: Mon, 11 Apr 2011 16:26:13 +0100
Subject: [PATCH 165/386] target-arm: Simplify three-register pairwise code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Since we know that the case of (pairwise && q) has been caught
earlier, we can simplify the register setup code for each pass
in the three-register-same-size Neon loop.

Signed-off-by: Juha Riihimäki <juha.riihimaki@nokia.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 5ffbace5ae..0cf933d021 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4328,7 +4328,6 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
     int count;
     int pairwise;
     int u;
-    int n;
     uint32_t imm, mask;
     TCGv tmp, tmp2, tmp3, tmp4, tmp5;
     TCGv_i64 tmp64;
@@ -4480,16 +4479,12 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
 
         if (pairwise) {
             /* Pairwise.  */
-            if (q)
-                n = (pass & 1) * 2;
-            else
-                n = 0;
-            if (pass < q + 1) {
-                tmp = neon_load_reg(rn, n);
-                tmp2 = neon_load_reg(rn, n + 1);
+            if (pass < 1) {
+                tmp = neon_load_reg(rn, 0);
+                tmp2 = neon_load_reg(rn, 1);
             } else {
-                tmp = neon_load_reg(rm, n);
-                tmp2 = neon_load_reg(rm, n + 1);
+                tmp = neon_load_reg(rm, 0);
+                tmp2 = neon_load_reg(rm, 1);
             }
         } else {
             /* Elementwise.  */
@@ -5147,6 +5142,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                     /* VMOV, VMVN.  */
                     tmp = tcg_temp_new_i32();
                     if (op == 14 && invert) {
+                        int n;
                         uint32_t val;
                         val = 0;
                         for (n = 0; n < 4; n++) {
@@ -5575,6 +5571,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                     break;
                 case 33: /* VTRN */
                     if (size == 2) {
+                        int n;
                         for (n = 0; n < (q ? 4 : 2); n += 2) {
                             tmp = neon_load_reg(rm, n);
                             tmp2 = neon_load_reg(rd, n + 1);
@@ -5866,7 +5863,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 }
             } else if ((insn & (1 << 10)) == 0) {
                 /* VTBL, VTBX.  */
-                n = ((insn >> 5) & 0x18) + 8;
+                int n = ((insn >> 5) & 0x18) + 8;
                 if (insn & (1 << 6)) {
                     tmp = neon_load_reg(rd, 0);
                 } else {

From cc13115bdecb4596fd4201f16455220a7d1a85f8 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 11 Apr 2011 16:26:14 +0100
Subject: [PATCH 166/386] target-arm: Handle UNDEF cases for Neon "2 regs and
 shift" insns

Correctly handle all the UNDEF cases for Neon instructions of the
"2 registers and shift" form, and make sure that we check for these
cases early enough not to leak TCG temporaries.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 41 ++++++++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 19 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 0cf933d021..c0ffa9fca8 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4744,7 +4744,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
             /* Two registers and shift.  */
             op = (insn >> 8) & 0xf;
             if (insn & (1 << 7)) {
-                /* 64-bit shift.   */
+                /* 64-bit shift. */
+                if (op > 7) {
+                    return 1;
+                }
                 size = 3;
             } else {
                 size = 2;
@@ -4757,6 +4760,12 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
             if (op < 8) {
                 /* Shift by immediate:
                    VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
+                if (q && ((rd | rm) & 1)) {
+                    return 1;
+                }
+                if (!u && (op == 4 || op == 6)) {
+                    return 1;
+                }
                 /* Right shifts are encoded as N - shift, where N is the
                    element size in bits.  */
                 if (op <= 4)
@@ -4804,20 +4813,13 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                                 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
                             break;
                         case 4: /* VSRI */
-                            if (!u)
-                                return 1;
                             gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
                             break;
                         case 5: /* VSHL, VSLI */
                             gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
                             break;
                         case 6: /* VQSHLU */
-                            if (u) {
-                                gen_helper_neon_qshlu_s64(cpu_V0,
-                                                          cpu_V0, cpu_V1);
-                            } else {
-                                return 1;
-                            }
+                            gen_helper_neon_qshlu_s64(cpu_V0, cpu_V0, cpu_V1);
                             break;
                         case 7: /* VQSHL */
                             if (u) {
@@ -4865,8 +4867,6 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                             GEN_NEON_INTEGER_OP(rshl);
                             break;
                         case 4: /* VSRI */
-                            if (!u)
-                                return 1;
                             GEN_NEON_INTEGER_OP(shl);
                             break;
                         case 5: /* VSHL, VSLI */
@@ -4874,13 +4874,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                             case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
                             case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
                             case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
-                            default: return 1;
+                            default: abort();
                             }
                             break;
                         case 6: /* VQSHLU */
-                            if (!u) {
-                                return 1;
-                            }
                             switch (size) {
                             case 0:
                                 gen_helper_neon_qshlu_s8(tmp, tmp, tmp2);
@@ -4892,7 +4889,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                                 gen_helper_neon_qshlu_s32(tmp, tmp, tmp2);
                                 break;
                             default:
-                                return 1;
+                                abort();
                             }
                             break;
                         case 7: /* VQSHL */
@@ -4950,7 +4947,9 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 /* Shift by immediate and narrow:
                    VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
                 int input_unsigned = (op == 8) ? !u : u;
-
+                if (rm & 1) {
+                    return 1;
+                }
                 shift = shift - (1 << (size + 3));
                 size++;
                 if (size == 3) {
@@ -5018,9 +5017,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                     tcg_temp_free_i32(tmp2);
                 }
             } else if (op == 10) {
-                /* VSHLL */
-                if (q || size == 3)
+                /* VSHLL, VMOVL */
+                if (q || (rd & 1)) {
                     return 1;
+                }
                 tmp = neon_load_reg(rm, 0);
                 tmp2 = neon_load_reg(rm, 1);
                 for (pass = 0; pass < 2; pass++) {
@@ -5061,6 +5061,9 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 }
             } else if (op >= 14) {
                 /* VCVT fixed-point.  */
+                if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
+                    return 1;
+                }
                 /* We have already masked out the must-be-1 top bit of imm6,
                  * hence this 32-shift where the ARM ARM has 64-imm6.
                  */

From 2bc70834e867e7a0c4f30d374405acf8d81bba03 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 11 Apr 2011 16:26:15 +0100
Subject: [PATCH 167/386] target-arm: Collapse VSRI case into VSHL, VSLI

Collapse some switch cases for VSRI into those for VSHL, VSLI,
since the bodies are the same. (This is not completely obvious
for the size < 3 case, but since for VSRI we know U=1 the
GEN_NEON_INTEGER_OP() expansion is equivalent to the open-coded
VSHL/VSLI case.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index c0ffa9fca8..a86c54c564 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4813,8 +4813,6 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                                 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
                             break;
                         case 4: /* VSRI */
-                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
-                            break;
                         case 5: /* VSHL, VSLI */
                             gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
                             break;
@@ -4867,8 +4865,6 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                             GEN_NEON_INTEGER_OP(rshl);
                             break;
                         case 4: /* VSRI */
-                            GEN_NEON_INTEGER_OP(shl);
-                            break;
                         case 5: /* VSHL, VSLI */
                             switch (size) {
                             case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;

From 7d80fee5b9e663148ddee714e3b755a0af20508d Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 11 Apr 2011 16:26:16 +0100
Subject: [PATCH 168/386] target-arm: Handle UNDEF cases for Neon invalid
 modified-immediates

For Neon "one register and a modified immediate value" forms, the
combination op=1 cmode=1111 is unallocated and should UNDEF.
All instructions of this form also UNDEF if Q == 1 and Vd<0> == 1.
We also add a comment on the only UNPREDICTABLE in this space.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index a86c54c564..0a9b3cf354 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -5084,11 +5084,18 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
             }
         } else { /* (insn & 0x00380080) == 0 */
             int invert;
+            if (q && (rd & 1)) {
+                return 1;
+            }
 
             op = (insn >> 8) & 0xf;
             /* One register and immediate.  */
             imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
             invert = (insn & (1 << 5)) != 0;
+            /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
+             * We choose to not special-case this and will behave as if a
+             * valid constant encoding of 0 had been given.
+             */
             switch (op) {
             case 0: case 1:
                 /* no-op */
@@ -5120,6 +5127,9 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                     imm = ~imm;
                 break;
             case 15:
+                if (invert) {
+                    return 1;
+                }
                 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
                       | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
                 break;

From 695272dcb976897639c034b8fe3d32699ada6482 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 11 Apr 2011 16:26:17 +0100
Subject: [PATCH 169/386] target-arm: Handle UNDEF cases for Neon
 3-regs-different-widths

Add missing UNDEF checks for instructions in the Neon "3 registers of
different widths" data processing space.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 56 +++++++++++++++++++++++++++---------------
 1 file changed, 36 insertions(+), 20 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 0a9b3cf354..9ff5af0475 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -5174,31 +5174,47 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 int src1_wide;
                 int src2_wide;
                 int prewiden;
-                /* prewiden, src1_wide, src2_wide */
-                static const int neon_3reg_wide[16][3] = {
-                    {1, 0, 0}, /* VADDL */
-                    {1, 1, 0}, /* VADDW */
-                    {1, 0, 0}, /* VSUBL */
-                    {1, 1, 0}, /* VSUBW */
-                    {0, 1, 1}, /* VADDHN */
-                    {0, 0, 0}, /* VABAL */
-                    {0, 1, 1}, /* VSUBHN */
-                    {0, 0, 0}, /* VABDL */
-                    {0, 0, 0}, /* VMLAL */
-                    {0, 0, 0}, /* VQDMLAL */
-                    {0, 0, 0}, /* VMLSL */
-                    {0, 0, 0}, /* VQDMLSL */
-                    {0, 0, 0}, /* Integer VMULL */
-                    {0, 0, 0}, /* VQDMULL */
-                    {0, 0, 0}  /* Polynomial VMULL */
+                /* undefreq: bit 0 : UNDEF if size != 0
+                 *           bit 1 : UNDEF if size == 0
+                 *           bit 2 : UNDEF if U == 1
+                 * Note that [1:0] set implies 'always UNDEF'
+                 */
+                int undefreq;
+                /* prewiden, src1_wide, src2_wide, undefreq */
+                static const int neon_3reg_wide[16][4] = {
+                    {1, 0, 0, 0}, /* VADDL */
+                    {1, 1, 0, 0}, /* VADDW */
+                    {1, 0, 0, 0}, /* VSUBL */
+                    {1, 1, 0, 0}, /* VSUBW */
+                    {0, 1, 1, 0}, /* VADDHN */
+                    {0, 0, 0, 0}, /* VABAL */
+                    {0, 1, 1, 0}, /* VSUBHN */
+                    {0, 0, 0, 0}, /* VABDL */
+                    {0, 0, 0, 0}, /* VMLAL */
+                    {0, 0, 0, 6}, /* VQDMLAL */
+                    {0, 0, 0, 0}, /* VMLSL */
+                    {0, 0, 0, 6}, /* VQDMLSL */
+                    {0, 0, 0, 0}, /* Integer VMULL */
+                    {0, 0, 0, 2}, /* VQDMULL */
+                    {0, 0, 0, 5}, /* Polynomial VMULL */
+                    {0, 0, 0, 3}, /* Reserved: always UNDEF */
                 };
 
                 prewiden = neon_3reg_wide[op][0];
                 src1_wide = neon_3reg_wide[op][1];
                 src2_wide = neon_3reg_wide[op][2];
+                undefreq = neon_3reg_wide[op][3];
 
-                if (size == 0 && (op == 9 || op == 11 || op == 13))
+                if (((undefreq & 1) && (size != 0)) ||
+                    ((undefreq & 2) && (size == 0)) ||
+                    ((undefreq & 4) && u)) {
                     return 1;
+                }
+                if ((src1_wide && (rn & 1)) ||
+                    (src2_wide && (rm & 1)) ||
+                    (!src2_wide && (rd & 1))) {
+                    return 1;
+                }
 
                 /* Avoid overlapping operands.  Wide source operands are
                    always aligned so will never overlap with wide
@@ -5279,8 +5295,8 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                         tcg_temp_free_i32(tmp2);
                         tcg_temp_free_i32(tmp);
                         break;
-                    default: /* 15 is RESERVED.  */
-                        return 1;
+                    default: /* 15 is RESERVED: caught earlier  */
+                        abort();
                     }
                     if (op == 13) {
                         /* VQDMULL */

From 3e3326dfb003df0f2f9209c78c25b965aa6022f1 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 11 Apr 2011 16:26:18 +0100
Subject: [PATCH 170/386] target-arm: Handle UNDEF cases for Neon 2 regs +
 scalar forms

Add missing checks for cases which must UNDEF in the Neon "2 registers and
a scalar" data processing instruction space.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 37 +++++++++++++++++++++++++++----------
 1 file changed, 27 insertions(+), 10 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 9ff5af0475..15c2015d90 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -5368,16 +5368,29 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                     }
                 }
             } else {
-                /* Two registers and a scalar.  */
+                /* Two registers and a scalar. NB that for ops of this form
+                 * the ARM ARM labels bit 24 as Q, but it is in our variable
+                 * 'u', not 'q'.
+                 */
+                if (size == 0) {
+                    return 1;
+                }
                 switch (op) {
-                case 0: /* Integer VMLA scalar */
                 case 1: /* Float VMLA scalar */
-                case 4: /* Integer VMLS scalar */
                 case 5: /* Floating point VMLS scalar */
-                case 8: /* Integer VMUL scalar */
                 case 9: /* Floating point VMUL scalar */
+                    if (size == 1) {
+                        return 1;
+                    }
+                    /* fall through */
+                case 0: /* Integer VMLA scalar */
+                case 4: /* Integer VMLS scalar */
+                case 8: /* Integer VMUL scalar */
                 case 12: /* VQDMULH scalar */
                 case 13: /* VQRDMULH scalar */
+                    if (u && ((rd | rn) & 1)) {
+                        return 1;
+                    }
                     tmp = neon_get_scalar(size, rm);
                     neon_store_scratch(0, tmp);
                     for (pass = 0; pass < (u ? 4 : 2); pass++) {
@@ -5402,7 +5415,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                             case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
                             case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
                             case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
-                            default: return 1;
+                            default: abort();
                             }
                         }
                         tcg_temp_free_i32(tmp2);
@@ -5430,15 +5443,19 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                         neon_store_reg(rd, pass, tmp);
                     }
                     break;
-                case 2: /* VMLAL sclar */
                 case 3: /* VQDMLAL scalar */
-                case 6: /* VMLSL scalar */
                 case 7: /* VQDMLSL scalar */
-                case 10: /* VMULL scalar */
                 case 11: /* VQDMULL scalar */
-                    if (size == 0 && (op == 3 || op == 7 || op == 11))
+                    if (u == 1) {
                         return 1;
-
+                    }
+                    /* fall through */
+                case 2: /* VMLAL sclar */
+                case 6: /* VMLSL scalar */
+                case 10: /* VMULL scalar */
+                    if (rd & 1) {
+                        return 1;
+                    }
                     tmp2 = neon_get_scalar(size, rm);
                     /* We need a copy of tmp2 because gen_neon_mull
                      * deletes it during pass 0.  */

From 52579ea1c201ce10a5fe6f5734373543e462e345 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 11 Apr 2011 16:26:19 +0100
Subject: [PATCH 171/386] target-arm: Handle UNDEF cases for VEXT

VEXT must UNDEF if Q == 1 && (Vd<0> == 1 || Vr<0> == 1 || Vm<0> == 1)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 15c2015d90..f47e5ea487 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -5514,6 +5514,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 if (imm > 7 && !q)
                     return 1;
 
+                if (q && ((rd | rn | rm) & 1)) {
+                    return 1;
+                }
+
                 if (imm == 0) {
                     neon_load_reg64(cpu_V0, rn);
                     if (q) {

From 600b828c448f108b89e1f864f0420a49ccb70d43 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 11 Apr 2011 16:26:20 +0100
Subject: [PATCH 172/386] target-arm: Simplify checking of size field in Neon
 2reg-misc forms

Many of the Neon "2 register misc" instruction forms require invalid
size fields to cause the instruction to UNDEF. Pull this information
out into an array; this simplifies the code and also means we can do
the check early and avoid the problem of leaking TCG temporaries in
the illegal_op case.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 255 +++++++++++++++++++++++++++++------------
 1 file changed, 179 insertions(+), 76 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index f47e5ea487..472824889d 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3662,7 +3662,7 @@ static inline TCGv neon_get_scalar(int size, int reg)
 static int gen_neon_unzip(int rd, int rm, int size, int q)
 {
     TCGv tmp, tmp2;
-    if (size == 3 || (!q && size == 2)) {
+    if (!q && size == 2) {
         return 1;
     }
     tmp = tcg_const_i32(rd);
@@ -3701,7 +3701,7 @@ static int gen_neon_unzip(int rd, int rm, int size, int q)
 static int gen_neon_zip(int rd, int rm, int size, int q)
 {
     TCGv tmp, tmp2;
-    if (size == 3 || (!q && size == 2)) {
+    if (!q && size == 2) {
         return 1;
     }
     tmp = tcg_const_i32(rd);
@@ -4312,6 +4312,113 @@ static const uint8_t neon_3r_sizes[] = {
     [NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */
 };
 
+/* Symbolic constants for op fields for Neon 2-register miscellaneous.
+ * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
+ * table A7-13.
+ */
+#define NEON_2RM_VREV64 0
+#define NEON_2RM_VREV32 1
+#define NEON_2RM_VREV16 2
+#define NEON_2RM_VPADDL 4
+#define NEON_2RM_VPADDL_U 5
+#define NEON_2RM_VCLS 8
+#define NEON_2RM_VCLZ 9
+#define NEON_2RM_VCNT 10
+#define NEON_2RM_VMVN 11
+#define NEON_2RM_VPADAL 12
+#define NEON_2RM_VPADAL_U 13
+#define NEON_2RM_VQABS 14
+#define NEON_2RM_VQNEG 15
+#define NEON_2RM_VCGT0 16
+#define NEON_2RM_VCGE0 17
+#define NEON_2RM_VCEQ0 18
+#define NEON_2RM_VCLE0 19
+#define NEON_2RM_VCLT0 20
+#define NEON_2RM_VABS 22
+#define NEON_2RM_VNEG 23
+#define NEON_2RM_VCGT0_F 24
+#define NEON_2RM_VCGE0_F 25
+#define NEON_2RM_VCEQ0_F 26
+#define NEON_2RM_VCLE0_F 27
+#define NEON_2RM_VCLT0_F 28
+#define NEON_2RM_VABS_F 30
+#define NEON_2RM_VNEG_F 31
+#define NEON_2RM_VSWP 32
+#define NEON_2RM_VTRN 33
+#define NEON_2RM_VUZP 34
+#define NEON_2RM_VZIP 35
+#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
+#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
+#define NEON_2RM_VSHLL 38
+#define NEON_2RM_VCVT_F16_F32 44
+#define NEON_2RM_VCVT_F32_F16 46
+#define NEON_2RM_VRECPE 56
+#define NEON_2RM_VRSQRTE 57
+#define NEON_2RM_VRECPE_F 58
+#define NEON_2RM_VRSQRTE_F 59
+#define NEON_2RM_VCVT_FS 60
+#define NEON_2RM_VCVT_FU 61
+#define NEON_2RM_VCVT_SF 62
+#define NEON_2RM_VCVT_UF 63
+
+static int neon_2rm_is_float_op(int op)
+{
+    /* Return true if this neon 2reg-misc op is float-to-float */
+    return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
+            op >= NEON_2RM_VRECPE_F);
+}
+
+/* Each entry in this array has bit n set if the insn allows
+ * size value n (otherwise it will UNDEF). Since unallocated
+ * op values will have no bits set they always UNDEF.
+ */
+static const uint8_t neon_2rm_sizes[] = {
+    [NEON_2RM_VREV64] = 0x7,
+    [NEON_2RM_VREV32] = 0x3,
+    [NEON_2RM_VREV16] = 0x1,
+    [NEON_2RM_VPADDL] = 0x7,
+    [NEON_2RM_VPADDL_U] = 0x7,
+    [NEON_2RM_VCLS] = 0x7,
+    [NEON_2RM_VCLZ] = 0x7,
+    [NEON_2RM_VCNT] = 0x1,
+    [NEON_2RM_VMVN] = 0x1,
+    [NEON_2RM_VPADAL] = 0x7,
+    [NEON_2RM_VPADAL_U] = 0x7,
+    [NEON_2RM_VQABS] = 0x7,
+    [NEON_2RM_VQNEG] = 0x7,
+    [NEON_2RM_VCGT0] = 0x7,
+    [NEON_2RM_VCGE0] = 0x7,
+    [NEON_2RM_VCEQ0] = 0x7,
+    [NEON_2RM_VCLE0] = 0x7,
+    [NEON_2RM_VCLT0] = 0x7,
+    [NEON_2RM_VABS] = 0x7,
+    [NEON_2RM_VNEG] = 0x7,
+    [NEON_2RM_VCGT0_F] = 0x4,
+    [NEON_2RM_VCGE0_F] = 0x4,
+    [NEON_2RM_VCEQ0_F] = 0x4,
+    [NEON_2RM_VCLE0_F] = 0x4,
+    [NEON_2RM_VCLT0_F] = 0x4,
+    [NEON_2RM_VABS_F] = 0x4,
+    [NEON_2RM_VNEG_F] = 0x4,
+    [NEON_2RM_VSWP] = 0x1,
+    [NEON_2RM_VTRN] = 0x7,
+    [NEON_2RM_VUZP] = 0x7,
+    [NEON_2RM_VZIP] = 0x7,
+    [NEON_2RM_VMOVN] = 0x7,
+    [NEON_2RM_VQMOVN] = 0x7,
+    [NEON_2RM_VSHLL] = 0x7,
+    [NEON_2RM_VCVT_F16_F32] = 0x2,
+    [NEON_2RM_VCVT_F32_F16] = 0x2,
+    [NEON_2RM_VRECPE] = 0x4,
+    [NEON_2RM_VRSQRTE] = 0x4,
+    [NEON_2RM_VRECPE_F] = 0x4,
+    [NEON_2RM_VRSQRTE_F] = 0x4,
+    [NEON_2RM_VCVT_FS] = 0x4,
+    [NEON_2RM_VCVT_FU] = 0x4,
+    [NEON_2RM_VCVT_SF] = 0x4,
+    [NEON_2RM_VCVT_UF] = 0x4,
+};
+
 /* Translate a NEON data processing instruction.  Return nonzero if the
    instruction is invalid.
    We process data in a mixture of 32-bit and 64-bit chunks.
@@ -5566,10 +5673,12 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 /* Two register misc.  */
                 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
                 size = (insn >> 18) & 3;
+                /* UNDEF for unknown op values and bad op-size combinations */
+                if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
+                    return 1;
+                }
                 switch (op) {
-                case 0: /* VREV64 */
-                    if (size == 3)
-                        return 1;
+                case NEON_2RM_VREV64:
                     for (pass = 0; pass < (q ? 2 : 1); pass++) {
                         tmp = neon_load_reg(rm, pass * 2);
                         tmp2 = neon_load_reg(rm, pass * 2 + 1);
@@ -5592,10 +5701,8 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                         }
                     }
                     break;
-                case 4: case 5: /* VPADDL */
-                case 12: case 13: /* VPADAL */
-                    if (size == 3)
-                        return 1;
+                case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
+                case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
                     for (pass = 0; pass < q + 1; pass++) {
                         tmp = neon_load_reg(rm, pass * 2);
                         gen_neon_widen(cpu_V0, tmp, size, op & 1);
@@ -5607,7 +5714,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                         case 2: tcg_gen_add_i64(CPU_V001); break;
                         default: abort();
                         }
-                        if (op >= 12) {
+                        if (op >= NEON_2RM_VPADAL) {
                             /* Accumulate.  */
                             neon_load_reg64(cpu_V1, rd + pass);
                             gen_neon_addl(size);
@@ -5615,7 +5722,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                         neon_store_reg64(cpu_V0, rd + pass);
                     }
                     break;
-                case 33: /* VTRN */
+                case NEON_2RM_VTRN:
                     if (size == 2) {
                         int n;
                         for (n = 0; n < (q ? 4 : 2); n += 2) {
@@ -5628,24 +5735,24 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                         goto elementwise;
                     }
                     break;
-                case 34: /* VUZP */
+                case NEON_2RM_VUZP:
                     if (gen_neon_unzip(rd, rm, size, q)) {
                         return 1;
                     }
                     break;
-                case 35: /* VZIP */
+                case NEON_2RM_VZIP:
                     if (gen_neon_zip(rd, rm, size, q)) {
                         return 1;
                     }
                     break;
-                case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
-                    if (size == 3)
-                        return 1;
+                case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
+                    /* also VQMOVUN; op field and mnemonics don't line up */
                     TCGV_UNUSED(tmp2);
                     for (pass = 0; pass < 2; pass++) {
                         neon_load_reg64(cpu_V0, rm + pass);
                         tmp = tcg_temp_new_i32();
-                        gen_neon_narrow_op(op == 36, q, size, tmp, cpu_V0);
+                        gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
+                                           tmp, cpu_V0);
                         if (pass == 0) {
                             tmp2 = tmp;
                         } else {
@@ -5654,9 +5761,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                         }
                     }
                     break;
-                case 38: /* VSHLL */
-                    if (q || size == 3)
+                case NEON_2RM_VSHLL:
+                    if (q) {
                         return 1;
+                    }
                     tmp = neon_load_reg(rm, 0);
                     tmp2 = neon_load_reg(rm, 1);
                     for (pass = 0; pass < 2; pass++) {
@@ -5667,7 +5775,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                         neon_store_reg64(cpu_V0, rd + pass);
                     }
                     break;
-                case 44: /* VCVT.F16.F32 */
+                case NEON_2RM_VCVT_F16_F32:
                     if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
                       return 1;
                     tmp = tcg_temp_new_i32();
@@ -5689,7 +5797,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                     neon_store_reg(rd, 1, tmp2);
                     tcg_temp_free_i32(tmp);
                     break;
-                case 46: /* VCVT.F32.F16 */
+                case NEON_2RM_VCVT_F32_F16:
                     if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
                       return 1;
                     tmp3 = tcg_temp_new_i32();
@@ -5714,7 +5822,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 default:
                 elementwise:
                     for (pass = 0; pass < (q ? 4 : 2); pass++) {
-                        if (op == 30 || op == 31 || op >= 58) {
+                        if (neon_2rm_is_float_op(op)) {
                             tcg_gen_ld_f32(cpu_F0s, cpu_env,
                                            neon_reg_offset(rm, pass));
                             TCGV_UNUSED(tmp);
@@ -5722,183 +5830,178 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                             tmp = neon_load_reg(rm, pass);
                         }
                         switch (op) {
-                        case 1: /* VREV32 */
+                        case NEON_2RM_VREV32:
                             switch (size) {
                             case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
                             case 1: gen_swap_half(tmp); break;
-                            default: return 1;
+                            default: abort();
                             }
                             break;
-                        case 2: /* VREV16 */
-                            if (size != 0)
-                                return 1;
+                        case NEON_2RM_VREV16:
                             gen_rev16(tmp);
                             break;
-                        case 8: /* CLS */
+                        case NEON_2RM_VCLS:
                             switch (size) {
                             case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
                             case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
                             case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
-                            default: return 1;
+                            default: abort();
                             }
                             break;
-                        case 9: /* CLZ */
+                        case NEON_2RM_VCLZ:
                             switch (size) {
                             case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
                             case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
                             case 2: gen_helper_clz(tmp, tmp); break;
-                            default: return 1;
+                            default: abort();
                             }
                             break;
-                        case 10: /* CNT */
-                            if (size != 0)
-                                return 1;
+                        case NEON_2RM_VCNT:
                             gen_helper_neon_cnt_u8(tmp, tmp);
                             break;
-                        case 11: /* VNOT */
-                            if (size != 0)
-                                return 1;
+                        case NEON_2RM_VMVN:
                             tcg_gen_not_i32(tmp, tmp);
                             break;
-                        case 14: /* VQABS */
+                        case NEON_2RM_VQABS:
                             switch (size) {
                             case 0: gen_helper_neon_qabs_s8(tmp, tmp); break;
                             case 1: gen_helper_neon_qabs_s16(tmp, tmp); break;
                             case 2: gen_helper_neon_qabs_s32(tmp, tmp); break;
-                            default: return 1;
+                            default: abort();
                             }
                             break;
-                        case 15: /* VQNEG */
+                        case NEON_2RM_VQNEG:
                             switch (size) {
                             case 0: gen_helper_neon_qneg_s8(tmp, tmp); break;
                             case 1: gen_helper_neon_qneg_s16(tmp, tmp); break;
                             case 2: gen_helper_neon_qneg_s32(tmp, tmp); break;
-                            default: return 1;
+                            default: abort();
                             }
                             break;
-                        case 16: case 19: /* VCGT #0, VCLE #0 */
+                        case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
                             tmp2 = tcg_const_i32(0);
                             switch(size) {
                             case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
                             case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
                             case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
-                            default: return 1;
+                            default: abort();
                             }
                             tcg_temp_free(tmp2);
-                            if (op == 19)
+                            if (op == NEON_2RM_VCLE0) {
                                 tcg_gen_not_i32(tmp, tmp);
+                            }
                             break;
-                        case 17: case 20: /* VCGE #0, VCLT #0 */
+                        case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
                             tmp2 = tcg_const_i32(0);
                             switch(size) {
                             case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
                             case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
                             case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
-                            default: return 1;
+                            default: abort();
                             }
                             tcg_temp_free(tmp2);
-                            if (op == 20)
+                            if (op == NEON_2RM_VCLT0) {
                                 tcg_gen_not_i32(tmp, tmp);
+                            }
                             break;
-                        case 18: /* VCEQ #0 */
+                        case NEON_2RM_VCEQ0:
                             tmp2 = tcg_const_i32(0);
                             switch(size) {
                             case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
                             case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
                             case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
-                            default: return 1;
+                            default: abort();
                             }
                             tcg_temp_free(tmp2);
                             break;
-                        case 22: /* VABS */
+                        case NEON_2RM_VABS:
                             switch(size) {
                             case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
                             case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
                             case 2: tcg_gen_abs_i32(tmp, tmp); break;
-                            default: return 1;
+                            default: abort();
                             }
                             break;
-                        case 23: /* VNEG */
-                            if (size == 3)
-                                return 1;
+                        case NEON_2RM_VNEG:
                             tmp2 = tcg_const_i32(0);
                             gen_neon_rsb(size, tmp, tmp2);
                             tcg_temp_free(tmp2);
                             break;
-                        case 24: /* Float VCGT #0 */
+                        case NEON_2RM_VCGT0_F:
                             tmp2 = tcg_const_i32(0);
                             gen_helper_neon_cgt_f32(tmp, tmp, tmp2);
                             tcg_temp_free(tmp2);
                             break;
-                        case 25: /* Float VCGE #0 */
+                        case NEON_2RM_VCGE0_F:
                             tmp2 = tcg_const_i32(0);
                             gen_helper_neon_cge_f32(tmp, tmp, tmp2);
                             tcg_temp_free(tmp2);
                             break;
-                        case 26: /* Float VCEQ #0 */
+                        case NEON_2RM_VCEQ0_F:
                             tmp2 = tcg_const_i32(0);
                             gen_helper_neon_ceq_f32(tmp, tmp, tmp2);
                             tcg_temp_free(tmp2);
                             break;
-                        case 27: /* Float VCLE #0 */
+                        case NEON_2RM_VCLE0_F:
                             tmp2 = tcg_const_i32(0);
                             gen_helper_neon_cge_f32(tmp, tmp2, tmp);
                             tcg_temp_free(tmp2);
                             break;
-                        case 28: /* Float VCLT #0 */
+                        case NEON_2RM_VCLT0_F:
                             tmp2 = tcg_const_i32(0);
                             gen_helper_neon_cgt_f32(tmp, tmp2, tmp);
                             tcg_temp_free(tmp2);
                             break;
-                        case 30: /* Float VABS */
+                        case NEON_2RM_VABS_F:
                             gen_vfp_abs(0);
                             break;
-                        case 31: /* Float VNEG */
+                        case NEON_2RM_VNEG_F:
                             gen_vfp_neg(0);
                             break;
-                        case 32: /* VSWP */
+                        case NEON_2RM_VSWP:
                             tmp2 = neon_load_reg(rd, pass);
                             neon_store_reg(rm, pass, tmp2);
                             break;
-                        case 33: /* VTRN */
+                        case NEON_2RM_VTRN:
                             tmp2 = neon_load_reg(rd, pass);
                             switch (size) {
                             case 0: gen_neon_trn_u8(tmp, tmp2); break;
                             case 1: gen_neon_trn_u16(tmp, tmp2); break;
-                            case 2: abort();
-                            default: return 1;
+                            default: abort();
                             }
                             neon_store_reg(rm, pass, tmp2);
                             break;
-                        case 56: /* Integer VRECPE */
+                        case NEON_2RM_VRECPE:
                             gen_helper_recpe_u32(tmp, tmp, cpu_env);
                             break;
-                        case 57: /* Integer VRSQRTE */
+                        case NEON_2RM_VRSQRTE:
                             gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
                             break;
-                        case 58: /* Float VRECPE */
+                        case NEON_2RM_VRECPE_F:
                             gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
                             break;
-                        case 59: /* Float VRSQRTE */
+                        case NEON_2RM_VRSQRTE_F:
                             gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
                             break;
-                        case 60: /* VCVT.F32.S32 */
+                        case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
                             gen_vfp_sito(0);
                             break;
-                        case 61: /* VCVT.F32.U32 */
+                        case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
                             gen_vfp_uito(0);
                             break;
-                        case 62: /* VCVT.S32.F32 */
+                        case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
                             gen_vfp_tosiz(0);
                             break;
-                        case 63: /* VCVT.U32.F32 */
+                        case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
                             gen_vfp_touiz(0);
                             break;
                         default:
-                            /* Reserved: 21, 29, 39-56 */
-                            return 1;
+                            /* Reserved op values were caught by the
+                             * neon_2rm_sizes[] check earlier.
+                             */
+                            abort();
                         }
-                        if (op == 30 || op == 31 || op >= 58) {
+                        if (neon_2rm_is_float_op(op)) {
                             tcg_gen_st_f32(cpu_F0s, cpu_env,
                                            neon_reg_offset(rd, pass));
                         } else {

From fc2a9b37849d25d21d161c1319581420499ab4b2 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 11 Apr 2011 16:26:21 +0100
Subject: [PATCH 173/386] target-arm: Handle UNDEF cases for Neon 2 register
 misc forms

Add missing UNDEF checks for Neon "two register miscellaneous" forms:
 * all instructions except VMOVN,VQMOVN must UNDEF
   if Q==1 && (Vd<0> == 1 || Vm<0> == 1)
 * VMOVN,VQMOVN,VCVT.F16.F32 UNDEF if Q == 1 || Vm<0> == 1
 * VSHLL,VCVT.F32.F16 UNDEF if Q == 1 || Vd<0> == 1
(The only other UNDEF case is VZIP,VUZP if Q == 0 && size == 10,
which we already handle.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 472824889d..b647c7bdde 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -5677,6 +5677,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
                     return 1;
                 }
+                if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
+                    q && ((rm | rd) & 1)) {
+                    return 1;
+                }
                 switch (op) {
                 case NEON_2RM_VREV64:
                     for (pass = 0; pass < (q ? 2 : 1); pass++) {
@@ -5747,6 +5751,9 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                     break;
                 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
                     /* also VQMOVUN; op field and mnemonics don't line up */
+                    if (rm & 1) {
+                        return 1;
+                    }
                     TCGV_UNUSED(tmp2);
                     for (pass = 0; pass < 2; pass++) {
                         neon_load_reg64(cpu_V0, rm + pass);
@@ -5762,7 +5769,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                     }
                     break;
                 case NEON_2RM_VSHLL:
-                    if (q) {
+                    if (q || (rd & 1)) {
                         return 1;
                     }
                     tmp = neon_load_reg(rm, 0);
@@ -5776,8 +5783,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                     }
                     break;
                 case NEON_2RM_VCVT_F16_F32:
-                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
-                      return 1;
+                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
+                        q || (rm & 1)) {
+                        return 1;
+                    }
                     tmp = tcg_temp_new_i32();
                     tmp2 = tcg_temp_new_i32();
                     tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
@@ -5798,8 +5807,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                     tcg_temp_free_i32(tmp);
                     break;
                 case NEON_2RM_VCVT_F32_F16:
-                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16))
-                      return 1;
+                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
+                        q || (rd & 1)) {
+                        return 1;
+                    }
                     tmp3 = tcg_temp_new_i32();
                     tmp = neon_load_reg(rm, 0);
                     tmp2 = neon_load_reg(rm, 1);

From 56907d776e1133bf4f633e4e542267d23d2c09cf Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 11 Apr 2011 16:26:22 +0100
Subject: [PATCH 174/386] target-arm: Treat UNPREDICTABLE VTBL, VTBX case as
 UNDEF

Catch the UNPREDICTABLE case for Neon VTBL,VTBX, and UNDEF it
rather than allowing the helper function to index off the end
of the register file.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index b647c7bdde..be25c8f33a 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6023,7 +6023,14 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 }
             } else if ((insn & (1 << 10)) == 0) {
                 /* VTBL, VTBX.  */
-                int n = ((insn >> 5) & 0x18) + 8;
+                int n = ((insn >> 8) & 3) + 1;
+                if ((rn + n) > 32) {
+                    /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
+                     * helper function running off the end of the register file.
+                     */
+                    return 1;
+                }
+                n <<= 3;
                 if (insn & (1 << 6)) {
                     tmp = neon_load_reg(rd, 0);
                 } else {

From 133da6aae1edc0118fbac8cd9ba46dff69ddd5c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juha=20Riihim=C3=A4ki?= <juha.riihimaki@nokia.com>
Date: Mon, 11 Apr 2011 16:26:23 +0100
Subject: [PATCH 175/386] target-arm: Handle UNDEF cases for VDUP (scalar)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Handle the UNDEF cases for VDUP(scalar):
 imm4 == x000
 Q == 1 && Vd<0> == 1

Signed-off-by: Juha Riihimäki <juha.riihimaki@nokia.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index be25c8f33a..6190028d08 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6057,6 +6057,9 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 tcg_temp_free_i32(tmp);
             } else if ((insn & 0x380) == 0) {
                 /* VDUP */
+                if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
+                    return 1;
+                }
                 if (insn & (1 << 19)) {
                     tmp = neon_load_reg(rm, 1);
                 } else {

From c29aca44614e12a310dd903dc4fd56b14a6b71c9 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Tue, 12 Apr 2011 13:56:40 +0100
Subject: [PATCH 176/386] softfloat: Add setter function for tininess detection
 mode

Add a setter function for the underflow tininess detection mode,
in line with the similar functions for other parts of the float status
structure.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 7abcbe899e..c7654d4c63 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -211,6 +211,10 @@ typedef struct float_status {
 
 void set_float_rounding_mode(int val STATUS_PARAM);
 void set_float_exception_flags(int val STATUS_PARAM);
+INLINE void set_float_detect_tininess(int val STATUS_PARAM)
+{
+    STATUS(float_detect_tininess) = val;
+}
 INLINE void set_flush_to_zero(flag val STATUS_PARAM)
 {
     STATUS(flush_to_zero) = val;

From 9df38c47d01eb1fd7eb9d60ac70a4170e638b4a2 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Tue, 12 Apr 2011 13:56:41 +0100
Subject: [PATCH 177/386] target-arm: Detect tininess before rounding for FP
 operations

The ARM architecture mandates that we detect tininess before rounding,
so set the softfloat fp_status up appropriately.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/helper.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index ce9a9d8fd2..9172fc7279 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -269,6 +269,10 @@ void cpu_reset(CPUARMState *env)
     set_flush_to_zero(1, &env->vfp.standard_fp_status);
     set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status);
     set_default_nan_mode(1, &env->vfp.standard_fp_status);
+    set_float_detect_tininess(float_tininess_before_rounding,
+                              &env->vfp.fp_status);
+    set_float_detect_tininess(float_tininess_before_rounding,
+                              &env->vfp.standard_fp_status);
     tlb_flush(env, 1);
 }
 

From d54f10bba7635b5ad8b750afd2bb2f0f8eb68b45 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Date: Fri, 17 Dec 2010 15:58:21 +0000
Subject: [PATCH 178/386] docs: Describe zero data clusters in QED
 specification

Zero data clusters are a space-efficient way of storing zeroed regions
of the image.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 docs/specs/qed_spec.txt | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/docs/specs/qed_spec.txt b/docs/specs/qed_spec.txt
index 1d5fa87e01..7982e058b2 100644
--- a/docs/specs/qed_spec.txt
+++ b/docs/specs/qed_spec.txt
@@ -89,6 +89,7 @@ L1, L2, and data cluster offsets must be aligned to header.cluster_size.  The fo
 
 ===Data cluster offsets===
 * 0 - unallocated.  The data cluster is not yet allocated.
+* 1 - zero.  The data cluster contents are all zeroes and no cluster is allocated.
 
 Future format extensions may wish to store per-offset information.  The least significant 12 bits of an offset are reserved for this purpose and must be set to zero.  Image files with cluster_size > 2^12 will have more unused bits which should also be zeroed.
 
@@ -97,6 +98,13 @@ Reads to an unallocated area of the image file access the backing file.  If ther
 
 Writes to an unallocated area cause a new data clusters to be allocated, and a new L2 table if that is also unallocated.  The new data cluster is populated with data from the backing file (or zeroes if no backing file) and the data being written.
 
+===Zero data clusters===
+Zero data clusters are a space-efficient way of storing zeroed regions of the image.
+
+Reads to a zero data cluster produce zeroes.  Note that the difference between an unallocated and a zero data cluster is that zero data clusters stop the reading of contents from the backing file.
+
+Writes to a zero data cluster cause a new data cluster to be allocated.  The new data cluster is populated with zeroes and the data being written.
+
 ===Logical offset translation===
 Logical offsets are translated into cluster offsets as follows:
 

From 21df65b6444858ddee3a86d8666571bb41695614 Mon Sep 17 00:00:00 2001
From: Anthony Liguori <aliguori@us.ibm.com>
Date: Fri, 17 Dec 2010 15:58:22 +0000
Subject: [PATCH 179/386] qed: Add support for zero clusters

Zero clusters are similar to unallocated clusters except instead of reading
their value from a backing file when one is available, the cluster is always
read as zero.

This implements read support only.  At this stage, QED will never write a
zero cluster.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/qed-check.c   |  5 +++--
 block/qed-cluster.c | 31 +++++++++++++++++++++----------
 block/qed.c         | 21 ++++++++++++++++-----
 block/qed.h         | 26 ++++++++++++++++++++++++++
 4 files changed, 66 insertions(+), 17 deletions(-)

diff --git a/block/qed-check.c b/block/qed-check.c
index 4600932bf2..ea4ebc8e20 100644
--- a/block/qed-check.c
+++ b/block/qed-check.c
@@ -72,7 +72,8 @@ static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table)
     for (i = 0; i < s->table_nelems; i++) {
         uint64_t offset = table->offsets[i];
 
-        if (!offset) {
+        if (qed_offset_is_unalloc_cluster(offset) ||
+            qed_offset_is_zero_cluster(offset)) {
             continue;
         }
 
@@ -111,7 +112,7 @@ static int qed_check_l1_table(QEDCheck *check, QEDTable *table)
         unsigned int num_invalid_l2;
         uint64_t offset = table->offsets[i];
 
-        if (!offset) {
+        if (qed_offset_is_unalloc_cluster(offset)) {
             continue;
         }
 
diff --git a/block/qed-cluster.c b/block/qed-cluster.c
index 0ec864b14c..3e19ad1766 100644
--- a/block/qed-cluster.c
+++ b/block/qed-cluster.c
@@ -23,7 +23,8 @@
  * @n:              Maximum number of clusters
  * @offset:         Set to first cluster offset
  *
- * This function scans tables for contiguous allocated or free clusters.
+ * This function scans tables for contiguous clusters.  A contiguous run of
+ * clusters may be allocated, unallocated, or zero.
  */
 static unsigned int qed_count_contiguous_clusters(BDRVQEDState *s,
                                                   QEDTable *table,
@@ -38,9 +39,14 @@ static unsigned int qed_count_contiguous_clusters(BDRVQEDState *s,
     *offset = last;
 
     for (i = index + 1; i < end; i++) {
-        if (last == 0) {
-            /* Counting free clusters */
-            if (table->offsets[i] != 0) {
+        if (qed_offset_is_unalloc_cluster(last)) {
+            /* Counting unallocated clusters */
+            if (!qed_offset_is_unalloc_cluster(table->offsets[i])) {
+                break;
+            }
+        } else if (qed_offset_is_zero_cluster(last)) {
+            /* Counting zero clusters */
+            if (!qed_offset_is_zero_cluster(table->offsets[i])) {
                 break;
             }
         } else {
@@ -87,14 +93,19 @@ static void qed_find_cluster_cb(void *opaque, int ret)
     n = qed_count_contiguous_clusters(s, request->l2_table->table,
                                       index, n, &offset);
 
-    ret = offset ? QED_CLUSTER_FOUND : QED_CLUSTER_L2;
-    len = MIN(find_cluster_cb->len, n * s->header.cluster_size -
-              qed_offset_into_cluster(s, find_cluster_cb->pos));
-
-    if (offset && !qed_check_cluster_offset(s, offset)) {
+    if (qed_offset_is_unalloc_cluster(offset)) {
+        ret = QED_CLUSTER_L2;
+    } else if (qed_offset_is_zero_cluster(offset)) {
+        ret = QED_CLUSTER_ZERO;
+    } else if (qed_check_cluster_offset(s, offset)) {
+        ret = QED_CLUSTER_FOUND;
+    } else {
         ret = -EINVAL;
     }
 
+    len = MIN(find_cluster_cb->len, n * s->header.cluster_size -
+              qed_offset_into_cluster(s, find_cluster_cb->pos));
+
 out:
     find_cluster_cb->cb(find_cluster_cb->opaque, ret, offset, len);
     qemu_free(find_cluster_cb);
@@ -132,7 +143,7 @@ void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
     len = MIN(len, (((pos >> s->l1_shift) + 1) << s->l1_shift) - pos);
 
     l2_offset = s->l1_table->offsets[qed_l1_index(s, pos)];
-    if (!l2_offset) {
+    if (qed_offset_is_unalloc_cluster(l2_offset)) {
         cb(opaque, QED_CLUSTER_L1, 0, len);
         return;
     }
diff --git a/block/qed.c b/block/qed.c
index 75ae2440ee..c8c5930448 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -573,7 +573,7 @@ static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t l
 {
     QEDIsAllocatedCB *cb = opaque;
     *cb->pnum = len / BDRV_SECTOR_SIZE;
-    cb->is_allocated = ret == QED_CLUSTER_FOUND;
+    cb->is_allocated = (ret == QED_CLUSTER_FOUND || ret == QED_CLUSTER_ZERO);
 }
 
 static int bdrv_qed_is_allocated(BlockDriverState *bs, int64_t sector_num,
@@ -745,7 +745,10 @@ static void qed_copy_from_backing_file(BDRVQEDState *s, uint64_t pos,
  * @table:          L2 table
  * @index:          First cluster index
  * @n:              Number of contiguous clusters
- * @cluster:        First cluster byte offset in image file
+ * @cluster:        First cluster offset
+ *
+ * The cluster offset may be an allocated byte offset in the image file, the
+ * zero cluster marker, or the unallocated cluster marker.
  */
 static void qed_update_l2_table(BDRVQEDState *s, QEDTable *table, int index,
                                 unsigned int n, uint64_t cluster)
@@ -753,7 +756,10 @@ static void qed_update_l2_table(BDRVQEDState *s, QEDTable *table, int index,
     int i;
     for (i = index; i < index + n; i++) {
         table->offsets[i] = cluster;
-        cluster += s->header.cluster_size;
+        if (!qed_offset_is_unalloc_cluster(cluster) &&
+            !qed_offset_is_zero_cluster(cluster)) {
+            cluster += s->header.cluster_size;
+        }
     }
 }
 
@@ -1075,6 +1081,7 @@ static void qed_aio_write_data(void *opaque, int ret,
 
     case QED_CLUSTER_L2:
     case QED_CLUSTER_L1:
+    case QED_CLUSTER_ZERO:
         qed_aio_write_alloc(acb, len);
         break;
 
@@ -1114,8 +1121,12 @@ static void qed_aio_read_data(void *opaque, int ret,
 
     qemu_iovec_copy(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
 
-    /* Handle backing file and unallocated sparse hole reads */
-    if (ret != QED_CLUSTER_FOUND) {
+    /* Handle zero cluster and backing file reads */
+    if (ret == QED_CLUSTER_ZERO) {
+        qemu_iovec_memset(&acb->cur_qiov, 0, acb->cur_qiov.size);
+        qed_aio_next_io(acb, 0);
+        return;
+    } else if (ret != QED_CLUSTER_FOUND) {
         qed_read_backing_file(s, acb->cur_pos, &acb->cur_qiov,
                               qed_aio_next_io, acb);
         return;
diff --git a/block/qed.h b/block/qed.h
index 2925e37b1c..3e1ab84781 100644
--- a/block/qed.h
+++ b/block/qed.h
@@ -161,6 +161,7 @@ typedef struct {
 
 enum {
     QED_CLUSTER_FOUND,         /* cluster found */
+    QED_CLUSTER_ZERO,          /* zero cluster found */
     QED_CLUSTER_L2,            /* cluster missing in L2 */
     QED_CLUSTER_L1,            /* cluster missing in L1 */
 };
@@ -298,4 +299,29 @@ static inline bool qed_check_table_offset(BDRVQEDState *s, uint64_t offset)
            qed_check_cluster_offset(s, end_offset);
 }
 
+static inline bool qed_offset_is_cluster_aligned(BDRVQEDState *s,
+                                                 uint64_t offset)
+{
+    if (qed_offset_into_cluster(s, offset)) {
+        return false;
+    }
+    return true;
+}
+
+static inline bool qed_offset_is_unalloc_cluster(uint64_t offset)
+{
+    if (offset == 0) {
+        return true;
+    }
+    return false;
+}
+
+static inline bool qed_offset_is_zero_cluster(uint64_t offset)
+{
+    if (offset == 1) {
+        return true;
+    }
+    return false;
+}
+
 #endif /* BLOCK_QED_H */

From 8aa71917f7be78151cff50b850a25f26de614b13 Mon Sep 17 00:00:00 2001
From: Amit Shah <amit.shah@redhat.com>
Date: Sat, 9 Apr 2011 15:54:38 +0530
Subject: [PATCH 180/386] atapi: Drives can be locked without media present

Drivers are free to lock drives without any media present.  Such a
condition should not result in an error condition.

See Table 341 in MMC-5 spec for details.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/core.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index c11d457b7a..a290142c57 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1230,13 +1230,8 @@ static void ide_atapi_cmd(IDEState *s)
         ide_atapi_cmd_reply(s, 18, max_len);
         break;
     case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
-        if (bdrv_is_inserted(s->bs)) {
-            bdrv_set_locked(s->bs, packet[4] & 1);
-            ide_atapi_cmd_ok(s);
-        } else {
-            ide_atapi_cmd_error(s, SENSE_NOT_READY,
-                                ASC_MEDIUM_NOT_PRESENT);
-        }
+        bdrv_set_locked(s->bs, packet[4] & 1);
+        ide_atapi_cmd_ok(s);
         break;
     case GPCMD_READ_10:
     case GPCMD_READ_12:

From 88f2bb58ef97ca269b29fe92bb4834f5ddbcde80 Mon Sep 17 00:00:00 2001
From: Amit Shah <amit.shah@redhat.com>
Date: Sat, 9 Apr 2011 15:54:39 +0530
Subject: [PATCH 181/386] atapi: Report correct errors on guest eject request

Table 629 of the MMC-5 spec mentions two different error conditions when
a CDROM eject is requested: a) while a disc is inserted and b) while a
disc is not inserted.

Ensure we return the appropriate error for the present condition of the
drive and disc status.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/core.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index a290142c57..b5de22e86a 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1304,7 +1304,7 @@ static void ide_atapi_cmd(IDEState *s)
         break;
     case GPCMD_START_STOP_UNIT:
         {
-            int start, eject, err = 0;
+            int start, eject, sense, err = 0;
             start = packet[4] & 1;
             eject = (packet[4] >> 1) & 1;
 
@@ -1317,7 +1317,11 @@ static void ide_atapi_cmd(IDEState *s)
                 ide_atapi_cmd_ok(s);
                 break;
             case -EBUSY:
-                ide_atapi_cmd_error(s, SENSE_NOT_READY,
+                sense = SENSE_NOT_READY;
+                if (bdrv_is_inserted(s->bs)) {
+                    sense = SENSE_ILLEGAL_REQUEST;
+                }
+                ide_atapi_cmd_error(s, sense,
                                     ASC_MEDIA_REMOVAL_PREVENTED);
                 break;
             default:

From 0c370a35498bf9e300a035864bee7ce8460da669 Mon Sep 17 00:00:00 2001
From: Amit Shah <amit.shah@redhat.com>
Date: Tue, 12 Apr 2011 21:36:03 +0530
Subject: [PATCH 182/386] atapi: Allow GET_EVENT_STATUS_NOTIFICATION after
 media change

After a media change, the only commands allowed from the guest were
REQUEST_SENSE and INQUIRY.  The guest may also issue
GET_EVENT_STATUS_NOTIFICATION commands to get media
changed notification.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/core.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index b5de22e86a..f0da95d728 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1102,13 +1102,21 @@ static void ide_atapi_cmd(IDEState *s)
         printf("\n");
     }
 #endif
-    /* If there's a UNIT_ATTENTION condition pending, only
-       REQUEST_SENSE and INQUIRY commands are allowed to complete. */
+    /*
+     * If there's a UNIT_ATTENTION condition pending, only
+     * REQUEST_SENSE, INQUIRY, GET_CONFIGURATION and
+     * GET_EVENT_STATUS_NOTIFICATION commands are allowed to complete.
+     * MMC-5, section 4.1.6.1 lists only these commands being allowed
+     * to complete, with other commands getting a CHECK condition
+     * response unless a higher priority status, defined by the drive
+     * here, is pending.
+     */
     if (s->sense_key == SENSE_UNIT_ATTENTION &&
-	s->io_buffer[0] != GPCMD_REQUEST_SENSE &&
-	s->io_buffer[0] != GPCMD_INQUIRY) {
-	ide_atapi_cmd_check_status(s);
-	return;
+        s->io_buffer[0] != GPCMD_REQUEST_SENSE &&
+        s->io_buffer[0] != GPCMD_INQUIRY &&
+        s->io_buffer[0] != GPCMD_GET_EVENT_STATUS_NOTIFICATION) {
+        ide_atapi_cmd_check_status(s);
+        return;
     }
     switch(s->io_buffer[0]) {
     case GPCMD_TEST_UNIT_READY:

From 493accd624149e9dcf4b89dcbbdbc42621cbc231 Mon Sep 17 00:00:00 2001
From: Amit Shah <amit.shah@redhat.com>
Date: Tue, 12 Apr 2011 21:36:04 +0530
Subject: [PATCH 183/386] atapi: Move GET_EVENT_STATUS_NOTIFICATION command
 handling to its own function

This makes the code more readable.

Also, there's a block like:

if () {
  ...
} else {
  ...
}

Split that into

if () {
  ...
  return;
}
...

Signed-off-by: Amit Shah <amit.shah@redhat.com>
Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/core.c | 37 ++++++++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index f0da95d728..4e4ade2bf9 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1084,6 +1084,29 @@ static int ide_dvd_read_structure(IDEState *s, int format,
     }
 }
 
+static void handle_get_event_status_notification(IDEState *s,
+                                                 uint8_t *buf,
+                                                 const uint8_t *packet)
+{
+    unsigned int max_len;
+
+    max_len = ube16_to_cpu(packet + 7);
+
+    if (!(packet[1] & 0x01)) { /* asynchronous mode */
+        /* Only polling is supported, asynchronous mode is not. */
+        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                            ASC_INV_FIELD_IN_CMD_PACKET);
+        return;
+    }
+
+    /* polling */
+    /* We don't support any event class (yet). */
+    cpu_to_ube16(buf, 0x00); /* No event descriptor returned */
+    buf[2] = 0x80;           /* No Event Available (NEA) */
+    buf[3] = 0x00;           /* Empty supported event classes */
+    ide_atapi_cmd_reply(s, 4, max_len);
+}
+
 static void ide_atapi_cmd(IDEState *s)
 {
     const uint8_t *packet;
@@ -1529,19 +1552,7 @@ static void ide_atapi_cmd(IDEState *s)
             break;
         }
     case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
-        max_len = ube16_to_cpu(packet + 7);
-
-        if (packet[1] & 0x01) { /* polling */
-            /* We don't support any event class (yet). */
-            cpu_to_ube16(buf, 0x00); /* No event descriptor returned */
-            buf[2] = 0x80;           /* No Event Available (NEA) */
-            buf[3] = 0x00;           /* Empty supported event classes */
-            ide_atapi_cmd_reply(s, 4, max_len);
-        } else { /* asynchronous mode */
-            /* Only polling is supported, asynchronous mode is not. */
-            ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                                ASC_INV_FIELD_IN_CMD_PACKET);
-        }
+        handle_get_event_status_notification(s, buf, packet);
         break;
     default:
         ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,

From 8f8e834d70216372619b79a10392cdf208bbd3d0 Mon Sep 17 00:00:00 2001
From: Amit Shah <amit.shah@redhat.com>
Date: Tue, 12 Apr 2011 21:36:05 +0530
Subject: [PATCH 184/386] atapi: GESN: Use structs for commonly-used field
 types

Instead of using magic numbers, use structs that are more descriptive of
the fields being used.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/core.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 4e4ade2bf9..f976947cc5 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1088,11 +1088,23 @@ static void handle_get_event_status_notification(IDEState *s,
                                                  uint8_t *buf,
                                                  const uint8_t *packet)
 {
+    struct {
+        uint8_t opcode;
+        uint8_t polled;        /* lsb bit is polled; others are reserved */
+        uint8_t reserved2[2];
+        uint8_t class;
+        uint8_t reserved3[2];
+        uint16_t len;
+        uint8_t control;
+    } __attribute__((packed)) *gesn_cdb;
+
     unsigned int max_len;
 
-    max_len = ube16_to_cpu(packet + 7);
+    gesn_cdb = (void *)packet;
+    max_len = be16_to_cpu(gesn_cdb->len);
 
-    if (!(packet[1] & 0x01)) { /* asynchronous mode */
+    /* It is fine by the MMC spec to not support async mode operations */
+    if (!(gesn_cdb->polled & 0x01)) { /* asynchronous mode */
         /* Only polling is supported, asynchronous mode is not. */
         ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
                             ASC_INV_FIELD_IN_CMD_PACKET);

From 0af63ba3629e6f826846a73636ca391a810b2c6e Mon Sep 17 00:00:00 2001
From: Amit Shah <amit.shah@redhat.com>
Date: Tue, 12 Apr 2011 21:36:06 +0530
Subject: [PATCH 185/386] atapi: GESN: Standardise event response handling for
 future additions

Handle GET_EVENT_STATUS_NOTIFICATION's No Event Available response in a
generic way so that future additions to the code to handle other
response types is easier.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/core.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index f976947cc5..a38cc14aaf 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1098,9 +1098,17 @@ static void handle_get_event_status_notification(IDEState *s,
         uint8_t control;
     } __attribute__((packed)) *gesn_cdb;
 
-    unsigned int max_len;
+    struct {
+        uint16_t len;
+        uint8_t notification_class;
+        uint8_t supported_events;
+    } __attribute((packed)) *gesn_event_header;
+
+    unsigned int max_len, used_len;
 
     gesn_cdb = (void *)packet;
+    gesn_event_header = (void *)buf;
+
     max_len = be16_to_cpu(gesn_cdb->len);
 
     /* It is fine by the MMC spec to not support async mode operations */
@@ -1111,12 +1119,17 @@ static void handle_get_event_status_notification(IDEState *s,
         return;
     }
 
-    /* polling */
+    /* polling mode operation */
+
     /* We don't support any event class (yet). */
-    cpu_to_ube16(buf, 0x00); /* No event descriptor returned */
-    buf[2] = 0x80;           /* No Event Available (NEA) */
-    buf[3] = 0x00;           /* Empty supported event classes */
-    ide_atapi_cmd_reply(s, 4, max_len);
+    gesn_event_header->supported_events = 0;
+
+    gesn_event_header->notification_class = 0x80; /* No event available */
+    used_len = sizeof(*gesn_event_header);
+
+    gesn_event_header->len = cpu_to_be16(used_len
+                                         - sizeof(*gesn_event_header));
+    ide_atapi_cmd_reply(s, used_len, max_len);
 }
 
 static void ide_atapi_cmd(IDEState *s)

From 996faf1ad4a93342e381766d95686b16624f0dbd Mon Sep 17 00:00:00 2001
From: Amit Shah <amit.shah@redhat.com>
Date: Tue, 12 Apr 2011 21:36:07 +0530
Subject: [PATCH 186/386] atapi: GESN: implement 'media' subcommand

Implement the 'media' sub-command of the GET_EVENT_STATUS_NOTIFICATION
command.  This helps us report tray open, tray closed, no media, media
present states to the guest.

Newer Linux kernels (2.6.38+) rely on this command to revalidate discs
after media change.

This patch also sends out tray open/closed status to the guest driver
when requested e.g. via the CDROM_DRIVE_STATUS ioctl (thanks Markus).
Without such notification, the guest and qemu's tray open/close status
was frequently out of sync, causing installers like Anaconda detecting
no disc instead of tray open, confusing them terribly.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/core.c     | 113 ++++++++++++++++++++++++++++++++++++++++++++--
 hw/ide/internal.h |   6 +++
 2 files changed, 115 insertions(+), 4 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index a38cc14aaf..f028ddb495 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1084,6 +1084,48 @@ static int ide_dvd_read_structure(IDEState *s, int format,
     }
 }
 
+static unsigned int event_status_media(IDEState *s,
+                                       uint8_t *buf)
+{
+    enum media_event_code {
+        MEC_NO_CHANGE = 0,       /* Status unchanged */
+        MEC_EJECT_REQUESTED,     /* received a request from user to eject */
+        MEC_NEW_MEDIA,           /* new media inserted and ready for access */
+        MEC_MEDIA_REMOVAL,       /* only for media changers */
+        MEC_MEDIA_CHANGED,       /* only for media changers */
+        MEC_BG_FORMAT_COMPLETED, /* MRW or DVD+RW b/g format completed */
+        MEC_BG_FORMAT_RESTARTED, /* MRW or DVD+RW b/g format restarted */
+    };
+    enum media_status {
+        MS_TRAY_OPEN = 1,
+        MS_MEDIA_PRESENT = 2,
+    };
+    uint8_t event_code, media_status;
+
+    media_status = 0;
+    if (s->bs->tray_open) {
+        media_status = MS_TRAY_OPEN;
+    } else if (bdrv_is_inserted(s->bs)) {
+        media_status = MS_MEDIA_PRESENT;
+    }
+
+    /* Event notification descriptor */
+    event_code = MEC_NO_CHANGE;
+    if (media_status != MS_TRAY_OPEN && s->events.new_media) {
+        event_code = MEC_NEW_MEDIA;
+        s->events.new_media = false;
+    }
+
+    buf[4] = event_code;
+    buf[5] = media_status;
+
+    /* These fields are reserved, just clear them. */
+    buf[6] = 0;
+    buf[7] = 0;
+
+    return 8; /* We wrote to 4 extra bytes from the header */
+}
+
 static void handle_get_event_status_notification(IDEState *s,
                                                  uint8_t *buf,
                                                  const uint8_t *packet)
@@ -1104,6 +1146,26 @@ static void handle_get_event_status_notification(IDEState *s,
         uint8_t supported_events;
     } __attribute((packed)) *gesn_event_header;
 
+    enum notification_class_request_type {
+        NCR_RESERVED1 = 1 << 0,
+        NCR_OPERATIONAL_CHANGE = 1 << 1,
+        NCR_POWER_MANAGEMENT = 1 << 2,
+        NCR_EXTERNAL_REQUEST = 1 << 3,
+        NCR_MEDIA = 1 << 4,
+        NCR_MULTI_HOST = 1 << 5,
+        NCR_DEVICE_BUSY = 1 << 6,
+        NCR_RESERVED2 = 1 << 7,
+    };
+    enum event_notification_class_field {
+        ENC_NO_EVENTS = 0,
+        ENC_OPERATIONAL_CHANGE,
+        ENC_POWER_MANAGEMENT,
+        ENC_EXTERNAL_REQUEST,
+        ENC_MEDIA,
+        ENC_MULTIPLE_HOSTS,
+        ENC_DEVICE_BUSY,
+        ENC_RESERVED,
+    };
     unsigned int max_len, used_len;
 
     gesn_cdb = (void *)packet;
@@ -1121,12 +1183,32 @@ static void handle_get_event_status_notification(IDEState *s,
 
     /* polling mode operation */
 
-    /* We don't support any event class (yet). */
-    gesn_event_header->supported_events = 0;
+    /*
+     * These are the supported events.
+     *
+     * We currently only support requests of the 'media' type.
+     */
+    gesn_event_header->supported_events = NCR_MEDIA;
 
-    gesn_event_header->notification_class = 0x80; /* No event available */
-    used_len = sizeof(*gesn_event_header);
+    /*
+     * We use |= below to set the class field; other bits in this byte
+     * are reserved now but this is useful to do if we have to use the
+     * reserved fields later.
+     */
+    gesn_event_header->notification_class = 0;
 
+    /*
+     * Responses to requests are to be based on request priority.  The
+     * notification_class_request_type enum above specifies the
+     * priority: upper elements are higher prio than lower ones.
+     */
+    if (gesn_cdb->class & NCR_MEDIA) {
+        gesn_event_header->notification_class |= ENC_MEDIA;
+        used_len = event_status_media(s, buf);
+    } else {
+        gesn_event_header->notification_class = 0x80; /* No event available */
+        used_len = sizeof(*gesn_event_header);
+    }
     gesn_event_header->len = cpu_to_be16(used_len
                                          - sizeof(*gesn_event_header));
     ide_atapi_cmd_reply(s, used_len, max_len);
@@ -1655,6 +1737,7 @@ static void cdrom_change_cb(void *opaque, int reason)
     s->sense_key = SENSE_UNIT_ATTENTION;
     s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED;
     s->cdrom_changed = 1;
+    s->events.new_media = true;
     ide_set_irq(s->bus);
 }
 
@@ -2799,6 +2882,25 @@ static bool ide_drive_pio_state_needed(void *opaque)
     return (s->status & DRQ_STAT) != 0;
 }
 
+static bool ide_atapi_gesn_needed(void *opaque)
+{
+    IDEState *s = opaque;
+
+    return s->events.new_media || s->events.eject_request;
+}
+
+/* Fields for GET_EVENT_STATUS_NOTIFICATION ATAPI command */
+const VMStateDescription vmstate_ide_atapi_gesn_state = {
+    .name ="ide_drive/atapi/gesn_state",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields = (VMStateField []) {
+        VMSTATE_BOOL(events.new_media, IDEState),
+        VMSTATE_BOOL(events.eject_request, IDEState),
+    }
+};
+
 const VMStateDescription vmstate_ide_drive_pio_state = {
     .name = "ide_drive/pio_state",
     .version_id = 1,
@@ -2852,6 +2954,9 @@ const VMStateDescription vmstate_ide_drive = {
         {
             .vmsd = &vmstate_ide_drive_pio_state,
             .needed = ide_drive_pio_state_needed,
+        }, {
+            .vmsd = &vmstate_ide_atapi_gesn_state,
+            .needed = ide_atapi_gesn_needed,
         }, {
             /* empty */
         }
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index d533fb63b3..ba7e9a8ee2 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -373,6 +373,11 @@ typedef int DMAFunc(IDEDMA *);
 typedef int DMAIntFunc(IDEDMA *, int);
 typedef void DMARestartFunc(void *, int, int);
 
+struct unreported_events {
+    bool eject_request;
+    bool new_media;
+};
+
 /* NOTE: IDEState represents in fact one drive */
 struct IDEState {
     IDEBus *bus;
@@ -408,6 +413,7 @@ struct IDEState {
     BlockDriverState *bs;
     char version[9];
     /* ATAPI specific */
+    struct unreported_events events;
     uint8_t sense_key;
     uint8_t asc;
     uint8_t cdrom_changed;

From 2d56a546a73ca3f588196f4065621ff5f11f50e4 Mon Sep 17 00:00:00 2001
From: Mitnick Lyu <mitnick.lyu@gmail.com>
Date: Wed, 13 Apr 2011 17:30:54 +0800
Subject: [PATCH 187/386] vpc.c: Use get_option_parameter() does the search

Use get_option_parameter() to instead of duplicating the loop, and
use BDRV_SECTOR_SIZE to instead of 512

Signed-off-by: Mitnick Lyu <mitnick.lyu@gmail.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vpc.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/block/vpc.c b/block/vpc.c
index 7b025be01d..56865da5bc 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -505,12 +505,8 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options)
     int ret = -EIO;
 
     // Read out options
-    while (options && options->name) {
-        if (!strcmp(options->name, "size")) {
-            total_sectors = options->value.n / 512;
-        }
-        options++;
-    }
+    total_sectors = get_option_parameter(options, BLOCK_OPT_SIZE)->value.n /
+                    BDRV_SECTOR_SIZE;
 
     // Create the file
     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);

From 7f7454ec296b3403b4accec55349a8f0232d3576 Mon Sep 17 00:00:00 2001
From: Anthony Liguori <aliguori@us.ibm.com>
Date: Wed, 13 Apr 2011 07:41:19 -0500
Subject: [PATCH 188/386] lm32: fix build breakage due to uninitialized
 variable 'r'

gcc 4.5.2 correctly complains that r is potentially uninitialized in this
function.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/milkymist-pfpu.c | 2 +-
 roms/seabios        | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/milkymist-pfpu.c b/hw/milkymist-pfpu.c
index 4831e00b81..94e631510f 100644
--- a/hw/milkymist-pfpu.c
+++ b/hw/milkymist-pfpu.c
@@ -163,7 +163,7 @@ static int pfpu_decode_insn(MilkymistPFPUState *s)
     uint32_t reg_b = (insn >> 11) & 0x7f;
     uint32_t op = (insn >> 7) & 0xf;
     uint32_t reg_d = insn & 0x7f;
-    uint32_t r;
+    uint32_t r = 0;
     int latency = 0;
 
     switch (op) {
diff --git a/roms/seabios b/roms/seabios
index cc975646af..06d0bdd9e2 160000
--- a/roms/seabios
+++ b/roms/seabios
@@ -1 +1 @@
-Subproject commit cc975646af69f279396d4d5e1379ac6af80ee637
+Subproject commit 06d0bdd9e2e20377b3180e4986b14c8549b393e4

From cc9453f457888bdd3ab7b37988adbfc4712fa125 Mon Sep 17 00:00:00 2001
From: Anthony Liguori <aliguori@us.ibm.com>
Date: Wed, 13 Apr 2011 08:16:53 -0500
Subject: [PATCH 189/386] Revert SeaBIOS change due to overzealous commit -a

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 roms/seabios | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/roms/seabios b/roms/seabios
index 06d0bdd9e2..cc975646af 160000
--- a/roms/seabios
+++ b/roms/seabios
@@ -1 +1 @@
-Subproject commit 06d0bdd9e2e20377b3180e4986b14c8549b393e4
+Subproject commit cc975646af69f279396d4d5e1379ac6af80ee637

From 4d9ad7f793605abd9806fc932b3e04e028894565 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 11 Apr 2011 16:32:08 +0100
Subject: [PATCH 190/386] target-arm: Don't overflow when calculating value for
 signed VABAL

In the VABAL instruction we take the absolute difference of two
values of size x and store it in a result of size 2x. This means
we have to be careful to calculate the absolute difference using
a wide enough type that we don't accidentally overflow.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/neon_helper.c | 38 +++++++++++++++++++++-----------------
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index c3ac96a099..7df925ad31 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -1514,9 +1514,13 @@ uint64_t HELPER(neon_addl_saturate_s64)(uint64_t a, uint64_t b)
     return result;
 }
 
-#define DO_ABD(dest, x, y, type) do { \
-    type tmp_x = x; \
-    type tmp_y = y; \
+/* We have to do the arithmetic in a larger type than
+ * the input type, because for example with a signed 32 bit
+ * op the absolute difference can overflow a signed 32 bit value.
+ */
+#define DO_ABD(dest, x, y, intype, arithtype) do {            \
+    arithtype tmp_x = (intype)(x);                            \
+    arithtype tmp_y = (intype)(y);                            \
     dest = ((tmp_x > tmp_y) ? tmp_x - tmp_y : tmp_y - tmp_x); \
     } while(0)
 
@@ -1524,12 +1528,12 @@ uint64_t HELPER(neon_abdl_u16)(uint32_t a, uint32_t b)
 {
     uint64_t tmp;
     uint64_t result;
-    DO_ABD(result, a, b, uint8_t);
-    DO_ABD(tmp, a >> 8, b >> 8, uint8_t);
+    DO_ABD(result, a, b, uint8_t, uint32_t);
+    DO_ABD(tmp, a >> 8, b >> 8, uint8_t, uint32_t);
     result |= tmp << 16;
-    DO_ABD(tmp, a >> 16, b >> 16, uint8_t);
+    DO_ABD(tmp, a >> 16, b >> 16, uint8_t, uint32_t);
     result |= tmp << 32;
-    DO_ABD(tmp, a >> 24, b >> 24, uint8_t);
+    DO_ABD(tmp, a >> 24, b >> 24, uint8_t, uint32_t);
     result |= tmp << 48;
     return result;
 }
@@ -1538,12 +1542,12 @@ uint64_t HELPER(neon_abdl_s16)(uint32_t a, uint32_t b)
 {
     uint64_t tmp;
     uint64_t result;
-    DO_ABD(result, a, b, int8_t);
-    DO_ABD(tmp, a >> 8, b >> 8, int8_t);
+    DO_ABD(result, a, b, int8_t, int32_t);
+    DO_ABD(tmp, a >> 8, b >> 8, int8_t, int32_t);
     result |= tmp << 16;
-    DO_ABD(tmp, a >> 16, b >> 16, int8_t);
+    DO_ABD(tmp, a >> 16, b >> 16, int8_t, int32_t);
     result |= tmp << 32;
-    DO_ABD(tmp, a >> 24, b >> 24, int8_t);
+    DO_ABD(tmp, a >> 24, b >> 24, int8_t, int32_t);
     result |= tmp << 48;
     return result;
 }
@@ -1552,8 +1556,8 @@ uint64_t HELPER(neon_abdl_u32)(uint32_t a, uint32_t b)
 {
     uint64_t tmp;
     uint64_t result;
-    DO_ABD(result, a, b, uint16_t);
-    DO_ABD(tmp, a >> 16, b >> 16, uint16_t);
+    DO_ABD(result, a, b, uint16_t, uint32_t);
+    DO_ABD(tmp, a >> 16, b >> 16, uint16_t, uint32_t);
     return result | (tmp << 32);
 }
 
@@ -1561,22 +1565,22 @@ uint64_t HELPER(neon_abdl_s32)(uint32_t a, uint32_t b)
 {
     uint64_t tmp;
     uint64_t result;
-    DO_ABD(result, a, b, int16_t);
-    DO_ABD(tmp, a >> 16, b >> 16, int16_t);
+    DO_ABD(result, a, b, int16_t, int32_t);
+    DO_ABD(tmp, a >> 16, b >> 16, int16_t, int32_t);
     return result | (tmp << 32);
 }
 
 uint64_t HELPER(neon_abdl_u64)(uint32_t a, uint32_t b)
 {
     uint64_t result;
-    DO_ABD(result, a, b, uint32_t);
+    DO_ABD(result, a, b, uint32_t, uint64_t);
     return result;
 }
 
 uint64_t HELPER(neon_abdl_s64)(uint32_t a, uint32_t b)
 {
     uint64_t result;
-    DO_ABD(result, a, b, int32_t);
+    DO_ABD(result, a, b, int32_t, int64_t);
     return result;
 }
 #undef DO_ABD

From 420b6c317de87890e06225de6e2f8af7bf714df0 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Thu, 14 Apr 2011 14:11:56 +0100
Subject: [PATCH 191/386] tests/test-mmap.c: Check mmap() return value before
 using it

Correct the position of a "stop if MAP_FAILED" check in the mmap()
tests, so that if mmap() does fail we print a failure message
rather than segfaulting inside memcpy().

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 tests/test-mmap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/test-mmap.c b/tests/test-mmap.c
index fcb365f40c..c578e2572a 100644
--- a/tests/test-mmap.c
+++ b/tests/test-mmap.c
@@ -164,6 +164,7 @@ void check_aligned_anonymous_unfixed_colliding_mmaps(void)
 		nlen = pagesize * 8;
 		p3 = mmap(NULL, nlen, PROT_READ, 
 			  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+		fail_unless (p3 != MAP_FAILED);
 
 		/* Check if the mmaped areas collide.  */
 		if (p3 < p2 
@@ -174,7 +175,6 @@ void check_aligned_anonymous_unfixed_colliding_mmaps(void)
 
 		/* Make sure we get pages aligned with the pagesize. The
 		   target expects this.  */
-		fail_unless (p3 != MAP_FAILED);
 		p = (uintptr_t) p3;
 		fail_unless ((p & pagemask) == 0);
 		munmap (p2, pagesize);

From 3b2319a30b5ae528787bf3769b1a28a863b53252 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Wed, 13 Apr 2011 10:03:43 +0200
Subject: [PATCH 192/386] really fix -icount in the iothread case

The correct fix for -icount is to consider the biggest difference
between iothread and non-iothread modes.  In the traditional model,
CPUs run _before_ the iothread calls select (or WaitForMultipleObjects
for Win32).  In the iothread model, CPUs run while the iothread
isn't holding the mutex, i.e. _during_ those same calls.

So, the iothread should always block as long as possible to let
the CPUs run smoothly---the timeout might as well be infinite---and
either the OS or the CPU thread itself will let the iothread know
when something happens.  At this point, the iothread wakes up and
interrupts the CPU.

This is exactly the approach that this patch takes: when cpu_exec_all
returns in -icount mode, and it is because a vm_clock deadline has
been met, it wakes up the iothread to process the timers.  This is
really the "bulk" of fixing icount.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 cpus.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/cpus.c b/cpus.c
index 41bec7cc56..cbeac7a40e 100644
--- a/cpus.c
+++ b/cpus.c
@@ -830,6 +830,9 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
 
     while (1) {
         cpu_exec_all();
+        if (use_icount && qemu_next_deadline() <= 0) {
+            qemu_notify_event();
+        }
         qemu_tcg_wait_io_event();
     }
 

From ab33fcda9f96b9195dfb3fcf5bd9bb5383caeaea Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Wed, 13 Apr 2011 10:03:44 +0200
Subject: [PATCH 193/386] enable vm_clock to "warp" in the iothread+icount case

The previous patch however is not enough, because if the virtual CPU
goes to sleep waiting for a future timer interrupt to wake it up, qemu
deadlocks.  The timer interrupt never comes because time is driven by
icount, but the vCPU doesn't run any insns.

You could say that VCPUs should never go to sleep in icount
mode if there is a pending vm_clock timer; rather time should
just warp to the next vm_clock event with no sleep ever taking place.
Even better, you can sleep for some time related to the
time left until the next event, to avoid that the warps are too visible
externally; for example, you could be sending network packets continously
instead of every 100ms.

This is what this patch implements.  qemu_clock_warp is called: 1)
whenever a vm_clock timer is adjusted, to ensure the warp_timer is
synchronized; 2) at strategic points in the CPU thread, to make sure
the insn counter is synchronized before the CPU starts running.
In any case, the warp_timer is disabled while the CPU is running,
because the insn counter will then be making progress on its own.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 cpus.c        |  8 ++++-
 qemu-common.h |  1 +
 qemu-timer.c  | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 qemu-timer.h  |  1 +
 4 files changed, 102 insertions(+), 2 deletions(-)

diff --git a/cpus.c b/cpus.c
index cbeac7a40e..6a50199039 100644
--- a/cpus.c
+++ b/cpus.c
@@ -155,7 +155,7 @@ static bool cpu_thread_is_idle(CPUState *env)
     return true;
 }
 
-static bool all_cpu_threads_idle(void)
+bool all_cpu_threads_idle(void)
 {
     CPUState *env;
 
@@ -739,6 +739,9 @@ static void qemu_tcg_wait_io_event(void)
     CPUState *env;
 
     while (all_cpu_threads_idle()) {
+       /* Start accounting real time to the virtual clock if the CPUs
+          are idle.  */
+        qemu_clock_warp(vm_clock);
         qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
     }
 
@@ -1073,6 +1076,9 @@ bool cpu_exec_all(void)
 {
     int r;
 
+    /* Account partial waits to the vm_clock.  */
+    qemu_clock_warp(vm_clock);
+
     if (next_cpu == NULL) {
         next_cpu = first_cpu;
     }
diff --git a/qemu-common.h b/qemu-common.h
index 82e27c18d3..4f6037bab9 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -298,6 +298,7 @@ void qemu_notify_event(void);
 void qemu_cpu_kick(void *env);
 void qemu_cpu_kick_self(void);
 int qemu_cpu_is_self(void *env);
+bool all_cpu_threads_idle(void);
 
 /* work queue */
 struct qemu_work_item {
diff --git a/qemu-timer.c b/qemu-timer.c
index 50f1943afd..4959688895 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -153,6 +153,8 @@ void cpu_disable_ticks(void)
 struct QEMUClock {
     int type;
     int enabled;
+
+    QEMUTimer *warp_timer;
 };
 
 struct QEMUTimer {
@@ -386,6 +388,90 @@ void qemu_clock_enable(QEMUClock *clock, int enabled)
     clock->enabled = enabled;
 }
 
+static int64_t vm_clock_warp_start;
+
+static void icount_warp_rt(void *opaque)
+{
+    if (vm_clock_warp_start == -1) {
+        return;
+    }
+
+    if (vm_running) {
+        int64_t clock = qemu_get_clock_ns(rt_clock);
+        int64_t warp_delta = clock - vm_clock_warp_start;
+        if (use_icount == 1) {
+            qemu_icount_bias += warp_delta;
+        } else {
+            /*
+             * In adaptive mode, do not let the vm_clock run too
+             * far ahead of real time.
+             */
+            int64_t cur_time = cpu_get_clock();
+            int64_t cur_icount = qemu_get_clock_ns(vm_clock);
+            int64_t delta = cur_time - cur_icount;
+            qemu_icount_bias += MIN(warp_delta, delta);
+        }
+        if (qemu_timer_expired(active_timers[QEMU_CLOCK_VIRTUAL],
+                               qemu_get_clock_ns(vm_clock))) {
+            qemu_notify_event();
+        }
+    }
+    vm_clock_warp_start = -1;
+}
+
+void qemu_clock_warp(QEMUClock *clock)
+{
+    int64_t deadline;
+
+    if (!clock->warp_timer) {
+        return;
+    }
+
+    /*
+     * There are too many global variables to make the "warp" behavior
+     * applicable to other clocks.  But a clock argument removes the
+     * need for if statements all over the place.
+     */
+    assert(clock == vm_clock);
+
+    /*
+     * If the CPUs have been sleeping, advance the vm_clock timer now.  This
+     * ensures that the deadline for the timer is computed correctly below.
+     * This also makes sure that the insn counter is synchronized before the
+     * CPU starts running, in case the CPU is woken by an event other than
+     * the earliest vm_clock timer.
+     */
+    icount_warp_rt(NULL);
+    if (!all_cpu_threads_idle() || !active_timers[clock->type]) {
+        qemu_del_timer(clock->warp_timer);
+        return;
+    }
+
+    vm_clock_warp_start = qemu_get_clock_ns(rt_clock);
+    deadline = qemu_next_deadline();
+    if (deadline > 0) {
+        /*
+         * Ensure the vm_clock proceeds even when the virtual CPU goes to
+         * sleep.  Otherwise, the CPU might be waiting for a future timer
+         * interrupt to wake it up, but the interrupt never comes because
+         * the vCPU isn't running any insns and thus doesn't advance the
+         * vm_clock.
+         *
+         * An extreme solution for this problem would be to never let VCPUs
+         * sleep in icount mode if there is a pending vm_clock timer; rather
+         * time could just advance to the next vm_clock event.  Instead, we
+         * do stop VCPUs and only advance vm_clock after some "real" time,
+         * (related to the time left until the next event) has passed.  This
+         * rt_clock timer will do this.  This avoids that the warps are too
+         * visible externally---for example, you will not be sending network
+         * packets continously instead of every 100ms.
+         */
+        qemu_mod_timer(clock->warp_timer, vm_clock_warp_start + deadline);
+    } else {
+        qemu_notify_event();
+    }
+}
+
 QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
                           QEMUTimerCB *cb, void *opaque)
 {
@@ -454,8 +540,10 @@ static void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
             qemu_rearm_alarm_timer(alarm_timer);
         }
         /* Interrupt execution to force deadline recalculation.  */
-        if (use_icount)
+        qemu_clock_warp(ts->clock);
+        if (use_icount) {
             qemu_notify_event();
+        }
     }
 }
 
@@ -576,6 +664,10 @@ void configure_icount(const char *option)
     if (!option)
         return;
 
+#ifdef CONFIG_IOTHREAD
+    vm_clock->warp_timer = qemu_new_timer_ns(rt_clock, icount_warp_rt, NULL);
+#endif
+
     if (strcmp(option, "auto") != 0) {
         icount_time_shift = strtol(option, NULL, 0);
         use_icount = 1;
diff --git a/qemu-timer.h b/qemu-timer.h
index 75d567578b..c01bcaba66 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -39,6 +39,7 @@ extern QEMUClock *host_clock;
 
 int64_t qemu_get_clock_ns(QEMUClock *clock);
 void qemu_clock_enable(QEMUClock *clock, int enabled);
+void qemu_clock_warp(QEMUClock *clock);
 
 QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
                           QEMUTimerCB *cb, void *opaque);

From 1ece93a91b8435b815ce7214cf41bbbbe7929e8b Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Wed, 13 Apr 2011 10:03:45 +0200
Subject: [PATCH 194/386] Revert wrong fixes for -icount in the iothread case

This reverts commits 225d02cd and c9f7383c.  While some parts of
the latter could be saved, I preferred a smooth, complete revert.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 qemu-timer.c | 66 ++++++++++++++++++++++++++++------------------------
 1 file changed, 36 insertions(+), 30 deletions(-)

diff --git a/qemu-timer.c b/qemu-timer.c
index 4959688895..7998f37a51 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -110,9 +110,12 @@ static int64_t cpu_get_clock(void)
     }
 }
 
+#ifndef CONFIG_IOTHREAD
 static int64_t qemu_icount_delta(void)
 {
-    if (use_icount == 1) {
+    if (!use_icount) {
+        return 5000 * (int64_t) 1000000;
+    } else if (use_icount == 1) {
         /* When not using an adaptive execution frequency
            we tend to get badly out of sync with real time,
            so just delay for a reasonable amount of time.  */
@@ -121,6 +124,7 @@ static int64_t qemu_icount_delta(void)
         return cpu_get_icount() - cpu_get_clock();
     }
 }
+#endif
 
 /* enable cpu_get_ticks() */
 void cpu_enable_ticks(void)
@@ -1147,39 +1151,41 @@ void quit_timers(void)
 
 int qemu_calculate_timeout(void)
 {
+#ifndef CONFIG_IOTHREAD
     int timeout;
-    int64_t add;
-    int64_t delta;
 
-    /* When using icount, making forward progress with qemu_icount when the
-       guest CPU is idle is critical. We only use the static io-thread timeout
-       for non icount runs.  */
-    if (!use_icount || !vm_running) {
-        return 5000;
-    }
-
-    /* Advance virtual time to the next event.  */
-    delta = qemu_icount_delta();
-    if (delta > 0) {
-        /* If virtual time is ahead of real time then just
-           wait for IO.  */
-        timeout = (delta + 999999) / 1000000;
-    } else {
-        /* Wait for either IO to occur or the next
-           timer event.  */
-        add = qemu_next_deadline();
-        /* We advance the timer before checking for IO.
-           Limit the amount we advance so that early IO
-           activity won't get the guest too far ahead.  */
-        if (add > 10000000)
-            add = 10000000;
-        delta += add;
-        qemu_icount += qemu_icount_round (add);
-        timeout = delta / 1000000;
-        if (timeout < 0)
-            timeout = 0;
+    if (!vm_running)
+        timeout = 5000;
+    else {
+     /* XXX: use timeout computed from timers */
+        int64_t add;
+        int64_t delta;
+        /* Advance virtual time to the next event.  */
+	delta = qemu_icount_delta();
+        if (delta > 0) {
+            /* If virtual time is ahead of real time then just
+               wait for IO.  */
+            timeout = (delta + 999999) / 1000000;
+        } else {
+            /* Wait for either IO to occur or the next
+               timer event.  */
+            add = qemu_next_deadline();
+            /* We advance the timer before checking for IO.
+               Limit the amount we advance so that early IO
+               activity won't get the guest too far ahead.  */
+            if (add > 10000000)
+                add = 10000000;
+            delta += add;
+            qemu_icount += qemu_icount_round (add);
+            timeout = delta / 1000000;
+            if (timeout < 0)
+                timeout = 0;
+        }
     }
 
     return timeout;
+#else /* CONFIG_IOTHREAD */
+    return 1000;
+#endif
 }
 

From cb842c90a485d9dbf05fa51e1500b3c1a1931256 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Wed, 13 Apr 2011 10:03:46 +0200
Subject: [PATCH 195/386] qemu_next_deadline should not consider host-time
 timers

It is purely for icount-based virtual timers.  And now that we got the
code right, rename the function to clarify the intended scope.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 cpus.c       |  4 ++--
 qemu-timer.c | 13 ++++---------
 qemu-timer.h |  2 +-
 3 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/cpus.c b/cpus.c
index 6a50199039..1fc34b75c2 100644
--- a/cpus.c
+++ b/cpus.c
@@ -833,7 +833,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
 
     while (1) {
         cpu_exec_all();
-        if (use_icount && qemu_next_deadline() <= 0) {
+        if (use_icount && qemu_next_icount_deadline() <= 0) {
             qemu_notify_event();
         }
         qemu_tcg_wait_io_event();
@@ -1050,7 +1050,7 @@ static int tcg_cpu_exec(CPUState *env)
         qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
         env->icount_decr.u16.low = 0;
         env->icount_extra = 0;
-        count = qemu_icount_round (qemu_next_deadline());
+        count = qemu_icount_round(qemu_next_icount_deadline());
         qemu_icount += count;
         decr = (count > 0xffff) ? 0xffff : count;
         count -= decr;
diff --git a/qemu-timer.c b/qemu-timer.c
index 7998f37a51..b8c0c8870d 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -452,7 +452,7 @@ void qemu_clock_warp(QEMUClock *clock)
     }
 
     vm_clock_warp_start = qemu_get_clock_ns(rt_clock);
-    deadline = qemu_next_deadline();
+    deadline = qemu_next_icount_deadline();
     if (deadline > 0) {
         /*
          * Ensure the vm_clock proceeds even when the virtual CPU goes to
@@ -765,21 +765,16 @@ static void host_alarm_handler(int host_signum)
     }
 }
 
-int64_t qemu_next_deadline(void)
+int64_t qemu_next_icount_deadline(void)
 {
     /* To avoid problems with overflow limit this to 2^32.  */
     int64_t delta = INT32_MAX;
 
+    assert(use_icount);
     if (active_timers[QEMU_CLOCK_VIRTUAL]) {
         delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -
                      qemu_get_clock_ns(vm_clock);
     }
-    if (active_timers[QEMU_CLOCK_HOST]) {
-        int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time -
-                 qemu_get_clock_ns(host_clock);
-        if (hdelta < delta)
-            delta = hdelta;
-    }
 
     if (delta < 0)
         delta = 0;
@@ -1169,7 +1164,7 @@ int qemu_calculate_timeout(void)
         } else {
             /* Wait for either IO to occur or the next
                timer event.  */
-            add = qemu_next_deadline();
+            add = qemu_next_icount_deadline();
             /* We advance the timer before checking for IO.
                Limit the amount we advance so that early IO
                activity won't get the guest too far ahead.  */
diff --git a/qemu-timer.h b/qemu-timer.h
index c01bcaba66..3a9228f7df 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -51,7 +51,7 @@ int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time);
 
 void qemu_run_all_timers(void);
 int qemu_alarm_pending(void);
-int64_t qemu_next_deadline(void);
+int64_t qemu_next_icount_deadline(void);
 void configure_alarms(char const *opt);
 void configure_icount(const char *option);
 int qemu_calculate_timeout(void);

From 1a00282a739d5cb7247ac3634ddd3e76537ef5eb Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Thu, 14 Apr 2011 19:19:00 +0200
Subject: [PATCH 196/386] sparc: Fix assertion caused by empty memory slot with
 0 byte

If the memory size given on the command line is equal to the
maximum size of memory defined by the hardware, there is no
"empty slot" after physical memory.

The following command

		qemu-system-sparc -m 256

raised an assertion:
exec.c:2614: cpu_register_physical_memory_offset: Assertion `size' failed

This can be fixed either at the caller side (don't call empty_slot_init)
or in empty_slot_init (do nothing) when size == 0. The second solution
was choosen here because it is more robust.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 hw/empty_slot.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/hw/empty_slot.c b/hw/empty_slot.c
index 664b8d9c4d..da8adc4d03 100644
--- a/hw/empty_slot.c
+++ b/hw/empty_slot.c
@@ -53,18 +53,21 @@ static CPUWriteMemoryFunc * const empty_slot_write[3] = {
 
 void empty_slot_init(target_phys_addr_t addr, uint64_t slot_size)
 {
-    DeviceState *dev;
-    SysBusDevice *s;
-    EmptySlot *e;
+    if (slot_size > 0) {
+        /* Only empty slots larger than 0 byte need handling. */
+        DeviceState *dev;
+        SysBusDevice *s;
+        EmptySlot *e;
 
-    dev = qdev_create(NULL, "empty_slot");
-    s = sysbus_from_qdev(dev);
-    e = FROM_SYSBUS(EmptySlot, s);
-    e->size = slot_size;
+        dev = qdev_create(NULL, "empty_slot");
+        s = sysbus_from_qdev(dev);
+        e = FROM_SYSBUS(EmptySlot, s);
+        e->size = slot_size;
 
-    qdev_init_nofail(dev);
+        qdev_init_nofail(dev);
 
-    sysbus_mmio_map(s, 0, addr);
+        sysbus_mmio_map(s, 0, addr);
+    }
 }
 
 static int empty_slot_init1(SysBusDevice *dev)

From 33d05394a6f5e7923bc115faf5122b7f38b0418a Mon Sep 17 00:00:00 2001
From: Blue Swirl <blauwirbel@gmail.com>
Date: Sun, 27 Mar 2011 09:07:54 +0000
Subject: [PATCH 197/386] json-lexer: fix conflict with mingw32 ERROR
 definition

The name ERROR is too generic, it conflicts with mingw32 ERROR definition.

Replace ERROR with IN_ERROR.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 json-lexer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/json-lexer.c b/json-lexer.c
index c736f42900..65c9720d65 100644
--- a/json-lexer.c
+++ b/json-lexer.c
@@ -28,7 +28,7 @@
  */
 
 enum json_lexer_state {
-    ERROR = 0,
+    IN_ERROR = 0,
     IN_DQ_UCODE3,
     IN_DQ_UCODE2,
     IN_DQ_UCODE1,
@@ -150,7 +150,7 @@ static const uint8_t json_lexer[][256] =  {
     /* Zero */
     [IN_ZERO] = {
         TERMINAL(JSON_INTEGER),
-        ['0' ... '9'] = ERROR,
+        ['0' ... '9'] = IN_ERROR,
         ['.'] = IN_MANTISSA,
     },
 
@@ -302,7 +302,7 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch)
             lexer->token = qstring_new();
             new_state = IN_START;
             break;
-        case ERROR:
+        case IN_ERROR:
             return -EINVAL;
         default:
             break;

From a08784dd11794fc60fcc724c7ef2cd1a75a5356d Mon Sep 17 00:00:00 2001
From: Blue Swirl <blauwirbel@gmail.com>
Date: Sun, 27 Mar 2011 14:12:29 +0000
Subject: [PATCH 198/386] Remove unused sysemu.h include directives

Remove unused sysemu.h include directives to speed up build
with the following patches.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 acl.c                | 1 -
 arm-semi.c           | 1 -
 balloon.c            | 1 -
 bt-host.c            | 1 -
 bt-vhci.c            | 1 -
 buffered_file.c      | 1 -
 device_tree.c        | 1 -
 hw/an5206.c          | 1 -
 hw/armv7m.c          | 1 -
 hw/axis_dev88.c      | 1 -
 hw/blizzard.c        | 1 -
 hw/bt-hci-csr.c      | 1 -
 hw/cris-boot.c       | 1 -
 hw/dummy_m68k.c      | 1 -
 hw/etraxfs.c         | 1 -
 hw/gumstix.c         | 1 -
 hw/ide/ich.c         | 1 -
 hw/ide/isa.c         | 1 -
 hw/ide/macio.c       | 1 -
 hw/ide/microdrive.c  | 1 -
 hw/ide/mmio.c        | 1 -
 hw/ide/pci.c         | 1 -
 hw/integratorcp.c    | 1 -
 hw/isa-bus.c         | 1 -
 hw/lm32_boards.c     | 1 -
 hw/mainstone.c       | 1 -
 hw/omap_sx1.c        | 1 -
 hw/ppc440_bamboo.c   | 1 -
 hw/ppc4xx_devs.c     | 1 -
 hw/stellaris.c       | 1 -
 hw/syborg.c          | 1 -
 hw/syborg_virtio.c   | 1 -
 hw/sysbus.c          | 1 -
 hw/tc58128.c         | 1 -
 hw/tosa.c            | 1 -
 hw/twl92230.c        | 1 -
 hw/virtio-balloon.c  | 1 -
 hw/virtio.c          | 1 -
 hw/vmport.c          | 1 -
 hw/xen_console.c     | 1 -
 hw/xen_domainbuild.c | 1 -
 hw/xen_machine_pv.c  | 1 -
 hw/xenfb.c           | 1 -
 hw/xilinx_timer.c    | 1 -
 kvm-stub.c           | 1 -
 migration-exec.c     | 1 -
 migration-fd.c       | 1 -
 migration-tcp.c      | 1 -
 migration-unix.c     | 1 -
 net.c                | 1 -
 net/slirp.c          | 1 -
 net/vde.c            | 1 -
 osdep.c              | 1 -
 qemu-config.c        | 1 -
 qemu-error.c         | 1 -
 qemu-tool.c          | 1 -
 56 files changed, 56 deletions(-)

diff --git a/acl.c b/acl.c
index 311dade4e2..82c27043c1 100644
--- a/acl.c
+++ b/acl.c
@@ -24,7 +24,6 @@
 
 
 #include "qemu-common.h"
-#include "sysemu.h"
 #include "acl.h"
 
 #ifdef CONFIG_FNMATCH
diff --git a/arm-semi.c b/arm-semi.c
index 1d5179b601..e9e6f8993f 100644
--- a/arm-semi.c
+++ b/arm-semi.c
@@ -33,7 +33,6 @@
 #define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024)
 #else
 #include "qemu-common.h"
-#include "sysemu.h"
 #include "gdbstub.h"
 #endif
 
diff --git a/balloon.c b/balloon.c
index 0021fef4b8..248c1b50a9 100644
--- a/balloon.c
+++ b/balloon.c
@@ -22,7 +22,6 @@
  * THE SOFTWARE.
  */
 
-#include "sysemu.h"
 #include "monitor.h"
 #include "qjson.h"
 #include "qint.h"
diff --git a/bt-host.c b/bt-host.c
index 6931e7cc62..095254ddc6 100644
--- a/bt-host.c
+++ b/bt-host.c
@@ -19,7 +19,6 @@
 
 #include "qemu-common.h"
 #include "qemu-char.h"
-#include "sysemu.h"
 #include "net.h"
 #include "bt-host.h"
 
diff --git a/bt-vhci.c b/bt-vhci.c
index 679c5e05d7..3c5772093e 100644
--- a/bt-vhci.c
+++ b/bt-vhci.c
@@ -19,7 +19,6 @@
 
 #include "qemu-common.h"
 #include "qemu-char.h"
-#include "sysemu.h"
 #include "net.h"
 #include "hw/bt.h"
 
diff --git a/buffered_file.c b/buffered_file.c
index b5e2baff46..41b42c3d5a 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -14,7 +14,6 @@
 #include "qemu-common.h"
 #include "hw/hw.h"
 #include "qemu-timer.h"
-#include "sysemu.h"
 #include "qemu-char.h"
 #include "buffered_file.h"
 
diff --git a/device_tree.c b/device_tree.c
index 21be070759..f5d5eb1bca 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -20,7 +20,6 @@
 
 #include "config.h"
 #include "qemu-common.h"
-#include "sysemu.h"
 #include "device_tree.h"
 #include "hw/loader.h"
 
diff --git a/hw/an5206.c b/hw/an5206.c
index b9f19a9944..42a0163fbd 100644
--- a/hw/an5206.c
+++ b/hw/an5206.c
@@ -9,7 +9,6 @@
 #include "hw.h"
 #include "pc.h"
 #include "mcf.h"
-#include "sysemu.h"
 #include "boards.h"
 #include "loader.h"
 #include "elf.h"
diff --git a/hw/armv7m.c b/hw/armv7m.c
index 304cd34bc2..72d010a63b 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -9,7 +9,6 @@
 
 #include "sysbus.h"
 #include "arm-misc.h"
-#include "sysemu.h"
 #include "loader.h"
 #include "elf.h"
 
diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index 57b5e2f041..0e2135afd0 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -26,7 +26,6 @@
 #include "net.h"
 #include "flash.h"
 #include "boards.h"
-#include "sysemu.h"
 #include "etraxfs.h"
 #include "loader.h"
 #include "elf.h"
diff --git a/hw/blizzard.c b/hw/blizzard.c
index 5f329ad13f..c5245504af 100644
--- a/hw/blizzard.c
+++ b/hw/blizzard.c
@@ -19,7 +19,6 @@
  */
 
 #include "qemu-common.h"
-#include "sysemu.h"
 #include "console.h"
 #include "devices.h"
 #include "vga_int.h"
diff --git a/hw/bt-hci-csr.c b/hw/bt-hci-csr.c
index 65ffa37fdf..d135ef4790 100644
--- a/hw/bt-hci-csr.c
+++ b/hw/bt-hci-csr.c
@@ -22,7 +22,6 @@
 #include "qemu-char.h"
 #include "qemu-timer.h"
 #include "irq.h"
-#include "sysemu.h"
 #include "net.h"
 #include "bt.h"
 
diff --git a/hw/cris-boot.c b/hw/cris-boot.c
index 2ef17f606c..37894f8b53 100644
--- a/hw/cris-boot.c
+++ b/hw/cris-boot.c
@@ -23,7 +23,6 @@
  */
 
 #include "hw.h"
-#include "sysemu.h"
 #include "loader.h"
 #include "elf.h"
 #include "cris-boot.h"
diff --git a/hw/dummy_m68k.c b/hw/dummy_m68k.c
index 61efb39896..cec1cc8e82 100644
--- a/hw/dummy_m68k.c
+++ b/hw/dummy_m68k.c
@@ -7,7 +7,6 @@
  */
 
 #include "hw.h"
-#include "sysemu.h"
 #include "boards.h"
 #include "loader.h"
 #include "elf.h"
diff --git a/hw/etraxfs.c b/hw/etraxfs.c
index 5ee5f979aa..b84d74a11e 100644
--- a/hw/etraxfs.c
+++ b/hw/etraxfs.c
@@ -24,7 +24,6 @@
 
 #include "sysbus.h"
 #include "boards.h"
-#include "sysemu.h"
 #include "net.h"
 #include "flash.h"
 #include "etraxfs.h"
diff --git a/hw/gumstix.c b/hw/gumstix.c
index ee63f634cc..853f7e1ee8 100644
--- a/hw/gumstix.c
+++ b/hw/gumstix.c
@@ -35,7 +35,6 @@
 #include "pxa.h"
 #include "net.h"
 #include "flash.h"
-#include "sysemu.h"
 #include "devices.h"
 #include "boards.h"
 #include "blockdev.h"
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index f242d7a81f..a3d475c59a 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -67,7 +67,6 @@
 #include <hw/isa.h>
 #include "block.h"
 #include "block_int.h"
-#include "sysemu.h"
 #include "dma.h"
 
 #include <hw/ide/pci.h>
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 8c59c5a47c..4ac745324c 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -27,7 +27,6 @@
 #include <hw/isa.h>
 #include "block.h"
 #include "block_int.h"
-#include "sysemu.h"
 #include "dma.h"
 
 #include <hw/ide/internal.h>
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index c1b4caab5b..7107f6b3c2 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -27,7 +27,6 @@
 #include <hw/mac_dbdma.h>
 #include "block.h"
 #include "block_int.h"
-#include "sysemu.h"
 #include "dma.h"
 
 #include <hw/ide/internal.h>
diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c
index 2ceeb87c0c..9fbbf0e78a 100644
--- a/hw/ide/microdrive.c
+++ b/hw/ide/microdrive.c
@@ -27,7 +27,6 @@
 #include <hw/pcmcia.h>
 #include "block.h"
 #include "block_int.h"
-#include "sysemu.h"
 #include "dma.h"
 
 #include <hw/ide/internal.h>
diff --git a/hw/ide/mmio.c b/hw/ide/mmio.c
index 82b24b673b..10f6f4063c 100644
--- a/hw/ide/mmio.c
+++ b/hw/ide/mmio.c
@@ -25,7 +25,6 @@
 #include <hw/hw.h>
 #include "block.h"
 #include "block_int.h"
-#include "sysemu.h"
 #include "dma.h"
 
 #include <hw/ide/internal.h>
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 35168cb469..65cb56c38c 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -28,7 +28,6 @@
 #include <hw/isa.h>
 #include "block.h"
 #include "block_int.h"
-#include "sysemu.h"
 #include "dma.h"
 
 #include <hw/ide/pci.h>
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index b049940821..a6c27be82c 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -10,7 +10,6 @@
 #include "sysbus.h"
 #include "primecell.h"
 #include "devices.h"
-#include "sysemu.h"
 #include "boards.h"
 #include "arm-misc.h"
 #include "net.h"
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index d07aa410f7..27655436a0 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -17,7 +17,6 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 #include "hw.h"
-#include "sysemu.h"
 #include "monitor.h"
 #include "sysbus.h"
 #include "isa.h"
diff --git a/hw/lm32_boards.c b/hw/lm32_boards.c
index 85190f0bfa..64629230cf 100644
--- a/hw/lm32_boards.c
+++ b/hw/lm32_boards.c
@@ -21,7 +21,6 @@
 #include "hw.h"
 #include "net.h"
 #include "flash.h"
-#include "sysemu.h"
 #include "devices.h"
 #include "boards.h"
 #include "loader.h"
diff --git a/hw/mainstone.c b/hw/mainstone.c
index 50691ca41e..4792f0e3ed 100644
--- a/hw/mainstone.c
+++ b/hw/mainstone.c
@@ -14,7 +14,6 @@
 #include "net.h"
 #include "devices.h"
 #include "boards.h"
-#include "sysemu.h"
 #include "flash.h"
 #include "blockdev.h"
 #include "sysbus.h"
diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c
index 06bccbdc4e..a7b687bc41 100644
--- a/hw/omap_sx1.c
+++ b/hw/omap_sx1.c
@@ -26,7 +26,6 @@
  * with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #include "hw.h"
-#include "sysemu.h"
 #include "console.h"
 #include "omap.h"
 #include "boards.h"
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index 645e84fd36..20b862939e 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -17,7 +17,6 @@
 #include "hw.h"
 #include "pci.h"
 #include "boards.h"
-#include "sysemu.h"
 #include "ppc440.h"
 #include "kvm.h"
 #include "kvm_ppc.h"
diff --git a/hw/ppc4xx_devs.c b/hw/ppc4xx_devs.c
index 5f581fe2c4..7f9ed17138 100644
--- a/hw/ppc4xx_devs.c
+++ b/hw/ppc4xx_devs.c
@@ -24,7 +24,6 @@
 #include "hw.h"
 #include "ppc.h"
 #include "ppc4xx.h"
-#include "sysemu.h"
 #include "qemu-log.h"
 
 //#define DEBUG_MMIO
diff --git a/hw/stellaris.c b/hw/stellaris.c
index 0d5292688e..7932c24576 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -14,7 +14,6 @@
 #include "qemu-timer.h"
 #include "i2c.h"
 #include "net.h"
-#include "sysemu.h"
 #include "boards.h"
 
 #define GPIO_A 0
diff --git a/hw/syborg.c b/hw/syborg.c
index 758c69a9cd..bc200e48aa 100644
--- a/hw/syborg.c
+++ b/hw/syborg.c
@@ -25,7 +25,6 @@
 #include "sysbus.h"
 #include "boards.h"
 #include "arm-misc.h"
-#include "sysemu.h"
 #include "net.h"
 
 static struct arm_boot_info syborg_binfo;
diff --git a/hw/syborg_virtio.c b/hw/syborg_virtio.c
index ee08c49105..2f3e6da4e2 100644
--- a/hw/syborg_virtio.c
+++ b/hw/syborg_virtio.c
@@ -26,7 +26,6 @@
 #include "sysbus.h"
 #include "virtio.h"
 #include "virtio-net.h"
-#include "sysemu.h"
 
 //#define DEBUG_SYBORG_VIRTIO
 
diff --git a/hw/sysbus.c b/hw/sysbus.c
index acad72abe4..2e22be7b25 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -18,7 +18,6 @@
  */
 
 #include "sysbus.h"
-#include "sysemu.h"
 #include "monitor.h"
 
 static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
diff --git a/hw/tc58128.c b/hw/tc58128.c
index 672a01c467..61b99dd4da 100644
--- a/hw/tc58128.c
+++ b/hw/tc58128.c
@@ -1,6 +1,5 @@
 #include "hw.h"
 #include "sh.h"
-#include "sysemu.h"
 #include "loader.h"
 
 #define CE1  0x0100
diff --git a/hw/tosa.c b/hw/tosa.c
index b8b6c4f390..a7967a286e 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -11,7 +11,6 @@
 #include "hw.h"
 #include "pxa.h"
 #include "arm-misc.h"
-#include "sysemu.h"
 #include "devices.h"
 #include "sharpsl.h"
 #include "pcmcia.h"
diff --git a/hw/twl92230.c b/hw/twl92230.c
index 8e74acc059..a75448f06a 100644
--- a/hw/twl92230.c
+++ b/hw/twl92230.c
@@ -22,7 +22,6 @@
 #include "hw.h"
 #include "qemu-timer.h"
 #include "i2c.h"
-#include "sysemu.h"
 #include "console.h"
 
 #define VERBOSE 1
diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
index 257baf8d4f..70a8710343 100644
--- a/hw/virtio-balloon.c
+++ b/hw/virtio-balloon.c
@@ -15,7 +15,6 @@
 #include "qemu-common.h"
 #include "virtio.h"
 #include "pc.h"
-#include "sysemu.h"
 #include "cpu.h"
 #include "monitor.h"
 #include "balloon.h"
diff --git a/hw/virtio.c b/hw/virtio.c
index 31bd9e32dc..6e8814cb64 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -16,7 +16,6 @@
 #include "trace.h"
 #include "qemu-error.h"
 #include "virtio.h"
-#include "sysemu.h"
 
 /* The alignment to use between consumer and producer parts of vring.
  * x86 pagesize again. */
diff --git a/hw/vmport.c b/hw/vmport.c
index 19010e4843..c8aefaabb8 100644
--- a/hw/vmport.c
+++ b/hw/vmport.c
@@ -24,7 +24,6 @@
 #include "hw.h"
 #include "isa.h"
 #include "pc.h"
-#include "sysemu.h"
 #include "kvm.h"
 #include "qdev.h"
 
diff --git a/hw/xen_console.c b/hw/xen_console.c
index d2261f4139..c6c8163813 100644
--- a/hw/xen_console.c
+++ b/hw/xen_console.c
@@ -33,7 +33,6 @@
 #include <xenctrl.h>
 
 #include "hw.h"
-#include "sysemu.h"
 #include "qemu-char.h"
 #include "xen_backend.h"
 
diff --git a/hw/xen_domainbuild.c b/hw/xen_domainbuild.c
index 371c56206d..4093587df1 100644
--- a/hw/xen_domainbuild.c
+++ b/hw/xen_domainbuild.c
@@ -1,7 +1,6 @@
 #include <signal.h>
 #include "xen_backend.h"
 #include "xen_domainbuild.h"
-#include "sysemu.h"
 #include "qemu-timer.h"
 #include "qemu-log.h"
 
diff --git a/hw/xen_machine_pv.c b/hw/xen_machine_pv.c
index 77a34bf111..0d7f73ed82 100644
--- a/hw/xen_machine_pv.c
+++ b/hw/xen_machine_pv.c
@@ -24,7 +24,6 @@
 
 #include "hw.h"
 #include "pc.h"
-#include "sysemu.h"
 #include "boards.h"
 #include "xen_backend.h"
 #include "xen_domainbuild.h"
diff --git a/hw/xenfb.c b/hw/xenfb.c
index da5297b498..1db75fbe49 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -44,7 +44,6 @@
 #include <xen/io/protocols.h>
 
 #include "hw.h"
-#include "sysemu.h"
 #include "console.h"
 #include "qemu-char.h"
 #include "xen_backend.h"
diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c
index 30827b03cd..d398c18e9e 100644
--- a/hw/xilinx_timer.c
+++ b/hw/xilinx_timer.c
@@ -23,7 +23,6 @@
  */
 
 #include "sysbus.h"
-#include "sysemu.h"
 #include "qemu-timer.h"
 
 #define D(x)
diff --git a/kvm-stub.c b/kvm-stub.c
index 30f6ec3956..1c95452140 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -11,7 +11,6 @@
  */
 
 #include "qemu-common.h"
-#include "sysemu.h"
 #include "hw/hw.h"
 #include "exec-all.h"
 #include "gdbstub.h"
diff --git a/migration-exec.c b/migration-exec.c
index 14718dd1d1..4b7aad8b6b 100644
--- a/migration-exec.c
+++ b/migration-exec.c
@@ -17,7 +17,6 @@
 #include "qemu_socket.h"
 #include "migration.h"
 #include "qemu-char.h"
-#include "sysemu.h"
 #include "buffered_file.h"
 #include "block.h"
 #include <sys/types.h>
diff --git a/migration-fd.c b/migration-fd.c
index 6d14505632..66d51c1cc0 100644
--- a/migration-fd.c
+++ b/migration-fd.c
@@ -16,7 +16,6 @@
 #include "migration.h"
 #include "monitor.h"
 #include "qemu-char.h"
-#include "sysemu.h"
 #include "buffered_file.h"
 #include "block.h"
 #include "qemu_socket.h"
diff --git a/migration-tcp.c b/migration-tcp.c
index e8dff9d71a..d3d80c9702 100644
--- a/migration-tcp.c
+++ b/migration-tcp.c
@@ -15,7 +15,6 @@
 #include "qemu_socket.h"
 #include "migration.h"
 #include "qemu-char.h"
-#include "sysemu.h"
 #include "buffered_file.h"
 #include "block.h"
 
diff --git a/migration-unix.c b/migration-unix.c
index 8b967f2938..c8625c7f65 100644
--- a/migration-unix.c
+++ b/migration-unix.c
@@ -15,7 +15,6 @@
 #include "qemu_socket.h"
 #include "migration.h"
 #include "qemu-char.h"
-#include "sysemu.h"
 #include "buffered_file.h"
 #include "block.h"
 
diff --git a/net.c b/net.c
index 8d6a555374..4f777c3dac 100644
--- a/net.c
+++ b/net.c
@@ -32,7 +32,6 @@
 #include "net/vde.h"
 #include "net/util.h"
 #include "monitor.h"
-#include "sysemu.h"
 #include "qemu-common.h"
 #include "qemu_socket.h"
 #include "hw/qdev.h"
diff --git a/net/slirp.c b/net/slirp.c
index b41c60a39b..e387a116ad 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -30,7 +30,6 @@
 #endif
 #include "net.h"
 #include "monitor.h"
-#include "sysemu.h"
 #include "qemu_socket.h"
 #include "slirp/libslirp.h"
 
diff --git a/net/vde.c b/net/vde.c
index 0b46fa6405..ac48ab2f0a 100644
--- a/net/vde.c
+++ b/net/vde.c
@@ -31,7 +31,6 @@
 #include "qemu-char.h"
 #include "qemu-common.h"
 #include "qemu-option.h"
-#include "sysemu.h"
 
 typedef struct VDEState {
     VLANClientState nc;
diff --git a/osdep.c b/osdep.c
index 327583baf7..56e6963f15 100644
--- a/osdep.c
+++ b/osdep.c
@@ -46,7 +46,6 @@ extern int madvise(caddr_t, size_t, int);
 
 #include "qemu-common.h"
 #include "trace.h"
-#include "sysemu.h"
 #include "qemu_socket.h"
 
 int qemu_madvise(void *addr, size_t len, int advice)
diff --git a/qemu-config.c b/qemu-config.c
index 323d3c2c29..14d34194d0 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -2,7 +2,6 @@
 #include "qemu-error.h"
 #include "qemu-option.h"
 #include "qemu-config.h"
-#include "sysemu.h"
 #include "hw/qdev.h"
 
 static QemuOptsList qemu_drive_opts = {
diff --git a/qemu-error.c b/qemu-error.c
index 5a35e7c1c2..41c191d528 100644
--- a/qemu-error.c
+++ b/qemu-error.c
@@ -12,7 +12,6 @@
 
 #include <stdio.h>
 #include "monitor.h"
-#include "sysemu.h"
 
 /*
  * Print to current monitor if we have one, else to stderr.
diff --git a/qemu-tool.c b/qemu-tool.c
index d45840de28..f4a6ad081c 100644
--- a/qemu-tool.c
+++ b/qemu-tool.c
@@ -15,7 +15,6 @@
 #include "monitor.h"
 #include "qemu-timer.h"
 #include "qemu-log.h"
-#include "sysemu.h"
 
 #include <sys/time.h>
 

From d8dfad9c41c3431dbb97ad722a93e6ad1e9e9279 Mon Sep 17 00:00:00 2001
From: Blue Swirl <blauwirbel@gmail.com>
Date: Sun, 27 Mar 2011 14:31:31 +0000
Subject: [PATCH 199/386] Use qemu-common.h or qemu-timer.h in place of
 sysemu.h

In some cases qemu-common.h or qemu-timer.h can be used in place
of sysemu.h.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 hw/pcie.c    | 3 +--
 hw/usb-hid.c | 2 +-
 net/dump.c   | 2 +-
 3 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/hw/pcie.c b/hw/pcie.c
index 6a113a9327..9de6149043 100644
--- a/hw/pcie.c
+++ b/hw/pcie.c
@@ -18,8 +18,7 @@
  * with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "sysemu.h"
-#include "range.h"
+#include "qemu-common.h"
 #include "pci_bridge.h"
 #include "pcie.h"
 #include "msix.h"
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index c25362cc95..89c293c466 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -26,7 +26,7 @@
 #include "console.h"
 #include "usb.h"
 #include "usb-desc.h"
-#include "sysemu.h"
+#include "qemu-timer.h"
 
 /* HID interface requests */
 #define GET_REPORT   0xa101
diff --git a/net/dump.c b/net/dump.c
index 83eda0fcc6..0d0cbb2591 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -24,9 +24,9 @@
 
 #include "dump.h"
 #include "qemu-common.h"
-#include "sysemu.h"
 #include "qemu-error.h"
 #include "qemu-log.h"
+#include "qemu-timer.h"
 
 typedef struct DumpState {
     VLANClientState nc;

From 082b5557996764fb21ba8cff17aabec7242ed342 Mon Sep 17 00:00:00 2001
From: Blue Swirl <blauwirbel@gmail.com>
Date: Sun, 27 Mar 2011 09:04:57 +0000
Subject: [PATCH 200/386] Move generic or OS function declarations to
 qemu-common.h

Move generic or OS related function declarations and macro
TFR to qemu-common.h.

Move win32 include directives to qemu-os-win32.h. While moving,
also add #include <winsock2.h> to fix a recent mingw32
build breakage.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 qemu-common.h   | 19 +++++++++++++++++++
 qemu-os-win32.h |  3 +++
 sysemu.h        | 21 ---------------------
 3 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/qemu-common.h b/qemu-common.h
index 4f6037bab9..f9f705da85 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -12,6 +12,7 @@
 #endif
 
 #define QEMU_BUILD_BUG_ON(x) typedef char __build_bug_on__##__LINE__[(x)?-1:1];
+#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
 
 typedef struct QEMUTimer QEMUTimer;
 typedef struct QEMUFile QEMUFile;
@@ -39,6 +40,14 @@ typedef struct Monitor Monitor;
 #include <sys/time.h>
 #include <assert.h>
 
+#ifdef _WIN32
+#include "qemu-os-win32.h"
+#endif
+
+#ifdef CONFIG_POSIX
+#include "qemu-os-posix.h"
+#endif
+
 #ifndef O_LARGEFILE
 #define O_LARGEFILE 0
 #endif
@@ -339,6 +348,16 @@ void qemu_progress_init(int enabled, float min_skip);
 void qemu_progress_end(void);
 void qemu_progress_print(float percent, int max);
 
+#define QEMU_FILE_TYPE_BIOS   0
+#define QEMU_FILE_TYPE_KEYMAP 1
+char *qemu_find_file(int type, const char *name);
+
+/* OS specific functions */
+void os_setup_early_signal_handling(void);
+char *os_find_datadir(const char *argv0);
+void os_parse_cmd_args(int index, const char *optarg);
+void os_pidfile_error(void);
+
 /* Convert a byte between binary and BCD.  */
 static inline uint8_t to_bcd(uint8_t val)
 {
diff --git a/qemu-os-win32.h b/qemu-os-win32.h
index 1a07e5e264..ed2753d1b7 100644
--- a/qemu-os-win32.h
+++ b/qemu-os-win32.h
@@ -26,6 +26,9 @@
 #ifndef QEMU_OS_WIN32_H
 #define QEMU_OS_WIN32_H
 
+#include <windows.h>
+#include <winsock2.h>
+
 /* Polling handling */
 
 /* return TRUE if no sleep should be done afterwards */
diff --git a/sysemu.h b/sysemu.h
index bbbd0fd799..f112c227ac 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -8,22 +8,9 @@
 #include "qemu-timer.h"
 #include "notify.h"
 
-#ifdef _WIN32
-#include <windows.h>
-#include "qemu-os-win32.h"
-#endif
-
-#ifdef CONFIG_POSIX
-#include "qemu-os-posix.h"
-#endif
-
 /* vl.c */
 extern const char *bios_name;
 
-#define QEMU_FILE_TYPE_BIOS   0
-#define QEMU_FILE_TYPE_KEYMAP 1
-char *qemu_find_file(int type, const char *name);
-
 extern int vm_running;
 extern const char *qemu_name;
 extern uint8_t qemu_uuid[];
@@ -100,12 +87,6 @@ int qemu_loadvm_state(QEMUFile *f);
 /* SLIRP */
 void do_info_slirp(Monitor *mon);
 
-/* OS specific functions */
-void os_setup_early_signal_handling(void);
-char *os_find_datadir(const char *argv0);
-void os_parse_cmd_args(int index, const char *optarg);
-void os_pidfile_error(void);
-
 typedef enum DisplayType
 {
     DT_DEFAULT,
@@ -191,8 +172,6 @@ extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 
 extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
 
-#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
-
 void do_usb_add(Monitor *mon, const QDict *qdict);
 void do_usb_del(Monitor *mon, const QDict *qdict);
 void usb_info(Monitor *mon);

From 70c3b5575ee3e0d528aa176c8c5add3e7355c01e Mon Sep 17 00:00:00 2001
From: Blue Swirl <blauwirbel@gmail.com>
Date: Sun, 27 Mar 2011 15:45:39 +0000
Subject: [PATCH 201/386] Move clock related functions to qemu-timer.h

Move declarations for clock related functions from sysemu.h to qemu-timer.h.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 qemu-timer.h | 4 ++++
 sysemu.h     | 4 ----
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/qemu-timer.h b/qemu-timer.h
index 3a9228f7df..bbc3452bc3 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -59,6 +59,10 @@ void init_clocks(void);
 int init_timer_alarm(void);
 void quit_timers(void);
 
+int64_t cpu_get_ticks(void);
+void cpu_enable_ticks(void);
+void cpu_disable_ticks(void);
+
 static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb,
                                            void *opaque)
 {
diff --git a/sysemu.h b/sysemu.h
index f112c227ac..a379024120 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -41,10 +41,6 @@ uint64_t ram_bytes_remaining(void);
 uint64_t ram_bytes_transferred(void);
 uint64_t ram_bytes_total(void);
 
-int64_t cpu_get_ticks(void);
-void cpu_enable_ticks(void);
-void cpu_disable_ticks(void);
-
 void qemu_system_reset_request(void);
 void qemu_system_shutdown_request(void);
 void qemu_system_powerdown_request(void);

From 17a4663e2dddbac36126a6fd7048634a4c95fa6e Mon Sep 17 00:00:00 2001
From: Blue Swirl <blauwirbel@gmail.com>
Date: Sun, 27 Mar 2011 16:05:08 +0000
Subject: [PATCH 202/386] Move CPU related functions to cpus.h

Move declarations of CPU related functions to cpus.h. Adjust the only user.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 cpus.h   | 4 ++++
 savevm.c | 1 +
 sysemu.h | 4 ----
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/cpus.h b/cpus.h
index e0211260c3..6fdeb0d8f2 100644
--- a/cpus.h
+++ b/cpus.h
@@ -8,6 +8,10 @@ void resume_all_vcpus(void);
 void pause_all_vcpus(void);
 void cpu_stop_current(void);
 
+void cpu_synchronize_all_states(void);
+void cpu_synchronize_all_post_reset(void);
+void cpu_synchronize_all_post_init(void);
+
 /* vl.c */
 extern int smp_cores;
 extern int smp_threads;
diff --git a/savevm.c b/savevm.c
index 03fce62975..be44fdb473 100644
--- a/savevm.c
+++ b/savevm.c
@@ -82,6 +82,7 @@
 #include "migration.h"
 #include "qemu_socket.h"
 #include "qemu-queue.h"
+#include "cpus.h"
 
 #define SELF_ANNOUNCE_ROUNDS 5
 
diff --git a/sysemu.h b/sysemu.h
index a379024120..6effd8a122 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -64,10 +64,6 @@ int load_vmstate(const char *name);
 void do_delvm(Monitor *mon, const QDict *qdict);
 void do_info_snapshots(Monitor *mon);
 
-void cpu_synchronize_all_states(void);
-void cpu_synchronize_all_post_reset(void);
-void cpu_synchronize_all_post_init(void);
-
 void qemu_announce_self(void);
 
 void main_loop_wait(int nonblocking);

From adc56dda0c4eed62149d28939b7d7e329ad95ae8 Mon Sep 17 00:00:00 2001
From: Blue Swirl <blauwirbel@gmail.com>
Date: Sun, 3 Apr 2011 08:23:19 +0000
Subject: [PATCH 203/386] migration: move some declarations to migration.h

Move a few migration related declarations to migration.h.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 arch_init.h | 2 --
 migration.h | 9 +++++++++
 sysemu.h    | 5 -----
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch_init.h b/arch_init.h
index c83360c3a6..86ebc149bc 100644
--- a/arch_init.h
+++ b/arch_init.h
@@ -22,8 +22,6 @@ enum {
 extern const uint32_t arch_type;
 
 void select_soundhw(const char *optarg);
-int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque);
-int ram_load(QEMUFile *f, void *opaque, int version_id);
 void do_acpitable_option(const char *optarg);
 void do_smbios_option(const char *optarg);
 void cpudef_init(void);
diff --git a/migration.h b/migration.h
index 21707922ef..050c56c5a4 100644
--- a/migration.h
+++ b/migration.h
@@ -139,4 +139,13 @@ void add_migration_state_change_notifier(Notifier *notify);
 void remove_migration_state_change_notifier(Notifier *notify);
 int get_migration_state(void);
 
+uint64_t ram_bytes_remaining(void);
+uint64_t ram_bytes_transferred(void);
+uint64_t ram_bytes_total(void);
+
+int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque);
+int ram_load(QEMUFile *f, void *opaque, int version_id);
+
+extern int incoming_expected;
+
 #endif
diff --git a/sysemu.h b/sysemu.h
index 6effd8a122..b0296a0d46 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -37,10 +37,6 @@ void qemu_del_vm_change_state_handler(VMChangeStateEntry *e);
 void vm_start(void);
 void vm_stop(int reason);
 
-uint64_t ram_bytes_remaining(void);
-uint64_t ram_bytes_transferred(void);
-uint64_t ram_bytes_total(void);
-
 void qemu_system_reset_request(void);
 void qemu_system_shutdown_request(void);
 void qemu_system_powerdown_request(void);
@@ -89,7 +85,6 @@ typedef enum DisplayType
 } DisplayType;
 
 extern int autostart;
-extern int incoming_expected;
 extern int bios_size;
 
 typedef enum {

From 61cc8701f3e019f154c3662f3c9f998629813745 Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Wed, 13 Apr 2011 22:45:22 +0200
Subject: [PATCH 204/386] Fix some typos in comments and documentation

helpfull -> helpful
usefull -> useful
cotrol -> control

and a grammar fix.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 qemu-options.hx     | 4 ++--
 savevm.c            | 2 +-
 target-arm/helper.c | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index ef60730e47..677c550103 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -937,8 +937,8 @@ a lot of bandwidth at the expense of quality.
 Disable adaptive encodings. Adaptive encodings are enabled by default.
 An adaptive encoding will try to detect frequently updated screen regions,
 and send updates in these regions using a lossy encoding (like JPEG).
-This can be really helpfull to save bandwidth when playing videos. Disabling
-adaptive encodings allow to restore the original static behavior of encodings
+This can be really helpful to save bandwidth when playing videos. Disabling
+adaptive encodings allows to restore the original static behavior of encodings
 like Tight.
 
 @end table
diff --git a/savevm.c b/savevm.c
index be44fdb473..f4ff1a1db4 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1008,7 +1008,7 @@ const VMStateInfo vmstate_info_buffer = {
 };
 
 /* unused buffers: space that was used for some fields that are
-   not usefull anymore */
+   not useful anymore */
 
 static int get_unused_buffer(QEMUFile *f, void *pv, size_t size)
 {
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 9172fc7279..a0ec6439da 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1378,7 +1378,7 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
             /* This may enable/disable the MMU, so do a TLB flush.  */
             tlb_flush(env, 1);
             break;
-        case 1: /* Auxiliary cotrol register.  */
+        case 1: /* Auxiliary control register.  */
             if (arm_feature(env, ARM_FEATURE_XSCALE)) {
                 env->cp15.c1_xscaleauxcr = val;
                 break;

From 7a734b8f68b4a72aba90c3abd9a52e341f4c996a Mon Sep 17 00:00:00 2001
From: Brad Hards <bradh@frogmouth.net>
Date: Wed, 13 Apr 2011 16:42:16 +1000
Subject: [PATCH 205/386] Makefile: Clean up after "make pdf"

Signed-off-by: Brad Hards <bradh@frogmouth.net>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 .gitignore | 3 +++
 Makefile   | 5 ++++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index 1d79680626..08013fc57b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,6 +44,9 @@ QMP/qmp-commands.txt
 *.ky
 *.log
 *.pdf
+*.cps
+*.fns
+*.kys
 *.pg
 *.pyc
 *.toc
diff --git a/Makefile b/Makefile
index fa93be5ed7..dc39efdeb4 100644
--- a/Makefile
+++ b/Makefile
@@ -163,7 +163,10 @@ distclean: clean
 	rm -f config-host.mak config-host.h* config-host.ld $(DOCS) qemu-options.texi qemu-img-cmds.texi qemu-monitor.texi
 	rm -f config-all-devices.mak
 	rm -f roms/seabios/config.mak roms/vgabios/config.mak
-	rm -f qemu-doc.info qemu-doc.aux qemu-doc.cp qemu-doc.dvi qemu-doc.fn qemu-doc.info qemu-doc.ky qemu-doc.log qemu-doc.pdf qemu-doc.pg qemu-doc.toc qemu-doc.tp qemu-doc.vr
+	rm -f qemu-doc.info qemu-doc.aux qemu-doc.cp qemu-doc.cps qemu-doc.dvi
+	rm -f qemu-doc.fn qemu-doc.fns qemu-doc.info qemu-doc.ky qemu-doc.kys
+	rm -f qemu-doc.log qemu-doc.pdf qemu-doc.pg qemu-doc.toc qemu-doc.tp
+	rm -f qemu-doc.vr
 	rm -f qemu-tech.info qemu-tech.aux qemu-tech.cp qemu-tech.dvi qemu-tech.fn qemu-tech.info qemu-tech.ky qemu-tech.log qemu-tech.pdf qemu-tech.pg qemu-tech.toc qemu-tech.tp qemu-tech.vr
 	for d in $(TARGET_DIRS) $(QEMULIBS); do \
 	rm -rf $$d || exit 1 ; \

From 94843f66ab06f45240d2afa7a648c5722da14dfb Mon Sep 17 00:00:00 2001
From: Brad Hards <bradh@frogmouth.net>
Date: Wed, 13 Apr 2011 19:45:31 +1000
Subject: [PATCH 206/386] usb: trivial spelling fixes

Signed-off-by: Brad Hards <bradh@frogmouth.net>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 hw/usb-msd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index 76f5b027b2..947fd3f83c 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -33,7 +33,7 @@ do { printf("usb-msd: " fmt , ## __VA_ARGS__); } while (0)
 
 enum USBMSDMode {
     USB_MSDM_CBW, /* Command Block.  */
-    USB_MSDM_DATAOUT, /* Tranfer data to device.  */
+    USB_MSDM_DATAOUT, /* Transfer data to device.  */
     USB_MSDM_DATAIN, /* Transfer data from device.  */
     USB_MSDM_CSW /* Command Status.  */
 };
@@ -253,7 +253,7 @@ static void usb_msd_command_complete(SCSIBus *bus, int reason, uint32_t tag,
         usb_msd_copy_data(s);
         if (s->usb_len == 0) {
             /* Set s->packet to NULL before calling usb_packet_complete
-               because annother request may be issued before
+               because another request may be issued before
                usb_packet_complete returns.  */
             DPRINTF("Packet complete %p\n", p);
             s->packet = NULL;

From 021730f7285923460e81004c9dae74b6a1c8aa0c Mon Sep 17 00:00:00 2001
From: Brad Hards <bradh@frogmouth.net>
Date: Wed, 13 Apr 2011 19:45:32 +1000
Subject: [PATCH 207/386] usb: initialise data element in Linux USB_DISCONNECT
 ioctl

This isn't used, but leaving it empty causes valgrind noise.

Signed-off-by: Brad Hards <bradh@frogmouth.net>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 usb-linux.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/usb-linux.c b/usb-linux.c
index 255009f539..d958853634 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -344,6 +344,7 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
         for (interface = 0; interface < nb_interfaces; interface++) {
             ctrl.ioctl_code = USBDEVFS_DISCONNECT;
             ctrl.ifno = interface;
+            ctrl.data = 0;
             ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
             if (ret < 0 && errno != ENODATA) {
                 perror("USBDEVFS_DISCONNECT");

From a0102082de4026833afbd2525e8a6320d1f92885 Mon Sep 17 00:00:00 2001
From: Brad Hards <bradh@frogmouth.net>
Date: Wed, 13 Apr 2011 19:45:33 +1000
Subject: [PATCH 208/386] usb: fix spelling errors in usb-linux.c

Signed-off-by: Brad Hards <bradh@frogmouth.net>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 usb-linux.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/usb-linux.c b/usb-linux.c
index d958853634..1f33c2c230 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -107,7 +107,7 @@ enum {
 /*
  * Control transfer state.
  * Note that 'buffer' _must_ follow 'req' field because
- * we need contigious buffer when we submit control URB.
+ * we need contiguous buffer when we submit control URB.
  */
 struct ctrl_struct {
     uint16_t len;
@@ -580,7 +580,7 @@ static int usb_host_handle_control(USBHostDevice *s, USBPacket *p)
     /*
      * Setup ctrl transfer.
      *
-     * s->ctrl is layed out such that data buffer immediately follows
+     * s->ctrl is laid out such that data buffer immediately follows
      * 'req' struct which is exactly what usbdevfs expects.
      */
     urb = &aurb->urb;

From b3b4c7f33fc8e51db75bf4abaf4a631c2f1fb23b Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:29 +0200
Subject: [PATCH 209/386] softfloat: use GCC builtins to count the leading
 zeros

Softfloat has its own implementation to count the leading zeros. However
a lot of architectures have either a dedicated instruction or an
optimized to do that. When using GCC >= 3.4, this patch uses GCC builtins
instead of the handcoded implementation.

Note that I amware that QEMU_GNUC_PREREQ is defined in osdep.h and that
clz32() and clz64() are defined in host-utils.h, but I think it is better
to keep the softfloat implementation self contained.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat-macros.h | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/fpu/softfloat-macros.h b/fpu/softfloat-macros.h
index 3128e60cbf..e82ce2332d 100644
--- a/fpu/softfloat-macros.h
+++ b/fpu/softfloat-macros.h
@@ -35,6 +35,17 @@ these four paragraphs for those parts of this code that are retained.
 
 =============================================================================*/
 
+/*----------------------------------------------------------------------------
+| This macro tests for minimum version of the GNU C compiler.
+*----------------------------------------------------------------------------*/
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+# define SOFTFLOAT_GNUC_PREREQ(maj, min) \
+         ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+# define SOFTFLOAT_GNUC_PREREQ(maj, min) 0
+#endif
+
+
 /*----------------------------------------------------------------------------
 | Shifts `a' right by the number of bits given in `count'.  If any nonzero
 | bits are shifted off, they are ``jammed'' into the least significant bit of
@@ -616,6 +627,13 @@ static uint32_t estimateSqrt32( int16 aExp, uint32_t a )
 
 static int8 countLeadingZeros32( uint32_t a )
 {
+#if SOFTFLOAT_GNUC_PREREQ(3, 4)
+    if (a) {
+        return __builtin_clz(a);
+    } else {
+        return 32;
+    }
+#else
     static const int8 countLeadingZerosHigh[] = {
         8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
@@ -647,7 +665,7 @@ static int8 countLeadingZeros32( uint32_t a )
     }
     shiftCount += countLeadingZerosHigh[ a>>24 ];
     return shiftCount;
-
+#endif
 }
 
 /*----------------------------------------------------------------------------
@@ -657,6 +675,13 @@ static int8 countLeadingZeros32( uint32_t a )
 
 static int8 countLeadingZeros64( uint64_t a )
 {
+#if SOFTFLOAT_GNUC_PREREQ(3, 4)
+    if (a) {
+        return __builtin_clzll(a);
+    } else {
+        return 64;
+    }
+#else
     int8 shiftCount;
 
     shiftCount = 0;
@@ -668,7 +693,7 @@ static int8 countLeadingZeros64( uint64_t a )
     }
     shiftCount += countLeadingZeros32( a );
     return shiftCount;
-
+#endif
 }
 
 /*----------------------------------------------------------------------------

From 602308f0f54daa7503ea0f4909b51aef5f3b0ca1 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:29 +0200
Subject: [PATCH 210/386] cpu-all.h: define CPU_LDoubleU

Add a CPU_LDoubleU type, matching the floatx80 definition and the long
double type on x86 hosts.

Based on a patch from Laurent Vivier <laurent@vivier.eu>.

Cc: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 cpu-all.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/cpu-all.h b/cpu-all.h
index dc0f2f02ab..0bae6df8ec 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -138,6 +138,16 @@ typedef union {
     uint64_t ll;
 } CPU_DoubleU;
 
+#if defined(FLOATX80)
+typedef union {
+     floatx80 d;
+     struct {
+         uint64_t lower;
+         uint16_t upper;
+     } l;
+} CPU_LDoubleU;
+#endif
+
 #if defined(CONFIG_SOFTFLOAT)
 typedef union {
     float128 q;

From 1ffd41ee0c5b3409492d237201d50b78578064e5 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:29 +0200
Subject: [PATCH 211/386] target-i386: use CPU_LDoubleU instead of a private
 union

Use CPU_LDoubleU in cpu_dump_state() instead of redefining a union for
doing the conversion.

Based on a patch from Laurent Vivier <laurent@vivier.eu>.

Cc: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/helper.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/target-i386/helper.c b/target-i386/helper.c
index d15fca591e..89df997436 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -404,16 +404,10 @@ void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
                     env->mxcsr);
         for(i=0;i<8;i++) {
 #if defined(USE_X86LDOUBLE)
-            union {
-                long double d;
-                struct {
-                    uint64_t lower;
-                    uint16_t upper;
-                } l;
-            } tmp;
-            tmp.d = env->fpregs[i].d;
+            CPU_LDoubleU u;
+            u.d = env->fpregs[i].d;
             cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
-                        i, tmp.l.lower, tmp.l.upper);
+                        i, u.l.lower, u.l.upper);
 #else
             cpu_fprintf(f, "FPR%d=%016" PRIx64,
                         i, env->fpregs[i].mmx.q);

From c41372230e441cb28dcf246d5f2a3226830156bd Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:29 +0200
Subject: [PATCH 212/386] target-i386: use float unions from cpu-all.h

Use float unions from cpu-all.h instead of redefining new (wrong for arm)
ones in target-i386. This also allows building cpu-exec.o with softfloat.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/exec.h | 27 ++-------------------------
 1 file changed, 2 insertions(+), 25 deletions(-)

diff --git a/target-i386/exec.h b/target-i386/exec.h
index 6f9f709d8a..63a23cd999 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -144,13 +144,7 @@ static inline void svm_check_intercept(uint32_t type)
 #ifdef USE_X86LDOUBLE
 
 /* only for x86 */
-typedef union {
-    long double d;
-    struct {
-        unsigned long long lower;
-        unsigned short upper;
-    } l;
-} CPU86_LDoubleU;
+typedef CPU_LDoubleU CPU86_LDoubleU;
 
 /* the following deal with x86 long double-precision numbers */
 #define MAXEXPD 0x7fff
@@ -162,24 +156,7 @@ typedef union {
 
 #else
 
-/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
-typedef union {
-    double d;
-#if !defined(HOST_WORDS_BIGENDIAN) && !defined(__arm__)
-    struct {
-        uint32_t lower;
-        int32_t upper;
-    } l;
-#else
-    struct {
-        int32_t upper;
-        uint32_t lower;
-    } l;
-#endif
-#ifndef __arm__
-    int64_t ll;
-#endif
-} CPU86_LDoubleU;
+typedef CPU_DoubleU CPU86_LDoubleU;
 
 /* the following deal with IEEE double-precision numbers */
 #define MAXEXPD 0x7ff

From 67dd64bfae87b4464b880de03c1d04f5f605d48d Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:29 +0200
Subject: [PATCH 213/386] target-i386: add floatx_{add,mul,sub} and use them

Add floatx_{add,mul,sub} defines, and use them instead of using direct
C operations.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/exec.h      |  6 ++++++
 target-i386/op_helper.c | 18 ++++++++----------
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/target-i386/exec.h b/target-i386/exec.h
index 63a23cd999..ae6b94740f 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -110,6 +110,9 @@ static inline void svm_check_intercept(uint32_t type)
 #define float64_to_floatx float64_to_floatx80
 #define floatx_to_float32 floatx80_to_float32
 #define floatx_to_float64 floatx80_to_float64
+#define floatx_add floatx80_add
+#define floatx_mul floatx80_mul
+#define floatx_sub floatx80_sub
 #define floatx_abs floatx80_abs
 #define floatx_chs floatx80_chs
 #define floatx_round_to_int floatx80_round_to_int
@@ -126,6 +129,9 @@ static inline void svm_check_intercept(uint32_t type)
 #define float64_to_floatx(x, e) (x)
 #define floatx_to_float32 float64_to_float32
 #define floatx_to_float64(x, e) (x)
+#define floatx_add float64_add
+#define floatx_mul float64_mul
+#define floatx_sub float64_sub
 #define floatx_abs float64_abs
 #define floatx_chs float64_chs
 #define floatx_round_to_int float64_round_to_int
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 43fbd0c778..a73427fe45 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -3711,22 +3711,22 @@ void helper_fucomi_ST0_FT0(void)
 
 void helper_fadd_ST0_FT0(void)
 {
-    ST0 += FT0;
+    ST0 = floatx_add(ST0, FT0, &env->fp_status);
 }
 
 void helper_fmul_ST0_FT0(void)
 {
-    ST0 *= FT0;
+    ST0 = floatx_mul(ST0, FT0, &env->fp_status);
 }
 
 void helper_fsub_ST0_FT0(void)
 {
-    ST0 -= FT0;
+    ST0 = floatx_sub(ST0, FT0, &env->fp_status);
 }
 
 void helper_fsubr_ST0_FT0(void)
 {
-    ST0 = FT0 - ST0;
+    ST0 = floatx_sub(FT0, ST0, &env->fp_status);
 }
 
 void helper_fdiv_ST0_FT0(void)
@@ -3743,24 +3743,22 @@ void helper_fdivr_ST0_FT0(void)
 
 void helper_fadd_STN_ST0(int st_index)
 {
-    ST(st_index) += ST0;
+    ST(st_index) = floatx_add(ST(st_index), ST0, &env->fp_status);
 }
 
 void helper_fmul_STN_ST0(int st_index)
 {
-    ST(st_index) *= ST0;
+    ST(st_index) = floatx_mul(ST(st_index), ST0, &env->fp_status);
 }
 
 void helper_fsub_STN_ST0(int st_index)
 {
-    ST(st_index) -= ST0;
+    ST(st_index) = floatx_sub(ST(st_index), ST0, &env->fp_status);
 }
 
 void helper_fsubr_STN_ST0(int st_index)
 {
-    CPU86_LDouble *p;
-    p = &ST(st_index);
-    *p = ST0 - *p;
+    ST(st_index) = floatx_sub(ST0, ST(st_index), &env->fp_status);
 }
 
 void helper_fdiv_STN_ST0(int st_index)

From 67b7861d63f5218fe46809f4f84d4412940b9260 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:29 +0200
Subject: [PATCH 214/386] softfloat: add float*_unordered_{,quiet}() functions

Add float*_unordered() functions to softfloat, matching the softfloat-native
ones. Also add float*_unordered_quiet() functions to match the others
comparison functions.

This allow target-i386/ops_sse.h to be compiled with softfloat.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++
 fpu/softfloat.h |   8 +++
 2 files changed, 175 insertions(+)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 03fb9487bd..11f6584067 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2393,6 +2393,25 @@ int float32_lt( float32 a, float32 b STATUS_PARAM )
 
 }
 
+/*----------------------------------------------------------------------------
+| Returns 1 if the single-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise.  The comparison is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float32_unordered( float32 a, float32 b STATUS_PARAM )
+{
+    a = float32_squash_input_denormal(a STATUS_VAR);
+    b = float32_squash_input_denormal(b STATUS_VAR);
+
+    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+       ) {
+        float_raise( float_flag_invalid STATUS_VAR);
+        return 1;
+    }
+    return 0;
+}
 /*----------------------------------------------------------------------------
 | Returns 1 if the single-precision floating-point value `a' is equal to
 | the corresponding value `b', and 0 otherwise.  The invalid exception is
@@ -2480,6 +2499,29 @@ int float32_lt_quiet( float32 a, float32 b STATUS_PARAM )
 
 }
 
+/*----------------------------------------------------------------------------
+| Returns 1 if the single-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.  The
+| comparison is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float32_unordered_quiet( float32 a, float32 b STATUS_PARAM )
+{
+    a = float32_squash_input_denormal(a STATUS_VAR);
+    b = float32_squash_input_denormal(b STATUS_VAR);
+
+    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+       ) {
+        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
+        return 1;
+    }
+    return 0;
+}
+
 /*----------------------------------------------------------------------------
 | Returns the result of converting the double-precision floating-point value
 | `a' to the 32-bit two's complement integer format.  The conversion is
@@ -3617,6 +3659,26 @@ int float64_lt( float64 a, float64 b STATUS_PARAM )
 
 }
 
+/*----------------------------------------------------------------------------
+| Returns 1 if the double-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise.  The comparison is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float64_unordered( float64 a, float64 b STATUS_PARAM )
+{
+    a = float64_squash_input_denormal(a STATUS_VAR);
+    b = float64_squash_input_denormal(b STATUS_VAR);
+
+    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+       ) {
+        float_raise( float_flag_invalid STATUS_VAR);
+        return 1;
+    }
+    return 0;
+}
+
 /*----------------------------------------------------------------------------
 | Returns 1 if the double-precision floating-point value `a' is equal to the
 | corresponding value `b', and 0 otherwise.  The invalid exception is raised
@@ -3704,6 +3766,29 @@ int float64_lt_quiet( float64 a, float64 b STATUS_PARAM )
 
 }
 
+/*----------------------------------------------------------------------------
+| Returns 1 if the double-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.  The
+| comparison is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float64_unordered_quiet( float64 a, float64 b STATUS_PARAM )
+{
+    a = float64_squash_input_denormal(a STATUS_VAR);
+    b = float64_squash_input_denormal(b STATUS_VAR);
+
+    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+       ) {
+        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
+        return 1;
+    }
+    return 0;
+}
+
 #ifdef FLOATX80
 
 /*----------------------------------------------------------------------------
@@ -4596,6 +4681,24 @@ int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
 
 }
 
+/*----------------------------------------------------------------------------
+| Returns 1 if the extended double-precision floating-point values `a' and `b'
+| cannot be compared, and 0 otherwise.  The comparison is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM )
+{
+    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
+              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
+         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
+              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
+       ) {
+        float_raise( float_flag_invalid STATUS_VAR);
+        return 1;
+    }
+    return 0;
+}
+
 /*----------------------------------------------------------------------------
 | Returns 1 if the extended double-precision floating-point value `a' is equal
 | to the corresponding value `b', and 0 otherwise.  The invalid exception is
@@ -4695,6 +4798,28 @@ int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM )
 
 }
 
+/*----------------------------------------------------------------------------
+| Returns 1 if the extended double-precision floating-point values `a' and `b'
+| cannot be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.
+| The comparison is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+int floatx80_unordered_quiet( floatx80 a, floatx80 b STATUS_PARAM )
+{
+    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
+              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
+         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
+              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
+       ) {
+        if (    floatx80_is_signaling_nan( a )
+             || floatx80_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
+        return 1;
+    }
+    return 0;
+}
+
 #endif
 
 #ifdef FLOAT128
@@ -5717,6 +5842,25 @@ int float128_lt( float128 a, float128 b STATUS_PARAM )
 
 }
 
+/*----------------------------------------------------------------------------
+| Returns 1 if the quadruple-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise.  The comparison is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float128_unordered( float128 a, float128 b STATUS_PARAM )
+{
+    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
+              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
+         || (    ( extractFloat128Exp( b ) == 0x7FFF )
+              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+       ) {
+        float_raise( float_flag_invalid STATUS_VAR);
+        return 1;
+    }
+    return 0;
+}
+
 /*----------------------------------------------------------------------------
 | Returns 1 if the quadruple-precision floating-point value `a' is equal to
 | the corresponding value `b', and 0 otherwise.  The invalid exception is
@@ -5816,6 +5960,29 @@ int float128_lt_quiet( float128 a, float128 b STATUS_PARAM )
 
 }
 
+/*----------------------------------------------------------------------------
+| Returns 1 if the quadruple-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.  The
+| comparison is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float128_unordered_quiet( float128 a, float128 b STATUS_PARAM )
+{
+    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
+              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
+         || (    ( extractFloat128Exp( b ) == 0x7FFF )
+              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+       ) {
+        if (    float128_is_signaling_nan( a )
+             || float128_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
+        return 1;
+    }
+    return 0;
+}
+
 #endif
 
 /* misc functions */
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index c7654d4c63..55c0c1cda5 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -323,9 +323,11 @@ float32 float32_log2( float32 STATUS_PARAM );
 int float32_eq( float32, float32 STATUS_PARAM );
 int float32_le( float32, float32 STATUS_PARAM );
 int float32_lt( float32, float32 STATUS_PARAM );
+int float32_unordered( float32, float32 STATUS_PARAM );
 int float32_eq_signaling( float32, float32 STATUS_PARAM );
 int float32_le_quiet( float32, float32 STATUS_PARAM );
 int float32_lt_quiet( float32, float32 STATUS_PARAM );
+int float32_unordered_quiet( float32, float32 STATUS_PARAM );
 int float32_compare( float32, float32 STATUS_PARAM );
 int float32_compare_quiet( float32, float32 STATUS_PARAM );
 float32 float32_min(float32, float32 STATUS_PARAM);
@@ -437,9 +439,11 @@ float64 float64_log2( float64 STATUS_PARAM );
 int float64_eq( float64, float64 STATUS_PARAM );
 int float64_le( float64, float64 STATUS_PARAM );
 int float64_lt( float64, float64 STATUS_PARAM );
+int float64_unordered( float64, float64 STATUS_PARAM );
 int float64_eq_signaling( float64, float64 STATUS_PARAM );
 int float64_le_quiet( float64, float64 STATUS_PARAM );
 int float64_lt_quiet( float64, float64 STATUS_PARAM );
+int float64_unordered_quiet( float64, float64 STATUS_PARAM );
 int float64_compare( float64, float64 STATUS_PARAM );
 int float64_compare_quiet( float64, float64 STATUS_PARAM );
 float64 float64_min(float64, float64 STATUS_PARAM);
@@ -538,9 +542,11 @@ floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
 int floatx80_eq( floatx80, floatx80 STATUS_PARAM );
 int floatx80_le( floatx80, floatx80 STATUS_PARAM );
 int floatx80_lt( floatx80, floatx80 STATUS_PARAM );
+int floatx80_unordered( floatx80, floatx80 STATUS_PARAM );
 int floatx80_eq_signaling( floatx80, floatx80 STATUS_PARAM );
 int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM );
+int floatx80_unordered_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_is_quiet_nan( floatx80 );
 int floatx80_is_signaling_nan( floatx80 );
 floatx80 floatx80_maybe_silence_nan( floatx80 );
@@ -621,9 +627,11 @@ float128 float128_sqrt( float128 STATUS_PARAM );
 int float128_eq( float128, float128 STATUS_PARAM );
 int float128_le( float128, float128 STATUS_PARAM );
 int float128_lt( float128, float128 STATUS_PARAM );
+int float128_unordered( float128, float128 STATUS_PARAM );
 int float128_eq_signaling( float128, float128 STATUS_PARAM );
 int float128_le_quiet( float128, float128 STATUS_PARAM );
 int float128_lt_quiet( float128, float128 STATUS_PARAM );
+int float128_unordered_quiet( float128, float128 STATUS_PARAM );
 int float128_compare( float128, float128 STATUS_PARAM );
 int float128_compare_quiet( float128, float128 STATUS_PARAM );
 int float128_is_quiet_nan( float128 );

From b4a0ef7911297567e17b56d96ae06d6283049630 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:29 +0200
Subject: [PATCH 215/386] softfloat-native: add float*_unordered_quiet()
 functions

Add float*_unordered_quiet() functions to march the softfloat versions.
As FPU status is not tracked with softfloat-native, they don't differ
from the signaling version.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat-native.h | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
index 80b5f288e3..406e180c51 100644
--- a/fpu/softfloat-native.h
+++ b/fpu/softfloat-native.h
@@ -237,7 +237,10 @@ INLINE int float32_lt_quiet( float32 a, float32 b STATUS_PARAM)
 INLINE int float32_unordered( float32 a, float32 b STATUS_PARAM)
 {
     return isunordered(a, b);
-
+}
+INLINE int float32_unordered_quiet( float32 a, float32 b STATUS_PARAM)
+{
+    return isunordered(a, b);
 }
 int float32_compare( float32, float32 STATUS_PARAM );
 int float32_compare_quiet( float32, float32 STATUS_PARAM );
@@ -346,7 +349,10 @@ INLINE int float64_lt_quiet( float64 a, float64 b STATUS_PARAM)
 INLINE int float64_unordered( float64 a, float64 b STATUS_PARAM)
 {
     return isunordered(a, b);
-
+}
+INLINE int float64_unordered_quiet( float64 a, float64 b STATUS_PARAM)
+{
+    return isunordered(a, b);
 }
 int float64_compare( float64, float64 STATUS_PARAM );
 int float64_compare_quiet( float64, float64 STATUS_PARAM );
@@ -450,7 +456,10 @@ INLINE int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM)
 INLINE int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM)
 {
     return isunordered(a, b);
-
+}
+INLINE int floatx80_unordered_quiet( floatx80 a, floatx80 b STATUS_PARAM)
+{
+    return isunordered(a, b);
 }
 int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
 int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );

From a4d2d1a063897b859b7f25e414b229370b679bc8 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:29 +0200
Subject: [PATCH 216/386] target-alpha: use new float64_unordered_quiet()
 function

Use float64_unordered_quiet() in helper_cmptun() instead of doing the
the comparison manually.

According to the "Alpha Compiler Writer's Guide", we should use the
_quiet version here, as CMPTUN and CMPTEQ should generate InvalidOp
for SNaNs but not for QNaNs.

Thanks to Peter Maydell <peter.maydell@linaro.org> and Richard
Henderson <rth@twiddle.net> for digging into the manuals.

Acked-by: Richard Henderson  <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-alpha/op_helper.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 6c2ae2061f..36f4f6d3b8 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -904,10 +904,11 @@ uint64_t helper_cmptun (uint64_t a, uint64_t b)
     fa = t_to_float64(a);
     fb = t_to_float64(b);
 
-    if (float64_is_quiet_nan(fa) || float64_is_quiet_nan(fb))
+    if (float64_unordered_quiet(fa, fb, &FP_STATUS)) {
         return 0x4000000000000000ULL;
-    else
+    } else {
         return 0;
+    }
 }
 
 uint64_t helper_cmpteq(uint64_t a, uint64_t b)

From 3a599383592a26f2c614e1a7d92efd1e8eb26c6d Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:29 +0200
Subject: [PATCH 217/386] target-mips: use new float*_unordered*() functions

Use the new float*_unordered*() functions from softfloat instead of
redefining a private version.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-mips/op_helper.c | 168 +++++++++++++++++-----------------------
 1 file changed, 70 insertions(+), 98 deletions(-)

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index bd16ce3543..e9de692fe1 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2889,40 +2889,26 @@ void helper_cmpabs_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
         CLEAR_FP_COND(cc, env->active_fpu);                    \
 }
 
-static int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
-{
-    if (float64_is_signaling_nan(a) ||
-        float64_is_signaling_nan(b) ||
-        (sig && (float64_is_quiet_nan(a) || float64_is_quiet_nan(b)))) {
-        float_raise(float_flag_invalid, status);
-        return 1;
-    } else if (float64_is_quiet_nan(a) || float64_is_quiet_nan(b)) {
-        return 1;
-    } else {
-        return 0;
-    }
-}
-
 /* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_D(f,   (float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status), 0))
-FOP_COND_D(un,  float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status))
-FOP_COND_D(eq,  !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ueq, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(olt, !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ult, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ole, !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ule, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+ * but float64_unordered_quiet() is still called. */
+FOP_COND_D(f,   (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status), 0))
+FOP_COND_D(un,  float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status))
+FOP_COND_D(eq,  !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ueq, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(olt, !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ult, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ole, !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ule, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
 /* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_D(sf,  (float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status), 0))
-FOP_COND_D(ngle,float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status))
-FOP_COND_D(seq, !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ngl, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(lt,  !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(nge, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(le,  !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ngt, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+ * but float64_unordered() is still called. */
+FOP_COND_D(sf,  (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status), 0))
+FOP_COND_D(ngle,float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status))
+FOP_COND_D(seq, !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ngl, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(lt,  !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(nge, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(le,  !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ngt, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
 
 #define FOP_COND_S(op, cond)                                   \
 void helper_cmp_s_ ## op (uint32_t fst0, uint32_t fst1, int cc)    \
@@ -2947,40 +2933,26 @@ void helper_cmpabs_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \
         CLEAR_FP_COND(cc, env->active_fpu);                    \
 }
 
-static flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
-{
-    if (float32_is_signaling_nan(a) ||
-        float32_is_signaling_nan(b) ||
-        (sig && (float32_is_quiet_nan(a) || float32_is_quiet_nan(b)))) {
-        float_raise(float_flag_invalid, status);
-        return 1;
-    } else if (float32_is_quiet_nan(a) || float32_is_quiet_nan(b)) {
-        return 1;
-    } else {
-        return 0;
-    }
-}
-
 /* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_S(f,   (float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status), 0))
-FOP_COND_S(un,  float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status))
-FOP_COND_S(eq,  !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ueq, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(olt, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ult, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ole, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ule, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)  || float32_le(fst0, fst1, &env->active_fpu.fp_status))
+ * but float32_unordered_quiet() is still called. */
+FOP_COND_S(f,   (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status), 0))
+FOP_COND_S(un,  float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status))
+FOP_COND_S(eq,  !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(olt, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ole, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_le(fst0, fst1, &env->active_fpu.fp_status))
 /* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_S(sf,  (float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status), 0))
-FOP_COND_S(ngle,float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status))
-FOP_COND_S(seq, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ngl, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(lt,  !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(nge, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(le,  !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ngt, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)  || float32_le(fst0, fst1, &env->active_fpu.fp_status))
+ * but float32_unordered() is still called. */
+FOP_COND_S(sf,  (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0))
+FOP_COND_S(ngle,float32_unordered(fst1, fst0, &env->active_fpu.fp_status))
+FOP_COND_S(seq, !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(lt,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(nge, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(le,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_le(fst0, fst1, &env->active_fpu.fp_status))
 
 #define FOP_COND_PS(op, condl, condh)                           \
 void helper_cmp_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc)    \
@@ -3023,38 +2995,38 @@ void helper_cmpabs_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
 }
 
 /* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_PS(f,   (float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status), 0),
-                 (float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status), 0))
-FOP_COND_PS(un,  float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status),
-                 float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status))
-FOP_COND_PS(eq,  !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)   && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ueq, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(olt, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ult, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ole, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)   && float32_le(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ule, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)    || float32_le(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+ * but float32_unordered_quiet() is still called. */
+FOP_COND_PS(f,   (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status), 0),
+                 (float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status), 0))
+FOP_COND_PS(un,  float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status),
+                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status))
+FOP_COND_PS(eq,  !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(olt, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ole, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_le(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_le(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
 /* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_PS(sf,  (float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status), 0),
-                 (float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status), 0))
-FOP_COND_PS(ngle,float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status),
-                 float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status))
-FOP_COND_PS(seq, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)   && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ngl, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(lt,  !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(nge, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(le,  !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)   && float32_le(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ngt, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)    || float32_le(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+ * but float32_unordered() is still called. */
+FOP_COND_PS(sf,  (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0),
+                 (float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status), 0))
+FOP_COND_PS(ngle,float32_unordered(fst1, fst0, &env->active_fpu.fp_status),
+                 float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status))
+FOP_COND_PS(seq, !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(lt,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(nge, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(le,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_le(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_le(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))

From e0b29ce1cf961223a21caa459b14647c1da117ec Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:29 +0200
Subject: [PATCH 218/386] target-i386: fix CMPUNORDPS/D and CMPORDPS/D
 instructions

SSE instructions CMPUNORDPS/D and CMPORDPS/D do not trigger an invalid
exception if operands are qNANs.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/ops_sse.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-i386/ops_sse.h b/target-i386/ops_sse.h
index 3232abd965..986cbe3d88 100644
--- a/target-i386/ops_sse.h
+++ b/target-i386/ops_sse.h
@@ -924,11 +924,11 @@ void helper_ ## name ## sd (Reg *d, Reg *s)\
 #define FPU_CMPEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? -1 : 0
 #define FPU_CMPLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? -1 : 0
 #define FPU_CMPLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? -1 : 0
-#define FPU_CMPUNORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? - 1 : 0
+#define FPU_CMPUNORD(size, a, b) float ## size ## _unordered_quiet(a, b, &env->sse_status) ? - 1 : 0
 #define FPU_CMPNEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? 0 : -1
 #define FPU_CMPNLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? 0 : -1
 #define FPU_CMPNLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? 0 : -1
-#define FPU_CMPORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? 0 : -1
+#define FPU_CMPORD(size, a, b) float ## size ## _unordered_quiet(a, b, &env->sse_status) ? 0 : -1
 
 SSE_HELPER_CMP(cmpeq, FPU_CMPEQ)
 SSE_HELPER_CMP(cmplt, FPU_CMPLT)

From 211315fb5eb35c055e3134d58f2880d466bd5902 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:29 +0200
Subject: [PATCH 219/386] softfloat: rename float*_eq() into float*_eq_quiet()

float*_eq functions have a different semantics than other comparison
functions. Fix that by first renaming float*_quiet() into float*_eq_quiet().

Note that it is purely mechanical, and the behaviour should be unchanged.
That said it clearly highlight problems due to this different semantics,
they are fixed later in this patch series.

Cc: Alexander Graf <agraf@suse.de>
Acked-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat-native.h            |  6 +++---
 fpu/softfloat.c                   |  8 ++++----
 fpu/softfloat.h                   |  8 ++++----
 linux-user/arm/nwfpe/fpa11_cprt.c |  2 +-
 target-alpha/op_helper.c          |  4 ++--
 target-i386/ops_sse.h             |  8 ++++----
 target-microblaze/op_helper.c     |  4 ++--
 target-mips/op_helper.c           | 32 +++++++++++++++----------------
 target-ppc/op_helper.c            |  4 ++--
 9 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
index 406e180c51..0c7f48b4fa 100644
--- a/fpu/softfloat-native.h
+++ b/fpu/softfloat-native.h
@@ -210,7 +210,7 @@ INLINE float32 float32_div( float32 a, float32 b STATUS_PARAM)
 }
 float32 float32_rem( float32, float32  STATUS_PARAM);
 float32 float32_sqrt( float32  STATUS_PARAM);
-INLINE int float32_eq( float32 a, float32 b STATUS_PARAM)
+INLINE int float32_eq_quiet( float32 a, float32 b STATUS_PARAM)
 {
     return a == b;
 }
@@ -321,7 +321,7 @@ INLINE float64 float64_div( float64 a, float64 b STATUS_PARAM)
 }
 float64 float64_rem( float64, float64 STATUS_PARAM );
 float64 float64_sqrt( float64 STATUS_PARAM );
-INLINE int float64_eq( float64 a, float64 b STATUS_PARAM)
+INLINE int float64_eq_quiet( float64 a, float64 b STATUS_PARAM)
 {
     return a == b;
 }
@@ -428,7 +428,7 @@ INLINE floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM)
 }
 floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
 floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
-INLINE int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM)
+INLINE int floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM)
 {
     return a == b;
 }
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 11f6584067..492ef36a3d 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2318,7 +2318,7 @@ float32 float32_log2( float32 a STATUS_PARAM )
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float32_eq( float32 a, float32 b STATUS_PARAM )
+int float32_eq_quiet( float32 a, float32 b STATUS_PARAM )
 {
     a = float32_squash_input_denormal(a STATUS_VAR);
     b = float32_squash_input_denormal(b STATUS_VAR);
@@ -3582,7 +3582,7 @@ float64 float64_log2( float64 a STATUS_PARAM )
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float64_eq( float64 a, float64 b STATUS_PARAM )
+int float64_eq_quiet( float64 a, float64 b STATUS_PARAM )
 {
     uint64_t av, bv;
     a = float64_squash_input_denormal(a STATUS_VAR);
@@ -4592,7 +4592,7 @@ floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM )
 | Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
+int floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM )
 {
 
     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
@@ -5754,7 +5754,7 @@ float128 float128_sqrt( float128 a STATUS_PARAM )
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float128_eq( float128 a, float128 b STATUS_PARAM )
+int float128_eq_quiet( float128 a, float128 b STATUS_PARAM )
 {
 
     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 55c0c1cda5..738a50c11f 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -320,7 +320,7 @@ float32 float32_rem( float32, float32 STATUS_PARAM );
 float32 float32_sqrt( float32 STATUS_PARAM );
 float32 float32_exp2( float32 STATUS_PARAM );
 float32 float32_log2( float32 STATUS_PARAM );
-int float32_eq( float32, float32 STATUS_PARAM );
+int float32_eq_quiet( float32, float32 STATUS_PARAM );
 int float32_le( float32, float32 STATUS_PARAM );
 int float32_lt( float32, float32 STATUS_PARAM );
 int float32_unordered( float32, float32 STATUS_PARAM );
@@ -436,7 +436,7 @@ float64 float64_div( float64, float64 STATUS_PARAM );
 float64 float64_rem( float64, float64 STATUS_PARAM );
 float64 float64_sqrt( float64 STATUS_PARAM );
 float64 float64_log2( float64 STATUS_PARAM );
-int float64_eq( float64, float64 STATUS_PARAM );
+int float64_eq_quiet( float64, float64 STATUS_PARAM );
 int float64_le( float64, float64 STATUS_PARAM );
 int float64_lt( float64, float64 STATUS_PARAM );
 int float64_unordered( float64, float64 STATUS_PARAM );
@@ -539,7 +539,7 @@ floatx80 floatx80_mul( floatx80, floatx80 STATUS_PARAM );
 floatx80 floatx80_div( floatx80, floatx80 STATUS_PARAM );
 floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
 floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
-int floatx80_eq( floatx80, floatx80 STATUS_PARAM );
+int floatx80_eq_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_le( floatx80, floatx80 STATUS_PARAM );
 int floatx80_lt( floatx80, floatx80 STATUS_PARAM );
 int floatx80_unordered( floatx80, floatx80 STATUS_PARAM );
@@ -624,7 +624,7 @@ float128 float128_mul( float128, float128 STATUS_PARAM );
 float128 float128_div( float128, float128 STATUS_PARAM );
 float128 float128_rem( float128, float128 STATUS_PARAM );
 float128 float128_sqrt( float128 STATUS_PARAM );
-int float128_eq( float128, float128 STATUS_PARAM );
+int float128_eq_quiet( float128, float128 STATUS_PARAM );
 int float128_le( float128, float128 STATUS_PARAM );
 int float128_lt( float128, float128 STATUS_PARAM );
 int float128_unordered( float128, float128 STATUS_PARAM );
diff --git a/linux-user/arm/nwfpe/fpa11_cprt.c b/linux-user/arm/nwfpe/fpa11_cprt.c
index be54e9515d..801189798b 100644
--- a/linux-user/arm/nwfpe/fpa11_cprt.c
+++ b/linux-user/arm/nwfpe/fpa11_cprt.c
@@ -159,7 +159,7 @@ PerformComparisonOperation(floatx80 Fn, floatx80 Fm)
    }
 
    /* test for equal condition */
-   if (floatx80_eq(Fn,Fm, &fpa11->fp_status))
+   if (floatx80_eq_quiet(Fn,Fm, &fpa11->fp_status))
    {
       flags |= CC_ZERO;
    }
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 36f4f6d3b8..9f71db4c3a 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -918,7 +918,7 @@ uint64_t helper_cmpteq(uint64_t a, uint64_t b)
     fa = t_to_float64(a);
     fb = t_to_float64(b);
 
-    if (float64_eq(fa, fb, &FP_STATUS))
+    if (float64_eq_quiet(fa, fb, &FP_STATUS))
         return 0x4000000000000000ULL;
     else
         return 0;
@@ -957,7 +957,7 @@ uint64_t helper_cmpgeq(uint64_t a, uint64_t b)
     fa = g_to_float64(a);
     fb = g_to_float64(b);
 
-    if (float64_eq(fa, fb, &FP_STATUS))
+    if (float64_eq_quiet(fa, fb, &FP_STATUS))
         return 0x4000000000000000ULL;
     else
         return 0;
diff --git a/target-i386/ops_sse.h b/target-i386/ops_sse.h
index 986cbe3d88..ac0f150070 100644
--- a/target-i386/ops_sse.h
+++ b/target-i386/ops_sse.h
@@ -921,11 +921,11 @@ void helper_ ## name ## sd (Reg *d, Reg *s)\
     d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
 }
 
-#define FPU_CMPEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? -1 : 0
+#define FPU_CMPEQ(size, a, b) float ## size ## _eq_quiet(a, b, &env->sse_status) ? -1 : 0
 #define FPU_CMPLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? -1 : 0
 #define FPU_CMPLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? -1 : 0
 #define FPU_CMPUNORD(size, a, b) float ## size ## _unordered_quiet(a, b, &env->sse_status) ? - 1 : 0
-#define FPU_CMPNEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? 0 : -1
+#define FPU_CMPNEQ(size, a, b) float ## size ## _eq_quiet(a, b, &env->sse_status) ? 0 : -1
 #define FPU_CMPNLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? 0 : -1
 #define FPU_CMPNLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? 0 : -1
 #define FPU_CMPORD(size, a, b) float ## size ## _unordered_quiet(a, b, &env->sse_status) ? 0 : -1
@@ -1216,8 +1216,8 @@ void helper_pfadd(MMXReg *d, MMXReg *s)
 
 void helper_pfcmpeq(MMXReg *d, MMXReg *s)
 {
-    d->MMX_L(0) = float32_eq(d->MMX_S(0), s->MMX_S(0), &env->mmx_status) ? -1 : 0;
-    d->MMX_L(1) = float32_eq(d->MMX_S(1), s->MMX_S(1), &env->mmx_status) ? -1 : 0;
+    d->MMX_L(0) = float32_eq_quiet(d->MMX_S(0), s->MMX_S(0), &env->mmx_status) ? -1 : 0;
+    d->MMX_L(1) = float32_eq_quiet(d->MMX_S(1), s->MMX_S(1), &env->mmx_status) ? -1 : 0;
 }
 
 void helper_pfcmpge(MMXReg *d, MMXReg *s)
diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
index 39b8ec1e15..b7cd6b288f 100644
--- a/target-microblaze/op_helper.c
+++ b/target-microblaze/op_helper.c
@@ -338,7 +338,7 @@ uint32_t helper_fcmp_eq(uint32_t a, uint32_t b)
     set_float_exception_flags(0, &env->fp_status);
     fa.l = a;
     fb.l = b;
-    r = float32_eq(fa.f, fb.f, &env->fp_status);
+    r = float32_eq_quiet(fa.f, fb.f, &env->fp_status);
     flags = get_float_exception_flags(&env->fp_status);
     update_fpu_flags(flags & float_flag_invalid);
 
@@ -384,7 +384,7 @@ uint32_t helper_fcmp_ne(uint32_t a, uint32_t b)
     fa.l = a;
     fb.l = b;
     set_float_exception_flags(0, &env->fp_status);
-    r = !float32_eq(fa.f, fb.f, &env->fp_status);
+    r = !float32_eq_quiet(fa.f, fb.f, &env->fp_status);
     flags = get_float_exception_flags(&env->fp_status);
     update_fpu_flags(flags & float_flag_invalid);
 
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index e9de692fe1..31a19bab75 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2893,8 +2893,8 @@ void helper_cmpabs_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
  * but float64_unordered_quiet() is still called. */
 FOP_COND_D(f,   (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status), 0))
 FOP_COND_D(un,  float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status))
-FOP_COND_D(eq,  !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ueq, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(eq,  !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ueq, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(olt, !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(ult, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(ole, !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
@@ -2903,8 +2903,8 @@ FOP_COND_D(ule, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)
  * but float64_unordered() is still called. */
 FOP_COND_D(sf,  (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status), 0))
 FOP_COND_D(ngle,float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status))
-FOP_COND_D(seq, !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ngl, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(seq, !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ngl, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(lt,  !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(nge, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(le,  !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
@@ -2937,8 +2937,8 @@ void helper_cmpabs_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \
  * but float32_unordered_quiet() is still called. */
 FOP_COND_S(f,   (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status), 0))
 FOP_COND_S(un,  float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status))
-FOP_COND_S(eq,  !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(eq,  !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(olt, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(ole, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
@@ -2947,8 +2947,8 @@ FOP_COND_S(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)
  * but float32_unordered() is still called. */
 FOP_COND_S(sf,  (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0))
 FOP_COND_S(ngle,float32_unordered(fst1, fst0, &env->active_fpu.fp_status))
-FOP_COND_S(seq, !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(seq, !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(lt,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(nge, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(le,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
@@ -3000,10 +3000,10 @@ FOP_COND_PS(f,   (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status
                  (float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status), 0))
 FOP_COND_PS(un,  float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status),
                  float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status))
-FOP_COND_PS(eq,  !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(eq,  !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
 FOP_COND_PS(olt, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
                  !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
 FOP_COND_PS(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
@@ -3018,10 +3018,10 @@ FOP_COND_PS(sf,  (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0),
                  (float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status), 0))
 FOP_COND_PS(ngle,float32_unordered(fst1, fst0, &env->active_fpu.fp_status),
                  float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status))
-FOP_COND_PS(seq, !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(seq, !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
 FOP_COND_PS(lt,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
                  !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
 FOP_COND_PS(nge, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 8c993a1cf5..898ffd0b79 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -3364,7 +3364,7 @@ static inline uint32_t efststeq(uint32_t op1, uint32_t op2)
     CPU_FloatU u1, u2;
     u1.l = op1;
     u2.l = op2;
-    return float32_eq(u1.f, u2.f, &env->vec_status) ? 4 : 0;
+    return float32_eq_quiet(u1.f, u2.f, &env->vec_status) ? 4 : 0;
 }
 
 static inline uint32_t efscmplt(uint32_t op1, uint32_t op2)
@@ -3678,7 +3678,7 @@ uint32_t helper_efdtsteq (uint64_t op1, uint64_t op2)
     CPU_DoubleU u1, u2;
     u1.ll = op1;
     u2.ll = op2;
-    return float64_eq(u1.d, u2.d, &env->vec_status) ? 4 : 0;
+    return float64_eq_quiet(u1.d, u2.d, &env->vec_status) ? 4 : 0;
 }
 
 uint32_t helper_efdcmplt (uint64_t op1, uint64_t op2)

From 2657d0ff8f71cc5c084ee958d0087a5313099e74 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:29 +0200
Subject: [PATCH 220/386] softfloat: rename float*_eq_signaling() into
 float*_eq()

float*_eq_signaling functions have a different semantics than other
comparison functions. Fix that by renaming float*_quiet_signaling() into
float*_eq().

Note that it is purely mechanical, and the behaviour should be unchanged.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat-native.h | 6 +++---
 fpu/softfloat.c        | 8 ++++----
 fpu/softfloat.h        | 8 ++++----
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
index 0c7f48b4fa..ea7a15e1c4 100644
--- a/fpu/softfloat-native.h
+++ b/fpu/softfloat-native.h
@@ -222,7 +222,7 @@ INLINE int float32_lt( float32 a, float32 b STATUS_PARAM)
 {
     return a < b;
 }
-INLINE int float32_eq_signaling( float32 a, float32 b STATUS_PARAM)
+INLINE int float32_eq( float32 a, float32 b STATUS_PARAM)
 {
     return a <= b && a >= b;
 }
@@ -333,7 +333,7 @@ INLINE int float64_lt( float64 a, float64 b STATUS_PARAM)
 {
     return a < b;
 }
-INLINE int float64_eq_signaling( float64 a, float64 b STATUS_PARAM)
+INLINE int float64_eq( float64 a, float64 b STATUS_PARAM)
 {
     return a <= b && a >= b;
 }
@@ -440,7 +440,7 @@ INLINE int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM)
 {
     return a < b;
 }
-INLINE int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM)
+INLINE int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM)
 {
     return a <= b && a >= b;
 }
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 492ef36a3d..2e029405d8 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2419,7 +2419,7 @@ int float32_unordered( float32 a, float32 b STATUS_PARAM )
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float32_eq_signaling( float32 a, float32 b STATUS_PARAM )
+int float32_eq( float32 a, float32 b STATUS_PARAM )
 {
     uint32_t av, bv;
     a = float32_squash_input_denormal(a STATUS_VAR);
@@ -3686,7 +3686,7 @@ int float64_unordered( float64 a, float64 b STATUS_PARAM )
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float64_eq_signaling( float64 a, float64 b STATUS_PARAM )
+int float64_eq( float64 a, float64 b STATUS_PARAM )
 {
     uint64_t av, bv;
     a = float64_squash_input_denormal(a STATUS_VAR);
@@ -4706,7 +4706,7 @@ int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM )
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM )
+int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
 {
 
     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
@@ -5868,7 +5868,7 @@ int float128_unordered( float128 a, float128 b STATUS_PARAM )
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float128_eq_signaling( float128 a, float128 b STATUS_PARAM )
+int float128_eq( float128 a, float128 b STATUS_PARAM )
 {
 
     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 738a50c11f..b9440b2c75 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -324,7 +324,7 @@ int float32_eq_quiet( float32, float32 STATUS_PARAM );
 int float32_le( float32, float32 STATUS_PARAM );
 int float32_lt( float32, float32 STATUS_PARAM );
 int float32_unordered( float32, float32 STATUS_PARAM );
-int float32_eq_signaling( float32, float32 STATUS_PARAM );
+int float32_eq( float32, float32 STATUS_PARAM );
 int float32_le_quiet( float32, float32 STATUS_PARAM );
 int float32_lt_quiet( float32, float32 STATUS_PARAM );
 int float32_unordered_quiet( float32, float32 STATUS_PARAM );
@@ -440,7 +440,7 @@ int float64_eq_quiet( float64, float64 STATUS_PARAM );
 int float64_le( float64, float64 STATUS_PARAM );
 int float64_lt( float64, float64 STATUS_PARAM );
 int float64_unordered( float64, float64 STATUS_PARAM );
-int float64_eq_signaling( float64, float64 STATUS_PARAM );
+int float64_eq( float64, float64 STATUS_PARAM );
 int float64_le_quiet( float64, float64 STATUS_PARAM );
 int float64_lt_quiet( float64, float64 STATUS_PARAM );
 int float64_unordered_quiet( float64, float64 STATUS_PARAM );
@@ -543,7 +543,7 @@ int floatx80_eq_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_le( floatx80, floatx80 STATUS_PARAM );
 int floatx80_lt( floatx80, floatx80 STATUS_PARAM );
 int floatx80_unordered( floatx80, floatx80 STATUS_PARAM );
-int floatx80_eq_signaling( floatx80, floatx80 STATUS_PARAM );
+int floatx80_eq( floatx80, floatx80 STATUS_PARAM );
 int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_unordered_quiet( floatx80, floatx80 STATUS_PARAM );
@@ -628,7 +628,7 @@ int float128_eq_quiet( float128, float128 STATUS_PARAM );
 int float128_le( float128, float128 STATUS_PARAM );
 int float128_lt( float128, float128 STATUS_PARAM );
 int float128_unordered( float128, float128 STATUS_PARAM );
-int float128_eq_signaling( float128, float128 STATUS_PARAM );
+int float128_eq( float128, float128 STATUS_PARAM );
 int float128_le_quiet( float128, float128 STATUS_PARAM );
 int float128_lt_quiet( float128, float128 STATUS_PARAM );
 int float128_unordered_quiet( float128, float128 STATUS_PARAM );

From b689362d14e7b5689c6e006f962268764ed5df64 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:29 +0200
Subject: [PATCH 221/386] softfloat: move float*_eq and float*_eq_quiet

I am not a big fan of code moving, but having the signaling version in
the middle of quiet versions and vice versa doesn't make the code easy
to read.

This patch is a simple code move, basically swapping locations of
float*_eq and float*_eq_quiet.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat.c | 101 ++++++++++++++++++++++++------------------------
 fpu/softfloat.h |  16 ++++----
 2 files changed, 58 insertions(+), 59 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 2e029405d8..efd718bbcb 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2314,26 +2314,26 @@ float32 float32_log2( float32 a STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the single-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise.  The comparison is performed
+| the corresponding value `b', and 0 otherwise.  The invalid exception is
+| raised if either operand is a NaN.  Otherwise, the comparison is performed
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float32_eq_quiet( float32 a, float32 b STATUS_PARAM )
+int float32_eq( float32 a, float32 b STATUS_PARAM )
 {
+    uint32_t av, bv;
     a = float32_squash_input_denormal(a STATUS_VAR);
     b = float32_squash_input_denormal(b STATUS_VAR);
 
     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
        ) {
-        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid STATUS_VAR);
-        }
+        float_raise( float_flag_invalid STATUS_VAR);
         return 0;
     }
-    return ( float32_val(a) == float32_val(b) ) ||
-            ( (uint32_t) ( ( float32_val(a) | float32_val(b) )<<1 ) == 0 );
-
+    av = float32_val(a);
+    bv = float32_val(b);
+    return ( av == bv ) || ( (uint32_t) ( ( av | bv )<<1 ) == 0 );
 }
 
 /*----------------------------------------------------------------------------
@@ -2412,29 +2412,28 @@ int float32_unordered( float32 a, float32 b STATUS_PARAM )
     }
     return 0;
 }
+
 /*----------------------------------------------------------------------------
 | Returns 1 if the single-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise.  The invalid exception is
-| raised if either operand is a NaN.  Otherwise, the comparison is performed
+| the corresponding value `b', and 0 otherwise.  The comparison is performed
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float32_eq( float32 a, float32 b STATUS_PARAM )
+int float32_eq_quiet( float32 a, float32 b STATUS_PARAM )
 {
-    uint32_t av, bv;
     a = float32_squash_input_denormal(a STATUS_VAR);
     b = float32_squash_input_denormal(b STATUS_VAR);
 
     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
        ) {
-        float_raise( float_flag_invalid STATUS_VAR);
+        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
         return 0;
     }
-    av = float32_val(a);
-    bv = float32_val(b);
-    return ( av == bv ) || ( (uint32_t) ( ( av | bv )<<1 ) == 0 );
-
+    return ( float32_val(a) == float32_val(b) ) ||
+            ( (uint32_t) ( ( float32_val(a) | float32_val(b) )<<1 ) == 0 );
 }
 
 /*----------------------------------------------------------------------------
@@ -3578,11 +3577,12 @@ float64 float64_log2( float64 a STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the double-precision floating-point value `a' is equal to the
-| corresponding value `b', and 0 otherwise.  The comparison is performed
+| corresponding value `b', and 0 otherwise.  The invalid exception is raised
+| if either operand is a NaN.  Otherwise, the comparison is performed
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float64_eq_quiet( float64 a, float64 b STATUS_PARAM )
+int float64_eq( float64 a, float64 b STATUS_PARAM )
 {
     uint64_t av, bv;
     a = float64_squash_input_denormal(a STATUS_VAR);
@@ -3591,9 +3591,7 @@ int float64_eq_quiet( float64 a, float64 b STATUS_PARAM )
     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
        ) {
-        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid STATUS_VAR);
-        }
+        float_raise( float_flag_invalid STATUS_VAR);
         return 0;
     }
     av = float64_val(a);
@@ -3681,12 +3679,11 @@ int float64_unordered( float64 a, float64 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the double-precision floating-point value `a' is equal to the
-| corresponding value `b', and 0 otherwise.  The invalid exception is raised
-| if either operand is a NaN.  Otherwise, the comparison is performed
+| corresponding value `b', and 0 otherwise.  The comparison is performed
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float64_eq( float64 a, float64 b STATUS_PARAM )
+int float64_eq_quiet( float64 a, float64 b STATUS_PARAM )
 {
     uint64_t av, bv;
     a = float64_squash_input_denormal(a STATUS_VAR);
@@ -3695,7 +3692,9 @@ int float64_eq( float64 a, float64 b STATUS_PARAM )
     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
        ) {
-        float_raise( float_flag_invalid STATUS_VAR);
+        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
         return 0;
     }
     av = float64_val(a);
@@ -4586,13 +4585,13 @@ floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM )
 }
 
 /*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is
-| equal to the corresponding value `b', and 0 otherwise.  The comparison is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
+| Returns 1 if the extended double-precision floating-point value `a' is equal
+| to the corresponding value `b', and 0 otherwise.  The invalid exception is
+| raised if either operand is a NaN.  Otherwise, the comparison is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM )
+int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
 {
 
     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
@@ -4600,10 +4599,7 @@ int floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM )
          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
               && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
        ) {
-        if (    floatx80_is_signaling_nan( a )
-             || floatx80_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid STATUS_VAR);
-        }
+        float_raise( float_flag_invalid STATUS_VAR);
         return 0;
     }
     return
@@ -4700,13 +4696,13 @@ int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM )
 }
 
 /*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is equal
-| to the corresponding value `b', and 0 otherwise.  The invalid exception is
-| raised if either operand is a NaN.  Otherwise, the comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| Returns 1 if the extended double-precision floating-point value `a' is
+| equal to the corresponding value `b', and 0 otherwise.  The comparison is
+| performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
+int floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM )
 {
 
     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
@@ -4714,7 +4710,10 @@ int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
               && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
        ) {
-        float_raise( float_flag_invalid STATUS_VAR);
+        if (    floatx80_is_signaling_nan( a )
+             || floatx80_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
         return 0;
     }
     return
@@ -5750,11 +5749,12 @@ float128 float128_sqrt( float128 a STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the quadruple-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise.  The comparison is performed
+| the corresponding value `b', and 0 otherwise.  The invalid exception is
+| raised if either operand is a NaN.  Otherwise, the comparison is performed
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float128_eq_quiet( float128 a, float128 b STATUS_PARAM )
+int float128_eq( float128 a, float128 b STATUS_PARAM )
 {
 
     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
@@ -5762,10 +5762,7 @@ int float128_eq_quiet( float128 a, float128 b STATUS_PARAM )
          || (    ( extractFloat128Exp( b ) == 0x7FFF )
               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
        ) {
-        if (    float128_is_signaling_nan( a )
-             || float128_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid STATUS_VAR);
-        }
+        float_raise( float_flag_invalid STATUS_VAR);
         return 0;
     }
     return
@@ -5863,12 +5860,11 @@ int float128_unordered( float128 a, float128 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the quadruple-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise.  The invalid exception is
-| raised if either operand is a NaN.  Otherwise, the comparison is performed
+| the corresponding value `b', and 0 otherwise.  The comparison is performed
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float128_eq( float128 a, float128 b STATUS_PARAM )
+int float128_eq_quiet( float128 a, float128 b STATUS_PARAM )
 {
 
     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
@@ -5876,7 +5872,10 @@ int float128_eq( float128 a, float128 b STATUS_PARAM )
          || (    ( extractFloat128Exp( b ) == 0x7FFF )
               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
        ) {
-        float_raise( float_flag_invalid STATUS_VAR);
+        if (    float128_is_signaling_nan( a )
+             || float128_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
         return 0;
     }
     return
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index b9440b2c75..340f0a9f2e 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -320,11 +320,11 @@ float32 float32_rem( float32, float32 STATUS_PARAM );
 float32 float32_sqrt( float32 STATUS_PARAM );
 float32 float32_exp2( float32 STATUS_PARAM );
 float32 float32_log2( float32 STATUS_PARAM );
-int float32_eq_quiet( float32, float32 STATUS_PARAM );
+int float32_eq( float32, float32 STATUS_PARAM );
 int float32_le( float32, float32 STATUS_PARAM );
 int float32_lt( float32, float32 STATUS_PARAM );
 int float32_unordered( float32, float32 STATUS_PARAM );
-int float32_eq( float32, float32 STATUS_PARAM );
+int float32_eq_quiet( float32, float32 STATUS_PARAM );
 int float32_le_quiet( float32, float32 STATUS_PARAM );
 int float32_lt_quiet( float32, float32 STATUS_PARAM );
 int float32_unordered_quiet( float32, float32 STATUS_PARAM );
@@ -436,11 +436,11 @@ float64 float64_div( float64, float64 STATUS_PARAM );
 float64 float64_rem( float64, float64 STATUS_PARAM );
 float64 float64_sqrt( float64 STATUS_PARAM );
 float64 float64_log2( float64 STATUS_PARAM );
-int float64_eq_quiet( float64, float64 STATUS_PARAM );
+int float64_eq( float64, float64 STATUS_PARAM );
 int float64_le( float64, float64 STATUS_PARAM );
 int float64_lt( float64, float64 STATUS_PARAM );
 int float64_unordered( float64, float64 STATUS_PARAM );
-int float64_eq( float64, float64 STATUS_PARAM );
+int float64_eq_quiet( float64, float64 STATUS_PARAM );
 int float64_le_quiet( float64, float64 STATUS_PARAM );
 int float64_lt_quiet( float64, float64 STATUS_PARAM );
 int float64_unordered_quiet( float64, float64 STATUS_PARAM );
@@ -539,11 +539,11 @@ floatx80 floatx80_mul( floatx80, floatx80 STATUS_PARAM );
 floatx80 floatx80_div( floatx80, floatx80 STATUS_PARAM );
 floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
 floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
-int floatx80_eq_quiet( floatx80, floatx80 STATUS_PARAM );
+int floatx80_eq( floatx80, floatx80 STATUS_PARAM );
 int floatx80_le( floatx80, floatx80 STATUS_PARAM );
 int floatx80_lt( floatx80, floatx80 STATUS_PARAM );
 int floatx80_unordered( floatx80, floatx80 STATUS_PARAM );
-int floatx80_eq( floatx80, floatx80 STATUS_PARAM );
+int floatx80_eq_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_unordered_quiet( floatx80, floatx80 STATUS_PARAM );
@@ -624,11 +624,11 @@ float128 float128_mul( float128, float128 STATUS_PARAM );
 float128 float128_div( float128, float128 STATUS_PARAM );
 float128 float128_rem( float128, float128 STATUS_PARAM );
 float128 float128_sqrt( float128 STATUS_PARAM );
-int float128_eq_quiet( float128, float128 STATUS_PARAM );
+int float128_eq( float128, float128 STATUS_PARAM );
 int float128_le( float128, float128 STATUS_PARAM );
 int float128_lt( float128, float128 STATUS_PARAM );
 int float128_unordered( float128, float128 STATUS_PARAM );
-int float128_eq( float128, float128 STATUS_PARAM );
+int float128_eq_quiet( float128, float128 STATUS_PARAM );
 int float128_le_quiet( float128, float128 STATUS_PARAM );
 int float128_lt_quiet( float128, float128 STATUS_PARAM );
 int float128_unordered_quiet( float128, float128 STATUS_PARAM );

From f5a64251f2db2271970a1f4b7f8176d4de4dec91 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:30 +0200
Subject: [PATCH 222/386] softfloat: improve description of comparison
 functions

Make clear for all comparison functions which ones trigger an exception
for all NaNs, and which one only for sNaNs.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat.c | 85 ++++++++++++++++++++++++++++---------------------
 1 file changed, 48 insertions(+), 37 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index efd718bbcb..6ce0b61c19 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2338,9 +2338,9 @@ int float32_eq( float32 a, float32 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the single-precision floating-point value `a' is less than
-| or equal to the corresponding value `b', and 0 otherwise.  The comparison
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
+| or equal to the corresponding value `b', and 0 otherwise.  The invalid
+| exception is raised if either operand is a NaN.  The comparison is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float32_le( float32 a, float32 b STATUS_PARAM )
@@ -2367,8 +2367,9 @@ int float32_le( float32 a, float32 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the single-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise.  The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| the corresponding value `b', and 0 otherwise.  The invalid exception is
+| raised if either operand is a NaN.  The comparison is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float32_lt( float32 a, float32 b STATUS_PARAM )
@@ -2395,8 +2396,9 @@ int float32_lt( float32 a, float32 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the single-precision floating-point values `a' and `b' cannot
-| be compared, and 0 otherwise.  The comparison is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| be compared, and 0 otherwise.  The invalid exception is raised if either
+| operand is a NaN.  The comparison is performed according to the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float32_unordered( float32 a, float32 b STATUS_PARAM )
@@ -2415,8 +2417,9 @@ int float32_unordered( float32 a, float32 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the single-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise.  The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
+| exception.  The comparison is performed according to the IEC/IEEE Standard
+| for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float32_eq_quiet( float32 a, float32 b STATUS_PARAM )
@@ -3602,9 +3605,9 @@ int float64_eq( float64 a, float64 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the double-precision floating-point value `a' is less than or
-| equal to the corresponding value `b', and 0 otherwise.  The comparison is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
+| equal to the corresponding value `b', and 0 otherwise.  The invalid
+| exception is raised if either operand is a NaN.  The comparison is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float64_le( float64 a, float64 b STATUS_PARAM )
@@ -3631,8 +3634,9 @@ int float64_le( float64 a, float64 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the double-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise.  The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| the corresponding value `b', and 0 otherwise.  The invalid exception is
+| raised if either operand is a NaN.  The comparison is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float64_lt( float64 a, float64 b STATUS_PARAM )
@@ -3659,8 +3663,9 @@ int float64_lt( float64 a, float64 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the double-precision floating-point values `a' and `b' cannot
-| be compared, and 0 otherwise.  The comparison is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| be compared, and 0 otherwise.  The invalid exception is raised if either
+| operand is a NaN.  The comparison is performed according to the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float64_unordered( float64 a, float64 b STATUS_PARAM )
@@ -3679,8 +3684,9 @@ int float64_unordered( float64 a, float64 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the double-precision floating-point value `a' is equal to the
-| corresponding value `b', and 0 otherwise.  The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
+| exception.The comparison is performed according to the IEC/IEEE Standard
+| for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float64_eq_quiet( float64 a, float64 b STATUS_PARAM )
@@ -4614,8 +4620,9 @@ int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
 /*----------------------------------------------------------------------------
 | Returns 1 if the extended double-precision floating-point value `a' is
 | less than or equal to the corresponding value `b', and 0 otherwise.  The
-| comparison is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
+| invalid exception is raised if either operand is a NaN.  The comparison is
+| performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM )
@@ -4646,9 +4653,9 @@ int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the extended double-precision floating-point value `a' is
-| less than the corresponding value `b', and 0 otherwise.  The comparison
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
+| less than the corresponding value `b', and 0 otherwise.  The invalid
+| exception is raised if either operand is a NaN.  The comparison is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
@@ -4679,8 +4686,9 @@ int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the extended double-precision floating-point values `a' and `b'
-| cannot be compared, and 0 otherwise.  The comparison is performed according
-| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| cannot be compared, and 0 otherwise.  The invalid exception is raised if
+| either operand is a NaN.   The comparison is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM )
 {
@@ -4697,9 +4705,9 @@ int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the extended double-precision floating-point value `a' is
-| equal to the corresponding value `b', and 0 otherwise.  The comparison is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
+| equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
+| cause an exception.  The comparison is performed according to the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM )
@@ -5776,9 +5784,9 @@ int float128_eq( float128 a, float128 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the quadruple-precision floating-point value `a' is less than
-| or equal to the corresponding value `b', and 0 otherwise.  The comparison
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
+| or equal to the corresponding value `b', and 0 otherwise.  The invalid
+| exception is raised if either operand is a NaN.  The comparison is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float128_le( float128 a, float128 b STATUS_PARAM )
@@ -5809,8 +5817,9 @@ int float128_le( float128 a, float128 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the quadruple-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise.  The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| the corresponding value `b', and 0 otherwise.  The invalid exception is
+| raised if either operand is a NaN.  The comparison is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float128_lt( float128 a, float128 b STATUS_PARAM )
@@ -5841,8 +5850,9 @@ int float128_lt( float128 a, float128 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the quadruple-precision floating-point values `a' and `b' cannot
-| be compared, and 0 otherwise.  The comparison is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| be compared, and 0 otherwise.  The invalid exception is raised if either
+| operand is a NaN. The comparison is performed according to the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float128_unordered( float128 a, float128 b STATUS_PARAM )
@@ -5860,8 +5870,9 @@ int float128_unordered( float128 a, float128 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the quadruple-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise.  The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
+| exception.  The comparison is performed according to the IEC/IEEE Standard
+| for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float128_eq_quiet( float128 a, float128 b STATUS_PARAM )

From 019702c8156ee442378a520b733d823c0c62072b Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:30 +0200
Subject: [PATCH 223/386] target-ppc: fix SPE comparison functions

efstst*() functions are fast SPE funtions which do not take into account
special values (infinites, NaN, etc.), while efscmp*() functions are
IEEE754 compliant.

Given that float32_*() functions are IEEE754 compliant, the efscmp*()
functions are correctly implemented, while efstst*() are not. This
patch reverse the implementation of this two groups of functions and
fix the comments. It also use float32_eq() instead of float32_eq_quiet()
as qNaNs should not be ignored.

Cc: Alexander Graf <agraf@suse.de>
Cc: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-ppc/op_helper.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 898ffd0b79..28d40ac9aa 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -3343,7 +3343,7 @@ HELPER_SPE_VECTOR_ARITH(fsmul);
 HELPER_SPE_VECTOR_ARITH(fsdiv);
 
 /* Single-precision floating-point comparisons */
-static inline uint32_t efststlt(uint32_t op1, uint32_t op2)
+static inline uint32_t efscmplt(uint32_t op1, uint32_t op2)
 {
     CPU_FloatU u1, u2;
     u1.l = op1;
@@ -3351,7 +3351,7 @@ static inline uint32_t efststlt(uint32_t op1, uint32_t op2)
     return float32_lt(u1.f, u2.f, &env->vec_status) ? 4 : 0;
 }
 
-static inline uint32_t efststgt(uint32_t op1, uint32_t op2)
+static inline uint32_t efscmpgt(uint32_t op1, uint32_t op2)
 {
     CPU_FloatU u1, u2;
     u1.l = op1;
@@ -3359,30 +3359,30 @@ static inline uint32_t efststgt(uint32_t op1, uint32_t op2)
     return float32_le(u1.f, u2.f, &env->vec_status) ? 0 : 4;
 }
 
-static inline uint32_t efststeq(uint32_t op1, uint32_t op2)
+static inline uint32_t efscmpeq(uint32_t op1, uint32_t op2)
 {
     CPU_FloatU u1, u2;
     u1.l = op1;
     u2.l = op2;
-    return float32_eq_quiet(u1.f, u2.f, &env->vec_status) ? 4 : 0;
+    return float32_eq(u1.f, u2.f, &env->vec_status) ? 4 : 0;
 }
 
-static inline uint32_t efscmplt(uint32_t op1, uint32_t op2)
+static inline uint32_t efststlt(uint32_t op1, uint32_t op2)
 {
-    /* XXX: TODO: test special values (NaN, infinites, ...) */
-    return efststlt(op1, op2);
+    /* XXX: TODO: ignore special values (NaN, infinites, ...) */
+    return efscmplt(op1, op2);
 }
 
-static inline uint32_t efscmpgt(uint32_t op1, uint32_t op2)
+static inline uint32_t efststgt(uint32_t op1, uint32_t op2)
 {
-    /* XXX: TODO: test special values (NaN, infinites, ...) */
-    return efststgt(op1, op2);
+    /* XXX: TODO: ignore special values (NaN, infinites, ...) */
+    return efscmpgt(op1, op2);
 }
 
-static inline uint32_t efscmpeq(uint32_t op1, uint32_t op2)
+static inline uint32_t efststeq(uint32_t op1, uint32_t op2)
 {
-    /* XXX: TODO: test special values (NaN, infinites, ...) */
-    return efststeq(op1, op2);
+    /* XXX: TODO: ignore special values (NaN, infinites, ...) */
+    return efscmpeq(op1, op2);
 }
 
 #define HELPER_SINGLE_SPE_CMP(name)                                           \

From 06a0e6b104718803bceecbb5efd4125bcf71d8c7 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:30 +0200
Subject: [PATCH 224/386] target-mips: simplify FP comparisons

As the softfloat comparison functions already test for NaN, there is no
need to always call the float*_unordered*() functions.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-mips/op_helper.c | 72 ++++++++++++++++++++---------------------
 1 file changed, 36 insertions(+), 36 deletions(-)

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 31a19bab75..abcb6eb8bc 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2893,21 +2893,21 @@ void helper_cmpabs_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
  * but float64_unordered_quiet() is still called. */
 FOP_COND_D(f,   (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status), 0))
 FOP_COND_D(un,  float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status))
-FOP_COND_D(eq,  !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(eq,  float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(ueq, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(olt, !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ult, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ole, !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ule, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(olt, float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ult, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ole, float64_le_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ule, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
 /* NOTE: the comma operator will make "cond" to eval to false,
  * but float64_unordered() is still called. */
 FOP_COND_D(sf,  (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status), 0))
 FOP_COND_D(ngle,float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status))
-FOP_COND_D(seq, !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ngl, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(lt,  !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(seq, float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ngl, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(lt,  float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(nge, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(le,  !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(le,  float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(ngt, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
 
 #define FOP_COND_S(op, cond)                                   \
@@ -2937,21 +2937,21 @@ void helper_cmpabs_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \
  * but float32_unordered_quiet() is still called. */
 FOP_COND_S(f,   (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status), 0))
 FOP_COND_S(un,  float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status))
-FOP_COND_S(eq,  !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(eq,  float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(olt, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ole, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_le(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(olt, float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ole, float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status))
 /* NOTE: the comma operator will make "cond" to eval to false,
  * but float32_unordered() is still called. */
 FOP_COND_S(sf,  (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0))
 FOP_COND_S(ngle,float32_unordered(fst1, fst0, &env->active_fpu.fp_status))
-FOP_COND_S(seq, !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(lt,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(seq, float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(lt,  float32_lt(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(nge, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(le,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(le,  float32_le(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_le(fst0, fst1, &env->active_fpu.fp_status))
 
 #define FOP_COND_PS(op, condl, condh)                           \
@@ -3000,33 +3000,33 @@ FOP_COND_PS(f,   (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status
                  (float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status), 0))
 FOP_COND_PS(un,  float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status),
                  float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status))
-FOP_COND_PS(eq,  !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(eq,  float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
 FOP_COND_PS(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
                  float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(olt, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ole, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_le(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_le(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(olt, float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_lt_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ole, float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_le_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
 /* NOTE: the comma operator will make "cond" to eval to false,
  * but float32_unordered() is still called. */
 FOP_COND_PS(sf,  (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0),
                  (float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status), 0))
 FOP_COND_PS(ngle,float32_unordered(fst1, fst0, &env->active_fpu.fp_status),
                  float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status))
-FOP_COND_PS(seq, !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(lt,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(seq, float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(lt,  float32_lt(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
 FOP_COND_PS(nge, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
                  float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(le,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_le(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(le,  float32_le(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
 FOP_COND_PS(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_le(fst0, fst1, &env->active_fpu.fp_status),
                  float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))

From 353ebb7ac22f2866ac3680a3340aa21185c50407 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:30 +0200
Subject: [PATCH 225/386] target-mips: don't hardcode softfloat exception bits

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-mips/op_helper.c | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index abcb6eb8bc..0a623614fc 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2077,22 +2077,27 @@ void helper_ctc1 (target_ulong arg1, uint32_t reg)
         helper_raise_exception(EXCP_FPE);
 }
 
-static inline char ieee_ex_to_mips(char xcpt)
+static inline int ieee_ex_to_mips(int xcpt)
 {
-    return (xcpt & float_flag_inexact) >> 5 |
-           (xcpt & float_flag_underflow) >> 3 |
-           (xcpt & float_flag_overflow) >> 1 |
-           (xcpt & float_flag_divbyzero) << 1 |
-           (xcpt & float_flag_invalid) << 4;
-}
-
-static inline char mips_ex_to_ieee(char xcpt)
-{
-    return (xcpt & FP_INEXACT) << 5 |
-           (xcpt & FP_UNDERFLOW) << 3 |
-           (xcpt & FP_OVERFLOW) << 1 |
-           (xcpt & FP_DIV0) >> 1 |
-           (xcpt & FP_INVALID) >> 4;
+    int ret = 0;
+    if (xcpt) {
+        if (xcpt & float_flag_invalid) {
+            ret |= FP_INVALID;
+        }
+        if (xcpt & float_flag_overflow) {
+            ret |= FP_OVERFLOW;
+        }
+        if (xcpt & float_flag_underflow) {
+            ret |= FP_UNDERFLOW;
+        }
+        if (xcpt & float_flag_divbyzero) {
+            ret |= FP_DIV0;
+        }
+        if (xcpt & float_flag_inexact) {
+            ret |= FP_INEXACT;
+        }
+    }
+    return ret;
 }
 
 static inline void update_fcr31(void)

From 30a00bc142796f6d436b0b79f01757afb1e4c1e7 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:30 +0200
Subject: [PATCH 226/386] target-mips: fix c.ps.* instructions

Contrary to cabs.ps.* instructions, c.ps.* should not compare the absolute
value of the operand, but directly the operands.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-mips/op_helper.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 0a623614fc..b35a6d2936 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2962,10 +2962,10 @@ FOP_COND_S(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || fl
 #define FOP_COND_PS(op, condl, condh)                           \
 void helper_cmp_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc)    \
 {                                                               \
-    uint32_t fst0 = float32_abs(fdt0 & 0XFFFFFFFF);             \
-    uint32_t fsth0 = float32_abs(fdt0 >> 32);                   \
-    uint32_t fst1 = float32_abs(fdt1 & 0XFFFFFFFF);             \
-    uint32_t fsth1 = float32_abs(fdt1 >> 32);                   \
+    uint32_t fst0 = fdt0 & 0XFFFFFFFF;                          \
+    uint32_t fsth0 = fdt0 >> 32;                                \
+    uint32_t fst1 = fdt1 & 0XFFFFFFFF;                          \
+    uint32_t fsth1 = fdt1 >> 32;                                \
     int cl = condl;                                             \
     int ch = condh;                                             \
                                                                 \

From 6a385343e42c500f8404ecf9365ff63f4c942057 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Thu, 14 Apr 2011 00:49:30 +0200
Subject: [PATCH 227/386] target-mips: clear softfpu exception state for
 comparison instructions

MIPS FPU instructions should start with a clean softfpu status. This
is done for the most instructions, but not for comparison ones.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-mips/op_helper.c | 41 +++++++++++++++++++++++++----------------
 1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index b35a6d2936..8cba535a32 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2874,7 +2874,9 @@ uint64_t helper_float_mulr_ps(uint64_t fdt0, uint64_t fdt1)
 #define FOP_COND_D(op, cond)                                   \
 void helper_cmp_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc)    \
 {                                                              \
-    int c = cond;                                              \
+    int c;                                                     \
+    set_float_exception_flags(0, &env->active_fpu.fp_status);  \
+    c = cond;                                                  \
     update_fcr31();                                            \
     if (c)                                                     \
         SET_FP_COND(cc, env->active_fpu);                      \
@@ -2884,6 +2886,7 @@ void helper_cmp_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc)    \
 void helper_cmpabs_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
 {                                                              \
     int c;                                                     \
+    set_float_exception_flags(0, &env->active_fpu.fp_status);  \
     fdt0 = float64_abs(fdt0);                                  \
     fdt1 = float64_abs(fdt1);                                  \
     c = cond;                                                  \
@@ -2918,7 +2921,9 @@ FOP_COND_D(ngt, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || fl
 #define FOP_COND_S(op, cond)                                   \
 void helper_cmp_s_ ## op (uint32_t fst0, uint32_t fst1, int cc)    \
 {                                                              \
-    int c = cond;                                              \
+    int c;                                                     \
+    set_float_exception_flags(0, &env->active_fpu.fp_status);  \
+    c = cond;                                                  \
     update_fcr31();                                            \
     if (c)                                                     \
         SET_FP_COND(cc, env->active_fpu);                      \
@@ -2928,6 +2933,7 @@ void helper_cmp_s_ ## op (uint32_t fst0, uint32_t fst1, int cc)    \
 void helper_cmpabs_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \
 {                                                              \
     int c;                                                     \
+    set_float_exception_flags(0, &env->active_fpu.fp_status);  \
     fst0 = float32_abs(fst0);                                  \
     fst1 = float32_abs(fst1);                                  \
     c = cond;                                                  \
@@ -2962,13 +2968,15 @@ FOP_COND_S(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || fl
 #define FOP_COND_PS(op, condl, condh)                           \
 void helper_cmp_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc)    \
 {                                                               \
-    uint32_t fst0 = fdt0 & 0XFFFFFFFF;                          \
-    uint32_t fsth0 = fdt0 >> 32;                                \
-    uint32_t fst1 = fdt1 & 0XFFFFFFFF;                          \
-    uint32_t fsth1 = fdt1 >> 32;                                \
-    int cl = condl;                                             \
-    int ch = condh;                                             \
-                                                                \
+    uint32_t fst0, fsth0, fst1, fsth1;                          \
+    int ch, cl;                                                 \
+    set_float_exception_flags(0, &env->active_fpu.fp_status);   \
+    fst0 = fdt0 & 0XFFFFFFFF;                                   \
+    fsth0 = fdt0 >> 32;                                         \
+    fst1 = fdt1 & 0XFFFFFFFF;                                   \
+    fsth1 = fdt1 >> 32;                                         \
+    cl = condl;                                                 \
+    ch = condh;                                                 \
     update_fcr31();                                             \
     if (cl)                                                     \
         SET_FP_COND(cc, env->active_fpu);                       \
@@ -2981,13 +2989,14 @@ void helper_cmp_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc)    \
 }                                                               \
 void helper_cmpabs_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
 {                                                               \
-    uint32_t fst0 = float32_abs(fdt0 & 0XFFFFFFFF);             \
-    uint32_t fsth0 = float32_abs(fdt0 >> 32);                   \
-    uint32_t fst1 = float32_abs(fdt1 & 0XFFFFFFFF);             \
-    uint32_t fsth1 = float32_abs(fdt1 >> 32);                   \
-    int cl = condl;                                             \
-    int ch = condh;                                             \
-                                                                \
+    uint32_t fst0, fsth0, fst1, fsth1;                          \
+    int ch, cl;                                                 \
+    fst0 = float32_abs(fdt0 & 0XFFFFFFFF);                      \
+    fsth0 = float32_abs(fdt0 >> 32);                            \
+    fst1 = float32_abs(fdt1 & 0XFFFFFFFF);                      \
+    fsth1 = float32_abs(fdt1 >> 32);                            \
+    cl = condl;                                                 \
+    ch = condh;                                                 \
     update_fcr31();                                             \
     if (cl)                                                     \
         SET_FP_COND(cc, env->active_fpu);                       \

From 685ff50f698f11dec8e9e193e8bc86b051a8cf26 Mon Sep 17 00:00:00 2001
From: Alon Levy <alevy@redhat.com>
Date: Wed, 13 Apr 2011 14:42:00 +0300
Subject: [PATCH 228/386] libcacard: fix opposite usage of isspace

Signed-off-by: Alon Levy <alevy@redhat.com>
Tested-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 libcacard/vcard_emul_nss.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c
index 71f2ba3ae5..baada52a3c 100644
--- a/libcacard/vcard_emul_nss.c
+++ b/libcacard/vcard_emul_nss.c
@@ -955,7 +955,7 @@ count_tokens(const char *str, char token, char token_end)
 static const char *
 strip(const char *str)
 {
-    for (; *str && !isspace(*str); str++) {
+    for (; *str && isspace(*str); str++) {
     }
     return str;
 }
@@ -963,7 +963,7 @@ strip(const char *str)
 static const char *
 find_blank(const char *str)
 {
-    for (; *str && isspace(*str); str++) {
+    for (; *str && !isspace(*str); str++) {
     }
     return str;
 }

From 7b59220ef31a9c8758f8de16e6aaf3fc14b6540c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Llu=C3=ADs?= <xscript@gmx.net>
Date: Wed, 13 Apr 2011 18:38:24 +0200
Subject: [PATCH 229/386] move helpers.h to helper.h
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This provides a consistent naming scheme across all targets.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/helper.c                | 2 +-
 target-arm/{helpers.h => helper.h} | 0
 target-arm/iwmmxt_helper.c         | 2 +-
 target-arm/neon_helper.c           | 2 +-
 target-arm/op_helper.c             | 2 +-
 target-arm/translate.c             | 6 +++---
 6 files changed, 7 insertions(+), 7 deletions(-)
 rename target-arm/{helpers.h => helper.h} (100%)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index a0ec6439da..12127dee74 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -5,7 +5,7 @@
 #include "cpu.h"
 #include "exec-all.h"
 #include "gdbstub.h"
-#include "helpers.h"
+#include "helper.h"
 #include "qemu-common.h"
 #include "host-utils.h"
 #if !defined(CONFIG_USER_ONLY)
diff --git a/target-arm/helpers.h b/target-arm/helper.h
similarity index 100%
rename from target-arm/helpers.h
rename to target-arm/helper.h
diff --git a/target-arm/iwmmxt_helper.c b/target-arm/iwmmxt_helper.c
index 3941f1fd89..ebe6eb9fae 100644
--- a/target-arm/iwmmxt_helper.c
+++ b/target-arm/iwmmxt_helper.c
@@ -24,7 +24,7 @@
 
 #include "cpu.h"
 #include "exec.h"
-#include "helpers.h"
+#include "helper.h"
 
 /* iwMMXt macros extracted from GNU gdb.  */
 
diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index 7df925ad31..f5b173aa71 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -11,7 +11,7 @@
 
 #include "cpu.h"
 #include "exec.h"
-#include "helpers.h"
+#include "helper.h"
 
 #define SIGNBIT (uint32_t)0x80000000
 #define SIGNBIT64 ((uint64_t)1 << 63)
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 3de2610348..ee7286b77a 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -17,7 +17,7 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 #include "exec.h"
-#include "helpers.h"
+#include "helper.h"
 
 #define SIGNBIT (uint32_t)0x80000000
 #define SIGNBIT64 ((uint64_t)1 << 63)
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 6190028d08..fc9ff8d9e8 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -30,9 +30,9 @@
 #include "tcg-op.h"
 #include "qemu-log.h"
 
-#include "helpers.h"
+#include "helper.h"
 #define GEN_HELPER 1
-#include "helpers.h"
+#include "helper.h"
 
 #define ENABLE_ARCH_4T    arm_feature(env, ARM_FEATURE_V4T)
 #define ENABLE_ARCH_5     arm_feature(env, ARM_FEATURE_V5)
@@ -129,7 +129,7 @@ void arm_translate_init(void)
 #endif
 
 #define GEN_HELPER 2
-#include "helpers.h"
+#include "helper.h"
 }
 
 static inline TCGv load_cpu_offset(int offset)

From 5ee8ad71e159e724e2fa1af6b2c502668179502a Mon Sep 17 00:00:00 2001
From: Alex Williamson <alex.williamson@redhat.com>
Date: Mon, 18 Apr 2011 11:46:01 -0600
Subject: [PATCH 230/386] PXE: Use consistent naming for PXE ROMs

And add missing ROMs to tarbin build target.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
---
 Makefile                                        |  16 ++++++++--------
 configure                                       |   2 +-
 hw/e1000.c                                      |   2 +-
 hw/eepro100.c                                   |   2 +-
 hw/ne2000.c                                     |   2 +-
 hw/pcnet-pci.c                                  |   2 +-
 hw/rtl8139.c                                    |   2 +-
 hw/virtio-pci.c                                 |   2 +-
 pc-bios/{pxe-e1000.bin => pxe-e1000.rom}        | Bin
 ...e-eepro100-80861209.rom => pxe-eepro100.rom} | Bin
 pc-bios/{pxe-ne2k_pci.bin => pxe-ne2k_pci.rom}  | Bin
 pc-bios/{pxe-pcnet.bin => pxe-pcnet.rom}        | Bin
 pc-bios/{pxe-rtl8139.bin => pxe-rtl8139.rom}    | Bin
 pc-bios/{pxe-virtio.bin => pxe-virtio.rom}      | Bin
 14 files changed, 15 insertions(+), 15 deletions(-)
 rename pc-bios/{pxe-e1000.bin => pxe-e1000.rom} (100%)
 rename pc-bios/{gpxe-eepro100-80861209.rom => pxe-eepro100.rom} (100%)
 rename pc-bios/{pxe-ne2k_pci.bin => pxe-ne2k_pci.rom} (100%)
 rename pc-bios/{pxe-pcnet.bin => pxe-pcnet.rom} (100%)
 rename pc-bios/{pxe-rtl8139.bin => pxe-rtl8139.rom} (100%)
 rename pc-bios/{pxe-virtio.bin => pxe-virtio.rom} (100%)

diff --git a/Makefile b/Makefile
index fa93be5ed7..9df4fff630 100644
--- a/Makefile
+++ b/Makefile
@@ -177,10 +177,8 @@ ifdef INSTALL_BLOBS
 BLOBS=bios.bin vgabios.bin vgabios-cirrus.bin \
 vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin \
 ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc \
-gpxe-eepro100-80861209.rom \
-pxe-e1000.bin \
-pxe-ne2k_pci.bin pxe-pcnet.bin \
-pxe-rtl8139.bin pxe-virtio.bin \
+pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \
+pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \
 bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
 multiboot.bin linuxboot.bin \
 s390-zipl.rom \
@@ -326,10 +324,12 @@ tarbin:
 	$(datadir)/openbios-sparc32 \
 	$(datadir)/openbios-sparc64 \
 	$(datadir)/openbios-ppc \
-	$(datadir)/pxe-ne2k_pci.bin \
-	$(datadir)/pxe-rtl8139.bin \
-	$(datadir)/pxe-pcnet.bin \
-	$(datadir)/pxe-e1000.bin \
+	$(datadir)/pxe-e1000.rom \
+	$(datadir)/pxe-eepro100.rom \
+	$(datadir)/pxe-ne2k_pci.rom \
+	$(datadir)/pxe-pcnet.rom \
+	$(datadir)/pxe-rtl8139.rom \
+	$(datadir)/pxe-virtio.rom \
 	$(docdir)/qemu-doc.html \
 	$(docdir)/qemu-tech.html \
 	$(mandir)/man1/qemu.1 \
diff --git a/configure b/configure
index ae97e11a97..813ef7a7a2 100755
--- a/configure
+++ b/configure
@@ -3445,7 +3445,7 @@ FILES="Makefile tests/Makefile"
 FILES="$FILES tests/cris/Makefile tests/cris/.gdbinit"
 FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
 FILES="$FILES roms/seabios/Makefile roms/vgabios/Makefile"
-for bios_file in $source_path/pc-bios/*.bin $source_path/pc-bios/*.dtb $source_path/pc-bios/openbios-*; do
+for bios_file in $source_path/pc-bios/*.bin $source_path/pc-bios/*.rom $source_path/pc-bios/*.dtb $source_path/pc-bios/openbios-*; do
     FILES="$FILES pc-bios/`basename $bios_file`"
 done
 mkdir -p $DIRS
diff --git a/hw/e1000.c b/hw/e1000.c
index fe3e812610..f160bfc2ab 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1220,7 +1220,7 @@ static PCIDeviceInfo e1000_info = {
     .qdev.vmsd  = &vmstate_e1000,
     .init       = pci_e1000_init,
     .exit       = pci_e1000_uninit,
-    .romfile    = "pxe-e1000.bin",
+    .romfile    = "pxe-e1000.rom",
     .qdev.props = (Property[]) {
         DEFINE_NIC_PROPERTIES(E1000State, conf),
         DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/eepro100.c b/hw/eepro100.c
index edf48f61d1..369ad7f840 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -2054,7 +2054,7 @@ static void eepro100_register_devices(void)
         PCIDeviceInfo *pci_dev = &e100_devices[i].pci;
         /* We use the same rom file for all device ids.
            QEMU fixes the device id during rom load. */
-        pci_dev->romfile = "gpxe-eepro100-80861209.rom";
+        pci_dev->romfile = "pxe-eepro100.rom";
         pci_dev->init = e100_nic_init;
         pci_dev->exit = pci_nic_uninit;
         pci_dev->qdev.props = e100_properties;
diff --git a/hw/ne2000.c b/hw/ne2000.c
index 5966359852..b668ad1070 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -742,7 +742,7 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
     if (!pci_dev->qdev.hotplugged) {
         static int loaded = 0;
         if (!loaded) {
-            rom_add_option("pxe-ne2k_pci.bin", -1);
+            rom_add_option("pxe-ne2k_pci.rom", -1);
             loaded = 1;
         }
     }
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 339a401967..40ee29d38b 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -310,7 +310,7 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
     if (!pci_dev->qdev.hotplugged) {
         static int loaded = 0;
         if (!loaded) {
-            rom_add_option("pxe-pcnet.bin", -1);
+            rom_add_option("pxe-pcnet.rom", -1);
             loaded = 1;
         }
     }
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index d5459336e5..8790a00afb 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3484,7 +3484,7 @@ static PCIDeviceInfo rtl8139_info = {
     .qdev.vmsd  = &vmstate_rtl8139,
     .init       = pci_rtl8139_init,
     .exit       = pci_rtl8139_uninit,
-    .romfile    = "pxe-rtl8139.bin",
+    .romfile    = "pxe-rtl8139.rom",
     .qdev.props = (Property[]) {
         DEFINE_NIC_PROPERTIES(RTL8139State, conf),
         DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 555f23f1da..c19629d507 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -877,7 +877,7 @@ static PCIDeviceInfo virtio_info[] = {
         .qdev.size  = sizeof(VirtIOPCIProxy),
         .init       = virtio_net_init_pci,
         .exit       = virtio_net_exit_pci,
-        .romfile    = "pxe-virtio.bin",
+        .romfile    = "pxe-virtio.rom",
         .qdev.props = (Property[]) {
             DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
                             VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
diff --git a/pc-bios/pxe-e1000.bin b/pc-bios/pxe-e1000.rom
similarity index 100%
rename from pc-bios/pxe-e1000.bin
rename to pc-bios/pxe-e1000.rom
diff --git a/pc-bios/gpxe-eepro100-80861209.rom b/pc-bios/pxe-eepro100.rom
similarity index 100%
rename from pc-bios/gpxe-eepro100-80861209.rom
rename to pc-bios/pxe-eepro100.rom
diff --git a/pc-bios/pxe-ne2k_pci.bin b/pc-bios/pxe-ne2k_pci.rom
similarity index 100%
rename from pc-bios/pxe-ne2k_pci.bin
rename to pc-bios/pxe-ne2k_pci.rom
diff --git a/pc-bios/pxe-pcnet.bin b/pc-bios/pxe-pcnet.rom
similarity index 100%
rename from pc-bios/pxe-pcnet.bin
rename to pc-bios/pxe-pcnet.rom
diff --git a/pc-bios/pxe-rtl8139.bin b/pc-bios/pxe-rtl8139.rom
similarity index 100%
rename from pc-bios/pxe-rtl8139.bin
rename to pc-bios/pxe-rtl8139.rom
diff --git a/pc-bios/pxe-virtio.bin b/pc-bios/pxe-virtio.rom
similarity index 100%
rename from pc-bios/pxe-virtio.bin
rename to pc-bios/pxe-virtio.rom

From 36d8d02dc8c45780cae74e2ba7a6135b95c16f81 Mon Sep 17 00:00:00 2001
From: Alex Williamson <alex.williamson@redhat.com>
Date: Mon, 18 Apr 2011 11:46:41 -0600
Subject: [PATCH 231/386] PXE: Refresh all PXE ROMs from the ipxe submodule

Add script to make this easy to repeat later.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
---
 pc-bios/README              |  17 +++----
 pc-bios/pxe-e1000.rom       | Bin 72192 -> 67072 bytes
 pc-bios/pxe-eepro100.rom    | Bin 56832 -> 61440 bytes
 pc-bios/pxe-ne2k_pci.rom    | Bin 56320 -> 61440 bytes
 pc-bios/pxe-pcnet.rom       | Bin 56832 -> 61440 bytes
 pc-bios/pxe-rtl8139.rom     | Bin 56320 -> 61440 bytes
 pc-bios/pxe-virtio.rom      | Bin 56320 -> 60416 bytes
 scripts/refresh-pxe-roms.sh |  99 ++++++++++++++++++++++++++++++++++++
 8 files changed, 107 insertions(+), 9 deletions(-)
 create mode 100755 scripts/refresh-pxe-roms.sh

diff --git a/pc-bios/README b/pc-bios/README
index 646a31a313..fe221a940f 100644
--- a/pc-bios/README
+++ b/pc-bios/README
@@ -18,16 +18,15 @@
   https://github.com/dgibson/SLOF, and the image currently in qemu is
   built from git tag qemu-slof-20110323.
 
-- The PXE roms come from Rom-o-Matic gPXE 0.9.9 with BANNER_TIMEOUT=0
+- The PXE roms come from the iPXE project. Built with BANNER_TIME 0.
+  Sources available at http://ipxe.org.  Vendor:Device ID -> ROM mapping:
 
-  e1000 8086:100E
-  eepro100 8086:1209 (also used for 8086:1229 and 8086:2449)
-  ns8390 1050:0940
-  pcnet32 1022:2000
-  rtl8139 10ec:8139
-  virtio 1af4:1000
-
-  http://rom-o-matic.net/
+	8086:100e -> pxe-e1000.rom
+	8086:1209 -> pxe-eepro100.rom
+	1050:0940 -> pxe-ne2k_pci.rom
+	1022:2000 -> pxe-pcnet.rom
+	10ec:8139 -> pxe-rtl8139.rom
+	1af4:1000 -> pxe-virtio.rom
 
 - The S390 zipl loader is an addition to the official IBM s390-tools
   package. That fork is maintained in its own git repository at:
diff --git a/pc-bios/pxe-e1000.rom b/pc-bios/pxe-e1000.rom
index 7ac744eb39f55aa1d6f18cc9257efe1aa3be401d..2e5f8b28a414960cd58f793957435e9451be8fb4 100644
GIT binary patch
literal 67072
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

literal 72192
zcmZs?2UrtZ*C;&cl_Wrb(4!PVx>BVWsvw8~q)10FB1I4rKoKbcB!pluM@8YF$F6Wh
zssbU>tbj@}Qf(7Mwa_6qzTfxV``_pOJ5Ofz+I!DhE35CxjQ<^;=p^6^{NF7bPy?(1
zy0eFGK{kN|NFf*$0C)fd0J3@iS*lGxK!-@jfc`&V5ReE+fnR_6masp^SSB-hi;2lz
zX6)XSJxNJS<D`^*z&?7AE1)MuOHEJTlAdmyt`GQoyLc#00{{g23)X4aX;_W=Lp4$Z
zNh~AYS|Mnbh&jtmub^fU5C#V=;LT|OXaa9X9t5bBRO#RwSaBx^fiwIVzKp=dI!M(k
zm6QNR&e9(mtQ~ouSsqPOe=cr^6)u1xSfw#o3M(7{`(W7;Sc*|GXb+U7s1?7k8DMG=
zYY0$)KZbxvp+gGAFCd*Z1F15V>%e$eF(|!^K)lU}U<5Nl8YR=t%&jE?T}F-r0Q?aI
zYuc>WY))5-0RiaV16s$ISVK)e|Iqb@=}IhB0gYI5SX`v8L_-E(KSSrYFtwYYFzK`j
z%&euPMVBG5i~$%YkQp%Ityo)_uCyBih|x_8e^B6Hjgk>(VqPuqe@O1w!J7PkND7-)
z|Ew268IcTP4H614_@fvGg4PKG*qssv@o6VpL~McpZ@<PN8FA8q+IHy*JcAwwNI64E
zIm74oGI!3mk^rWxZyXQ@{qJEUWKR5&qi77{bW8D{fmYJMKqzMhJPG~7J%j6D2xFMd
zNoh(2$l#A*_Wiuh;5eAV+NC_e8Bu0Jv$_8kF6JH}7+==YKmz~Ko-9-<S!d|~OqR5m
z&6!Dze_n6G{1J{Ev?&n)@z5q67>I;6LM31!<cf5h4sFthfxjT7EI0ui2Z*<c<tWXl
zIx6r2i~VC^RK5Q{<I|@aQ30ydE~JM8bb#vQ<R|Uz*a1*Iymy(|09bm;-b06|&dihq
zBPS{|i5i`BfU$ocD`hVgFg7*@u-HFlEp0UEmjK2AF9@1VS%3J9gZ$w$2GUdt1H&PW
z-Xq{B@Q2S^kfw4N=mjZdO8MLZ7&FQ<U<|455yleZ4A?8mA7uYU)cX&;L-G5QsefE$
z|ABo}MoLoR|E4P?ln6)>LLf~eFmM@Q#CrL<?keu(e38n(`w4KA!L^jCfGZU_cmN7s
zhnBp3(rHMKy$yRoJ;aPk`47gu>3gGD%>79RumB@~5vYOmBWQ9yS#q=FEK9bL19iD!
zcwMe5;s1jw6dJ*Zo$QwW+E^nvJyss}A|xaPr73lS@E1PxYRD@^Cep0sm7@4pJpg#5
zD}V~Xe+GY17pw(L<dr{jr9ry|3_7u_js}#B#xTkgfGf+tN@Ezd$OM4-i&)MG68sUv
z|7mnT|9lA(QHa<kCN`pgYJwe>1%E}VlzBx83ked?@8wAa2o6ZZb3p<Izmo*Qr6$)&
zDtHD$fr4i(op2BaNRM=Fq8(OkzX|w2BE3jD`&m-C1uT~oj<$d>uwNn#1ZSmyHVS<A
zXMs<p445aWq}J~Qz@w7!Whuy#?3PkEsrlcmNhH$FWdQik`ON>E-~4aJ{W)K9CiDRI
z=NZNo;w@qsQbUmtD?<1L1S+DMs0d!ufTUgzklJ=c_--PkU_rv5GXfcAEydkZAB0PN
zadjVqmuEd7kw_Svf)A47&gM}G7zz}3H-i#z7a)~-5QDzNAVSU$NQl%HJcPKu<$Egv
z4b+i<lI}VRP%==`QZiZsGJ+)C#ohk{NtbG`NteD*(nJx<r6Ej;KuWxnGZ7}>x4=2h
zP<AwQrqCIl9StW67(Rb|cej9Er-=j&q>^FyFap8%0AqfT0qLQewe0(OCy2prCo<Sy
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
O0MuIH|J(nKJMh0mlr&=i

diff --git a/pc-bios/pxe-eepro100.rom b/pc-bios/pxe-eepro100.rom
index 2ca59ec369fa3aa829aa64b80339dc9aaab9026f..d292e8feca0b63b512a3b04db37caa590ca003e4 100644
GIT binary patch
literal 61440
zcmagFcUTi$_b58)2?<H)p$7>_7gP`glr9Qt=qOz<M5GA`phyiUAqKH`UlH}Sp<tm(
zARtAtfCZ6&fTB(e0aOH}%?aQ4yXQRj+&}K{JiD&F)}FOj-An>*XNZpiHNgM-$pNT<
z1EA4<SV(u>?0YB|rw9OA00IsG82}6bax?w|PNOH%VX`sc>~c30hzDeyspWPGV!33p
zSjp>Gt=f~EvD+dkB^KC24|WHPWEiO#8S67LEHaFNfNgG@Rb`+s_)%n^S)bWW>@vYf
z9W?0*>E;4aw?x97FW-$2%)zZ7&<zQuA)C?wFd5m7P6nuzRM{XId889`K{EUpzKo#1
zwXmv}8YzK{yt!pE?5zc(?9Bo*gbWUYESd#Pkd+qTCqz*nsD{ji5Gm$IKu6$8iq?@X
zyFQjashS7}gd-@Jte2{Cqzl$**Ow+=sR!Og906s^h@@ML2*yrENCPzC$}%ZwHDu&%
z0DxsSuqUkESWO$sFrWa#yFkn5IrgByYMJg)gk*)lez{eMuxc)8He^6HF#zKzx(-3Q
z$;?0)%9=4i12p7HDmV%JADmmavZenYoFakEGA4TjBa%U?A?`&mWZPvl0OWg=#t}H!
z1TeTZv4|91^fDy|cZOj#&G^q-$>4CYzpr7gBp|NB0Y=@%bpXJ~6GFPn)d(;QK@4t}
zP(onjbpccvvROEovWzSd!HBXFSxx^BYjAgg*3a`sI%wcOygvz-@ueO9|4f!NTTNR*
z7Qe3vT$Xov3NDBTz@u<MI0EFt8{iQ59(GYS{uVCSg#gpxm)NMkL@)wIx<x9(=tk92
zfi4C;sEG<N{NiASkPZgmJVpD`8R3k=X%-fGpQ^`jm3)bV%Z}P74)`Ac!ZJXUDIkMk
z!~S06&dLZZ!Wi61P#=CNf)U*MUsjZ90fw;*`$JkXS!2QeVp?Zg<(9>fnr3BTX<=z@
zZD(a3yDn<??lo4{|D7=Uzogfg3Q%P-B`Xr?vSRC2fVz2`zm**zM^D+Eno4zLrNo=N
zP+3XT=%hr(o>+FuZYp45VFAd=0T8sT4jBMyxtb+{dx0*ZuAp(5Ny)HfCdI)7A_N!%
zYuGjfRszdRx(5>sAwXZ)B^FAyU_D^LD62y-3Y%Fd3&^4l@shHP>c5n?EfY=MyC<2t
zD=CS!Coz`FNJ&cg-^7W!|Hw$lP@-T0V<ZRx45qiQyZ@0l+^<%mlDAKQgO@LYCh$uP
zo=kKYybXy6&<`$fLdsUW1!VJmW^|?{vWuF^ic0wp_T3q~quH!INr}sEm$X+7@S#6~
zy;Nn%IQ>#pGF1lvn=@2E72rREQ`A}8Ru=l=^4z819jy#H=}N5=P%<3DD2oR!&QD#6
zVc4VN0oD|$Om<p~Kt_-b+K;Hq{bIw*QM4)9q#R_(3nLiv+=>5ZgR@{2EP}ywrUC$w
z`3y;Co=0?rgoI#pW$GE;MfVFRgjlE|)Fuh30RucDI>@n+FUghiFUesc!L9VW1u`yz
zeUM~YMo-vD29dyWb?7Mw2M#@L?nHtJKvvReBnLUIJ*&WbkZh4`b`+{y50*hi!_6Q9
z`~b-;$w^s<h5_F#1Nc<Rg9T6}wQf5A9)v#6%eri6hm3-cOz#-77x$rCHOKzG9V}~K
zWY8G_3?^{mwd^pKg@eJg#2p1x;~)mJQq~~K8ga6&u1v|t7(xad$$%xoWequ`tWZR9
z#;_!q$1Le4=?Yp$mB{>qnq!b)fdGlxOn{MAH2>&FVS!pQP|{sX0ZRHxnoEXDK<KS(
znzkgH?o!jmkjiAnOtxm0^VEnD#t6P7+n`^=Ck(g?V$6JGz<L_?puj+g!D%NkINv52
zoDNz2eKJJ0d(xFSCsJ8VnGzrzMw`Ea)6IDRT?nFM%9ViN5K`HH4pGM6W#eN7&4MUk
z`B+*RGONCDk*LeyF3L{XYWm14hVUDbk=LG!l`()+Gs_TuM>6WhWOB`@UoOFTh!IX?
z-a^xvUx2PuIYALdCX*YNBuhl5KsNYYHb}OT8Lmli-ICxj2BgWRmhAxge^4WA3NVbi
zTFf%S<r36{WOU~LOXu@{==7P%hLKQ-NOmHHQufM6MK4vjZH&A&04ZCQCmmdd5`L9q
z<ShaK8AwGl8kcKEFoQe6sOye`$xwr-2moweDnBVRm=loBap2O$6y5T(vP12f0{}?p
zG$8XCL4FNUC=j(2!iZP~DZeP2I1gNsiELDBBn|-NJom&hsR_Fil2Z0l_asI|N6U=L
zo?Y>~spiz^sKmr1*0NoZ=^uNyoXq4z?T=52iuwNql)aVASTX_@7*<loRtYBd8UrR`
zBfxkdWr|_d%y0t30ER*{7zCvLVQ@f1iXuZejEyZuGdviaNr>gckTJvR8Msac^$fIH
zF4+nUXK>|z`g+T&oMnG9=KPj<5Ka$_5g5zhvmAlnhB8v&l4Hx{@UaY@4udnkz)%pi
z%4BT^BSfa@GR7`H6^&hxc&khUeHe9AK!U|#@Q`2;qU$W%?LN<v=8JQOi3)~gWB_x?
zPB<%qAc&3rmK*!|`(KRivM$kUVYHVjDG0C*3MPQ*T}hAzP}%b>22?^1eTxJMkUR<i
zbLOk-u4{+V!>$~H0UJkSZX#HCC^}^3CX9u|M{bpF89h#b)0Vy+2dAab!*p|SH<Y@;
zqU;Ay*lYxKOIB~_tC=2zZpaLmMY%FLRj+od++fn-gQ~SW{PqEh4)hO`zW^|v69hhl
zx@NoNWwNvU<jOQVeG__q{v~;?6{&i0C)$CU0?A$vQwIYc;nb}}k7N<f|EOn4H}{=1
z34&y<t*bSdNH6IxX(@SQHA?hl0x+v)Qz&O%YW2*DB=fLVQfi419W;L)I0(pmB(fEP
zhL$c8nY&;Nx~dJNb5Q9&%C;OrG0Ip<41*=8Y4HPr3NXrXHeAD8r6=A>|8=^ID8?ll
zUZvFRo5E_%4D*Zj?tPVgnkGJ*K0?!Un=6|wuKs~ZfZ&(V&f4j!z*+eA1_Xe@q8LnT
z+jpxUG|tOh8LSW74ZJ1??>u$v`x<|h^_yL#&`7DXk1md=_M{Vo36`DG{KQgHoJ?nS
zEC)}FFjzPv;>jzFng!z!B!Y5AF*27ng=r1oekC3Ez=mZl3oUoH!4nvfCd`8oKm#4M
z1LSTvgq#^-<S(iTvW|3?=gJ9(kqyVdjetzxv~10yp++5@VnDOcq8y3UN?svKls{2o
z?1IQcBb^@C4DAY0SNGxucX2ntEjr0esCuzz6S624gKMq>*^4Pl7G)l3HbH$P#yU2#
z*mXPsn&t?}(b6ODWd`G&Kgft|NRw2rRW>!8Q-P_5qI5FOMa)3|+ukyMTua1~XiGi$
zRt?{?ft_()E+dn7_pWBNUO01MUL+4KTWQW1Ssu0xi|_yz7<HZ=Ve{?zDSDNFI2=-6
z9hgv{mK_(4%~ICIghlb#NllZy7~0rUmn=BU*N%czQIU(%HE$fKo_bKkvaOACs!_8M
ztckHhD`~PhoDJx!Y|<ka(IScmpkBeXV#?LLsD&hZ3%MRh?yxr)2{l6a1TiRu2;5zr
zj?4a^4eNS&q1>T{qI-ktgv<1Yt{2K{k4pUgHT+_Ep)|#kRvDv{&<AN`Jkjtq6cP~|
z+NHc@)xt$bdLVnnwl_zfN8SC|t7`M`GxDDntXJ)}z{I96Lvpzc>{8gJ*OxReVqdDX
z{zY62f6H$d@dGe!wE3yFFJ4IrrKQL&0Q0w3X+8x3tI_>(&oEnODQhd;mjL|z#}5rb
z(hIOFOUdYq-a1#X7ms?NbF(28mSS<>Lc?NVIu^^u>5z1bRoQ^<K-lZ3mhq4S8maJa
ztr)B?!}Hp~sF6OQJp2*KA~YCvq<gH_D=F3=W#J!)@`H5&zy(pYOP^v1g{K^A_-QF&
zFYPW2uF%7<_eZkN+apuchjxl)cyb81y*Gi43dN=kB~~Ov@bCy6!`M{4Cp9Md-f&`)
zh>=-?dd^SM{FE>JB4@y;jUWSp%6eh;eETiPP$-eR^obj;#fUQg^*BG?fPCG6Bh6W}
znoI^OAX%v32sp4lPS-@tidyY-h9`7`0tF|X?TPQS(op$h(=82XhR^S7qu~**6Wz14
zs1LPSY3L3#3WD@dZ1hO|j*=|HQZ0bMlH0(B|84M@-G1LkmiWk`rYizWQ&9D5j|R?P
zC&x@Do{sU~)2HQh4_?C}<|7tUG;TEYOajhZ{aDz)F4g8wzSXC2X~;vLc2xBAIbMJc
zi2VZP!^^T7Cd0xDr`-fsKDt0D&cDA+zf4T$p%4K`WEgfU0X({dsrltF$W`HTx$~U%
zX^*^da^BJe^6_b|B=B~%^s*#mHs|p}@SpAK#vP~ci#b^^GKPT73zo!-TKWcOFAyBx
z&}b|)#8$J|YWyOa3cjgtRK;+=gQ{9J*Q<|?y^l)G+MyGh6wyCw^GO$c0U<2rU;hT9
zhI0C7^J-~J#}4;{$tYdzgfRVQ=%31t5$uI|QA2g!T;#7ylDm#D5c4p1p$J<koqDEd
z0|4<DNw%IW%n!!okRp(X*s&;s4-gP+&}W7*jn`Xs6AQ!)g{OqSHif}$=`yRm9sAKH
z9>0ma`M(C720+s_ix>WrxKd?_0?d>M$jd2&EkSD3|0_L!0}lsJ90u0OVtwR4uQAR#
zJ4#QGE*z~lo{z);d9rl4JoNm9N<FdKcR9>*Hc$%pl$8*$1VI-7o;MB2Q>JkhxI2*C
zC@gmmfxC~)-LG6*Bb`{%YUTNByV0;bIo?j}E=(L@sBs?RrI2|ClsU5i8&wO_=MreG
z=!^6Ko_Rw$B%*CofW^}YaTI=Gv@*S`mWnRvYZNU){|y66x?y8svT)DzN50x}keHhE
zFjr?I&3Me%)hM0RH>ky^C2!;zP**Ux<}*VB0-Zh2u_{`|FSy@-UptC2!&gD>HYlSl
ztsEheRAaihv~e%m_&FDpS!2Ef+0;>w`)xW`yI~#I+OO6!_6HkrKq{D=HUju_WIBZK
z46gI!F<Tp6&kU(ZZbw2a8m*2-{&FtrCaL;UR{DH1z1GSG3#w9rqh8k@BS;9f+p;rj
zCebES=s6HBGq^DAqUbWA^wYZXzNj37cc>`B;p`#pGHilDw*uYA7gC{eo>uetDn}J~
z#`czUv_oiLb=lIU`AfN=5SzrTHNQhZ7rrS4j`4lq3{lO*(nKq_hgTY!z-b{eq>CqU
z%{H2au*{s97SgHaTdje94BkaWMT0)62;zR4>D8Om>%#SI3<+-yqH)`IO&?Csd!4x(
zE}fg;_M3S3NylrI@!)kl(yCeUctpIWh<9iW*&klIHR9(aCUcv&EvEzC0NTmth{j8t
z!LYSnEIH4y3zM>tRm^qlT@p-M1?0WwzP@U+8mwDN`!aNk+gjMnCh!CAf)gk>cXpiH
zHx1pBnuWER{ALKnaLx#c^OunB5HiuHx#8{bEp#c%g2!<yEkZ>fJUHTCO1EHXAXE@_
zZGBn2gP%Ztn3vcO6LPSFS2;c2a@5)*k{7IHg<xc&IhmC0F7rnrx!Sp=j`!livJO``
z!3oK!=Fd#!Qejm2fc5hJu2W6(XG~nk#-IVTG0Ih$>qp^Pa0F*7-?c66WDz<JVF5|n
zk7WDBYNwka3VdaJonkMzlsIxj^jV^XZRH0bnG=V%&Ln(c<VCtR5#g28am|0Zq6DSq
z;gRs`p`A^f*V35_nhu($j1Kz3fL=F075XeI=N)H^@ZqeLRHZkgW|9QkfkdC1`OD4Y
zO%2vg^>W&W93I9OUMTLFDBJtQU5j&YH;G3$vwmPS8Q+K2xW5D<J(Fg?+4?o$xo*W+
z8m<HRK(|m7{V|m1nMin`kLi$TRP&u(nvvK@h(J(m=YP;4j-!y-5+}l%guV#KiA*k(
zvJ6<9X2h8=U9q<41l`mnkB5AS7~r}f-CH`w-*6U(3T?OYlt#N1$o-@ntK`Jvi^?tH
zkS`ZhsbDdBrVaXiziASxDR`zD9wRZCeoAIx>Xu%Ak-)8<NzEV02Yks@x1*e3<^L?y
z{+H)^*dvA)0zdZBzt4=<nYi<xKhx5~4_zfbJVD-wf~j2IU*Jfhn&=OU=)3Jgjt&Xg
z*bo*CBa(x%BitTlM7E!pe2by;JzxdB+!Hr?d+HKa@O1VO?qRd`k_Nl5&)8?2*UbFD
zN}O%;)!|T}-v?>L$A)Q}3^34x;lWu#vPZhbS!V{k>%Z*p-z4@{|7m;e#A83MFW;wu
zdm>Fsb+^>U=f}L>5T4X>5(;hSWX!SU1fba7F1sP#qV`?DXsYJF>Y~YSyXRhseLI|t
zEFbf3M$GW}EnELhHk}0RS_nVeHIpXltXmg;-yZSgx`!M<%{<A83pO>phMIX6e=o)!
zcTtBgz_Ftn4r5SgL9<~c%4y81mydgaLgVfZ;+*eZh<VhBLf|^if1CdjfyX^L&9?%>
zFE5@VaR2qdvORVHuqOO*SL|aezSsETy?M(xwAGux`9}P$o^kN{TVz*Z_qlzu&S!$`
z``H7bctaxopuGw<an86U)9EFczJ1NqTd!fI4P<WXPF?_ze!7d_SQoOXa)aAXqUaLA
z>4I`y<O)8vcjd6WK}T-UIXgSMkjHd%hX29X6WVscxw&Sc<bp`Wda8eMM}3-Z$Lxk$
z_9HjA_o!Nj{^`uK-}NzwddK*YOz~Q{cFg+HphHJ6dDIiQlQI5S-w##ysRjHX?!hN5
zRdEW;x{W4$bO^U_(^LLIIo$){y2ylN(|9yeXN~UyhuV}N?O%nopJcz-6S*%EvCW%n
z+fq~E`7{tk*W#V<-r{+yv2ES4HqP+IaXA(Wxjt+*Br}btxY7GH=ew@(`<Yq!?qDqe
zO$|FCNbKT1(hIt}<>E76={8~Zz}3CRm|G87pXu-fNseRQ>lH{fBncv|M0b`xc5$Sm
zbpBCtAg8-hV;zqlQeC}KMLb=xI1v5F2@XRgyV`#In|}GB)YXB3Cb(0r)^zBF!F1i_
z#Wj@iLqm1cdbe<Jg|+i)_j$Ehp1U_Jd=s*LlV&czQQ3svT+#bDZ~Q}{dc}A8tOlrt
z&K{;F_?%U!m!l}v!kRyH3j4W{Tb^SYunsexUon|`NDlR4w(fy#M9}F<J@;$rN{xGK
z@gE+zs)_iG{WI(`w8Y5V{>-lX&d8(oX9H(lC})pF8;{Hx?No;Q=KXR&J@LVWtpCu-
zOQT5ax|>8sX71xhl=#Vz-jeYo&rdXj#J~M!H=YJp4Yc^TMtV48Gvt@81Y5fnzxyp%
z!RBbj8ULwax3=xvv{m^svZbU%*+go+A`2@^;(WOmZFR2Z1tn{iRWR$DucJGzfA-BN
z0H5!zI{PB{MEksp<Kx}w5iq7kP94%6eS9M1L#{~#MJp(v4yFEUtkZdxTr0;`ir{vi
zTX*(Lbrw>$E{?Jwul338Ws@1-6N_r-NgS#ADdBv9&A=GrifCTzjqBudTjG?(1H_!x
zh&Y-#o5=myBi^cP+{qP6kQTKrIr7|2VV`;A2qtY_p&)0seW(Xp@AIKEL{Z^ALbg8v
zqrcfc(O}m?PdTmKXk~q<8lw_U)JLhF1aoHOx&A6Zv8i6?OwS5ATxSvdex>x)S|b$a
zciG2vtB(r0g`e97?B&U%{P6BHEWht5MY40a_k$$r@#F3`;Un<7`mTE+vw;ZyI8XlS
zMh(0ds9+#|4wx6c{Y)9M)THu!DHGt$y}`TYQ;1*SkFnJZ`!zpW3Ki`q-L*2y8V^<@
z&O)hLDkqi>g-9#9GhDdtk*?H#gb6BNR(80;>i9|{du^01Jp0>Y!h|%VFU==RzlE_u
z33-z?-F<6Gh~q(xG-u1F2s&?_h;`VqT73=A?-J3xr9&@@OF$@F#1BJ$dzuH<Dgq5o
zE+om!?|Y+BBM@GhfarvMi>j>r=33PG&85DxCrOG$Q*KgOb0J>cvzieRo;<nD-ZO86
zbGmvg_H0FCPPcFtYdDO>wKSMy&Q_M0S28CRz+b7zb(z*_f3yi@!Y?0(Yvliy_!u+)
z&|0U4G9vKuhW-*Sp4Njx5nGL!W1fpKbKuNR?|Fs|Ib|b~tj4L1%zQlfIW04Ko&(|1
z34~d@3m&%XB#KH)Ti0~<9ks-L^ssABsp7&92Db(8QyJTCT^(H^7QkQQKFdoE9w#q|
zM)%BFx^(h)K=s{Wji=_|`{uLL6f+dycAW`V2e*u&U0_#z^5$x5s{d%Ew04#&57cA#
zeYr7Yv+EU9>|*<orQ-VY*S)J68d*`BE9GFta$!#tJhNWcSIM(#H3#80Z%&!Dx5l2&
zUBAh9bf!13RDlVVl>NMO{cT_&FLpAo{KoZxLcjdlNt0`<R2)Q(Bh48~QB1Tum~0sm
zrYX>e-@ElZFT>LQOgdb45xOXG;ttgv+37NwHIcgxo!9bng{xDYSCVs0#hpRlVn3%G
zvx2*rk1bAj-Y4OQa7F}s56iUC6jS!DJ=yO>`{8$nezb=@3bZuF`Oyw#ZVk8%y&0-z
z?Ha`Tc*dmovESCX25=D))uwJcKg%e2S8I~+2hwgjaIm4<usY8kQb})nBf-TCxP{F6
zMRGoW!=!zd$kiKGsWZGzq$B$h4TEsy{^!#8l_8Bu9qOrMxH1Y-qm|4>q&}X8sW%(Q
zElg{hP(w`LCGWdSeE_U$tB%^cI|+_RLpf#IY-)Hn;HvLusUD?<+H$En0}UQF84bD9
zs&p)GY~`Jmp9PvpZ^4INc~40%^43?U<?2f1r(GgE@Z)JDQN-1-Hw<$*x=U*AmdIRH
zSjl@R==4tIG$LXr7NLD%XL_|LOl9G|!^U#Mog1vQd@C6e^C+~@X214bJF2BFYvp56
zwtF2`XoUxFqgp!g^ZvPLsnvTuw%ojc)z?swsCG5QsLQUku1ULadak}d9&;{t!}HRv
znGuavf9olZ^H7O=L(&utU6)9yv|KDpypIY?M--#WQm_o19QMMOrU7L}{k1&swS@w~
z>~L&)$T%pJ-(pF203WNz1S1kL8^Bxm6WV^wgKzGgLUX6!SNQIUvtG69W`2Qx%xp=V
z_I;dh3(k8VNq$V56M2)~!5Q;{V59}utK%Bvk47vk)RfXT@LBoUCxyIq`?yS|ksGRU
zbnCv>fHP&=j&#um{~#W+Gf0KEcmLFKjkQluS@D2KIToCkxK}y9N0qu!bs9at=0Kns
z&)Xs}2l-S}^a-&+iDv4elvb-{n!zM3)w2!z#P?dqR|S<6(1PsZ`N7B2dFk;N<?9bn
zJp%&Om)^VI8E!QCF7d3-D~ok{rEb4u;gyY!iFZ`jTU6$s#10ak`VVNIu|Kx@S3Ix1
zF#m4gk^IF-z0ar5HzO5<i`rt_BVeSB&`Pv^)pX9c$WSu1n4CMem1UMgKxfWZJl(Vj
z>BZhAu}1G@St9cnbM_~&lw;YBq-$Mr!Vx*Hx1DKM@38YGOVyTP`rbO@F@IGKW<Pe~
zbXA^oBEyX0Y$rr?xVoAMS%_Wlxah<TP-Mc;cJm39ta5d&ak5gH?B7T2uWHEDv*m?g
zRrBT@blG1w9dO>eLc;JwgvTY{k(%XwAxt*J>kbzN7r#3`4o}bC8h<$C+<UR|etS}i
zS#YitZ69BnZfvSOq#wWQ@0qYl0WnWvlh^2<(j-Mm>LeLjwme5lgS+HdrL(F0>baO5
z<Cg^s$6I+h6VP*WkLV$7eJ$yHA!Ewy;A!hPtCEAmhp3ulrUq|RQX8r8rKkV=lvB@e
zQ0V6)Lr2~)%8sai+_{fY-U;Bfo*zws)i5iOFMc@fY-sRd9-jDoL#q1l+a8IFZo?5;
zfmpJNli8SV(57lMxbxZbbnTsb4o;#^>z=1u=CzZx2=|8ZwzbK>(wqXFIIZM+wq=7Y
zDKBjl%bn&Dwu9i9-Y)iPOqpuE(#{GwTmN_Gly~&&*!UOk*Yfc?{0zG=99zdf8)H=&
z_P!z{IWM?nq*M5L!_TIQPqlm15OoJgF!`crgmUGI;C~*V7Xr=BiSPIY%5H9L#>gNP
zM2|y5J#*k+F_veBd(sf-br$TTe#<I!6&Azuk0smQIpj1?ekka;cJ$rdlJ}+0!IXP{
zq{B@Umzo_Z#!K}8R&%Z{d2i<;nt$J|A{+aS(5}|^Y1MhRb~pt<FO=*MN^2HtYRIbb
z?P&Ry$ac3DSY;6sjxF>}NJofyR>m(i*KV6<FAfW_j{WS$p4utn*{shm9B09Wm4bm|
zb%n<gpUz|rRg4p#YL0OfPX1biAbe}DMh5pfmU9Q0wsIHZ7C+~QAFmiu?29b&#dJTV
zq-)n-#DjUh?Z#e5vYtFvuD8gtC$j@deNQ_loa&G3P55B$r}yAjJZjv%8@row#I+!Q
z?7LldpG7C{=l5Db(9NuZ4Y1Z+c}XqbOUUnDxo-mjPu$QJiT3!;MZ?wBceV3;*1oBi
z=X62Qr$Uu>s&KnFf3vbt4Oy&J@vNYtUeXR4k%}aAgek?Zxm;UJDms)mr5o}?d??@O
zW0avPp{QWZ)e-d^1<+czTChr`xqj1zgifYu%03Wm(;@J>BXhqa=lUa>!y`*M=JG!J
z?Xdc?*rSuk>y30PwfgI%iWP1;hRzuq&T`MJPp5~>K}+{FeAZvI^q^Sd@D!2C2x&rl
z;!do=8r!MUMRlqv3$I|BPYw|wgQD~18eOyE7}?FvKx4`g!{$Dtn_1X0>R{XTdC<!0
zw?o;tw;#av`H>0{TC!xd_M}<e+Lgm#Zot5F$w|BVN1bH<PU-qMzGc$^RMq~T;fT^&
zzqKJThq)cx-kj*NA#?i(%k=GsC9`n00x!sHexkk)*8gzhDtey7U3g`MCVPc?u4tQO
z;gE{@o%A!c`A9^Q2lhLP8&18PSkoLBjjRLo*mn~Wd5v!l_SA2BdXv__vOFs{{|K!$
zM~i120KUI5Fv-7cyJ}<LxcnnuI<rBr-FTAj2X;#r+Yau?u!NNxZ%}rOTs&QLzz#)%
zVD;Q2%U0O7{^s&F)rN<Zva`RSHKW#ynUJf4iV7E%XQ4-nSI=i$%4`+CQZatAI`+n6
zQNu&KRu#$q+9ka&;w3jOqwmKf+9~wRjoE~C%CO(2*lVOGw9dHqH(}4p&fn)=w~5Fi
z52aRm$4uf6{cU|EH2!I7O$QE5jD5TnzQZ?Q+t|l}if<~<^yRG|6>#<bM5Q-PQW1{w
zb-@qM>I;U-h#k2aTi-8r+Y~eb4U=$te<QzmOk=(>cu~QXZ1rQSqW&Zbi!{e(bO=L8
zMjMiQ$YK)C;=QHA&WS@uQ-TV&Dhs&z184ea2bx^?`5X7(b3;>_)jSbY)}gvlBw*Q^
zAeq<B-1;y7j$K}B9X}|F^e9Rh^<ij{GX4pk&QldH;LXXbxOYCc6h;trJnlNCf$hWX
zy6<_bL(bGHJKIf8INPVBXw+5Y{cQO9IR4vJi=JJ#26|qf@PTaRuJ=W#OsS9;e_z|<
zZuaQqdv{MXa<j4P&(yNIltp)<I{`w{YNDbdb8mk26#qb0v`Wn%Vp;nQ0A;;l!BF*J
zAku{!!1RCz5=_yWWWuAy$Pn@h<#o3y?6TLNbns|4c?Icix8)BxMhz+ZE!z44UYkwP
z{1H=w9+-@L1L<R(S8aLXzs|djV*kUo<1V}<C4a;(W6RVH(#qO%reMkEywJG18l^C>
z3aiX+1_pFAIn&!N-|w_vtUF-#!3^076yT;$+efS`KhV>v&BlMFC&NtNnz>(iKh=Lh
z?_bmJ7Hx{6=&Y;CWrrAFF->ibZ>5v(14qHNAYfK~mG=ouLZ4{OL~Mu-UIY7zWbhi~
zTU9ZWn_l0v!`JBM8l8K9#3~BE)#is)YSxmm{uzpfa;hmGUt828RjAzL74k-1iLqTK
z4-JzadajliwSGEdyPkhL*+_{^kbBTD_8@jWTUm}urO6p6K`|G?Oo}~GMa9pDz?xxx
zM(|Zsu{!Ki?_c&z@%?6LL#WD6qpqT0r7#>6z37qz@>9&tA>eSA{p`O+twp67u2(1>
z^Qn{j(W5tSmu3wYq_@=k)8JmFQ<P89ZZGaN8EaB;R6ST5#q{2jJ959Kd1rK`8!t*t
zLv`A5e8Ttsu;wqGyhEPwqV>4`!MF8?PgQDwhd(_cL-La}#!YI7$M8?vIo1{;+q70g
z_;+vv+<Y$$weCQOSfFAPgh5=?;yE7k%QYxErF_2#J&IMk5RHT%7--4lHGbx{Uk8T#
zkY&4Ls#3Z~N;UGTrAT3kP>Pmt$Bp1!xfRd8X;Cwu#Y7Wo9fRUFZ4FsW2;HQ`;LNIQ
zG+9r28hEw!@UIuOBxvpHH`c^dJhIXlHfHmyCU0f_9~hjJ3CE>X@7;s2zj0ffM#NAw
z@3Mw2tX0RORM50n)emFy_7Sm^TpX^?rtc$#=}n>tQbZs7(g^tC6t<>3iK{slAB!Wd
zT|-o)NaO9}@1~IPhgB44_M%spiTOk&$_bn@rCzin^$)z1xQ~K|IcD!TA1lTi#H`h`
zw$H5oMxw56(Oy`g@#?ZPo`%z>+|nhkj#bMar1-$NUkX;LSXHJ?$I}W{5Z6#})w-7x
zk|}!&G95ny6rFW1E9N`aYoy_C04k}hgD*QDvQcca4TZy^b^$uu-EpMQfYM9+x~|tz
zLYd(>e!;(08Kv>r(c6J;;y21i+;;;%jEM3b<|wGY&~)K&!e>FX(Ha7v!ZLCf%%^EK
z;?chE^~H5+Ex6vS%ir(6yne)tX0&=noZWyHpCrf1GL#Y1fbV;<w_naBel{uD_xiWP
z;BO0DpePt;v;Fs;4J*vetX8d0AF9bbZ*6I()Ii)~NPJ&2FG#0IRtp%qWO600p-8uW
zd)5$|7(khMymJli{oq7vrnAdo@fV_;m5ctr^A1CT%_@kOd`seL!T0&g0v~Nf;{5~X
zu4G>R{ug)mbj^_#v+hN~ch!6%YKsD}JMEuuL-&FU8%*$Vf{j+>aKT_c_b@hq6{2OR
zg3K1AZ}b%0!AmR!F^Y250$b6*;$J-0SkP{ORuGUIlody-zt5`*a`9-npE`K=iuzF7
zIJDi|MRu2X+a8TjG}Jpg{{uz&$o;XAPT{5-ogQ{QZFP+fp8v3e69}PPTJtiH4>r9!
zh7y2F=nFoQ)tn5tQaWB9ePexq<qN;?h3Ue$B3EjrP>jaL%Kouay$;t%$N>n&6OQ$d
zQ%on(JGOE52e7LU-TIKBYLZ{Sd1R?Yd@%BMQeYx~9mW%`pMB%B8zx>ZLIhW{?dE=+
zC(z-ldY_y$FQ~#=xF60BL#hT$XBbDQ#2HyIej&XrtO+G?zDy3!IjRfvTmAIVo0=47
z`WOcNRfWAblD!rpB{-}jb5@jyPUr8QvU+CCIK1#_7aZJXzIs0yVTrayuKKmk-8tq#
zv?(2Z7F((LvsWLE@Iv|sH(9vTai+91kHW}z(x<CE;ejs-Lh=JEc5mhcCdX(V$=aYG
zHd95Jxm~VTD~Qp3CHqt*)cNL`la|krXlIsVbK$mclzBC(UZiWVu+#K8Ji(BQDR2dG
z`ZJ{>r8%<$ev0)7KeAHpU7yjFuBx@k4OQ|5`Ny!aM303-ioxGzZc115X3dFr8F6aS
zbQZx4xh8~XkSW2?p_D&-ZqmD+(#6#b%LQ1v?tS@BHp7g~s*ZD{bgn~kRa?zm!`<qh
zHPz0k6w;`G5jYsEWjgK{x(62=9X0+&bwA7%JjY{zRj10;Ump58Q1a?q5-$G?=&zGr
zkO)Aq)-uC#ovO>-jIpxYc&)fpi}(+UXY#wfZ=c`J>ATaO$o*F8x@Sf^#9;lw$L&QA
zt$kEyv?nLnYIQ2yUuC0fl^bp8unWOwCkJ;`BMTw6z8V8bO|04;hGm$pmrF%|Ud#%4
zi*%4!<UuZJs3x?AnW6YI8k_!i4`oRH@4SjrCiAjEDe)Hq9UcL{oKz!PUrs+-7K1GJ
z$Atzb*d-1l?}Ntgwc^vqYMKdIx_`g2<#p^)y1d39kTuM;2UKf64jv6wlaw*BPUTGE
zp*_9%9UBQJf}RE6ZtXsY*e<VHtD=FdZ^c%M7P+r@cWD&4CO4-#v$K^)v(1x8p*{%D
z{f#p=Avo`3y3$RC?hm!lKx94Op0_APHHKOWmCBlaA6><&2pq6*|Ky1~)a#xkMzer(
z6JVXx?^0ZuZ*!lP5(;{FRhb<S801U$VfM^cs8y*j-&NB5z}=gL6USly%=XtF1;1J%
zhuL?Y)=R2};}9T7xcStmZC$o%Yb)PVt`8mui{l4bSf0}O@HYERYx~U5*Y9|H!glbX
zsh7J4m~YKq>U6XmYif!dXN{I&xSV1D&?E~UKA2lNT<ABs(>(a8-E_<GjL9>_@7J29
z5T;=;RId-De}d<XM7UCNA@i$KZy=UA&r8{^GZnsy?|^2_S4bniJh%IhhH08(zJJCG
zAQ*R=J=XjbN5}w=DIJ3lskV8l@l9~MRIOA5MyvQLLM<wCPG~j%WeistK`jhxU4(xo
zMixZW!~rs`H(lzCTPly?aSj13hd%B?o+syD_)=J@f9#BjCQDk7T#SQh)!UnwauidR
z2nE%ZFLvl}%T>2{@2<7>msefQiMq$_oYIau{KF%qx_VCnLGQ)pZQw6s>FDL_!B02!
zq^zZpRa-bmx|*_@tOF4lBwjM1{E73?(!ygeclkddz@O;L-Ak6Ncx-Tu@+od1zk#j9
zuxp=uJI%)Vn%PyVz!oRTw%CsEX0u%`O2~$vvk^RB0*`%xDbh@IB^vi`O1nJZMW)>0
zx!+Jxbb?7MvZbUvh5f0-IV_Lv)yKcV^D}dDo!mqqzhjzrqUB@v4?iuDb{C6i>vg8m
zI)W|#EnaJSkVd`bx@qysf!}v-T<p7v(ERhA8v|EyPi+W_|64`vkMkq^>|NM4oLqjH
z{s)D}s(6hi%I_i)kTfejhV#LURGZeh+ES-<k377?+2Ml*5~si%?wM=kem2j8%qQ3;
zg@q1tw~@oa%d>npD)*N&@FjL*jynJ}UCuQ<^n5(k>Wvm$@wKIj_K#PjZ*U88`ISuF
zKUx4y@#8}PXBD+GZKGbE0fxrg63=az3fRgje(U+__*pFaK;JZ74o)-*@+;TYnHu6b
zT5vkz8;t%0Z7hm9s+iYtlKd(p0@>=KD3(Lwqhklk(vq*a;*Oe6rFu1d)`bF<P3(E<
zii^b?gYC=@p$;BE)DbO{Ryp568dPeqy(LKP=4q>T7x-J(PK2-K^}Rwgs$K{aC4QYJ
z7j3~{uy7Zg3PtNN{zd~{Vql5rCgWGNF@Er@DRO~tVDfp`Gr91cCN}{s)5hXJ+S0fb
z87kPXyXHMF(dd3b;&qqNR1X)kcWbvDoOeYJ<U4B}dfE`y0F|TaXZe`~PP^@OfbX~I
z=6sdb2Trpk<im3P<!W&yYM%gxvOG!uveLl;K{uOrk`pCz__Vlk)g4=Oz2Te6D3mN)
zP=RQ(-zG2&MMkQkQRF={tFi4)L<9-Qs;1zU+!aar87mME5^FuiCU6o>aKsM)*jyIg
zIW^?@$!3P$*4IqSA+TKo6zB%<x3HWhM4@)FRME3sjRk+?Zie3CV&$9KnZpUx&;WpX
z7?7hn6qhI_kOt8iWaAI-laGXt{y?E~Q3Y=~2`RzxR`P3kOfwc6)c|iJ`abtXBUr1l
zp#UtO6o^tOj8sVeS8bG7HBQJj)fbLempfq5KPwT~T<f7;pR$Xl8?c|6&mrbr5?qWC
zBm&L&H5Qj(brn0l@pzGPUt>i;Js&Gq1bp#1VR0})SD86DNy)ksL=l4t>tfOEuC-`p
zQ;dYd3-VU_6sT(7pSU(r-Lx6*Kq~c7e{%>YzgJPIE*?NsMZ-6dVKC;T>P{v*A#VQz
z`Wq)~`ULj3V(#g)XjLVGs?l1FeNLw%-5N(y(67|iCu`J^^(j?)YXV+q6lz#RGXuD;
zob~kUyU0IJK_l(e*NTrhs2Mi7rO+JUEHu8kqS*oQ`)t$H9!c(e@QhLuEgVgFAPHzv
zmai}Neq)4{D<sS_XNt~?+4!q&<e~MdJCSvY9$0LAuN*8g)Mx>8v3s5}Mb-|b=y&U#
z?jc<P^Ha}k*`Mr0)?eLr<0|YC@@)`GwK`+-G3B(tGK>BV?iYnI%1G0sA{&KMAOezd
zwP?{z(w*9?$0*3qF%53$x-nFqG*9)Z*81>)CWF2s>k;6KQTJPlcA>T0>9&-1-i9@M
zb2IJOCU?OScP&rdAIPouI4|XYob|6g>hSb(x12;2?CFh>>yQspxIwqQZpo`SJxX4I
z)MM>X9)>O$i7|KHs%4^_)xbB%Px^qpG9<5J5*@YUqWIILUrgGe>a!}_=<^=%LG3pt
z+ru@SI#8hRU$|-n_!jy|ZaHweRKLoTv+abHJ<djnX(3p_`6r9gXWK3Ndb1qWY!e}K
zQ#Xu<{^1reHQ$4Jde25R+<4TZPnZ+8_yH(yZDlJ;b3Xpp5jf@wCd+}j6ZYcyac9}x
zT$WoVuOHjng3JG<)E4n8q2BlrxAb5yGkQ&3t$bXZ#xEh#5UceX&~WKqGoTsc<Evcj
zy$ba+So<bIR0{I3qw4n9SndO#J+VUUr@==Wc`dfMQz1sX*7gM29N#)~R$)c7GDU!$
z9_zaan~X8S)*0>>tP7T9cDoy3+65b8UgyJp#YTvwnBi5GBkd<qW7ap3YnZBVFE95r
zho{fFZ_dd3RIMCh>MB+-I!wTE+Un$jS+{xv`0FTL<h}NG0MJ;lIgj||pmztrZi<0r
z9$3*|szDFxR9UT$mD0{2Nv}K0o(t)*zhTVE=N&&=;`oUtZ8^_xqNMebA*rzgmKBz+
z{5vRR^>~7V;$oF@!@#jb2mG$TAIGm~$~oYaI(Iu*-gqENyoht~R;UKj{6rDW3E-2?
zKSs;nz{_q2>q8_VzQ!<iz&1Gv5=EVDOREUfmAJ|Mkl6ie>JfG|l{(EpCN4DHYKP12
z_KPqc4m6fJNpKNDPY}@)#!}D{vty=v7bn_mi9XQp`>O-1?6<=|^z=(jv^Q<@HspyE
z=tDp-=kwBZWYv<%<>&?7jJ?kY-TlY&)Y(Gx<WY-cgdz7q%HEcwBQ*LcqeWww5KqP*
z2q{w9f}{-@Pbfwa1WsRh-bg~c#IN2*Eo0o3UCSlAaXTB<tB{5UeSh&Yh1Sm4T>&|e
zL_@z>nzYewCKa{rngq{xhQzQA?4Koh9T$6LS_(JsX-eYblzqj74|!gXTB@_cg<S&F
zMUM?n-?SNdKG8aZYlixHfvCsd4^zk&#;-@Tdl(>SRFCvkKMDdo&}vw6Ep6Lu-%5gb
zn@hNssrCU6H9-J!Br9vO7_r~Az*=*luz7AbY(-WcN=$8Q7OV)=GF34<`#G>Gi@y)n
zqttEuG@@#6W#7-b7-XOM9NhE>&hgty*_U8>Q(~uE!KXFaZ$%zA9EwuJ+!D(lPYl`~
zwi`T877Zfdsm~m8?Sb#BTOyjPVCCP`4T|((rZvs^QGw?0oodW28LdfJSXnmNiYEMm
z!?)+AxfQyDy?-w{XXa7dC;4z&vqZhQt&@IMviJ&gA0oJi)u>#=hmZqb4}Q|z$e?i;
z&%~|pU8-QsJbA1ySu%F?JLp_ct`6c855vWmF@r`P;^PKSOx-qpcRnopNte_n_8&{@
zQ7!QvBib;mfICVy(Nb)Y!ZnD_s#i?|#-<-nci}Gc+;RDpJnyX8NWN0UZMb;JIxo92
z*SA&f^3?;}rt$P&^6$3M(g?|5+Cpl`-aE(cpY=Gy<=vzFolGM$V?UZd6+e67rr!!y
z7KP3A9msUPVUwyZE{2_6jWjJd<JaXf%l{hX)cV!<`32Z19s0^9D@yl2RPJ+L7HH;z
ze<^yP)AD)x9sl6>2A`<sSG<w}MtAoM8wy+RpGe(0`l{>@p?)rU-x|~uKG&?(dSCH?
zOEV@Bn>f6~tj26B3-OvcI#uH`YGiJr1Kw=1qui>tS8LNmP?-vU?v<vc8~?O=6UDDK
zh2I*PMD7s_-7)3Z$zj`f^OR!r2u`!86fa5Urzdi?-jzBq31e}j5#Q2<4aWTrEp_i!
zRONLtj6d#I4$#JL10;2pwqn<rFyMK@ql}g^0xc!s#jaIL*F)f|DphW-pGEV0*96sq
zpXubUZ{J>NE3jncq<#Ija)q@}Gry&_?~i>ZQS|frYl%7dU@6bhjFsS2g-UX?xV1QS
z`cpM&F20O7Tc(E?2sD)sdtTOGd(-(&eJ{7`KzeUPy(nFR_<eoamj!2B&;8=ms^;(+
zc5U;1WO`=4O@=XNPV;TKKk|t79e8tyb0yShWrB!H7thVNLrq2@tW5rvZq8p^x~?bZ
zAcwaf+u?@p&#%4&?3Fo@_-@68>Qgtd62zQ6ThWPfG<jX_*EEkEr<N2WsvRANNxV!-
zi10fW_kp|6nm>q>7-^GvcnQgF&SxYLFXe|rKEBC#lS;gBww^6<@V}R~p4<IWJge_|
z!z)0p)^{>k`;nl&Au{wjr?u2ivyGV8`-as9y-CSSWfTw2Cu^j9l^Cd83Ab#M*W8VU
zx*sV=d`n*W#Y&VUGJK$@TkLntMB*gLl|SLi!Ko|NC3!ippDBQ7L21sW#;a@M-v6;M
zOq*;WB>6HkuEyc;Eq+zqB>I~*50#qkp|t8zYQ~YGsM&SR4F!8v^Ia`@)&!rSni=ya
zJZ`F`{#rsgQp1+}5&k#}?jUxHQaqiYe7?)`MR>a-2g#>s^XxWCMxWU?Jsx^J8MT(D
zt-_In2XMwMC7Kl~YZ>mBKE7V%yw@3#=wiwJE&5m@<tKOh4(wzPI*+N3L}KoN^_QHJ
zTe<BvH;31cgy2@MM(VXC-RW&r*p7RSyMnwi&KTC#UvUY0YGwJ9+k$lq?=sr1CC4}|
z^S&nzkSAR-T3KZ?C*XeetyAvk*CpvIB$!kyt?s_6e8SnGZ|EkfwryzfP00Cn?%Tx1
zrnA0#>2*{)o|ve7C8xuVR%UBA$s%sB)(kO;`$blj-yi%w9u7X*ay5_g=*2_Rm(81d
zdMnq8y%kV$k1MII#`gCY?lqqhcY^_mYtO)!R()P6G2Lo6#6s1lY)*`^P+l`$XP*r^
zQWATB)K8rD&kPs~{{wCIo`$=8<YgUbww|bjzoKdHRLQ>`&sg!P27?jIO}vsA*2el@
zo2OgAC>!?pT|w$sHCjHYM7y21s`u|CJ&zwa`Rl{FJ5bcFf~22->oWuhe+i74f0|2}
zX6aJ6T7M)k*I&_#pH(MVpCrRCilk`~s?CyasDt}{GtA@Bx%H<PAA8T5uHRAlu397T
z_|gT1Z6nzM_qSK)px)uGRDDs?W`-P6=lvj>_=fe|H7E^nR!;QMlxS~*U0AyH!z^Ve
zh?%Vm{xCf9$)d9s+S;>o2TZvTtJ!@JG?!PaiJB}c>@a?MY{x^xZj^QM;<lcKT+-#)
zm15U#zoPysMt55rKweJhsGgUG6!f`=O-gny>9a!XPo*bHcW~@T7YRIdgGmu_^rO94
zvZem4=5N}YSeI?t7WEfCi~<i0<`g&av;;2yC?)U;BerLa#bsrTKDouAmp0~yjqNoI
z-&L-fdpd3yRJ3Tucs=G}tWTg^EPs6z;0}J1=xCmJkJ};*mKcTQ@HT^z0MTK*ZgInw
ze%^<`CEZ<K)(Gow$=6qH+<8xA48JtK3Mqx<e5h!=rk~7GJ9C+(08gmu-WkAMOBZAg
zk#7mznrwG>DF}<BIwIq5>|zPtU+({wA8eVWwAHSg#MkiHZhqD2u#LCE%6Vm0h>GJB
zjI4^N`0)<-9`mK$%aYRE)A~FL%PMcqQQ4e<y?bx!Ap1|r=fIGQ$UXw>-&u=J;P7}c
zQo+ITN4Uu;xBgs-TmdD2=S{%<;`g)i4SA$?CBGNefA#IXkLJy%?ak_S<MVCJS&I7b
z8@sAq;06lSN&fQH>$XhaMlxHY?{eguCGw#f#IHGtxX|Bm=Ig^9{A-VKuJ@I{2zPvg
z6}C-R<vRz$UBr^NHF0Im^0lS};e4Izkiuaju7+4mMWIAm?O){WTlnlY=7GHu8=u_g
zz7aXeM4~Wes7P_bu`zqGr$LUK1#H|JH?P=~`CI%C!Nob(Zar(Yz}~K7v-vq-XV1ed
zZs_C4q7@;vD@G^yeMa1bT34?2=tv=R^M309i7IXHp)=;{R?m#fS5=4jsSvXayf69K
z?PUs8SIN8Eo2adHuAO%=QKU1e_dy>simR!1zhu=mW!RbP80WHmEUa^riPx)#jpo7S
z-z{CJXH}Y}em|2SIGxboReBUmo%6FC5e7s3_7^8sguN@=-Vh_rUK@Zk3gl8fwcabg
ztYEAq=+}mQH`ch7XaM!pl&xarnJ-~Dk+j8U*p*nv47ay_x)Y_h_oii5MyPSTXz&mt
z+_V#cO)}AVPsd30J#UB9g{*ze<jQT%yxU5GBXaj>4<LPpgKi^JS|qhYXpBV)c=VEA
z9y&F_3z)UFY7Pm1khZ4ct!~DJC!svYNS#xg25#2{n%F(N-eEAthdKD}-Qcq8z9``U
z&ueX_4>o15t(&RUfX!Z%wVCr?yFB?H611|Vq~uKBSssAg{_h}Le`lM*mXWR0jg?m^
ztDlZqiMWOb<_r4P<Yp+7R+P;)Ge#aOevHQ64Vx6255$q3PaQXLAm2;gQ@Hv(Cp!6G
z;UU$5gYw1^up4Eb{z<%<Cn~6avFn4_EssXHj0+MTMR(E32vkQ!8J)Jca_(xBiU;hu
z!jT{FKOZ+jua2Sz^PMZ#9H1iB&+;chE%_88I+dKDi|_BYo^DlFjC>lR|GMZ>bsb5v
zO1HMm@K3n|r3Sf~h-<>KBDcsDl_HO$DmfD^1dN%VTT{8M&*yV?ue_#?x+Es*9Zr^@
zAf-c>Z>#ww{C+lTWYgW?gm+vRlqZbKt!+x#1&6vjK3nG|2CJlSwI7YSBIU0(&{u1t
zJ-mFWSFW8`v7Glw{b4<~%I#3$V{eZMtSKCD{^561to(7tMV8F|I}9%1?}i+br>|?G
zBg@+CG?kODQ!I>ibef+5r$g^zt=2fgk^+dYxIa(VBzhSbYL@)mV!wmn1JvdP@wGG}
z^4rv+?Ih<~&m7LvC>+0}^C4}}yIXj=gr`VB8}G}!Zm!gSSRonQ53|5UCnLu;56-BB
z#;a?E-dOXdUf7z}5ZW#NxW$h<1fI+>Nmm^m!XzbQ!9g+oNVZZcHub$dF;_Q&{HsNL
zUVODJMC?g0eKcU#lM3bVs=|Qz_o*$v{dm60#x0ya3-)XaMSKi4acX1w3a4Vt8lAPl
zIbRk`DD@PNN5d|2z$uk0z`AOr#u<lf?aW(nj+1i8JTtl}a^)Z!2b%sK22nSetG&Y;
zlHMwLGjp|Fa1FMPyl1=$<8z=jOzdVAvxG)Dd#fG6AG)iUP5O1DtDuUi|4v5~i%^!g
z&fDi4D3}L~V=03`<v?T;xJ|vt^6U7`J`g!0p=Tw*Ebje0P!8zb!S@ncN*oS|&Zy41
zyYW-PU)@$=s;&b427X}gsY9}#1@Z~-nU8uudFzc|8xLhTN#wXo!f_-^gTIziSONUx
zZs2D-Pi6hc2w~PFV$EnM!~vq5P<#-sYhTUA>-ef0YY!LqCXmK$NZ1fQMOX$6uFLxy
z$G&7GZHgI^3mLfb^=})eIL|0bjVUFj{JcGs0Ns@<J(4?U^<K&`a4VW?srft^FS6;4
zmwzZu*cUbq@5&e%G8tQvSn-T`6j=Xr<9-{aPamA$8+jP9)=l)STxE}u^G5EYKuxcN
z&L{ho+T;(8C-w8wXZicFnJ1oZ<j0Gu>zLaO_rNoBl2I1Xd^N&z9d#Jx*GAVAdXj0l
zO7F$E+W*DSnLje&|8acxW*dfK?zwM`+*fnUQF9B)mE>I7kaG-~wT`c@Pp6|pq$oK?
z%q?A%5IMWHhETcL*T3+7|L}gjpU>Cx@tn}bpW_{=Rnf~k-y+%sh^XNm!A5v<N=zlo
zOeG((ViApn3aH&P(uS)~j9Dyl*#Zhx?2x~{ld1{dmi1#Ke2qKhgxF{f+^m$RMTGqk
zbgJUYHhy1{wNm*HcK}(!W75Vn$cQ`KMKK!K<a=1k=SZI#{E`5VcoGo#S9`#$Bm2+g
z{6})>^3m-`I)N(DKQY2;IE5Ekv`&+DKwzZWKFQnYzugQ=fp!Pf{EKIm2@%cmgjBOD
zzFVY%32~=|M4$GlJJ-sjIq-+?y-<{`v^x#{^l{$92RyBgYeov@@{=wlSrr!~+PI~f
z+EI+?fUaxfyWl!y1FDvN{}+djf-^#0Kl)d_wonBZZ;KU9cf7_xYR^5dTHOYzOiyu+
zu?JeTg!nj%{ko!!NQ-zGK!dxLkeNARAqO9bGEAOn+L>PMGOb-c-`xqRZ7DMLlwffX
zL($F-!j}g%+wjYJT(EZ8%?@QwFjxry@Ly$q8hDYZe!!83E#=Khhwz172td8hBgEn@
zF2TNE``%W2f3R4=PMp!1(P<hrUv3bg|2jOptY8&HK|*knhm^^Ssijn=*veUWtN`Eu
z9hci+9)z%mF}|3*&(JZ?rlUZ2{0ID(O~RTQ88Cj7ckg5b2UKY7391UdA_CNrS0wrs
zH&iu#OBHRf!-9??9R!8qxpUj+#(mYiQ1?~N{N@p9G(gfd^=-IYwUqMM=h0JmcEe_0
zEcb}h7~en6lRLZrt9_&Nwg|)0KU3sJI^=M0!oFZQ1YPV1V@@%rP9$tm$BH0ke~22&
zyNnJ?;q_q2mjS&Hgr(gfZO|un;~(@Ga9v6eY*o;rU#~S~aU{7+isL_#c(7y6)idRx
z_u?b>grU9#bc`6)cATyL3l`Ix3)lyZMYJY_>76<=OVNSEP~gJ5pjJz2m{!&|=ANNu
zd(^l?>XWd<?Z~F64D5E;6z?zZKb8V$VmAktvpdcE%Fm7)K!Z{5&z$p}k;_@9fbIEm
zX<jg}pG%4)F8$~2zx<HKX~bCOX(Nl3<e^wBbxAaRHsR5{R~&bC<!)K%QWqnB*l$Mn
z!RJydZuZ_EAQ|}#{$wCUKAQuK(+B1V@V|J?Z>|FhlaIe8W{o?UDz5G_U|+v)>?(@;
z!~__=?fDRNr05QK!%W-2crQ0saZ;wy?xSXKsC)gZ=3u9<?5!Y!rgtCp^Ia)M#bj7r
zse(v|)gjwl!4Mgau&~EaFx$DCF=gJEb8uA5oppNFkLiDFg)AbDtGwQVz1<;e^Y^-y
zgAPs)cfm@j5=c&)?a?!$bLD4sDPsF>C|;D6gZc*tk1)a9iq~(MxxUT6+cU~q;Aehz
z74%UV<`!=EYEp7_k=1$@pbMF^eL*-MzG`kdmi+HKMW{kRcYGjbN8i9xpK+Z)*FChZ
z{-a(!r_}i2fs4-_uxkd$!gZ<PMUmDI2s6RT4Sn(?Q|_oM!JOcv$EdCDPGPuJiNR&!
z*62&(X=~<86O{AuXG)pnDL-;|%d?j#BZ(j?)}lOOzA-HrA@2kYmD{4&k@~&p<8_p9
zJj`7S=UMR|vM|YHgDdvS&h}8e`;{`t2`dQ^NJm1SvgdaqFuQ)8KV~}ja@`qgvugMq
zR(Aw*P%Hg14Q!krY%Axzpk9NrAU|5K3?h(li*`L)b5)jrMgG4L-dNM7m1^Q&uGhvL
zq|7@WeelK>$_L`>@9HQtL#ilBJigoGY?rHhGVRh=T}oFB0Yos7E+VyF<yLJvIdEU5
z_}mvsnBxiO3ZC!B>RGE;#C80{Jy?3dlAbc@TSix)dvL5k@z2y^;PMN+ROjxLV(#_x
zJw!cbOokqRcg_i`aP0%P?;jwIu1RA)Tc`3uW6YfqsjUrRT~x*CMwF~CH@)l@SpnL&
zb%i+wzTRO5^9@a<dqAHc6V<S*igH{^)?)C6HYV8KryWYMJZ5^86b70CB|d%8@yd6f
zsH8dzRugH%#2he+P(db~g9I^@0(z<#QX@QaSIXS|1{O?C!|llC8FBlmD&~*5=?ZXA
z7w=&<m0(%WRmkW8HMu^>lT@m^yGF9T9TrRf+Ze;TjZU4d6+?U6e!*}6^|Z(laqdDv
z*Mjlfxhx3H6XKwjy~4fvGh~K6CgP(7oIC_+u^C4WtHEK8yZ*D@wD7M_<1GG`6ao!p
z{So!G)TF|paPHqf_Ri|#m7aMiuepB?J}?{?Be{IpT(SHIO<Blr1iVQh1(@Jt!Tyq!
z6<W&LeXi-|O^fZC_sw@WWuIKcFi-m4(LrSV;F+tZ|CcC4DO)|XLmr!WbLlx|mnhG{
z2-TEz;lGH9HUe+^)>>Wu(RSKVvoKF0vrD)E&vI8|ESWoA|6|%9ZlB}++wj2{_s~C~
z06R|gN=|=)O}KpN?!WTm?CDD$rL{t7_&ZXCMczd7GDp?aO2?r~{)%J4rT^|u<y`x3
z1!IeMY1rvR0Q{J|4(Ej!i|-MW7i#>Q$STY{dhac0Ys}Du)4kJT3pR?qNYg(5S&_e+
zVS@)iA<`=X!B-Q&m)Nf(M{<|Rmok3k0`WrT`;l$J2S-GutjN=`_QyWWb9c7I&~1)C
zfqR0o^IvYQAuUHC(eb#^i+vmf?<UkTX2yHSvNoVaaDS?K9j-aBIB#7=JzVPt_oL!V
zcD}pR0(bkV2kJKD_V4=F_v$LbQ&gXA)q)o%em72|pKUBY+XQXbf)-mm>UK)!rDr}Q
z?Vqm%QdciEWBS=UIOueW^!!0~C6Thu3vS(4Ol+67WRxx?)^F+&kZc>@;J?g3bKyd+
zY_fYBB@c8U^aGx`H_1i#$lr_>4B6^Ao|O5mBzPOxgb<kz|Alqe&ua~Ix?f~gG<*-*
zhDpo*Q~(-2pN0^b{)0FD!m2*bG$|?t^$9zlP`1PiylTiDdKC$sro^&EPMXj`tFLcD
zaiNR?^%Be=?z~omSJ5(9y+btF5!&deOKQZZCcPf(2|n9P9ryh6LA41sKr|#c>v|4W
z$RAW3<__(U&YIl!?1}~8Kh`1hpw5^P(;#4%@B7%%yoo^BDJL;U38=o~4bJ$Be$|li
zi0P_g8;}pT<Xm%QY8>FQtvbCqI8j-oGb0wr9S<;i-Dh?CXx=*GN9;N`+)!VKGVh<6
z4L9N|Pt0iKwVc~jVl4dNi+C|&eE%0aL6@>?c`LLjt~zt4_Mn~op;_)N?{@q<H!NSf
z;~+#hX%O80@t10xMD1g{`GU2KKN^*EnI9<`*>L&LzoG2;Fm;$D!8^gv#}pf#%F?N;
z&0Rd|0<5de>iNu<)>?XLp_Mb$ux{`=1*4RBGG2)~!&=}Z@GPADL2;P9_|zC-W{ZFG
zW#NJJCck+wh8wiolD3X<s}-}eAmN9LXYYt8gHGVBIY%0u?jL?<-@PQulI`}+)Qx$R
z-m^L@bP&i_^ZzC#FD5Sr?<HvyR_{`cUY(E>7^}rRwbI9a<0v*XxadQI_1rIAJP50o
zjenrzKhO&WL^#1f+_vdolY9-v?>6!K0KfHwDl>6NOj9H#MuPikx5F8jR)?0KppG;>
z#Cb38Cs|fff0e%TZn9bj1pMvDv}B^#@Wcy}GyjPOczOSAv*MhdcA!cAC+~FK`zTN|
z4Bg1sHO|vq;>zt*rBS^AZxF~VBTfUUW(MK8MCquGyr%V3b#VKyJH5FAU2FFqCX$=h
zu7Bm=e$-Mi*1Re0!Niy>8Z3go{DIbA69<h)BeL~@(BD&){t^3uy)IuYrZZm^lFX!=
zlNepM48%{|yb$yLIU?b42|;E)X22EWL~jSqf=`^6OW9EUCVcgxFykV239%4=PqoE!
zX%J+)f91OVVClRQUE-hgb)2f9H|Cd50_rGAE%ulv$nTEY;}oZlV#nvd*Vqfo!k#4M
z(m_IHYS#__hoK{Pm~s|N*I!7zFRlsbe5?IoQL9}leeaw`0=rmg-NGXJxbS}-LjJGW
zHYkV=U$j-}NsQ{?EZT>#WS8sR2=BHEYQ>q~xSFhPEG~)yAh3zL{~bdS-`jei`TfBm
z2=f+^yXmLmN-Z|Qv0;xNlvBexvmMOkLC1o~kb>0<zK8E!N-MoJl59VHRCTZunVM@L
zF}NK!j1{Qs9HGj#$fuD~_jd0D5(-i&XDbE^5y`)OK7F`ID0CbxXB@Aa^)K|}-eA1v
z7lFN(=pEv<h7$^^PR4Ion`G`*`|JdJA*BeS=y0PLWUWuZSzA)D`IH5%j=X^7{8L<@
zaMR?#J(xX1ncph`I~Vrp&sV5Of7TjMw48Ku4;QsZl&Vwhu7<qkQQ+o%X^+r(9PNz&
zsYkoy+|Lr<5#5iuHPG=~+wNG<H~8><EvbvQBY&TRGneMLXBLb|!m*GjRVgvKV9()4
z-KZM%nHLi881HXvO3ADdpSzPvMWg`_{N|;{(4ZgZem-@no|BRHy2t(cRYa;%?68*5
ziU;-@`=cm-Gzf7RSDVBs?qc+v^=ge$XUeMiL}EkSoxWVS7s;n7T*!0L(RmM>cp_CN
zqDpYKQlbLBNbwceLo)PmxxD*Q^HgqL&sp5DX54w-#AGShML>KHV@>QuyTm2h7xX8s
zu!;_taNQ9#{#cMYN_N`phDDzJ%L}i)PL-J^b3i>W+512Zp9B9|rXBljv8Ddg_j(SH
zvB<W3CjXo(`>n_6qhdA}&^E{Yv8&BEhdc;TZ*%|nbAe<G?;(_*!IeMJ8i;r`t1@Qm
zs3y)gLIv#<uL~o(peO^j^H+5?ZNot5KP*4Z#RTseYt<HV%yb0t#PBBWHq{Mg_qAhM
zt?O0Qnoq^kBgr#u@1IAk`8xz?F{NH9LN%R&m&be2D)ySIMp_1sGP*&H`AQlm5vOsZ
zUl{K`^YWw6p(CsdS%~bDq|-A2Z0)eiv|U%2l*XTnXz_xQM8aR@QSSe$Ceoy@#w65K
zH{bAAJhIvMKM+X6@5`c-giRXvHPq6v*^%jN^`DC*q7GQU&qSKGsrC<>Q6>l;g^!Iu
zF<BI}L$O5u2kO_)9)pKS4kmYBREx>{cgdm`4A)e#KU@5^&~X_Ub(|YT_UEXG9_-x$
ziL^|T{0-(cmR!tY6xtnp`~zY}uCqj{K0aW4d{4wFtMTrh_tK))o`F9#R2{|3Oxx?a
zMXz7Q$Q$NQ-|_Br?E%tGxbAq@-qW;3GnQ@0+pUfzzzZon%C>0F9l+s!!Y6L@u`>{W
zFb9g`Ya<53WVxm#*<303FqY-IZ6EaK9Utw@(axhey|ghZwMQk)_+@Y}kt_bq39Ix8
zbHDq<*G|SfqO+1gq?A!kO)ci0!*6oH5}u+(V9xA*BXY99TwB~fR7Y1j^ccNh;!!ZL
zF#F`@*80~USJxGx+|#FEM!#X62p!HO55@>Z?>(s%3o1VH9*;uLJL>>+=R1|6{>9CK
z2agXR&SKS$Nh%BNAIN)K^PaYTAet5T%E6p_Ybw2y^wX2#4L4@+=Bi|~6~2xxL!=5>
zOOwdufK3FR0a8Q69Du`K2P1@XKm1;elF?&;2&|0HIIxKSK7gPEVepHfrrRmiDZbDh
zqc)<wsE25(b&B-U=g0FQCfrX#Pag<*7IUk}TiBf&5vkQQUoigq)QFM%rwl#S-7_mr
zgUE#qg5}Yf(cXrFt_Ydeh%?+idu8&=ncte<S?$#`%!KD?i%IIV;lhEoqHN$RO57E5
z`3@tk72#Uu2%;ug*WkxG?)i0P{lG+qD^5xls=j0@l{U*X8n(EnN>pqZtGO<Ghim+(
z(UIJ!AJAXxdy|WokS!>M8j1U_bk-Sab8oe!QK2skUQoPO?O(_bHE;rP;Fi}NfK4_c
zNUaMCWlHV3w-(DIi{ue@`MUq2gthD-^dfvnP6e8wScJtn93&{uWxTP$7$UTW63tS<
zI_5Aq)ryuWZ0#7IRLd1@TZMn|DO+7dX%p>>5&4e7#j;1j^%LFOU(>!$Q}~=|wT@y|
z^{<AOIrs<dL2bSob-24?J*A6iU_L}$DXz@k%2$P;%rQjQJ<jHu92-C>ehaiKhq-w?
zygxy+p#0Om)Suh34hkthZ;b1fb<o}={JI%<<lwnQ!&SyoeTiqjT-QVwV>C~H*u&#q
z#<U1IX+ru(F~q8<7X-6)F^BJdaQ6C{$=^8WU@?>l>HZ(O`I*he)t<@5ZwGG?V^<A1
zl?IkUoOaVwL#L{|{wKPr^DROz&H)SlFL>A;c8QjBazMaqz*eQkr*<?saVN_~++QsR
zcafkLVUiO9Enn>a_)~?Mxh|E#LVU*sbru=uX6-E(;r}KU98e#wB5v?ym=qhssQk+Q
zy4v}`fDBT}g229i*}aK;5pJyp%mx=pI0z0FV+z3%#+wb7WsZRIB$ss|YWOW$wR5;U
zYnPYm4n>vHOuZndboH*k726AXA$u65#Os|Kvg=UbUHYa>%CUC1@|5Z3@j;;!8TvXI
z3o)RG%6%FMJw`#g!?NS~3C0REsPAEHxcuiYt0RS`(pD5hh>bi{12hdy>kt}{<IAeR
z)|RcFy(pC2$A^mpDI?Ufkd2^;17BhA3!kKC60P6(b1UJ4z+Uan(L!!tG5Br4u_IhC
zQB>nG1fz15Aj7e|A*?;;Gqk#Sz5^R4z;5Pl@gYsx#n&>Aq}KxVVp>phYlF&?YRi1n
z(JROT4Dp)Ss?bbm`OW`y=nVB3s#&qPSrb`%tj|%wMQ&0Y8t@Kz8wibhy70eQHNtKz
zO)Wo9%ky=FXS=HdMZv^-$gDNNcb+=}+rQser1=X_ES+JNSg~<h0-^mmz>GdNQxV-K
z|38^egW;m9LI-WUxwkA_$h`%y8ib~RfjQT9uTaQgp7F8CGgC@ch-S4fV@wI4S;QUn
z9{Tqj=;PFwImEqQ$}uZaxXdR$Ep`CrC%y19E_pq2I%yw8JI*(;%(_DlNx@CNld3`)
z#_D6_sS<Jv`X5AsmBEZZC$w9rc{F05u0|lTiG~z(HnE$hUeEcEyfXssSp3H6+xei=
z4lnJ#&3zdtG<rs#RZie>&&@n|&R|;RCc2XKKGjYenmbe3s)G(&aWV<S^Khjxt>0hO
z4>d^X;i*82!O4_U170>_KA&hW{Sxj=l_QBfI1n4G-LG>obO)T_Ei8AyWo47}<-8mw
zzCA^$8KhuhPSg^nl1@zALw?Rrd10-f?&B!o<@7aGCta81X5UK`ObZc{+T-xNk}J$p
zL{PNm31gb-sgmbiS6^UyqGiy*dEOi>|CJX`@mF`g0{390e0pXT;P`{m7WvA`o^uLm
z%1s3q9RRUo1Jg&NHy-uRl#c&Xkw33aN)w{Kf9Do&$Dfs+iV?_nz+UG$$bCuf^m<~&
z1XL+6yLv0pAAl(^qX%uT+CT}Fn8&L0bfMC*&>lz-e#Vqsxp*^%F#|cpdq+H9t~`&I
z2j*Cp8$-;w=pBzjkae{qJSVBFY-|dq#h2Gs<7)|*R=;<Wkka~z?D1|r`vW2@L#!&X
z4K2V<+386&IZ3>3St%4AIaYZMsSn#@P!zspVm`k7o`~rffV8HG20%n6rmf!#qfta8
zNwjg*A3QOqAa~8@mDl?Mp;$o-MyB<c)yOW0W88!uU+5>2jr%_kAv)Q&fq(Yj<jIpI
zW5V)<Ld-R8EC{0{1P&5#ryheLvA<3LYt^?Pb8A9D7{=tkU-Nj=*aav4R|AE2gr{W%
zjf51Dz7gBIY{)I$ST0{Q4ve%gsNs!FXpK7cgWam*VYgaNRoHu2r&qG=beyExo6no|
zGL$2!(yY{Cxkbw{={&}o$$nm1zx8S2d`yxo(~KT@tKdZW(gfAu8J~AlmQ1x%FO6g+
zzv(@6d0j4dYeuw~)~q;C1QUHc00F*q)V;YQG)Qd(wQDK!wO6>Jy}-9w4nqWc3zn-O
zbNPrUto#1`w9Z}RF5yB$?I2;gM)}8zbYL=FU!=QW>jK`aoep;D{|mH+ry!XzjSK!|
z0T64%AnR}wVM)Kf-RAxC;+?CFH7~leU=kNQ=(CJxljRvm(W30fgO`5g&=2nn33X6s
z@!Cthhk9WIqLp%auCQL_zio7XyI4g;uJ3SvV3D&R>+7Vy0Z5sjWPS3GbrjXRHHXSf
zj5mCBac!&)n1T}@_WX3H83|2Rm^Q(I>79fksn#FQ`)O1I(-?gUzMjiA=S#jbax}7Z
zHd{UpaW0nf`R!C}LAzj34~Kr<34yGi_kMhbS!v~pJ`Izp_W~{h5W?kSV%29*8K<R9
z6rI?DEmEx$E{uC7!`wZX;#GO@!Q%M16gsA>6d-MOU{X0Wb3B;$Y+T6Ia2;A$O!>HI
zzT;mKb`I9X50dw)srW1qo~?C2{0hhTKb7)*dCDLN&s%z(a5*<`dMe7i9N07-$wg#+
zx|;j2VX}oFD6su)OZYo381;PiMsW`cz06aKYI~`Cm(^?@nRPg|fmdA*ImBvK=?ZUa
zT+@p`v<4D<6pp&{GhS+4pUvzAd;i@~vVAR3Fl=+LI-Vf2Wag7l@$w+-xbf$4Q-h4L
zQ9gWWl(zioKmb|AT*&yRvZD>c!1hn|oOdQd1rdHjU^<mhow7N98g-J<xjRVM)HcQj
zA8SKZD^Xt$)WixZl}mjo#tQj+z5=nrN7SY4mC3!da-{EWK?X@l-Z;*j`&e&~Gskn>
zdZ#Iy>uo&wKsSt}3!eUAIKyuUTUk1MR`K)MZrvNN=Or6i#?JZ09*OFAQwM2Y{~LM3
z)=mj>%onzv9bU%Un{}!O^bP+(c&z+U?0na}3YV%GcYHj&KO89Z=2%%CkiOG2U=0Ku
zmzP_XvZGssg4#m<+51Y*qc|4!Xz5cxEpgG@UBNF2)y(7tUJfuFO+5{4_e+3Jn#4Q?
zM_W0`zhAX-Ns%b_fmr$}p?n;^6^&0qnHiRLBBGD`EsXTE5&3hD1GQztPt;@DN&aqG
z$|v0O->O+8L1Z{tk1iBhC}UYJ2pi|tJh^2ocQL!q<ns7VA3j$wXha>>07*r(u<F&&
zrr5vV`&8SF9k$ex1fmURzeN>Dy^ySczMn0u1hism`Y2ht@_-pjH>RY=>O?ljy%5|n
zqfvX#o`JpVgh)$-IF`CYSa)*?)6VGQIptyCetmsxfpb;7_*j(}qx8(pFxXsziUt5g
zam%T8-eRE%dy?{>++uhk%(*H+h0K{--y(RGH80LGR;mqb{0W|CIg(4a{h+`>QgewN
zcv$)Bjqg|`5NNk+;p1LFFM|3FJ#AlDC+<-))zZKR1kX<3E$CF7g|0`SC%RLU+_G4<
z?9o+gV)JZkj4$_BTJ6xwiE78RoU7M*BRkI8N?vOUQN8dHn4|3qGrPO{j#mrl>HKh{
zk7R2PcbkyvXt?M8<j_+$zP|xAa#pE`Wb1dBK?3=SJV;j=Lqi_}n=$u-=Q-vKZY<Lw
z&9?SuHkYeGzAuUAVul+=oOClJjTv(I@qUpu&5vT)WNI8rNkH}>Ix27jQI*24rC$}-
zxYd8)4NL|Cx+ur|nLk*83k41O2ZGkbp8U@X67AcOSeD=-g{t;Pk+z>$4U6wbA2svQ
zZ+A@k#|*+~M{EhF*4*9x%2xz84aM7vFrr*xp{FOqc}OvmlK^9G8vl3l2@}gCdfG#}
zT&Z_}jdL{#5_Y9vP-t=POitJyWTVIqi~vC)VCYd!;<dD<ouIBRGYM`m^lqgupCWl=
zkU4Ya^bE|y(K|5EdeXkEOY(#_1OkqE^yUu;2pBv@Jm5k8&1G$<HIWbIrJ?sfR|=_=
zLTdj?NOe5xNR9~j!JGV?8wvShE^H0b;ay{%+25qZO1Ew{5@I1On?aqcC89dbm|lAw
zFj)6q{p8d_GDuSDK0rhY1eP}c*46eoU9%ZX05xMlG53r7C3h+FQsW>wc~5gq^EEF!
zsgR1TU8E$M2n7jxIy-+rqkuXZ79h9!!M0@cB71Q&FE8^E-`ZhMx`GAEDz5x#!^(C7
zWcJtlklWZ7cTnR`{?LRI(bW5h&QD*D&3x!oaCRCV8)JBW5ndv!v$DQ5Lo%GcUGLa#
zFJCzR1%aID&zeDHeW43<310Qc;wv491{QRDV|A=)7~L~XepPjtAI!*FVmV&C3;2@s
ze%jrFaeOeaB7&1}UHyxq`Thc7O=o5WKM|_3>_Xs+K?G;Sj#WqGcE#mZG4~z$QcryM
zwXRg&H*n$B_q<C=J0JtaA;9`U<4<x1qO7Z}kj*Bi|A`|6NTNcxSC*A)X%ol>7<a5I
zYp#S>--H$yL-jq*mikn{$)E}stg;#qH)6Bg><I|J`58{m`2X_s;qN4G*=YomALd4f
z&0pCq5Nl^#hRrzLmfAe9IElw3FkPP#MQ7Ng$LU^Ae4>nDzK>pNR!hG-mbW|X(IReP
zhv+|owvtWX2Y5hL78lChkf}wQnm8<NelQNS>E|4{EiT=DFzm2`K65{;$esdJ;9h(=
zqhVef?)2*q)094G>aXcLVGsi6q28=J#;-nabqR=MXEwbCT?ZK1(=(-?*F?LkPs`e#
zll}DqP@?(DMXBpF@VQs#^^qDx>MY-&DR&NWusHgtQzBJn<ky02n>uF3M((2IQua!!
z;3$NB>(!({;6D@S>yRH$ZNk-C!LnKk20u~UKi(T_pbmOCD(E}wB>rd@Vb5k`8Mrc1
zoe8uLW^f#kws5TnUl#uOXfKKk>%*W-()D}^SlcjL?3ZM^*M=`v`NuBoUZu>9MS@|I
z)uW38mtC2}hbjrE7hU_KLXp!u(lL%SmKSE;Y1}!N*{eOEdoy+P0RAK>x@_(~F}eaK
z&2Fp{ho~Tk%(dd}B8O7B`WB&OM`l{6GGjxbJ~qaY+2Y_X;{OMeZ%+xgSn9r}vpPeu
z8&o18R_!~23t;K%YlfQzs#V(T9?{DJETXpTDOaL>2nMjZ857LhK%O8yk&i*7x4!f}
zhHU@6J<40S2J-RJc{dA^Zt^n|)uSJwiYMLNZR*%FFFYo=huh_x3h`6F7v6TfDtwze
zdp38YNIIV(v8Z?0vIZPG8-Nw_k|L#sf4D!&#@1`Au9E|%{?<j%Ej$1euPhJIM$oFW
zRo-%g<x$a&pD4#g`$ac&p@ka;CN%@{<f+xW34Ks!FPPyCw1=X#H!`ASHL`qj=E?HS
zwOl$X)dMkls!0mS&ci(vud@Pcey}P+lbQ>2HT%Uhe)SpqHOF2qxJd6o7_SkG(V1Z+
zrkzV#%z-1dx-;V1g|V{@)P6scpqp>xgC*h%nB9Iqf7JdcO`Qb2*j05FvFH^&yFL{t
zav7&VThOzsn?c6efs{gkf)<Mv(LA~HGrH~yjuXyu14gK(f&Qf)`%r0$0|Kc;o_IJH
zFb7&nL+c4oN^AQv(=f0=bO=c`p}a=sXkfH%YV;vhVd1Bt!oE$%xS;Nd&q#p=_;l%C
z_xga=H7D2sL03<OSJa=msVi42L$L>~5SOaHH&&cSxj@j>Rs(~5OcyX(BzQ=-W#T@~
zHQgV!BT)K2M2%DRtvIY*;Gpu{@Wc5ahC6WJF-cjmGD1-Ja_2?T)~d(=Y}FZ#4=_qU
zrqUfv3$|)~b4`phF^Bz|E4McO#-JmoMRxi*522l7PXBGrsVJ^z$TObw0%_jc@J+el
zfG+%nf`I6KTxi{kc8X<RG_!vRUNXUXd$_;p%M0!!k0*=Eh1!0<=$+W58q?$i+K{Rq
zLQl|IoBO+$606zgLO7TOaxtFU=}`r`VAvQgP6$0=OAdS~Y2+GUu40Xz=5+k7fbhc_
z{}?mYnuno=4E*}6F~hRcG4Q<kzzj%aepC)Cf{`8oToG~-0!s)VN|40Qs4nL&665)g
zKKH-ggfI+gUx&gzczZFuvdosvR8*%)d(6a{7;&35nKB#fx3ncYA+^}DIvf0(;~mes
zQFEQ8zHO@0LSsQ@7({|-vRp!r<0jKJ1|I{A60JPe!;tL~(2BN#FBEl+FiBbhZ*&)|
zMtM9YN-j!;QjKh|e=-<64D`;{^y(I22nbX=a5f@MJjs;q?#jv|M>@z$M!Eb#WK8>q
zVE5LfOU}iD$c%OWE6_$v@Ey!SY4t9T+PWSG5_u<wbVli1bAc&Hh$H-gKXENK>BJE=
zi%=~K9~=dJaJlSLjE_%cE%kfx5nV#5ZV`o<c77KA$$se(unwkCpnDA+R^=o@V{Oo;
ziu)jZNh8M|g=Y2~*ZS+=T37I_o2aw#AmiPlWRScm*{+vvL|nsdkHN3Il-v@tsP96k
zdSx=h1o>U1%jaU}QIQC%=+ki4Wd$O+{z|p#A0s0XXQ%R?dy4^Vrqth0g;$V#^1fD^
zg~qsDKa#;wW;V+?%EFlOd!~=#vv!y%&2;(A@Zm@?{es>U#5gZAHc75?kpb?p8HIec
zbR?aOQ6EYE2a_$E+nGR3>h%LD5h{<jt#Kxu7DXYv<AN=XN{8O>g1tK>K=cO%Ib;@@
zVmM*pF-D=n1dd~AS2O*CPqsj<vcEtSu?}HHSty!0L!{67Gk84c=e}|~P}-nSQb=0;
zuO79Jq>%Iwi}5mD0%j~Qcw>Uh63d8X0I;8n?Qu%<NYd^;<^c@$o;>Sx2*0DCA}l<t
z;xD|QVG>=6q5hVP!t20W9)De-$k*fYo3#kL9moBIr6)fUEzkF~BYeVGJ|PS#+f|2Q
zI3T!BLvL*~+&y-MYu1TF_L=PUx_rkvAk#M1X@99@Q<vW|)AiJvwmY3Hr0$hJ{An8i
zc|(lH36Z~bcRBejS4U)=V620~>`VUZeQW{aNSEWrCFTSIi_+=;fqlJSayx3T<Ui2*
zrY=}q81$yApXSi#t3dS^%clnK1KRR`g}k??rQycYFIi>(jQ}GQ0=pj7Y#m1zk_zS%
zks8G{_Ihf+9JHT<In-7$hv+bGz*9+U=#AFi^>d2RCt2>esDTGXjf{((?bnj?&Ps6j
zW=WDghzWnO&;EUlg2|xTg{5zN8N#dIVy~_uX*@e6X;ZEe6t1caoj2_@)*3=6XP)99
z7mfk41b5cH_q_>Ds$K$p>SloEFV35dG2alNgEub@qinq2AAye16lmRmu_N&}0m?IS
z&~I{MdlTjtX#6+1Y)Njfw_|0v9hvz~`65_q=iZi0QyAvaznVMr6nwXt7Vp%EK%n+6
z3bwb(p3B$rRbxxr_rywPb&On9vFj@+79uJo;ZyAj5y6iHF9d=E7F%Jm{1A5hewGz8
zKt7#WBUSB!4`d$3Ue*r6rK)-@IUCqNb&-UoKqnnUL?kC2Ej*fPy#RZ1$OK;XmjmU^
zug`0fb$~oc;g*KCAxjw#A6m(r{(dMVY@AM>yU-xa<_r|`w`_JZZU1@SMttFZsxRj2
zEI`<AtIcLV>F#J_!C`A%d<lj(gO>v6_yW81@l1+bH&+-t)WO4D1M_D*g&~fj=Tj~L
z_9$7J%%44XS3h>a;4h)bzM`*)j?;&P$r38uU#E{=%uTK9U=4NZ`dPV4B-;}$@&HF?
zj{;aZq7L#yk)<o}VK@msRiA^E=M)CfKV9p5Vo@b|8*JKP<F1tOZ87WP%Zrr>r}d*3
zOJeO1_pw4g9S4~5{;MvihHzZC7y;(SfNx9RsIJLB+_4DOUeWF!GMy^WY5VJd4%E85
zPs@Au2<vp<7Gg@NEaF689cuhaa@`v}VI3}#3u!elc8L14YHc-gi-UonVX5%9wSZ7F
z%<I#=MEnwz%)JIgn-!E|mfx=p&MbJdI<G0ou66<U%4m8k{2L{ffzSW58p>Ur)`vM*
zY$Z?XY8T0DCq{HON$^?%ox%{@H!ZgTnPugLi&nN&k%!frAyr_1e@RxiTu~Hinp@L;
ze)%wBOsu~XO&wr}C$(RgI^Lqnm!_G!BZk7ug)7ayL?zSN_#ykES;3)VEZx3EDg?hl
zz*Ij3onJE6tIRQCd}sV@#wX3(3-Nq*IV%SgtQQ7)dV?2u9W7%j5?b~)Ak)C9R!7-M
zF`Aq+E62w3jfv3+aEd~7MZLD7GFud)=r$H<7F{-4#9fz){xZ4`6;W3~<ConU9ljr@
zf5Yj*&uu;;l;FB_Svh)>_UeRM8REnh3CGBarcg1pU_hAeGx$f5g6@_bvODD523;VE
zY#E(xcvPCzKboSj6wUW62#<uNO0?H<DI|kp{q81yVjmlT2Q$I;AY?EofoL)g56R?%
zfMXrH64&xrPVtQi05+QM_ub0L3EJ^a{>p+~w20y(QNyqbo%$?)j6A?$Nu{*>V_jVV
zVPZ`K%Pu{mC*xr&IWY4rw(eA9g+DlZB^xx=M!WhAu`J;9@%64j<eJX5jb=LT>F>$A
z;Tr}+F~YmD#|#U;tB2$&|1aq%v0lahKcmF&w7jV2Xo;7qJ{QzPd7fuwmcUms_No_T
zBZz2^|A{4FqdZI!sIj^y?cT1OdDjbSdwUAO_Rxb7giMm_c}QV?glwdH>wah=EW?`V
zNjyR`iZ56{VB~j`?Z0m<10>%9x3lrm8<QTC$p%!(oCk8owwV%&>`M%t*C4O@fQV5W
z(-HP`WWRzThk}z-%hY`5oS>yRuNTy=Q<XKFjBVRAdB;D~*I!r=i@t*Weec*gs5F3#
zu%4?dxRB0`diqK9fV>Gbkx=0!&IYK+BDCCucRW~%??SXAHf>wCu4Y#LyXC$2j2l%R
zTQ*$1ztzir3JCR*X6rz$OWh9Lv&0+dW_&UhV|#(8E;w?FE?E#kJ$aEi2s?JG&C0-M
z&tM|mOt|mvpE;Su7SAa5!*w;Bg4`slK*hf!0Mu+NK3EWQ13{gu*OR0p64`Ucq#ZyL
z*RKs^-qfK1i1d{<nJJkC|99Y9*plftccQ5Fpm*#i1gU4n9vb`o2c)GjuPJk+y}hCt
zsuGV3mmy);K80h)rw`v669~GGGBJ~me=qcvI~m&;2w`mWoigE*u+wHXbyNesfz7Yo
zE2gh0(i<=#n@d0`>5MWm=}ViNOj9?Ew!3hqjW52l#=qa^L<9nkUgy+4u3sjCGu?mN
z(uwBhkyZ}YciVDVvo2>9FeW|y$ARn*;dOK=A+LYUR2z`SJFQ+hWc#j?Eu_};>-Q#-
z%TntvIXdY`d-R`oypCK_*5fdVD*%8r!1@MfQ2lQ~ab!|np94-dSRPoEwoo?X><|g6
zNlu+k)T=H5$Pl<9y7`^Hdbtq#&7xGq7dg?-`LISE;@}YBzO@4`GVYtSJJ?!N_azDZ
zB;;O7f@EM&SbQc>Os~7w$#GKXlW@4%4}R;yu&daI0ocJZD00MEMN7W}LO2)6{k>Z)
zhZ>ynjB(t{GIoHhlC^dVO7~atPihYV-K{HC)B4tZW}{1}y-k^cs}84QERrL=V~4!z
zpQZ%r%jUe)opU^num(D#K?a5&#BwOV+=+J6vzlxyYsvhXY%AtI+Ggy0p`qY0=CP^U
zy{7bU?Oo*$lEedkrhY|wmF3Q|0>2nB)arl+`lGHdJm-C#mbxDa&E=vzACAL&;2TOQ
zOr+vBBdydWiWsmoK^Sq$Y!E8!%t6ama7}eYUWkE&-IgsKuHaW~6+K#<C?{t<XCB3H
z6uV|&m~f*p$!CWny|$gca8Jzaua!QoAN=V4a1(GN<ma~jKjjjeZ%n6e5~Ia?T!R_z
z*-n9=j*6m*D_H9^Z9b}W-vhuW$8>T-W8@;JgCLifX~El>PEQQ%zD`OSpf{f<-XZ;q
z-BX1S6L#RzD~lGUe`MpQ_N+~>0B`6w$GO#p3LBAoO0yp;C!ZodOFiB8J3h>xtc6@X
z%$4rE(U^SBi#(WB`qrmL#hJC__9Z1rtA}Jg6}pM0qG8Qgp)~B>+oG56eDUt~=j4E`
z4?;7`)>$+h(A$Hky~Z7W<XfVU6;>)_bUvYx7Q0q<>^_*@z^zj;<V*lLYHdnQm>|a`
z`#~HH4U~F0sYZ4>&!Ee02hl~`1S=90gbKY!`fzv;swI1kW=?paTP#J}2&_$@v?%Am
zVfNHqaacqfh7z|Ql1AMH@ouIx>F(w|;$@{4+*)Zhb9_}LO8>?fy%%%b=}#a9)g)%=
z5Jl%&5+)1eKC^MV04Cb;UsBb9DA9tmEe@n2r#~#eKk&mlA`VK6*5V$`&Vc)Y*bvyk
zvEb_lvL6$@nlU<HDtmtye8A+zr7B?u4Kql10x76;987Ko-xTQ@sjP4Iihrmfz3$rW
z_|dJc`}T@EJhwpExXInBYiVhLGj=x5bvyrqCM+G?)o}WbW*0wzEomkMXktah;YdrW
zNPT&+eQaw>(-E)ZhfJvcAYk^MGv#r^Z;3I=Gwdu??Ohp<$d5gK`+#@UB-n<@p0x7(
z4r7{md<hCqr@bp8XSja#&VcWuy+Jc1X1LhvJxP$(BFFtC6*21ao~wM&192K5RjL6s
z)3j^6UXb#9Nm2f`2P-a4M*1nL^Rm@_)ZNoUB4fyL!kIU4smUa!*LOM3A|FSAgxym)
zM5)YvleBzVIAM)j-mo$T61n#42Hc$cKgHl;Ya+MUI}h&4O<y3RoUSLs&A3qfh{D(C
z7Va_eKIFHcTZ;SWp<!6vZpdb_eFN;v@rg38BxA|Gdz6B>a`Sr}n0|Zf%#D1}g2Nkw
zUD%8hr+`K*`{!!bnqfGE7t=iSfDslT@;ra@A7Dnm_h0UAc1!7b;5$~!sb&IgRGGx4
zzsKbxHU9}!YwFwQ+}!G=YeFsl)e4LIH31(3XvXy^!>>f>m&cg|gXh;xKZCceTW*!7
zX_SiU6nh$F-ZPb&)!?@fB_0c}OeBk@F-q#%fHbK~WwB$b=7xH)i1C4@ArA1N-QiW@
zBjG-2MT$+6^T!zCCg{!nh9*0tt98@emYTd+h~TujUW~hh_`;y@-2iS&_hhgfMsIo5
z!Ny#!@*>^)c(Uw$SDVBePfnSU;CLVgLUDQVVyJk*gKQ+OJ7zC_`CI(e)qt5S?&)N}
ziJcR~n42EWajMduOa~7H#VJ8g_sTm57q7t8+yMs{u8u2eB24uy30UuTp;qZ42tzT7
z1ps5-j(lE-G6$|L4UD}fI!MWgh6MCBNrhXUtGU@C;V=T}Ubl~-_tT0bHO|5RqQ@K*
z`pOnM={YP-RRTpJmkjz!m!}u~yjPCttyBuvSp}LT5NYwqu!@TX&h!@B^+g#@fg-F{
zi~HkQC^nUcbqpo(b|-)NKP`WtiK^f*0rRiQ)?u&@{`Coo!ZJ@zrz!F<4PMslJtr8(
zJ8YQ?rKjNm6wMC2&CM=x9F2+BmF)<p7nVro^ZE)gBF{CP<x$RR#zhc>vSz^Fa+717
z9g4tAg^F80o;*s6t?qRFZwC$i>sAg^vmYf&nB{S1-|fDp4J*7HWSKIIbAzB%kq!{6
zd{T<B>(%bndhjbhN{zN@NnMbG78rbY=8ugX)gcldzkSu-vuRiB-j`NaJ?hkm_yKE0
zUpMD<;A<J8G~<_8u^FvZFFCt1Wms?73-&{aaT?}k-5iAJ`4DD;+BKlqJ`x8ALb-3*
zWnOakf~=F@T%=8mjqX(mffO&Mq?{ut-lZTv&TS*a|J^%-4-SfqYXO{T>AQNlP-I%x
zLbiD2)Rl3re@)oD4CFS~LkRmK{2%=xv8G;B{&SVszB=@+6<7?dG_?sA>%#fPwXLmt
z{1b>bSL>@gbY075IBMShl{p5#Q@Uu6*K)<M)EV^o6xG|%e#RT9M!D$CK{{kU+uR@h
zWo<|J1WqhR%!A0j<*Ru?etx4DS9Hjc{dgvMrC-g&mEGE>rg_0b-h=(-NedME4t&ON
z`<N_GTSKOV`&Ex)m62b%K8<1P*(RwLlyTMH+$ByM41QHZO&w75=iZ8+gG?*>Ny>BQ
zp8)Nb=>-QFME?GtQnuZntsT@5XW*0@{{<o~pXF5KA3{v*KkE=^j?c-cjNban4^<Pr
z(h2kE00kDCo<fA9%37!g_V3=dvymYH&^ukilP5B|_yn~1?oAn0-@u^1>v*aZi#c5=
z@k`v`<a+?%_<65EfOK8jsRppM*Z!liT`i|Z?UFJaPh&gNF7U{GA9BSGe_Dd{$jqo$
zUeHKJbE^WYBv&3%YLRz>2I--MZ}dWUr;)rX&~S?cY;z3V<`3ibrt~@G_6|!Xea!s?
z-6BtYRS|4`rr2|aeNSD@+IMa21nrLGJ0(NG<s+`F1oraX0H(BVjgFHEjr>mqZdbgV
znA!!y<!wWR^?=V+^t0Q)1F0nls}eJ+Bw-U#oHf*Uz)Yre)BaqlQDBuopoP2FB}+RC
zQ5jt76x(>T+O|`h<y#>0C+zB9{I~OVQapEK8K`5xGV8iEzEV2(z>;pu5JdFsq&>R*
zfqpr<wy15l-5_%vK%S0i(`$Ed#kJTO^3Lj9HojQ+Hnk0c_vatiyVfz&(sQ9*9ZNET
z8j^>i>jU<;A6Rl=f+?zdc=nb{f6^oYY<DiRq#k7d+n^kmAU&2F`5X`|bm;gx>Hg&R
z3MYrhF++AoM}^;)E2J?xDMz+6o+sFMoaMMk2@a*5jm@nqy8ihy*qKR9O<KmYyBBz8
zJ{-MxMI42@V7JVR{*Yt=*PA#ZKlg0&<i4}#eTmQzX3P1qN8wQ6Ql?xk!W(nNH3D3}
z5O;Ur@uK6<7zc3a;SWjovk>Y<ArdZ}RZb~i$4YZkZr1B$-qD>1E%HcPUmJuf-Mgx%
z0CdHKcgvDJpZ;^yP7EXM@Q&`Gd(=kyWOke%r!i?*Ag}&7HnS?Q?}FcH?6#bws>IYM
zi;Og?sNn}0ps2qNkM+<pKB+|Oj(et>vBy$aq`d3(BAt10r4QtY`+{Lr3c-3(jFThX
zm7fcKr@Uo~)$&u!as~;jOX2S%#4jNXrB2C3V#$yrRZCbISK?7js=#>r{P4Z(1tvxa
zt%hu%i*2uU8xZX!ax&~ZFc$qOhxtjr-YSZr#RqwAZzTeUWEaGh;C867QaT5r3h~u)
z^PdM!>vnp5qVb%E6J1V<_u&J5Mvf9C^fRQ&s(_GrH!p0`9=)_*jKdc8dQ@D(sF8wy
zH5Lkd8Uq-+(rx-+-Fiju1Jm)G5Cr%c&?PGyRjOYa9wxe3>8~_3Lm~pHIYHVHNl&ti
z=^N1~2y&{ybS>(SH4>K!tAz-zebnH?tRbm*KDJG#?ao`slcR4#gv5GY?i8DnKJGO_
zDs=I7Vptr><7qaDC?Iz5ai7E-Z;h9t-lWiXTWEUcrsmZz@X${};=H~7sZYQMo;#P%
zm}sjnb=SBhRs02%U_HkQ5GP``k6qcy1@{jN!{_-Dw`iu)eCV8s63VNn^bTeCXqosd
z`|nt?KlMaoLY&?C+tgw~d@C<eH?J!cDDD1MrR4n5g~Nbeo*PgkV^Ndz`yA@21(0B<
zhw9J?vhq?LT?R$v0SX%E0AL2M<9|;pS34ocXmg+~*n>R(j|uxF3}nPVT&7@)TfX7l
z(ly@_VVdE1c$xg2;D;FFF4dS3E4v2WB7mOR!{!r#rrwRw+s)VZZy!V5_RZf#fsb-u
zEbVq2xrU~aSLruwPpIKjB2Vd9@k9QEbt-ztJ7l^t@D2GkPSfJ~vhlKdMt$CVIgF=X
z{1P!%eBj0hVI$w?)EGGOHt6w~U&lSWlsyI^sw8hS*WqBrF9>L5bi1xBFQ?c+X|K0N
z;;g@U#{v=Vesu-QH*0iW2sVI5=L!{y;Wh;XD7nJtNN3Y#LxMp4wOp~gB7sBOFc;H(
zWo{TZl-Ig!?s)Dh$;B*BS<*d4LY^K0dEu$EHO)=>`ulV_HXWlI!g3*Umj`G=OZPp0
zFHVY1>gb^$YHJ%@bOb}G4E1z_3%pGwOT+@%6?60VOq@r>(9cDPKjKZrdS2h3sA&jr
z>UGt-b5QA@sS0`+VLX=zM;h4m&?~YW(Z2B6S|RC-_I3ZE*g8P~!thsNjdATd^e4T1
zdCigH|311fdeVN&e&5h_rV-;*X1Kefa2`iiv>{=>vO2{J6dDDCJh!`kX>#_ui*B2o
zLQyyXd?rxTaWSlsTP7dr<L-2y76^_8b?ssj5AH?r8LwHc9&;s&Cs0(1o(k)bE7m9s
zHd}H`xX)qLAqHuA?HZz~D6`f}h9U-qSuho9y&6s@|9)+(Lx9LLri*<Ig!gkSNWN0E
z3mw96A4s1@WS&pt)VQ3w*7YI>Abz%(<_d@z%zKTAjqx=hf{d?nCaNs-<)-Liv(B)P
z-MMAw%WilxNYn3TBK(9y49He>z;$-8R8%=p^g6|&69dS6p`bSD<B0Q7x|JkXgj*W|
z%y`jq#O?_zdZ|7Xx70i&%j?sxH(Y{qA!mDvW>j&k2Qim&<NH%g#@Gt?r2!DB2lm*+
z=E|U_i)7(g$Hn=A?hUpzEA4jW(fYQTbwsv0s-RhD*$dlQA+#jT3>z($ehqwj(594d
z(o#&SHUVDyFHb1QTH(L2mf76&3Mzp{g{NQm9m;_<sfe~+vvMG1;{J}mb?WeO6@hs$
z#ENRhZ68a)eWQ&)qN^w@MOQB@Q~4}=0=yZ*eOCoCa0rZVRwDH-3NzwDR2YYJ{3gm~
zxg_taB`z3W;Y-yu|3O2<*VT%YuH~hq_yVi*cM+08Lc;)4sKQ=ifjKo-EOpm)Mx){v
z5>+t_Jf+>_RBy#`Jj=DWHssiDy!_A9dI<&*AFhK4&mepR)-v6LaKB-0%@faklHj6s
z->lZXQD^Ss*~fD4%JNVau*^Mii&eMImHXcq7ekXQ60uaFW{X*riHd2tiG3d&q!-CG
zYOzdftVR#Dujk=30FE})R5<Wm6w9xdoAp$Gdom>S<MUGc(=n9~<z!2POJ!~?%Xz(N
zf$rtiapB68bmqv;s*a&hAFRkM?}@Lp2;|l2c*szCfO0J3c+=|3FOvnXoSgthhsPQ1
z^oh<h0QxQ{#j*#|ahJ_PU*TDJwkAvIwAIng$D*w=q7EYg+=ha87kzDy+3Pf|9*YK9
zY$h)P`?b|A22tb+6LPdz41E!)-InsWZTT=gUu1m~-IZcj!$)8S&&~{9W2<>LuPd>7
zPXJKnWz{lloS4BUa9GQVU%kYss{8ocE2*^gNaCEVf2BacSbE?yXm5Wd4y59E69<k?
zF66jgP{%@WLIh%Cvjq9~fbk3aIGaCqP;u|v1|v-FY4;%6bp4x)4t7orU<lQ}^a@9a
zS{wJmc_^%#i3t8v39Ba-xlB4rm<*>qs3__LbzdTkSXk{`@eNUty~QP;MTCyg*{>y^
z^OWnda2y!Y`}`>PW0yoLB$bU0Kc9bLSo#9e<VN*MXPUHWDcAPyh06fkWCBSb_V94V
z1q&KMHS>R*yV)N~;5fF&^k&{K?z5XNW4>aS!b#hgx*zDMfz3HZsybIIU_bPQe2fFA
zZ%f`*RN9fDl-i;K+@L7N%H87&#c>%;bM<i03Y%p%;c|Nm?8D*YN_T@p0=ot#viBFe
z>~zR^S9kl>*@HJ@*$&5T5{+}P5;_<e3n5)?_oe)rnd(M2(Bst?`A`)_{6YQ`&U5{>
zb6fA2lppIGCyKg~<qF^VzwzEmZ0+4gHSB~!E<T$^4{K^S1X2}Q_Q4$@xab=Qqb>KQ
zKrYGl(d|r2aIvWQmHVvQ%F<6?zasqQ9h=Om4#SMZy2cb;;67QO#g-izT^7w*o|w!g
zp_{ITi0G3cq-H4l>A%@?Cz!7j%qOg}em{9CawjGh`hSYfJ09x)f#bK`<c>SeKKpFS
zo@Z~JEi2KuudH;3P|m6wPJ1t-AygzgvPVONh{|XkhbTqX{rvuY|MC9o{rG&|<Mnzz
z_r=CuW4#9{L}RK%C-im$myv%wyD`lJjysH|+BC%nyfG7c5rgjZ61Sdj;(}eQP<d^A
z@SsT>YjV4j(e3p4Fyk}NYtp-kGMzngWike*UvYH)?tbG#3^x~*vvs$ZO&;z|HNMfw
zqgc%E4S3G}r!I)={BZcIsF%}E4%e|mt6pCKn#+pH*)N*W&7#2p;dYLVW5c)s@Bciv
zcR-={?CI~*mmN95SRy<4XimVXv8>GeF#@BJ9N*q{sWOqXf^3R3guGG%;~t6o4f=|_
zz;$W6kW<jYWb*g)Vv(I$3J!8lwX<P+svLLvj534rRi9WhRKq?@*ds&;83~Md;NKN;
zq3E_~MDZDTx3b+6XNAUbc!Qk+@X$j?BY;max4o6L$ft;5`A4p@L>@Ye1+)1Z?zAbD
z=|KNAlVr`~yik-GTr4wng${~^WMLd4bXOMh_f@2z@2?%}eIen{p5ah;_2H-Nn~wPN
z7>%XBkzV+l`d4>dFq())jb*3mAipYkZb4cj_s07}r~J(V=TEjae1$buyt(xNklj^$
zOkT3s9$GL4@z2@14De|{G(Oj;dRJ)%WCIKseH}BL_W;5U)6Y^Xbt$pu&f>38JKG@M
zjiSv5CD3YJIo54)2iqGc&SIVvmz#P)bKXrWJ|5!r@MddqP*n;P_x4bZbuA%HQ8~5i
z)?!-~*Z8{I!0yF3Y@=SznP*upb$4o!7x>)*q65w6Ecs)g1FwUc5M)d&_XvQ9<^7FZ
z1Y0={dQq8wvcg+q7}wIIdjM^xATmmC+pwL`*F9KDZ$021#nnJ^0Y10RpEQk0pSY~t
zDh>QXA7k)R_bJA}BbTeBCiEDYO@C0j8{{FD%vnyDD2qsO;Ybf86Y5!r^3PoL3-A{F
z6nT(^jGP<PW?pD#=;_oKtbzPAW4fpOOG&rT;*YLrD8Nv<pRa9W?q0eO%|L_N3Okus
z69><iqAy&=Rz2c+C4ra+jhqZ&2PJKnCOXFwTu~{|*=<Q!291u{)VmqE)X>5mK0s&d
ze5*z0oI^V-PtpezaMfBt>wcP_VFC;+HQP9QVM1_tgBRr5>>`gSw9~0Yetmx#iA?18
z1xDpf04sCkT9JGKCd*DcDerzoYI=!pLlyjQ+lYX-w=K^!0Qy8A!hsX)DfNieK!wad
zT<qdU_LcJ+SZ@W8Joj|Qj<E~`t%BJk-`;@s)V4PY-`|mY=?w8)f>!F(#c+jU*igjg
z9nK@lUkv%9Kq6tMYbHQs(2r(y_gQ@seBJAgBh@p8KUxIBoNbaP8vVH^M8z>#Gi7*5
zj*M;W3;EXF0=9tp<>}0rg){>bMm?o6Sj#~!j(3Cug(wXI#@^0oZck0FF!QINt5;7t
zop9!4`#UXi)?O_8<wBH{J{6uOjuif*&2*lzreh!KW>*qgY;>}>HyF~A*}=5;CsA+<
zW3Tt#!7ooM14PkTsx|?rC16eHW^_i!V|v%^FpTWx`3V88aho~H&^7onjS_1@-Hm#$
zpPhc;=Zz}#Q>ra#amF?tX+oV98=)9<?B&WY?tO6|a<>7}_|egzL?Q77zL|g<9j7}R
zPS_eT2Csw<@WWqzU_6fbFFyhGA&ln7|JB%N@Omz|b+)4>YN21#?48Ir+n_)ETZg93
zImwYiFScIV-rK1YeHmK6eQV(hdT&0Qt941aH!I)ZHco3BU1CX1Oo0WTlI#S%Oza_^
z{}9o6xM>s~5$*|;V$~co_(eazo%45AB>(`}&r2+`w6K2)KA#aCwp~zM_4#VLRkQxA
z0BKhdAO)|D!#Xf=u|icbV513p5MO`0XQqIq#0ysKeSGd7c}yaIS);nV1C;zGG~$Sk
zUp82U)+@KSkdj+5DW%1ad??I4qqBqsc?+LRZ{OtF;U2<AHkIz0Z<zd2dLk4m-e6`w
zhARZjQvxpnX?5qWb5n961sYSy_D)LIwFJRdPM=tcbf32#j0sqLfz#{T;jhgG7@4R?
zAF@r!*YxqeeR<u=$uVmeikucPDW+piOKw+5qU`bg>SysrxQC$AMoynP@W<%>->63{
z%g21)+cyL*HJjQ?P*xG==t$Z_Nm8R#dkxkuUFRq_k>q8MyHaS}1?-*>$@&E5`Di&C
zHqfB6&k`ZepBSvH_Moal<WJTF(wH4%k%$;>&@ErOo^yRNFq#6EQ?xi;SULDN9CY+e
zrEY7RajEq*N2l!iPiY`fQx4MJHT3CB5LUU+1yoK<1`mI(Q#Mu`O%BgD-6in3qyKY!
zKsDP<VZVdbdhn8lZD?#G<av6%P+05K>_JhiDRHg2#0e&$C$$rAunRkOX<mz((Kwg?
zT|npG?q770%OBM|V~HqC6+fr=N8*h7by{oY(3^}SQ4>k{Z@n-P($V6MgFBspw@LEI
zz|6aR(D|-$ajB`wOS74lH(HJ#Qdtgj4yF;Y-rd((0W_>C+2PM+5GWNJKQog1QQGSF
znrMA?rbGn3$JxN<TLA&1wQWs&Of(IdmU#~d-V_wJIvQ!79&uL5aKE#uBYB#hv)(ys
z;=Atb8B}mUj{T`!d|Y*E+xPIb=5jS$q-PAAX0`}w|HNyUgiXKhh=DnDx2QjK+9BnM
zLw=k+_ZrkpG}Vb4=o!s_3#SKONnm*lGBhG7)ob8n?{VvZf*$**%4;>eTK-5I^U0gW
z180vA+hm)5VjIxlJ(L^P`<+lnH-=td>M0$Gu*!vMwW`yPoQb8c0PV<F2g4Gy+vzh`
zec>NnzI)j^iJ(#04yixNI8#!g6IRwQDr`~3Up+KwP~I`3Dw_{?gVbiC^>i{*b+{C(
z<a8`YtDS21R<39xJ*?4|?@^{Z9WGJh59IF8yT7e#f+P>cT;9sr0*ak-U?mXbhaSHZ
z%Qf?$P6JP->SQtYcHlVZ-&2_t;wUjDZmOZI6zf$MIgu?A2sLV^)-Z(605G~36fF1q
zVW)7oq50iOG*3sLt#eDx&S=+BHvLC2ux>zRrvGrb%kFhSOQs0W(n$4KF#cDWE8Y<X
zl>gZez?j2QESp&nK}#v3Np<&|hpANo`z|KANN@w6-|XT8N`WSJBltQRyu?y8>B5x5
zsXY>YM)zN4{7XD7t26hXo)nfYnom_(>EAZpZ3tJuKHK$?ccGO_0JN)GE-|G{FfX=J
zI%XT3CRxZD^Y-U2^||S>k9=ylE>uv~LzSuqX9zY+lE`w#M(=Y^UWqFz|LJ@r-muI3
zP4Yw@%u^#VrNM$-BvzcaYw*e24k#Mug*Pyr0V)UOs{<vZ{V*U)OSfu$lSy`4yw-Vs
z>6*BTb`eMZtXaEPmWahVas62AA;wMd%IRa9qkp5JT;C_t1>uJX0*^U(e`^*Z+iG6<
z1&XB?go~w%A97_7Ch}?}2WsB!Y3zh;5y>G^pM|jF`^*Z>#KbFl??$eQk|v^xIR?G*
zFg#@Ij9G;gZNoKmHf3uvj17YnybiJ?w_d1+HyG*f1pWQx*oyx(g6zv&OCwfBqH6XJ
ziL7I=M$D6GM$Rt9z;UYOkt=v)>M)dAzK7aLmU_6MUU?Rg<du6fsgl`-ou>X8h+xD%
z!t2gv$ho%o;%>}}IO1XokXoJalUD{BHG-`{?*aqBHi|26@e1}3{@V;J2_MTz^>a2K
zEF4Vmka2W2A2^20Y0KX>8F?GW7Af8Z?7AUYQi@~rD?Uvu(URXDB!%JoK%^y`I{?=7
zht~m-1!n<7$e8{Izy<2c`OF`gbjTE_m%#nWcOuvphdg!o%0=f!xq{VwNA#&QFMbac
z{^q$}aUxgbsj*m*?o3>lPOpDsw}-zN(Y^2K+SHXo+3@4wW16e%gG)b^_WNkhOA@R@
zN2G9~jk?{JkqKPL`6Aqj@e;>MMvu&rFu5DTf3EaC|LD?^%4xCe6yb$xaNw6fzpb&v
zGK=0QUUX5AHeWWx$$YDwuOWVN&G=b~h!TI<rUf4yvZ@3bXr5&g(D35;o=N$`4IS;?
z-kt9kTZ5<b`{)N{1Y}>UKn;G;iP161LQJHEO_%q(XI%njQjz2Fd(rq%kd;gyf6{td
z@~u#4-B20UIM@jQ1gl&H8a^j_IaOs7wQ`;G;D9scjZu^E54(@GXYLXKnN|QO*`d%J
z#o}4>OpQCK4+HIn3}83iat0g-FPI9G_YU2=%ZtsOm~Bi|+oyc*2?6ha^y}9|3`0CW
z(q}7?@9fc%ss508XbV1i)}NJn>tq6UB~$|o?z(~jn7>MP)*;YUGtUJcH-_9}8XJ5u
zR^s>?mIzZmc?x$}&*=h9%RP`JlBIr<T!Q>s0vw$LwG4u%h;!#HH9uEszH}TuAx7DZ
zs{^=O8Yd0ro!o55>O2cg+)F*sP#gbz_@m(M5E`tJ1j*Wdx+VUsOgGV!p?F9P25Pn6
z<INCD3Z}&QYff>+1^RN3u$R<c)i$iwH!ZDw2Y3C6NCiEZt9-HX?mIw{+;TWr=nIbz
zHbY*P3G6*>77U{4{c(GYc4>PGdNppK4RBz6eixZj3iKBp9dyO3K=a-kWlfsIWxZ@f
zR`GS5D)a`im2x7M^2d3Bb78<X*);k3_xRS5_7e~?2`;I5!(E9Jt!Ta6=r-ec0h>8#
zL9JWgN=CK}%}!PbY{VTr+xS?Rw+=icr(S-(TCa`o;y_(ogZ9?}c9d9hEC>G<?ESzC
zWq$1cc6S8=k)p8Tkx~=C9z)kmZK(l(COoDo2#}ZN=U7TTI*>4J3EEaY*?UMdP)5Wz
zpt2cwzHJVSP#kZsdbZkm{C1?ZpYMLS$#g|s>ccP<(>m?<Fuze!OuQWI{`kd0yEv68
zE^QH`R)`t!f8x%LBtkMkMrRQ|l@@g3qkGCwbAC7f=ZE3J{h(cX-5mf*=SzsCHavsU
z{GD8X;O{BX@w6Q>s>B?cBc&6-Cl{@o!!K1TuK`Xr9GGxv6WeAV30&=RV#q`wkSXn=
z1~Ktv<68lr4hnVwj=M?i-DaMdceb}dMr`e7AEOkzGuelxW0slxFoT=XuS0xp0);9B
zi^z=QC@&{VAaw~5Kj$jUb3R4(%x1o^Z6GU$jgb)BJ18~rE?tvdeXi!cXA}U<i*<d{
z=we7(iRFX_rm_LU+@qL+`yFctn3F^eWubCtIh|hp?}-DD7#{FoYtSBskJKB}aT#i#
zQ}c5=<VqpN?V1~VG+D7UQZ5_K6?aGbltrnCB8P~MDTMmpNkc!0C$69(1N!I|?6-AA
zzTn6+D--x7{}bu(V}x?H>>xnzD;&6>1(qyWF9EkJ{vMg%xkIxbzVn68Z>3aS80c}@
zEf@30`O<?i$A{Lg-N=?MOL3^|q|@IX@PGEse#c}7W96HGU<1Qihpanq7k7yRpk`Ey
zLMtrLl4+BDlWNwz;OUrt01TTl$SJ0-Jh0p+d5@QKAJ7z4asAEnDo{?nmCD-#_?tI-
zK_Vq<zbj7fSRQLk&$S^>;*a7Fb?0gp(BU9~U0mqcfc;_1)njsUTvA64`R^gNLeZa&
zNUb1nI6|Yd{<N`E7B!fE_V{Dj34ewBePU!9_XCmSNeHii^0bhwE5WhY*od6lI%zg=
zn|X%dA1kL8v(6!8RIHf^1BvpV!~wROT$d}vQ-J+P{1ee`gJ2)8`e#n7zV4U+uvg=S
z%j`f2B$?;BblV^DsD`-Payrj%Ha`ak3=|ic)arO_B1r%S?&md00;vUiDWPAN)Bv76
zZtM%nKsvLPCr5%^n(s(R&&*RlpJyh_A)_{!kq4}FY|Xgkz7>(X`mBkeiWM=*;P}5z
zHZ%I(mlooZ46@ZJeFr{x&nf#|^N?_~_~5+w)z;K#VYiXe72OFC$<-!QCg7&-gt)Y)
zy#+)q8xjp(`dsvGVIR}ekV=>7wuj#aBe1%0C0tfEX_JJo>u-FZTGSz}CJN8AAB>0m
zrHr4!&(1#(0#6ulgd-$AI@5uZbio#Y3M)PXouHUq;OMRMzn}En{j|#r@log9y|7D|
zPp*vj(%I131yIKi#c>BF*!!}(=6(>e1~!QIhjR4aE%In9tko>2Y}<I54xi;F0UA>#
zqFnGJ*O|vtJgSN<?iRRVAN0TjMzjX|{pUa^qnblu=81^aQf5=#I`A#-lOG^ikI!Mh
zLP{9|TTZuqUY8g?{ec~V4BnBiWBcS72`F)aw64~GxMR~`3sT{b$f&Co6z+(U-A8ed
z`wW)`piZ)4z9O%YNvdW}5VX!@y<?~HZ1!DN*_A}qnJ8u@`^^HfyXss7({<~`nYk>i
zN8O2QkiZL7hr}hE@mQUck%@H%h#gVUCe7JuS>6<I`q3ae*^!@ldMs>ugY3!%dA`-X
z?^Gyz26If+8ncj5T98<I?n}mB01NHhbw0quN|Er>*@G`a@@OP!K+4h&R;F)?=5ibp
zj0e-ZzLEk=a?=;?aUASTpiNt|k#2++tuhJe`kp`t@I}2FnWjl2n?;O}-1Vb|ATXw6
zkB7w?0Teb?@p77PG$#^CVWdLUqCl;%kpT=xvaMJZ`oQ_gqmpZ9^v_n-#6v}$At}*q
zfA$kjza6Mx_g=~Jtqf&)qop(T!PDf(ch@dO>Bp4HQ^s|(_UAoDaP2JiA(76GKV+b~
zjA}2*4EPiz`<3$2^(ngyc>%slDE3yl1^5Qfe_|6av-!%5%M`xrP{L0l@n^C;`IaYV
zsAlK8mBpR)@~?EK_XA`dNfx8nH`rx=Y^Xv#G*5p!!XUxVwbbY9_QgOn4<1H*35d;#
z*U7reJQsCrkAzXD*$r;{bPx3ojM7a4$SX#yp()O$N~slTP?-%o-%e$-mOPPrrRmbc
z_~-_sJbqZwd2M;=qbQ5o^2;JJ)eUr%s4%98_x3X{xVQUbU2*Nj+3qU+Jst)tZo$yQ
z;M}(pNWiujd1Ch8x=<Jzkz~~EVIn+!Up8{b)pdV-j+Js0%ZKByKcgc(jaz>^|3ZJV
z$dtuF;l`f6nGf|@$dB-Q=9EPF)p2uCFn{*GP@>~=Q4|pchF|U~MjFRB#Hpzap24AJ
z-agK7g9My#X^6li&~eOl-6tT2svF`_hbzzOln%aq^##K^0C^&hm0EXR_y?5k(-2Dd
zM>1uAet>;t>KC6f)5JpYxjC5JhSC4dV?S1Y`ihv<zG$l#3&5XeCfzu}$1%eR=3;6>
zO@d+xi(4JRJ~*`mgQ9w8PpfSLf#gVvUIsp4p~6Yk#9U=K>$^QPL2+3EiI)(nn`e*J
z1S-{r>V&i6DY53uFP3>hBah2u3MY^JsaJKX31M}H27`7<twW~pT?v})gMc@1tT^!T
zJ0IdXT+cZj@=(ZM(%`~rh`l`;Y%k}SUgk4Ja#h?Gy=34M8M4>m5%nEt0J#P8v#HJW
z=QWHPzEo-lv#b9)%PI~i)ef?I;bI2xLnwQMSdwxLn!?<^R=cKU@(*$@J;ej)8LOp*
z=Ng90fMA7w`yU@c3+dVy#om8y`?oB|lY3({2TBTXeKNb;vZdv<#zn~q@t-8o_!j}L
za4@9C$`vAoEI4EIOza8Try!xn4GMheMxY-_pHR3UR$%3*G~~7B9Oh>Vc#yMAv5obZ
znf<Hp*&{g5-O;7y0DGk)M``DQ=FL`;Z%M)CV0cGQ{j%ui6&0t$f7#`4eyVJLY`j`t
zsBgze_TPo=+vnUR<_`b>4!BZtLdFW;Pus4DiQ>BB0`RphE;#X2BIJ3c-S(@THVQ-r
z#%F>@h!@<3?=xxaHuIb1jsw(Fittv`>{=uL8}e;)@>}JI_#-?&$X)bL_UC(!;$>q1
z_T(@&hnaOU(B-I7@gl;unKNzL=&#xS(y+~sD&gVZH4OThOl3pOx4g}hsbkQ}2Ll^|
za2;H+NzL(DVeWsE6PWSX7<1sF8bmX3t5{Nx)@WY$VaMY1U2CtFB-FuB)CD@7wK!e}
z+O|#k=(?Trt(8!c?kdNH6wYcGUfUg4SeU3eU>7W6uEY#PeaE!&nd4LnGilioN~Zp6
zjy-*eM2qlLL4rmim3-FXAEpU+tcDO;hNEKcWq5kA{BjJ1hLyW=E4&^}D}uFIxGh$c
z{^U>l8}MC#0DxFvor3KYwIMQWz96ml4AT$oF{rC#5<X|XbVAW8C-eB3r*)qhia|R#
zOb2}UPP+GtjV!->Sb7+QwGsbS4xK!C<CK@uubar=5cb;7Anb+fLvszW@f~eb;wy@2
zz9BsM*dT~uQr}v-WDKL0@L>k;c%N{p&E!}HLHBUw8_xP{inM!Xb!@cbFrE62n2~Ov
z4f@S6`h+2QHuu~b-A<i6OtErJ?dHcibR1a<F;ajz1lsnSTzzoQSp3#w=dny|<+Q_5
znTz~LSy$lIXp!0QcT+3_Ovb}K#jEh}!Q(nd&E?ygXJiROFvw+lHdy|!E_EBfPYf&c
zIE(N+dS%4H@#9n#SJ8Z&A!1q-k|~ujz&}*qr8qMrkntz9?r+tWg4r3}{36?g!k30P
zpO~5`35L84qWsDYu(@q_`zLJ_ch+I@rd@ksn&HE<hx6?ir837-^H0AyM<|$iMA{9F
zO|{r1lB^^k>&m=|kZRm~Y={h7MDh1YzI|AFj+Cg8#$VcSz>09EeHxzSB2yD3Avr(f
z;YctFH0q^l3mm(kxglULg+`RO_N1IQxG856UoK9+$Pf6_b6-c`$FGZTw#nGU)hqsK
z=f`h0EN_}!-;(5;PvGk{M}NehQa8;uKjN}U_|Rcghu4F<AXNL+(mH8PBf1^LdFlCG
zDWmQqEXUJ~vtQ<o?RE67@%cHIo!n@ApJFv4;?N&g@>CtJZk%-@A(jZ;lYfJ*mM|8%
zM{le>Im9MGvgZ`~*f2YeZ6lI|8cy0!HoEqT6?vWlk*rqN!ajt4J$S`ha67Dv8XRqu
z(~*Zg`1S1JX5-nrrSiAgA4Id#FQrS21QGbZ*H2<gCP9gosZCe&h&WTb566VUXA@Of
zv<udM%G*3tqbFBO;>u|nVkt)9VqX<;Y1dc$yygNn@ABGgo-w%ck)U7SS|%lnGLmU)
z`p$I!kD%7_>K@QMtX<kVC{U2d7)l?D40IN-XBIB9uLG#~z8iMg#chfd8X|j)FFWcc
z&mvSkyg73PwRPSnF6~p2{@C7+a>*4F_3&WTQ@u44V#%E!R(W(qyx5_!p%ut5IehUC
z_~Xw!H`4<j`$J{;DAfiPpO-`rRp9QUU)!7BT~vj4lY%eN*A8N{rMj&uR3ShBY}ue#
z7Vh_Vr6Sp2PNe6w>v6f?y7gWOX8&dyjHZCbYa+^y?*(YT00^AlwkEM~**U9IwQj1g
zuK`kYLub%by7VJ4qdA{1DGz`<L+f%6%kQ3wF)LX<b`n;iclXG@vxzUJ^v1`&O-5@u
z@q5KqrvuvxCa$ez(O4Y2qbj{o!B>xWj^#142~&V?6by_~Vt(s@oQX!tzNPQD<;Dsm
z|J+QV4~X$u1aRzw9US%(i3RPJEPwr3T>`A-OnLK?*LA~g@TVg_Mj-|nqyC|{cXx6(
zT8;_C{;iyd%6%wTpRbWX`%B*uBm=NNP&8Gz#3#LWPgez6{W8t1-y~W*Wp5~1^!$yl
zXBFGM#le(MeT`9IwOrKo=f8}VeNVh9t$;T2NcJ>LlWLyB=m7uQ%MkfsX|*|B&(4Fp
z^B-zwqA_UdV>hO(niMp&)%wt}QvJ9|YkQakUX~-ko3GYlM?NpC3gkpQe~O8WeJ;F#
zZHn|=8HOUAVtw1zm-lPTo{Xm7z5<*_B6e+=&+SD#c|F0fD<jC1N+$QqEPr##jSQF^
zu*T+86=!M6om!TO!k(A^I0NdSKpF;(?@s~D4s}PgANYls&AW6JaxmscL0gI}WyKNC
z3lY!yQW-)nC5V3<j3mWS+o%O6YXjdYV>H_aeJsQQhdu8NO89l$T4MF24M|)tqDfu^
zw|Y6=1s5#o)O)@&5J>L)y-<)T^K^N_&<A}|_zmpIQ|vPwq0pqJ=R9C|OqG-iwN)Nl
zd4n))MdPi5d;862^Y`1mC@jj12(&FGW?`vaJ3I+!PVt^OX>!Q!z6YYXP-=;@UUyG$
z4%4-@L2TDc`3=ye4uLIuRlHtrQ5t{Kko$#;RV`Ct?we_R{WN_ezCFB?4z}qRZ?Jk0
zLK*&vlEKBoqUd6UjX7~V$lHFny$5uEf9)hu%>65~a`$mtAT@#x@4Jl-HqQqxTjI`^
z?m!i(wuis9VE6M<u?^SuvdeJKuuld`3E@<L*}Su|32BGEjfTbB4NkdM0~6pGIV|Z2
z+DBKQWhJ-9+BujSaz0fvl~|C{;9D;t5NMbS@_pL${+z@LQ(j=b^qmdIl8Wrkkww=E
z#(!pF^@6bGW9IFQH!qeR+W;iJ=`cPkbx@&gUzQEe;iA`;Gt@((qwgf1yAK|Fj?D4&
z)Di-(go`}G@6tSO3FAP=ln3woe}uG(0M1x>mSwRX2ddw+Y8uI|4>*AHg*y28yv}nz
zr=-wKdm6<aix>)>fwU@-2JPgb1-yaYfR6Foz?EpJ&{=5_06^OzN}JFmCYrM6l~^;N
zlbsix^jjb@vZr>OFPieZQP-0#(1LG58x!4t)D)q@?y;VmCi0dJkR%21ZSk(5MC@Na
z@Ry|@<XEH*OW(}$ipMZb0P2Ll2agAYX&F3wDaLr1S4`S0eV2z{cBBqL<hoQVbHw^Z
zK46Gd;|3l#45FDzYh%;(Q+I7t!zSX4WCEkUVq<{1M$>LbTebCJRFJUOc}W6a5;1!(
zoDLX^Oh`o>4eHFjF4Oa)A=o<<c;Uz|xbI7)v^(&LXR6ZZ<a4Mf67XHUg!9bk*5lv}
zB|O4=BLjbd97EE~`{6Ul>oiXZ0i$AaPiPg=4LgpP$Kpk%xX}B#kYr?|hdRWqU*fE?
zx@-<O5}FDvkADseeY3mK0Bi`6dm1nAzVV+2RI#mE;XrKl`W#hvC7#ejQ!$X1w%GB6
ziH8c5>Vw2&{U<-PWBvW;N~=blx3_pN(567?cjv%jFWwpUg)cyCpFYU;IKmi#005~H
zu*0;N?q>bOD{oAyYJ2tXNm2GV%5FT>8KdG~N3LqNlifTzKp{AtcFgxENOoPv!`brn
zV3~m>=7-RCXPJ>HTH=(WIwC6mCpy+J%9)c)6D%D<_m<7OrJ;e#Z3U>K3PXT#vcxG_
zN59;*=dOF;yD4XWie+EWu{8SQnF6m)FhIUNG$AL!VW7iey5)4zzzPdCrZ200UUwTF
z`1f)cGAJe{*e^(xyjrM~oMPw)iS7_J|F;>u;fxdIRC3~XBMNRq*B#t>(#-Y7ON1BV
z;4QoO(~ah<{~p5CH|OCWPxY71#;d0$?eOv4gExKO088s~vu~@4?bk3uSSyvP_L$Bm
z*z+#}JvHl@X7gv4_)K8OGzj6{RYYW~Uz=NfuTnU5i8uQ`_zuo4I}*6JK#uUSUd$36
zYe_ZY7eel>|I)fs3>r9LW}k0nS>2Pv!C7?tC%tNkAZI{ev{FrhN8uY{aL4%pgVxJN
zK0c9fuI4m-kPw~+>fUVom$hTK6;bmvjqxy6m?BVmO?@GMCM3x-zQ-T!>E({kP!9iE
z+Vv@j6db#fa~vGGN%>f+h3Fv)9U#u|NLX}LB6~*Gh*KyKHSE(-;>*HB!RE*C^o3Zr
zfKCguJux#+A4RQU^(N_;h~<^w0(Cz51A;<@?A|Mpt6kdrOBcj}wl%D%kO!Qrk5$dD
zIL4=^!%_&ZIu5bzV$1lHMf<J1coEs&A9sMEDjOmxvRpac;xQ8$Bt)Gzs8Gq@vGBwh
za9s=Rf>MC(crevi7)CW6twUXM_8|f}5ru4b>~|tVr7IU8c}XsABfIFO*Ox3g2D(QC
zWhNN_VmoxrwcFz(P=eWOfldxczqoe0nnb*bmlq(6AgUNlBz$@jNQVUSS7ZV*RaE4T
z$yvG*!D)*-d~Ihg@!I8j{}I6L0s%NO2D^K)wb`ks5vnRNcUkxJ4|`gmeDAO%DT&AR
z<FODbbjlPamgd({$cbBAeWxTTf`Ed`e1@AXrb{^sFJ7{-SyVXL=Syn^LsttTt$4^%
z4q6NvEHC5IRJ;L-zPU^E_!Ou!s-zTxa=e?Kcz*h9kGh&aV!xrqd<Tx_i&<j$Gkt3b
zPVP~lVWq_7_A}~qz=oe)hf>Ce;E>~3!`7buh*pWl67R_dgGIK4sQm!8ZZw<i;S_y?
z;|FcFIO1>(WN_7M#k2J74+oNis)J4+%k;97mb5C*zS;4N&c|b9d(EW=55PqWwb(|?
zpFm-^W`F<c`?hUGrG78X0ZNr_sdHWen|y<e#JiUd)(_W1OZFAmbwk_@E8+FW*iN4w
zp#Tmx8-H2JwMU$O?5fu?5TKRU2+INUz{m){l@_MV5D`Nhd_>5m1!CWz$BJEBcUm*;
zOU`vw$TP<zX17plk&jMz@xdDVG|z4A^dyP9;5LvlQyEv>PwO_V3=bk+95ldR$%0F@
z5+Nq4Q>aqzmhOPYIP=Na`<V9GzkUUv#}l+>W)R!%wv$osiTY*}g_(Tj`N@0Tnil>X
z(%;u(p%okag9&QSv3sStxrp`?af|#*e!ef8(B2{0#PB}$m!meX?KHdLCq5azc!Ugv
z08D;NXnZ|o5jBh5uK>#JIIY`Ub|R?V2eu*_2tC-ozXr^Vgd~3rxDVHRf5z!KoZJpC
zemGIs)UdFO`R^pn7J5LN*`2ol$5TcD=~C)?)Jt=NnU#;Df|lg7;%Kw1(64;0LZ`p!
zA2b>#AN@S7Sl^|v`6Yq>4&kn3zUV)2<OQDTS%9-Gws(X}nID&$w~5AR=_sI2J(-*>
zzx@Vx1ZTaTvz_u{jUR)<hwOc#ED&kxQrsL8NbhgS8+9}n4<`@al;@10W_c}@#^PsK
zE?=K!O|Di>aiF~eKaQR<xh|{3G7S$Fpji2sF~h0HdrMpz<@&7R7g#q>OlTb_){W&A
zblzSd%s5N8`JT-FCxa9z;)~fAS)~^-n++S$?#prCD;jus62?Qx{W0{$;Ugy`bTJX(
zn*HRx8&jkM7$bIR*V#5*eBH705P#p#@{n*x<>1D~qhPPL%4pbopp+6HF4>a}%*BE*
z@g+Da$H7EStf}hLm=!<<fUJTL&`6jzpkD1T0f<a9h{`<og?G{Q5#J=%ger9;^&;gb
z3)j==J-oj(t8}n~Sfw?dyYryp=x}s?^N0kiZ1<1l3U1Xh{-?zkBKzDErcH)wu=MX7
zJyFfSli%U5Lj>`>oAw&>7>AgC(;DVJc7n)%I{@|iX`aj=JzJJXIY6f)PCn9V`+G0o
z=H;)3u8K@?%dt(%R*|6z&o!|In0?+VMsf%5q0-YoXfWO6B@|2r`rSI$Vz5IVye{F5
zu<UMqvzlA}jdt>q@?Q25%|DU&-FGgG`E%m@jEsn2`A_U#lBDBKd2D_`%UA8e(8hCR
znLHBdji`q#=P&aG588N@d|jSvvF{u}!eM2$<)K69pYrU2X{je<lR<JF<}+vNonA!n
zAH^JDI5IWY|9eiWIo{^vXa<J5y*tGv+x%zJC))2z=~w^Z4&H&Z^gbSZjop7+>!u8=
zzD*#uiw4D7lAJ21Gz~&%I!jFD_yB*}cT4S}-*^p)+)4O#ljHsw2BFscp#%4D^#syk
zZyxUG-R&1ia0`)^NX6w9fx;e)-CDEY>$aeeW@tZ<<x{H_<CC!c1z>aM_RIvQE=%yW
zwHavVJelzueE>B1VqccyZ#ch0Gbn&&;>hg@JOMGpp8v2ZiuVd5YM*_@#4rkX=X)e3
z$`%{O#x^#4TZiX>P6d1Kbe0?LaK=A5Lt3FPe8g}g@X`;e%P7CWNVI5|hfZl)Y0T4;
zz6~Uw$h7D<iB0D*7@1lXeC{8!vbzjN@prsIc*OkIJ$gfW5~sO(g!MDFu~Jn2Q_ii%
zXZhQa=<Li{)U3*ds}vXb1^(+V9{74wUH+>Xx2eE6x3WoEz0Eo1%~?pm1PI%cB}~l1
z$G^oy<)0uWvW&Qv&&KM2k3SPaa%Zn5WI2~Re8stHOLNG54cQhcpsIu=abwjeO$C61
zeOKsvKJ*sYm(NZm**vZ9$!WdGw+SqR+1W*8ax}`I4kr<m<$A0mh~&n&A)A971-|Pz
zaS2hx2X-2%<-!j={(CNNjQso-QQA?_F9wJ*bsgy$8kGY8D56U0jn#a2#UBXo2S7@j
zm(QCWA3DWwh8Yb3@Qt$g(tpd3gCNm4z+Wwo#R*)J-|ChfT50`2XjJ=w%6EtfK3LYa
zs`R%1I)D1aTY@DE&Y1O0AdpVWot-)0_qvEhF<I8$q-gr0KOdmv7EWT1^oTd`!Bkp%
zXHmQeLt#CGT$tVyM+#PFEZV(r)b%<pq4=p<fE#yW6dxBlK<g1+lHqqgt)R&e?v($)
z^U{I-sUr2<UC0o)f&W<#yqZgZX06B}!|%#VYKc3?asj{iU<SpZ>s}!1_gUenKEdeQ
z$vnlmSF_XeOV*GLv?cFi0_(DV*M1)!RkEw`x#L5o6v@0TX*jNlpzHvO2cur4WY;n!
z-8nx>_CPbP$aTp$TK|B@x7xG0e|7?=0m}UybMF|`$DXZ$Eebh*(g?bcohYO)RN3T_
zq|Y*7@ZPp1+v+7R9hC9%voU~0yKztgOtFmffX;^{jXUTm0Gli>XFovw`}1;%E9wEk
zPjUQ!a1I^hpHm1{E%~fQ6LMiLY%>7@W+W6I$P4JgaLGWSIFy@x)KQ|Q5n~_XF7d}@
zidWnB+Gq8Sx1EpA!vX5>OX@!vt*cR03K`GT>KPN9E7f2U#c>rb0r)so9=V3jY&tP-
znAYcF1gihFs=6Ks)HE_M?BjJ=s4D(niQ@DtXt+%oSg7%HnfS->a?x+r&LDhE*G_Kd
z^DJukE}VE&=gY{_ZIdIw!&|%l3eW*V;Hn_%&y$wNb~FTdjJxKq2P^hILmv<C;Dg>L
zjWOZ1vwpc>w;v<OM_p)c-BRkMjnUeb+ojtUa?j&dw=oPTK@g3Q6-`$899iT#mmHb3
zow}gnQ^i28JaQG_adD^Mx9xE+54(SMue6iCVq<wOYg>x5X8R<Q&2zqEB~4i*As1Az
zEMDLXOY+%Fy(0iR`~0p6e(f>@u8d3SC@Y#X<RTvx6?fh}Hoy}>hFx4@$Wrggj8)QM
zQGT~tk1NKz-RMr6GX^X#FKioWjS(~qW={i9sVUgk{1WB8`vj?*`cv#UF>zS^*$j-z
zvN)Ol%b9MZ^zCD|M*z_JB!ofWM5SvSKB5}zq9Z2T>0+}+TC+;_IdR9BZ*Z}_7nht&
zdXE|OhL}l6t2Z)RlJ-Ojat@8@Iwe6aoJog;;2vwHU=<Cx3lGOy12^E+0<UB}^s`3#
z02V4ColCksWzGJz)pxH12O#Q%YNvYkkxn@f?`q&Hb1tHOvwx3tz~{n*!if&Q8`)-o
z4T9JZNp?QY2>94x5uKYLW`j6&e3r4v5(@Rz$roggiEGA4a(uB#Kc=+mHo9f;dO@;#
zgYAqbL1KAYvUvLt3BcN|F;j2ZU>J~r7|su6b0vIolpk<1M%$1vbf6fo?rx!p&q7vD
z3SDz~xFg0Rcc+f-J`#u0T85@#7-sIBYC%iNDF)Y1)CLS<li}E8k;VZmbr$y7T;lT7
z#ETSd9aZx;Nl3Wn8}lvRsBCv}^RIs_^Lt4Zu0~s(SwCGh-?Bfd`BCeFM~-C{d8m4u
zGu1kMoDD!pby~)9RoC$Q0W<<<+9y``0kGhMhZM2dgE|kCSDB~0Eh7hO4pc_#fyybn
zze60PfT!kK14X7zMef^US!7{U4`5YmH3~#(w)m>hP^;sOkJb$M_<FIN@8Fnny;Ew3
zIuH<FASUZjuca2!_HWx4SP0k}uxZ<c>jPMng6dqaTu$<bPXHQn&j#By6gxO|K3ocy
zfhgarFRf$lin#G2Q5w)8sstyRPHcyZ>)}NjsdiqCq<iw*xQi<2T{^TDbNH^M>d=vJ
z<9fJD#Q7QPin4oi28b_pFitJyObV*mN4{i=IRpHZ(@g&~xv!fcQFJ_~p6LrTc#7)j
z7L`8_C8lEGbRg3{!w#Q#YYobYYgaw^jS<NuawW^;hK<`((;S8NgYbS=G#D%43dy7%
z*<s@y5bdQ)a?}1M&^s-u42)$koB@{+NEH>j`R6+wKXIV649}Rr8jAz&ToFk@wdIW$
zcZ)ui0KS)MtVsqxMmhN*@}00{wN=c6PS+?DX-<r-%p+<`T<{MVR=!6%L<3tZ7ofcp
zmFB4s334jgKtk?}EY%aFMQV_bz#GS|9P$U<9p@C*=)jcJ4?zzA6yN6AjTQUjrt#Z)
zIHf|Ya|R3!vCbzy&6%(L6tmX>BBvTc-vcf?R(a5}+N-sWb3@8}2(Uhx{zr^ci$&wy
zO?Ho!lmXlVSYjgJ;vQP>j;8Pc9IbfEnD*K*-}WDNPkrppb;0q+%6mngCW_G#z9fxe
zx@Dl$=t_V~5j@^No&!cHzt8C*lN0N8QTG5Jk{waP0O4d>PrYMWt>=FmhO9HZM0{h9
z<kFoo`PRoJ;#@zAZEELk60Oa#T)vVOqt$+}kR;<&??xyUzu06aHG=j;Y`*AnNCHr4
zLzwNA^=jpZjKr3+(p@I3G+aU$m<OvUln2f(w-QHMk&W7_w|*RdYF|ghHo$jP!_)A(
z)ht^uq1~A;gDzB<hm@js^OsR&X4u>gYVkQ*WIlk}gkWA~R}*D%$n_=KV8{vpU27@f
zWAblCpx+<x#?c>@>Lg0p=TkITzxWH3yp+7Q+-SX}Y@GUN0lgimw6eZ02wuf$l5vOo
zSSCJ7G4+@L&8;eASsQ{GO1pz0UGJ+4o#~Y^d`K2|E6A>`)WR{az{2T@0bp+1eY>_&
zP<xuAxH~t8-}>s3>}&X1_3W51^RbxYf9=(QR&Tt%Zfj7VQ56sl45v?)t9yE&z0CP<
zZ28xS#$7<U@z3=iJ$hrEd;p>@;o8Lap2?5ME(KkZj_hNiUyCk76*mahl3=cbBhv-<
z0BKDa=MU+v&EBo@GV(JR85jnL1$YL=iyS0Jr5#wP(UNeob4jSvXwyISO6<uH8>Hjs
z)i_{h)JyqQEekX*g++fS_&k5z$$zz;M*qnM<0kg8+v|2UmvjDH|L|7pmcHtI?Cv2&
z;sxMm9F37ZH>w%t;pIORP+VWE>Z8Ow!}pECUT7+c(9fFRTbY$=fSi-^nINC(pedH{
zN--N$=Xbk1rG4bqw{di*#ESTR?ZAEzi1NTeqqAkPk{O0ea7qL^=ht#*S0niT{5YrQ
zpa;WNz{+E|cDNsf7d9w#(BY<&xkq#cchPp<nBIPtf1;ujfExHx@Yl(Dszyx|Hq?WF
zTO$CI@3T4qJ3E0_LN&?SoX3pdxRCVE2*+F?-!|*Z;gocxVl5Fh#D;gU6@n&cKdc0#
z@H~V*Eg`tB4&_hoFk@2M#18izU+YUQx-vIx?=LA8Ke4KIl+77ZV~-g!e8ff!Iy`%P
zNn`|`fQ>^X$Z;SbR<!<qV%P<cnVAcFmHMnkwL8p6|1}_n<PNe}D~^u~v-~C%DjWaN
zn{%HdinCIZI1~tgT38c0R6j`)#_`Z*1RAFpq78HUFW-qiUpaPA!oIItG*^d^9q4eo
zaGP89nA#MmF%#65Ge<>15K~Y)e#{DB$FEL0*X{VazpNPODl9T^Tr$W$&%fS9cFKW}
zZR$T?g@!&us?|yGCA!Z9B2qQ$vo;!rDYp$5uADxF_*l#o6xTEOb^QP%PC1>~vX+Ih
zlPg|tdofaW=1*JJn`1>;;^s7xeD=7B<&W^qG(nZRPa)@Py(e`|&2D+nEi<iuR;Xkr
z2RtDQymsloX?nf)i7ru^QZJ#oKiwEUqRt%nw_S5e?&;zCKq0n&vm)ytD1krYSi@2Z
zbnFu;gBLef23sgSPuL+y!HfO#c%{G}<B#2oeW95-wVKnJ=KU#PdmdDY)4w#Mx17&Y
zZ!{yY?jIvb$X95s-*<|Oa%axWQ}=tOw#Fw6Msl1rLr#)xI7rsOXW?fhcMD7a-Hs#9
zA|QqjX*13om*DQ@%!zS6RU?2G{eE-W45JQfH+bG+;o7@RvyDdmNamw4mJzvanOsv=
zAZhk92mo-v6nn0Go_)oY4y7beF@O~1mnW2Z{}iP3(ml6(^9nEkj~556!1P2bMxLC2
z;IG0zZsp+kC{%gvk(FHuz}jB6_K9}s!Gw2c7kv0i?%@qzS3GsJVP!QXY2NjmF-TNn
zOI<m&fj_Bx$-#A2L;aTy6KW#UPyviguE>czFM?4rbA21L32U?3qOhFR+S01xt`r_Z
z^deQqlwzAF@?JXg$AJbP{ZNrZ)$6^<ZF4_fFb~lJOBCy8>uRih?d0Uj0$6wP{xd;(
z&T{tv8*xS^7zqQVOTcpj<%Ngi($i{gUk;dR<FasZ&^<No7<U)2^4?XQYf^*pzyu*Z
zMUr=F>~CBOR+J2&%)><#W}){>DG#b$?bIWr`XWeI2di4yj;lD2&Y<8hVuy^nH)!oc
zy>L(Zam#E(li1a>fBma@=}u8#?7??tyt-j=4{*|L{4IxAA2RlYD%HV_q=aGq;FRGy
z5b}2PQ`u-k=PAdmtZb2|6ehUUT#QX)wSNhIdz-deC$BAV*LbS%sYRKj)8fA(Ysa1j
z`2!W&br^rixIyfMp4*0j0_8b#AqMO2=0!<CCA&lAQ{We6%9=q~f{4oCIY8<e_h$A?
zCS?rpTHD%(2NB`d8E2uxv0L>Fc;Hufn8#WO5TBD>tp5xd1OD?%Gs}Bd%w1%Vo9AoD
z4gN?=Zc%V4n<Fm`4MXHf=@_dh?;FtM0aH3-!*W%xE@Kmvh(5RkW208T=gy%<Sp&|w
zY*I|VdiI^EX*=#^I9A>8T~GpGzsODyN2TUldqdQawl6q!<dkx}(|hd`tAbPNiHabh
zBgpf6VFV~>5Qa{wfnudYTiNk!|E{9s^x5m~Y>DSfouV6S?A+%EuirY6EReaDvk2ea
zBOM0Df;XI7wE>+LS_YO1(2+ZFw=P-?X$pY9BT^B!71V@rz%EU>S@RL>U;>D2{`;5+
zd(t18Jqbqhjtha?5g#T$h^SOp%DW3NmZFleF0IMjXzux&snFUF+(g7?bn8MD&@mzZ
zCgKU^S=_V4=FmisqxE9;sIoEcGpSAmLzDLR11%+oFqdE6iz&gsiGA2a93ulhU3%pd
zxO6s@UIFkkT*p9TTdQ6v1J0oH14jOA7xvu(UPL49><FO52#LNFZm3#tU^Puk>p&&8
zlRfjG6G{p7W$BvD|Eq}BUZR<q1$Gjd7dZDI?<&iL`p-dVtiAbo(i+(n5n5R>_vkvQ
zguf$n@BML6ZpdbGzQqRbSR5k0Y;Q!ogiYbmfOZh&Wb#RS;TW86w_bpxE;W%3&GCO8
z+Bq9i4Gxm4StI`SJn<3g59q+x7@y(08_GcxZR(20Y_iwxvLgcykt~@0^SjD&i(fuD
z=XBHoYMG!@jBHK5N(cy$XrYq5Z>?J(Edg_;(q?Z%;iGdwE%{mbq{U*7h6%=(*^-W7
zk^Z(Bu)eC1pU7HrdfQL1nZMclPdVRqJQ;&!e9hURi{D!nYd(woK&)pz<eWFVqPL*O
zWl841b_x|ef^Jy2>*fn<%-;?X#!5E~;EF~Kb6bC?HNhz>k&xRtZD0UiGUf=!ZM3+O
z5#A|erqX7qLHlYV!!@qga|o3_@bxI>KWpzF$%XKgW<{h+&U<Q}P$cU`p4y26|JCR7
zKZe@KtEY<m&=q@SH-1kN3O1M^>OqYDE_4lTg}@<_^~1fZev6q`hNj?-lEB(^4xDnA
zaSB%WjB&S*UNKf!<#`?043=-&L$P9axbT^==3`YwWrRJq1)`EpP5VOhJ(1w<FCe_7
ztY+Zl_(!A&cAL~msNxk?pTsfQm(Z(D!?mV^HxyAGgezKokZL#fCzFc8-k0gnUU1Zx
zb5&sVmhXri;Q=vr5Tw@upXt-0%|8^b&1c7(#@`<i8CGn2%}ay+geK1H1Z8D;`0dlw
zwoqe!wC%^G0ec_W3Mr-d)VfmqrW53<QZI-`cKRh>35cHwq4H-f<x8g|l5Sd_x7=9@
z=M#Ew@^;n!XSU1r2mJ6tpyfZ9f!6pd>(uuEPjzhs3EXnvrLzyD9S``b`sS6NB35<O
zVpt@JRB6GZuJ$}~0*gpV$X-f~r({x~OE*N>?YD1PNUGi37mhmT+zo0yB9Byaz2HpA
z$xd?ywA!^9JQE2d*wyU%PuVke0Rldv2IB7f6H1k{R<fiSBrDvkEO)vR)W7zkDe_1`
z%l3#s$;3@6W})ASdnPwn2kc-CAM*Y4kFTrenf_k26kY(p8hP0h^dDI`7b*52TTu)3
z<eFyy9WKY(t*pLW>w5kG4rqRWVc)5<SIcT|qx&tH>pqcxiR_b<`%&)=ZL|0q{sy{e
zey{}&DXO&hKZ0K2fsq)eVf)-x#fKqRLuZNBLSg&a)2*Mru=wFSs0DK<<fO=4hs=gq
z`&Rjki+B0_8v?(;F%r-rNmN$37&g8&3UonE(0}mRN}5X_lRgFvb~q)UH+F)}{B`#>
zMJs<s`oTi!%9l#*+A>oRNB$ytbOWc-7Xu*Qini}?-c48l&p-CFKs4-B<Pt#T!>j(F
zmA_$>x{fmO`?pK=n(>yNW+yo7!Xa)0-1av#$3WJkeP72ncsr2yq<z4-{t6eQ2AKYE
z74MT@je#&Pz;A_KZ@060Ce~k}wHB(i*8Ot15lI6l8vH&G1Y#SN^e&Jr;MzFFx)9Ks
zl`435P!pJM>>b!@Y*{_|55c;}a(}n5q--arlh~`hEbDX$(2&32Ip7=c(Pi#utvKd|
z<vs~5W(G)@9aqG`oOYG;uw(I$7zqo3CJ@sTuxD(-0ohq2Gw@g>(W_3|UtH)}NsPqG
z2`AUSQ9C<KKhJRnLiWz)hrIfRRQV{$->1_qO@l{6Cgc;u8Y6X9vWh<fzBUS#>P<3m
z$$OKBL`<Vlv@zZ0JHhN3b&<#AG0(YwWA!U3;B$Wz7$Qen-_)5i5By+#(>>F)*yNaA
z^C*?3e<MSDL;grCC*s~kuI|08tp@{M$!lV{QNLq+HA7t%vfE|Nj<(5av>FGvax5in
z$!?u3hTghodH^P2oMc+`dj>Ll@+UZ|1kJ@jo9=p;ZNpZ2udQzUHxO2BiwsOm;Q!a>
zUGiV6*MR6vorKsXl_VszTr3k)1aY93glAC9-bi-5g~TrLxZU<ppdu0y+jZdEJ}FAb
zsqCmc30|2jep2k8ZVD_`I8t*NDfwjoe?8UC>{ddEitGzv*_12sqN@zcU0vVREJ@ct
zPLzE9P=VH%LSgGG8^XjNwcD?S_qG4pV`l1m(3ctm(q{w;+F1h0geIw4*{*saw!tr_
zUDBL?905TwHBE_B%<;xz0D5dLQ~Oxq-_`dy-zgji9U-<>C~;qA*IUFIVu@vsBxu#f
zLC2t|d?*^F3pJ_)3}C{z-f2}LWvJ^h;!hFgc)2y<65Jlg^)Tax8u9EU!A?&gmDu%w
zKE3xbO)I`S&vDz&3-Y00A4?0_-`Ng;_+d3WDKZpsbFa529}tl^(npu+a53O1-vPud
zp|d=&1NUiJ3l4^-D3#?=_TPqejC<5hIVu0IqU#J~t8K$4Ia!jBn6bs4vG=HiST$;|
zP%8+M2ojW5gW9FLS{*OCRJG_p>9A_Ns-=ro6>Z-ZQPqW3$>+QOT<6Dq&X4o!e(vWQ
zt)lnJ%-=#|3m5bqm`!fQe01tQT>IK*zuY=vpF1~d9qZ7dzRqoG;Vnn2b#P&5Yt4BI
zFeJ!wVvw)(2EG*&C5E~sKhRlCA=TzbJQVkBsHvBQrAjBslXIi4I&Dwj82eY`bHkZw
z{dlH>oXZM%jngsEy?aOCeO4p&q%i-fe4cxPZ<m^*YiK)%aIy4r+`ON8rV<yXZhqZO
zq(bQ=adP0TAU9(Z>$6589?nJa2tk~Ia$BALR*%F|W8Ybvr7?P7H|J;m#+Mg|FU1la
z&F9z5q;b%2d|vQA#20KPes9Dt)Vv(=*q7Nz@`R-XqPMU1aerO~<10f|rr#xTAV3H1
zY5v@U+E-rPre;(L&M%u$EbbiOO{Y~}DGiI)>+L{?)-x=Ia;L&Q<$s|Cw)h~O`-Rc6
zs!q^y7Y&q5PcY}TI|WXV;qMO+&7(@-yO8jd5Ln+&=zB-s!bb{0cg=TS2CrHHzGSvg
z_}06j7BG%s@z$Rm`ma@B+o>J0*(lLdbXi?Van9BL;CnT#NQ@9V8!fFnWonU4{&vqT
zSMPlyge$zYptrkLlX>jpmcpZXTFQ&e7Sz!P+t%yJ7nSR8-oU0fy+PHyITEjF=ML)t
zsEwb_9JgqCjXhEWQ!-SNyTn*ModeU5$INWd>w7S<3)e+D7Q)?(3ondp4aSox8qkUY
z>y7cc!$+OX@zyUYZiSB3vJ4ujZ=v;QZ`tyQ0zK|m`Gjb9l`hzQQoq-d!n{^V=L@~!
zp5U>Ue@7Pi>_^GR=hyK8yHOqE(2e=Q>WWNvd}M<qEjtXGEC*3wOg6`h|4pM`tUn>w
zZNJwxni|tVEh#WBC@#boISQ%9a7l`RC;0gq|4?~|zQ`x24|Q7bn78iRa~+#M*Y_Kb
zj85^}e^ajOQs9BsXZ-gHV%=z4rGx%H<`ot$f9SR-th-14mO@vtoB9`l97_E}#qNJY
zs`b*DoLxbzOc8;9pHocNt!F}kRA_Qtm1{|*-PLVxl$P<ugSI+Vhp1VzjsmS!D2yxF
zS>viDF^)3m>bfk}-@rI=6$5CzN7$#9ju=z!%3hd-AlelJzd49^+?1Vcw605t*%+<b
z>1+KmG+!BJg}3Jj(iad$4Wc%$^>g3%5Z`ADvwrh`2c;3@tc}|CK;&;v_Uh*AAFKRn
z(lGW6^MPw4Fuhh;>)C8GHaqdWkqU+%^7utD)R8fg=1JWC8Z4RrUaP`_kZC0TO8|mZ
ztGues&1VQ}tj^WG+%YHh0+i|IW=VPR!^1;;?hcz<<tO*NC;)(2VxwhraN!}dbHndW
zcFibSRk9lw3hOcOnq3e@!;dGgV=qhLS%C+JvGc_Fl2G5_O^SWEY#H2r8D1E0M;v?6
z0w9n*^PkQHlEm}PL}i#+;|d;a;gBqw*O@`D>*^ZFexhoD;;=e(jZweDe8#o3HwY4A
zd7B@FXs*@LtD*keZPhCNA3AKaci|9(ydNLMBB~5`3Ng~hs%FEsP!kz?v5|l}@q(fI
zw>xHpN495r8rMBtK*)SKe&?ar{;(<jpT8IdNQyH>{~gxqY<!ODBAaWl?KipS_}w4g
zQf4{>-HI9Gz+F%W9N!vmTLI2OZ|@=h>M>)g9H9Qne_WFe*-M(;wXQ!MERF880=u_8
z)MhVD+kDSVC#=t1t&Z;cYzJAhN9k@LURHdQdJJT%SGeEMEiG6(4cdY$D{>Z@=nla`
z?PLLzTG}V>d_#vF_`b?s_rGA@$hAsyD{v3!_B$|=_y(xRJ)9BBCd?J?;kgLBaX(A(
z@bYBi4r_l@yR}75LUu)G!sl$+O%bC-r9Tiz7LJOc;B{xMwitnX4-l8Tcuj(lPNeV1
z=ZK=&^ZqZg^iQddsaPMFwif5Wnoj30fL7n~jPrZp2@E~O-`KM9km^3vdUuL%DwHT2
zJ`cHt9t;kL8qv2T7DP7RmMc1-cKl$8FTHbBysKkiW3%2<R%w+Q^gA^Co4~&4nf2F~
z{+rQhXF<-0UsbwaOYKVH@b-MRuCmR=pKn^&b6-U$bX|-Iy4wqz?Z!j8r618$DvAqz
zkNo|s;r~Q}qSB$bkf9sAbMKKz2;%)A+0H^{ae-;+p+7rChJqq}T+3W}%-q7s#Swv@
zSkC!uRBlgysAGF#8|Z{OC1%#1&(S$vT1@|^R11A{Mj(H#r!l=-)>7N0HhPG=)xuMS
ztXzuP%L#1EChz;hfDXY(4J!?d`U{>tnhE)u_2SLQrBA{B2Amk1$NU{5rlJ{>VvU&q
zpm!2&OMFu%{yFHpY+={VPEO1}6-m9BKr!0x;corKn<nU`u_KkG;c9Q}Y$jCss_j9c
z%MkxBAJ-A0&+(dp4!7Z7L&g85v?BUUy8G;Q`Vhfip*yL!^PSV@j#y=fV2^4&eWy1c
z`J<P{)4)3?^njUSyvr)l6VIF93d@aM^FL0z`ii#9B{5wEznW2PxZ7m?Uw;J>b$|N8
z%IVKOmxYj_t`2VaVEr%su0<DaSa3xk7A*%jOZZu>6Ls0%dN;-UB+3UJC(Bmw`r+Ai
z=ueCa{nre0_x=h!(O`0+DjBH+`L7CoqDUA9JHco<fc4UcKWN0P14>w;2cHo@>4mI>
z-?b$ZM$h#%PPU=Xnll7P^w@+ab`f#Bi;v0Rg;K29uj*3gKmH6aJBDxOI!P+?4OR0>
zg9D5kf9R5!Pib^}cz?FI-g}p^O2$8sFO58t?itkq1h;Th)^%~XGAJL9EPdwHzoz(r
zk8w|iL?M|u7<qD9nn(uqQLig)mC-DVK7zki{*dyd(31+;Higf4i3eBib;t+(a&kdB
zQ?F*WId3?y21Qg6?gaRYpfS!e=O#Lb7&NJ~Jak|$t0I=jXm5;8!W3tt5*r~s?vFK=
zF4eNBtNl>P057M9Gx#OS-#cfhg+q`s+^if6UUrOBTXC{LE%6Nbym=qZ_h^aS_N@#~
znS8Y&XWAPfPKbg)_c>gGqtvAA167Jczq(7qI}y-<@dAay%_A^g${4k}fni(HTXwRX
zQ1j0|kPEr&+i7tMrRNR1xv)p)NhbfoYwL-_;n`ANGTKrl1<9b={g7!fss6lUiDf;t
z3@i5sF)1kyB>e4p5_n4in6;=k&2B*ulgBRK{=3U{g@!*{9c7ankpW66dA2S_46fdX
zvI^fri=6(-55PA?8P}lR5E2;*zb!!cX_SwiP;i<o0H&!qU++Q{quRTm8ZJ;22%;$u
z1X^|c*X1r>=~x3rag7*lcJWS^3p_C&Y!7`yEnzf3>coX(lwN0YZcx`IWs9<uAgY$I
zLlfCXrg(*hu3aa-(YtS48iXzH(+MXgm%6|r#HjG~RIv$j``%{J=7cR5{LXopZ)a$M
zo+03Sb}uHKhJ>dVsZ=sVAomO7@EdM?$x@@M#_*pyk=qA?3U{U?v+^5c)~rB%{@tc^
zUr>)sQ1%D~@C?Ds{rXzLry>*EVC!;e2WCgaVOopo;;pLB1-!sQ2}5#`>oc!M*0RyY
z6!Dj?6`WqojCBPlg%b7kf7BM^Qh@aZMK_4r`nP{CZJddZfGij0x&JAx*XSPkQy%}t
zZ_`j@-_SW#9sGQirefMX0NB^qrEn@je2{-iMqCT>Cv)oJIIbH$u8!;9L6P(cgi6?+
z_#%ytR-4dv!p;QGK|LX5Q0|e~G<-e(Kf=kdAXa;_NJ1ZUmFQKtGQaX$-$V|*1M&7%
z4xP3*zh8sqw4$+(8NSVZg+H3TfW_=L5=Kgm6bLOu2K<P&5X;uq<RPiGA3nW-jr=mn
z*d39S{z@l};6)gOJXKn5@rN+zAJP5YWg$t!=4{oadUc!SzKUOBg?>E%-Qewcwb-bp
zRe7bnT3L;-Gh`Ryq%_IzX%dW5$1r`h?T}ty04X1@ph&A2G>CmvEcXzF-PZ<RQhHl2
zT8nfPL6??@-lFd*$CW(lE-Uv4jEpRXecojHw(59nDDq`7z|Kdsei4LSWoYdi=GgK?
z{4Um_tI5B1Ug;xdWs-D&v!k|K2GCYJJ{8_LkQL2?1PsgeAjq&X#C%05!Sdciq150)
zpk{r$*p#%S!8o3)qmyh68O7#?i#0~?0=bg5=^az)yQGyZXs##iQbHe&vK**?R}*or
z(mXNt67_hQoIF&0sM}w<+~rQ2RjKGq1UwVrj)^ef7ncr17$BmqCP#my=2yn7OmyQ9
zyLiF4j{BxE)%nlo_3iBpGkR-3&gu)`iXv6b0(SS|Un^(rTOMMvbpCWN>=oqUPh25X
z-3c-TLhmf<ng>J_$di}%D3^c#eWx^=CeyREt(2Y6GN!&&hAd<ct99Tj2Qg}AW)}mb
zy0-MP6&H@Wua^lK>z9UHo|pRF=VS-sY@u83SUcTpM1|B3fi5vX{3;dxx2?-m@Iav=
z;FnF=mhP(q`u7x)4mB;usv`LEqpio?{z|x{a@9G#PjvtMx)gqUd|P1jWpo-1+#Q!;
zA^wGQit?{_-j7&Cih8=~DB&#wqKz%fdaLJc{e$a0B>sD03n3m)p4+m^NH_b<v34qf
z?tdd(WALYn7dUp`xF|dFHQO|`kBk^$CaY;3t7$+IIv{vz`F%@O1N>Tz_4UqKJVweM
z!8;Q@IX_IafVzhkA|HW4G`y5wS%LnhG`bAc3xx*qD|5Qd1D6cOvi?ywmB$kXp_D+1
z1Z-IX3L^prnAmHjDiFAM4@T4SX@|jQ4e0rO#_DrY`M~Y&hZRTMj2rG7emod{HqHNA
zsI=Irzw_T!>O%^H{>-1(1RE+h^usi2!{A=b;qqPS|EL_>9vw#4uNiF<zzS8~?%Ac(
z6#iluY#OcCyPV!#9yfMcZ?rZXE`3%03`f5vnd0U5VwErUOVjO>g5n@WN8x>U^LEe*
ze@)M@-(caOZ}tm^o}1ZQPz_3y^eCVg7vrsCeXZcVf@YT~-xW{$2X@iu;+uX-uWFDD
zNz9)Y6s;W8sr2K%1b?`qTmI6ODj0G2QC|E?bNQ1;=JPz&YZckz#q9+&{JoY&lJVnk
zv~`4R``ezfHm?&ulh`Qt>-?A&=_c2VPQ8H#c<cr7j1j6Q>^kbhGcVCM2#D`iq9{24
ze&xn!wFcE?kY8k9LXOM*uej2DKGbDj?LItbX!cjoeW#YOvY(6SEZ!9Kp+vdsF%Tw#
z5eH4cZ@VhXVeXws@yNhkzQf{*wZS64WfX%X-&cxWcOm_rKbwG3vG2*2J1uoC+FqJ=
zcYb~!bsm38%I14;W|9tV458ST$e7iDyn*+C_}l+hZM`VS1;Upwz4`eMoCwi(i!i*~
z*RF9$KZ3!-z8!kxl##$Q<vRQ1l{ijhQDvP&-dLxx_Xf(tB|EP%LPX_9Mieu@@AM+p
zE1G&oOTIYsO{|h@@=y8`lsiW?<jb>nXk)5+V)6`juUkijG!4{xbO$FCmP3Qd$$zJ_
z9sLR&h(d`D<os^LdsG~dUvk-GxXyS($2;CdLyEK*>~bUn;^@uwWr}mdUQLI`70rJr
zT!hAcck!yY6ZpQ@-gamouuzlJDX&A-n#0un33r((AI*FxFlcIncbqukVrJLOlX0Fd
zUu?)%q){q!vK-qk+685x>_oGX>7^Z0=xC>gK`a_Zdi+e>n$e;+N$efZg**yzp`cz+
z3Oc@HHM&iPIZ{D2JL@l9ljuXcJr6DQM?`}LK~|0W=S?5Yl!=e&vPg~JRv`0bV&c+c
ze0a?;Dp0~0A|q4!igkO`yml|v^)|e+a`reXXinMn2nh0HE+PJ&nfDT_(&(tDHR03x
zyf_DQAWeImrNZx&KGc{k6z<LvxApE09Mf~8TcK)zi>Y6^f#zy$Z}ux8_6K>&_$t7U
z$MaGN#C4v7fccpl3quH`-@S7g&;NtthVRFTVYpUpS%H3;Jb6KYi2F=i%7&~NGVdf;
z3h9b7041q}r&RO0;#UV6QD?~7;Jj@9zl5!D^#**auSu%sns~jQo4A;}03{+to!w_M
zlmR2#G{8<2#HhkPqGc6+(iYxwoDHP1q>fsfbUVryQ`TzM%*!T<)<wuGHuD+cg2s1F
z_`Mw-_2a4V0B0YYt*mbmB5p5KBMJmDj-C5K+yj{L{3``l%k+<i=r;{d`Y2iTQpUzX
zc@3zS`Ty;1^Z_1X5-C}VuUsFU5SJ~kJO+(b**YMj<%{&8#`gcEq&b_<SI_KRpSM(*
zR0Fn9a=lxk>_AWP8GHinK)v5-v~r>U!Q=}!<&wu`#LXI`E9TuSdOM=E#6DO}Q>9>;
zjSRF8WUtkD_0!eRg<_{6jZnt;>B`)(Ay}%ERy6sSM+LL*&j(TX39!PT?+FrD(r|-c
z<0j0Fct2I}*{b_$QDiUecCE>0g~GW)*SF;MPqx$_SLWFYtvvAx%Rn)F;^KuI>G6LZ
z%H;Ca;olbUE*<D#CRXUWM{WIJu<wpdk@bDw$c3NdRpMbA6Vslp=Oo?A2$~!7*qFiF
zFzsaI`HGDr41NdvkG#)@RNuHnrQ2NDf(r@vObUM*@@&C_CEfs%&Tn;C;9vF<R|5;D
zd=)p)gA~X7UPk_VSxH8UG$4(&w)EXkZcZq?+W^T5;*qPxdM@6r4Q##EQPd%wvpnqL
zs9*jpX?DJUP*1)-@j;hl<r^jW>pgoUZYq}8cWZ_ZhaGOHYr@x^^1}t6D(AqLCMG9w
z;$ds~pDQ{pPE8ICI}Lo2O~2^W9{<lRtnpCCkdDXaLb~sXo1jirdwb6^{0hEjep@d=
zI0|dbBs@S>!{8Ifs73Tnw>CpjOv^!=e~%p?QmU)d)w&?AEq9IPYli4+kD~&8@eN{H
zj6uHVgx%e}MOst#)8TMa*~GhiNx9<Kl05+w2Kg=I<Ioe@h*iGpJ@s<d<>>wUfBtL_
z&<(#@wD*%h^8DDHoaeuRqPr>=805`qtjINcji><cDBg2$!>O)F<Ukw<==*ioO_%-F
z`G5+30nE-Efl49BHtXr@5#&Udeetpe;NTxcbAk*Vsn{V<4qA(zDTI6B1Gaq)f{NEf
zOBGcU_dd_>KPxJ|yF_DKcIYmQTHi{dn;4tg00^^uYg21uleicb5FgK>_jXRDr%D);
zWK2cPwCGM+<`$M4pO{Woan=@=rtw@cX0Mn{OsqkiXlj;|7Cj!oWX4;|Y&fi1n540g
zHu33QmKLJfO``}}Bn#<)T<S(Bm=bbAEtIsDK+8D`Q)6RM6QRr(Pg5)U<)bvSJiwhs
z5ngZK0(@ysfF}*^O>>r{xdXdsu7G3wcE&T!#6pP-x1v~|ydHVd$;O%H0jHWYGb6)_
zD8+DdAgXlJ^>j4e*O-IZKtSMNb#_KO5-_%c<Yp$u)U#9Hz3E*|XT>l}vYlA3aj`ib
zU)iCdiMY51=Uv|L4x!iRx3#ZdRO3>A#l><ZoObOB^x5y?wMom>*99~)h|nuMCO0WI
zHMQLe^+44()Fo6mfy<GxHCo@V-(>{Tq(dBInJF1bIq?pfIe&{3w&~v<q52A@hKfn-
zByKuAsZ9xX-Pso0do`&|=JMiOkka_teDtQMy{wV-*p8%{8+Oi^7?9cXI5RS<O~OGz
z5lIGZFz!1ZCUuUOg@gV7Y8qQJvjOtlDDMJsc8yIZ;x<@a`0!Mo2>Re&KuZhQS4A`1
z8z09=C0=RD$VjGbObKcB8Qd5yFJng}n#7JI(hLFgE{1Tmhy$duiE3VI#Ps+yUJ`7n
zs6AND51O9H3uAN9s(g!fO>&AdQ<<jE{1U`ADcb%?#i^Fj%hCEI63I3$VwBV(?qDRZ
zEFV6X#7ZoHpCYo7Cbq6iFKeI@iS+o)q&T<x3SZ*(0}3=_78<RVX<}#$IcJkOHMwp=
zO0<gk$Bc_sHeo5gYD+ax&?ga36Hnv}^s?rN0S4(VL?79#o$oTIzNHYIK%(nEtgJKf
z8ebXrUKn(;7+f)I5+^%;7CYExsF}!iji(Mya&ns%%`)QBmATBQpbS<;nt*RxMI_Qt
z0Y&nPDmRG~qc|3w)|fsUvG59X;WBQ%6?KkFY3~2?6VLpWyd!+B&o(}T*QYXxK7(ft
zNwM3pO6n6WqB}D+>ByazW_awxa8aJ3Pms5ZzsHexgS~^A>K4pE!`A?8`BkaIXOWlk
zBp}!v&1wlH0OwObgih=>PAlYOnu`Tm!#6DhmP{-Wao4j!#-8Yu+ikaa5+NKD_JPp$
zK<i?66j4NDDxry!kVF(sCvgM}g4zttl;T4aCECTOJ7rWR8u`XFz4mknr*VpG_v&*B
zadI_NGQvI8nwQS|)UXM$1imd9bX3P?N3&wAOpMK8Pry4n3Ce&y#><Q1+Vv=vm1_RU
z%G!qFblb(1pd1sGOY!%WQL}{sE|%G5iZ@hin5kKIe5nWdV%MRF>^*cw9Pp{n(tIw~
zgKh`~Jbcsoq_H+TkU!}3<;=M;i;UQ@j1(#_7G3x9S1S=ijZcUvBff5L`S{M2zen9s
zA;oBHch_<jTM4F}=uL5MFMdXMjUD1R!HFL2Ummql@B2T1TTnqB-N@YaH3tAlmjVNQ
zW6f`4JSn`1=$!n)cGoFsr^9{<ZZ3gD#LvFVlSB=&DEcCal6c$WSYLZmu#xPYPs$0#
zKWxo#knq<12g8BCfLCf<*w5U)wkeQnNAiLtes^}K_`;q!=}R@qu6ew_5jkkdE%kvr
z?1~H29KSn^Mv4Xeat(YalYc!0=d&r<=^Y=VQo(ybSM!OYI9Q+~S6e52WYGQ&#@Xr~
zJ4>)PW$DiDlWpyHs=d>xN!&q)W0F+XvdGlo7`%5(_JBxShp=gLJj206yq)Q98t4!f
z@0!s(C12c3ABwlLFw178D)<{`;`$O-izX#@K^&~%rpk{7jM664Go(y&P0Y<T<0P8y
z7>NdM#+!!3#9fkH+j*Vj@1rbDPPv}%v<o@K&T=X>%i35nx$8>}I=3tRMa`?^?cjtW
zhKX!sN2R1o`lIv<zUl8P+wbftfipwe)7XZ;g7l)70{yxS?G6Y9{iLJ-=Kv2NsfDC%
zr#pOFk~osS^O(utnb+|oo;BWI;aSl+q8evaO{VRrDE>g)8o*yUXojWybpY0%6dND-
zIf-=M7kilE<KGC>c|T|QGNV9W_Q5)`+r@hHh_mIX$n@o_z%c1-VWzwD<4w5!9ZU-;
zj(JSRKjYS9Hx4a#Hs_Pqb@`TdG%-W#ZC=lPno~eXQby$c@SfQfeiOmEqcVEQGau3d
z1w-5AbRuhFeN5QMVu_g+KAJB0jvP>vxlm_xwWs$bBe>$|B?I#fhS&rbeVg^H_|@)r
zN7$o*u16{y+E<8_Sby$Sth=u2M9K_`r7yO}4<n=C1ejo=4xD_10K!AOuP4+}q6SXY
zH2p$LU||ppW^H^GNK{C@#=>OYoqrcg+Odad58JVyr73@1lnO1ew~y>tEkH?Q3NF~c
zx+9N?j4gd(04Qg7R^b43)x<&ondE=l#?;G`4NmUajy6<>$NWsPW$sMHctksU+zZY&
zbfHiuSEmMu&R7Z|FbvqvrgM>8ZKJi%y96u+`QV6R^5IE!KQmad@A86nDD;+HDvspw
z;=aROIus_ou`lSnxZ$=D;}6KEhN3_KqOk7{NrLC0t5pweE8b0kQxXH{LZQ&AKl@_x
zL~#4y{1k_%vHawIPcv@sFTH^hH%Zr-@-3lp1LTD3=Hw}UQu7+MqIKZGL`2#4YeF^g
z!zstoPHk2>@42jsy6q9Gsk}<QMeg<s->ua+*tYQho=CjWs{kn~H2+iG<j}_R&!0x;
zR9_*j`btD!{`?{p?t<A=fOTG7zwq_%Ybd*1Xa&rA=~Z44=C7uesKuOPVgLUP>;E>X
ziw`bdefrKb+OunwbMN7UfxI(1f3)isi;Ta%fd9WosT5{2_Tu$_r>8!x@2yvf4{qwG
zs_Fi$7V0@)Q9pjo=Knpl$Nu(((c+Ij#va=D^Q&+?@<7q9yoS`-PX=33&X5ar-P^Ws
z;wYbjynr=}@3!~5o=xZ-d0s3)V#Q@Z@OS=SxQLh(41*`si6Oot&^YNDok(#3K^?6N
zJW;ANZZA~FszK8o^7IfV$Q)+8b6Q;$HY7OXB$J7KG~1TutHMg+#M0uT+h4}hP2oDs
zo^ex-1bX_tf-7a-WB&~P!MV5#oHnCQ1TnrE;Mmw6Oym95*OEFgaMkDKXxm%oVKGbM
zzYggK*`sp_vu_^75e=tm;wF8*C&eThURs6cW^iKcQAE43);kVM#8h@*AVVU<Af@HC
z`)J{$Zrp<@+UxdeLN14snohvhpLkaw$t7f~qmXT%ZX8Wvo)T$s*e8FDPP`rirh2QK
z5TiXmoNf~z9V2yZ2Y1AL>TQC2INCXY&VSpa(b5-B@xIob*DNEN*k`aKlGKw^LZ%T@
zniEC}_N{5!>QXbikDk7#aEfSeJHeV2<L-&hOh{xS5F8fdzf@VIJu32|SVUC<({?h!
z`etl=?P~m9JN_utL{>9HDu@xO`8{D(B44iMnyNoDew&c$HgY60&>)GeF8XyfVW-HM
z7&`Jm#+Un(xyU@#CU3zhrR<XUyjuY%W^arvy)NUhZ1ajOzHR^mhdd4fEA3&1r)y%O
zUk20FV^Vv>-~%TTlh|_v8OxY&>lJLeNugo1tfqs_X~uQZtE{E>T+*HR!toh<^bV0z
z-L`F^Z^Y9X@c|M$Nv`0p7XfsO0aq{f0sGwH#fq0Z*mJh*z|c~bi2aivaf|$F#^|#8
z=O`kHIB+qhpKpV$nSBeBb<sq|WhjX(Brs)MqK%p6Z&hRCIQqRI1;KsRFu-}LgoRsU
zlAINKmgtIrN3wOCEOnlXhMIkfHBVIzWk@?EysZ&6a}g0k=w~QT+x4`G+Ckm5VOTpt
zOK7JVXwGuG%$F?Y`ow43S-S34J@0)})FY8o;K8Tgxuf)es&l^?UBpmc$(Nf=(pcC@
z{5H-QO{h?&YC_v)jqlkjW++*<NFeXF>>xbxU#;+pjn{BTTP{c)o>Qw=kojN}op(wi
zuF^m*#K}-0bx!rZbW9R+CLrY%$JIdQVoR*izvC;j|Gv{z@l|hu<Tpnv#u=ubG<P^!
zbZ37quOq?P*o1RpJ0cz)`70hHEBk4ZVU$c-OMiOeq_;I!@+tA=VeUne95vPUFz5KG
z@dqy6oMW9zGMRK;K-?rid$KG}2K&4<gyg!ux2daTJ0Gc|oSm}CVVqIbs%#NSQB@~V
z-}KYYZtu4uVU|dy1pU1Zz)V1%;nIPwP|Xa-2l^A68M<hDub>hGVqmE4zFRY&sBjmA
ze<&OqnQQXCg04;c;Uo2Gh;vR4P(7_D%|53Phsu$Q-Sa58va@;SawI(9gUU=E`+_<Z
za|6%=02C3`lX=BEF3#}xDZ1{hwB%cnW{Fu+`+ih+p5{1jZ#i6g!UBY?v!UJqz;$!?
z*y-uz?KAm4_2({MKYxBua7buaxL91rzN<ldY`l_Fn5<e(n!)6vs2nddOE2f9Ce!tt
zzR@G_@`fuP@I(Pb)>LvXa?;FS^JZ#$hu+_Tm{h#b!`a){y?v2}k-suA;1lTK>W>i(
zHANSAC6t=EU@@M002zdUfANz}JcWEknHjzAj`8LCuTU~vri*V1O7Nyq?`uT^-*1z@
z^BqMc{;0p*cmR6=4(S#1b@BR7F>>2w{K{nJ|7iNfY{T@sqMW&il?B0cyDT-W%>Iwo
zwl+@xM_Ug&|No<Xv;+J9xMQzh!ABcY)39<8iKF!G(mthg{&fbOu6xBpquK4qkt3~`
z_Q;2F3N5X^QG;18G4T$38M*0Bw1Q2=K@3Fw=x<C>+Hb|T+8@2~zDWxwy|a*@yQ0`m
zWT0V+PCctoOkK$K8&?t{4fclZ<$q&-o&Y2K0yw^pq~W;{P%V8av4%+7SpE3}->ON;
zdY;|B5CHP^!4h9|Y}Y=L+mbKj1A+N(?qA6aN5}mOLnGJ2z{wq0KgfE_ktuecG9<?x
zgS~Epv{q<jWnF;$5O!eBdxC6lnLR0Q{6MN71c*fl#Li#}y^!0qwB4C46xoVWzxKm{
zlb;oz9=jW0M*vaU8ik^!V^X+TyVs(oE1hmZA)k<mPxBxjfKa4aIH7{o=5#CU#&u9>
zIcgF*avt~5d!z~iI=Y(;=>X;sC=7<$@i{gU6at?m!9Yd&VM+x3O1Z=m+Aj*+S7ujp
zS<neS#ykU`zkXxC=E6Sg4|#qT3EJoKb5eEutA*f`&Q5Kk&8ju-g{r6j9(dg|k3`|{
z0al5$!5en6xRp!dN7@gA8l;$syE`6YNXUnWJO7+?*l=q<5(Pho3xO5h_so7CkOeu0
zBZ`|$MqlX0B|{p`EUHi0A+0!<lWN#SNTtf>Cthzq2AzXl(mYwBy@ZZd_<H84<x}?b
ztrI2e^NCpP;bGi*og7;{@yaKzZe~r9!vVfFa@$RJRY!MwnL<;isD2^JKk81AnY`6L
z8uV%kVy4S!K;~SVwDE~_zD-GyG;dt+nP+@$QMs*dCyBnQHrYmL1^p!Rq-NyvY@qP&
z$ZNY(pb&fFR@bAFXSS5|YFlH#HpqwSA^ay>fHsAic*Dx9L?IvoiN%TQpI^x>vp>>2
zA{2Hu5oQ}ojE4qJTHMkm=7t$v4BDj=q~3LV*K6T9hoUyz%oKpR`&9^mg!CYOBix!~
z6A^OsmU}pj{zdQSOa;mPcah%%*Xd8sf4kYa>l7UGuA}hEJ-g?(5|1_YAPpY2dqPpH
zk}6MSBd3kHpnoE=A|od-bTB0$B7}kALSRn};p(FVqk(I1b~on>csy9Be-F3(vE}kl
zGlOfvH=J8WYVsZyKb9ObdhD2pRA3S}UO3)!vf4*M2--%$CuY64za6RRhX*?zf4+~r
z^)?fqUN?>$!JQzint509h4YV*{@&BW$3~w#{;qBBY%sl{b>P`a8ti8^_?Ox89}yKY
zsy&ai4r*1ha+VCuIae`d_I3OPnESE>`B4kqdF%PtFGx6MR>P8u1j(Dvoj;QBgXOA1
z?WexcpFGZEAZbu&k9zJTz{I#+cEdcliPE@2fCyWHIin*O$neU{cf#bk!s&60kA3?s
zb3eeXrFt4_l;G~haVH#@DH1hmA^@`V=jMsp4?ly4X3EQ)!@P@-j_#q~Q2zaTsKcR?
zeHpMYvkaq!pjB*`rx@geg>c?5*W;FA7~w~Jc<^C}AWK8VOWzJvpcH|tZo)$p7Fr=z
zBymV}7p}!~Hs(xrSYc^O&v`ASZb`?ASpw^+*j4kV;W%As<O`)<`g8E)y)X=3c9K`9
zzRg7iy=4Lu-QEP9mW2fDl&&aIoviF3K-|J{=O`OXJIq1}ACTErIx4mfT|6NXyr~iZ
zZARu=0dK5ctANcLm|hD9TPKX>eQo35WSux>9R_l@XGejGCbyc2+>yIF2NKpak1Y~2
zK5Ign2<bOV6lqkN+k4dh<t952;seQETH4*qPI1%690gkqkX|&SrkR^1xIkKovHAI?
zu2#UT5VSLZ93pA}Ls2~gl1B;q{~AK-?Cid;7(ylun}bw7JXiQgYrC$GL)z^nSibZ-
z(zsK*U)4=iNiNasyFtBM&yA!`<P}l%+|fQl^~jS{<l|mt*MqMdpNz9?k>`;PyC$9@
zy>ES~!AueACz0<DFW#MeVV>tZ#hIG27$p`WqZ6aq(O)j-N+P+8H-H(EzIJl7c>Q&i
zHnPXFF{N|)Bu*E3{&o~Wka?~m*fAJc`Sy?t^72Awf(H#}gN)JL^~T^#f$a1}hv~#i
zICjU42&8j1vK*pra6JAsR83Ab2C86W$ovU$g9xJcL(XknQ7DH<oP@-n<ahr-T2G4g
z{*#aoy6(Snmx{E<k6sc$-XLo+OEyYfeJoWWQbrN)f>TlrbDJ1Liievc?Jm0`egDh+
zL<;dROhfiL<i0`_BF&EztecSSbLW-1?1x+uDYFFEb!2&!e5RL|NQS)CYHdpFwat(#
zcR>L!@)k?7+#0+JUb%)e3n_@4kQ_nwfV<`Gz*e)R9qQ=gMG|qCy@XZ;*(pgG!0N55
zvK-*}q(#tq8@V4;#JuZo2W@IP^LBk!`k~zClVUrW={*>axfTpgwD-~q5VnrXGZpvy
zz)|j(%YUMBfGN<lUuj#7f<XLxc-JALGKZK69*A0BGdr1ctyJXX?&&9mDlhpVg+D$Y
z8eFbf#Lb<V0{Iqz;FP@fu?3Ne()x)*DX&`<I_*8jtOIvLz&}L+UFSF7(lMZ*9CyWz
z76RyXeL&d}?{qnP06@o=PV2uLvmsTnn6yaVORlB@X2<d8pC`<{pJUK5U!c?Kl$v9a
zKQMn{{(O&WVYe))w_v`jV}1+dA4IET05cNCH=y&fToVlAh{;shTh*E}52je9g4R)v
zf?S>-On}M9#cC}>oF_24;75fhb4>KKbBjGL(ih{7W3<iXyU~oID7eqWdXX>e3t(cG
zTjXOL?pCh4J<eGf^~&Oz!aJi|CYg!|fr6cixY<KA`9@0e6WmDkMlHC4Lm~v7D5DO{
z08T_$b*qqPC+CO-1n>S~w=8%0KE<OTv<1(fyS!D}r4zb7D6BZ)G*mV*Eo?a^+!+U#
zz{uhL?d$vxsf{7wP~b%YLg49<`d~i|7ce?}S?-~VF}d4`#X#h$;CjI3E!$=0#95qQ
zyj_I-QwVPEkx19L{xn&|(o<i4zVikSlzMtoh1-?6_f-F7!TXNS$NUaoKIY@!{7MVF
zSkmsCF;!x|y^3|d0;)Rnp8Fuu_bsmwbF31`XtA3z|7jOTRQQd#ubosqb#CO8`kRB#
zL)MR)iM9aesv8DJ^&gypytxAiksJ3}$fdT(=jM;!e02_x12+M{dLAj0D6#FX_y2RO
GQ20Nj;8;cg

literal 56832
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

diff --git a/pc-bios/pxe-ne2k_pci.rom b/pc-bios/pxe-ne2k_pci.rom
index 5cb68ab2da08df832be1a5451ad4806281abd7ab..62010cbc726fc5fb8fa8c9db9fafdb4140339d09 100644
GIT binary patch
literal 61440
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

literal 56320
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
OfQzC2zsBAFFa8hrhr+M`

diff --git a/pc-bios/pxe-pcnet.rom b/pc-bios/pxe-pcnet.rom
index 7a54baba1e485a8c97866df5369c0d3392361b6a..512d6d4339b7b3e3ea8b132d261d553f09bb3d96 100644
GIT binary patch
literal 61440
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

literal 56832
zcmZs?2V7F^+c<vMC@83?xY5)!cbOx#+*(@U-sVJdr=XTOQ4<lf@l;RQFdMdQIdfua
znQ2x=k~6DAxLR)IPv7@_f8+D}A3mIOU-!7K>s<Rj9DHsk@ymgG!2f;Z0?L2|Kz7*e
zseuPbfCz#?0U!y006=cif2L}Z6Uh)!AMoKX=no_SBH;Jmwi)d2nM$K2?=Uiorct9)
zB9fA5hDj+gKn&U63D6OtC1qsn$jC6v&;@+<IqsI50{{s0H>^j$NB;@xFV!$rB<>2X
zdQDQTOu$@i>4TaGK^Pp|4sT5dKqGh;@(@6(A&ENsVWmAF1WxgycvAe9>md*O6jOXD
zc`JWu(DxQh(Ra7Z{$1P!D_#Qmuo^?~BCMDT4#9GTuoQz*&<41YqFmZ*$)#<=)k;Ev
z_6Y<;1f|NB_Ck6rxoHwL>R=qK6cjC!#NDDCpafEanuK!>v|VK!ZA#uw0Qf5i`kcw2
z$%3{B0|L;#3v^7b&_`N+{iVAPrY$s60#vD{u-Gtdp{fMH=tLK`(KK72Fww9P%%rWX
zO`9S#ivlRek(n@DHPs5HEow#q0(8sLUlbTvlW@!dS5OE1Z<2fW(r5l3lDwAnzw>!e
zN*D!Ki-ZD{_Hi)^;#?jKVDtznxaJ-PAJ+l_-hPcmQes6NbzPzvSPD575OIbQafU4%
zr0rkqzymZX&sZQ9`rqA1$b#S%Q_c{^91!6@1+B3K{h-WwupIiAdkSl(K8#|rAfhP}
zAf<gmEaulW3UjA1tV_fLoDy!rGg<g=;fmb_IFqY7sz~5J+LMBcB<leEpTV*=lLZr@
z;je2gVt<7r4Q)vPKrFOH3kD*gO;90N45<+Hlc6oTFz`3zA{{OXP6D`FxJr~-cs&W|
z6&L?&VI-aZKjYIS8IS;y$Sy>uL^43KxAzjY_U;8pyZ3pUSOVhYl<3q{k^?Oz-oTzj
zOCm)kB~lK?&{LvGfT5uwATIvbtVM^d=qm}v0=<%IEjfSrjD`H=GYZmj5e9}rn)Z!>
z<G^1&t066wFwh-xktX7E2Vh94%!E-yx<?oa4KrbV#J|Y?i|D?;^ityvCX@cU%E81K
z5+x-m;eXK;5lR3=2qBP`F&MZCP^j*nPTr-1%r7GO4?F{oQdnjp6|h7i2NR*-HE7w}
zXFd94Dht+2N~MLT{0C!nMsy^db}%VX9H978{8W)%l4{J)W~>}(voaTgpEfH5tIcwf
z{6A0yLl01>e-4W7mTCYeQ~yAFgMxxkY9c2H?e!o(f%M7IkS1+?a)RFt0I)kl7L*14
z)A^gUWWk{!EB=mM^bg=r$ha%@wm{i<6s0mAs961dF^Xb^j0b4Hag`K*&R;S7?}O~+
zQz)b%iV-dXToVd-B55s7hxg%YB>M0nLH-=_-2#ySL9S4+;LoA7_uxUe$mDwPMV%lN
zDC%tMfrBtWbS7)!ti_cN8iDtPqD7+7DPheHuu@n&-Uh<J4?<BOI4uG+QQ*736Fh1p
zzye_nsbN0=9u-cmia@$BKt!Qj?Y~(Q3Pp_z0PvsdssFk5|1ZXUm|yaybpXcHJf#9x
zjk|(Wm6N3M5gxvNa;O#(g5AOuHs}B%+ddE)fP)k*2`OZXAH}4tbU@^TaFH*r$57Y>
z7F?lFNMRNY3rl-i$Aw@pP&&{G3PEo`Bz1oZd4+<5oZ$*_q&6%Br_uJk1AzwW@j%%?
zJrOA5mbI0Qmw^<2;XvuY|3IRtnj502z4B@(T%{<4i4cg0Ut~^)aN678Oa~|<5;|Y(
z0MCtt<2V$LzrGv5A=j%RK|PUVC>|6)@I63T{78YkA)B<t{JQN=VRYdrjIZ+|mI64q
zE3vk?%BV^ipnV)^&<7<O90kbjATp{-2JjEURdW6sn@C@O14Qdz=K&Fa?<JH&5ykj5
zO5p+>S^ApN{uNHi>$-vh0Fh8|bxV}?Z*WS(lfN+YC7Ap-R;~V5-=rwJP#Sym0RRjT
zQVx{yC=I|Kh^Xstm;;@KRi^==>PevLoXAV?Vh|B<1`q{pKXSb!5)9bzryTe@EVANo
zkzI<?h6lxGjbbuG*(*TBT%$mEbQl;9r2H0XhGGkb02HY<&<{xcLt%ih6lsyF&@m-Q
ziZg{VFQj=;n9nIDFF<qAtQVlk-!ol`Vh3*i53K%om7VC5w+{RgDV6aCLh%*pm}Ud~
z(iV{l6`c4>4iiIRsZtoTYZNIShY~^wpalJ2K9L?(Bji`ZfYm<y3I{G%5r`Dd@p7z5
zDX0br@I*|(g!e?0B!|m7$|lRcx7sWS%LbX99-`>P@s}ja44O<ydQt(1iEyT_u1(M6
zg$Yg+VNGU8s$LXdNs-H>@e+js7{#wwl$LzU%UzKAsO1=;ux>$SHAT)uTO@bYjVu&L
zWZh&>EU-)w&g868uSSWoye~8vSz#zt<syzdBXhHbvNWMEXHmMucMXlEi>b!is+Gvm
z0X31G^_R6H{Z`Kd!q(=eN4H19Ic8gFa{tl)-yBb=6bgC5csYvJ2P_GoREe1}wKL?N
zIm-Q4T&ILnc&{U7FPgEWwkjnXR9F>Auq2eWc${8OIzTqNvfJ=#3`79<_Xz|2^$6MZ
z(EUx!NHpS8V}BuJEYBO#-!EZWEO%J)r}K?`3yXE5cn1%6GF?*s*(W5*U(H`QBD@z8
zF7m8^zlog^0tuxYcs7ZYH>7aI<rA}(kb#D1x-n&;cKyIL=2DX@03HCE$cTU;=FTFx
zd`t7h;#fs#PgSnC$cLLoz+I8T=5;`%WMvCg)e=C7Ygk1@DJLgNoYL1QledTEA;%(u
zcyQZW3JPwy{=G~W-o4d2s9_Jj*aco3W6@S)SZP;Q_qd^hOCcr0OLj8a7i-Jv@S!uM
z?}_jBgW*9TP4pmBf}Zw@EJV%^q53s_RhR+%Pc)!>udxEqIL(c;)&9hf*+Afb#e*_8
z=DV#qmB|?tPC;(L-?+q>{xp`z#?$5Zp<&Lz8l}Ot=0RMNe7FG%!H*OwZ1s(8Vb6Dj
zqT>l_sQuwAR+Q#6y{<$4Td$}tDZvTl5MiHZwhda70<?t(M83{%t@)8)yDiERDFdg|
z89NnGKw)j>XF3jX6VV4%j;fM(p5PQEkvQNR;jg>rKZFS%2n#7kz!_m=M5E2$R7QvN
z_K`2~`iN>?v9?Q@!mf@YZ<Q&*e(x2p7*?>RbQxx>rH+F<s)@%)YWE9+4nzcVuFG%q
zR@jhz=^Fb6OJ7zu<<j>iC4^7H&v&5R>i7Ak<Ss5)ZBWn~As72EO58>D$#Rxq6`>sT
zn7C3B#YfyS<l48L@X~>%-(8rQ9dN@QYq(c@F93Y4y@!vKE+euCy8_eC4r^<U{a&$C
zOobw1FjieC^k$0d(RSG<3xlonZxE=|8;X@ToW5=aPd&jKsr$n6W<jmov2;W*I?a^D
zs|$+5z{DuJdJ1n+qa1nW6?*j)auj00sQvSSrKBeDK}vld9%!k7fwzQj+Xdnm%MG|m
zubH9BlyF@wyt8wQ@4s3MJbt5fJqf%g6lE$Kz?ycS$FWo$htXC2d|L`IbHihHR+62{
zX^4Cz#pBnt6QLb5k-P&AodcWFkljdxP}r9;jcG#Ak!<Z;WdKVPkIfqF+ewEm`+873
zg=y(k1IxQ(QLVm=Wm}u<gv;#Bwk%cM<<S~crGbGg^xp#)Qs(Z`w=3t^?e(IemuDkT
z%*?=yK23Pxu>gDFk%^$nhkS2nLug27;eta`!fIN}6|RFY#qOuJ7Xs!3=hr5s!9&n{
zv0(WIiYd#awf^&s$y{M{;qx|T;lXw0;??#{f$#00B^9^2gvF<i!OQy<bQxJ>dZb!V
z3m%0<=lKgpmM&oHYZ5TlgPNK&q`U5`GaDa5B1qt1W3wEJ`3<bKnqGoQe0m?AI>!5e
zJL!yW&N|3*QJpb6r3P|@Fut%qOBjB64IC57CvKcLHVje`YPGYP$5h&Z4T24ozOg<t
z(wet&aP^|#t_=i4J<eS#hI1D(UUZuQKrMs5OI=h{`lE7jjWAe8;l;agqEaBbM<10~
zXfP#8QK9T<o?C$)1Zr_dl$-Vg5MB|+g|z#>DuZ13-@4)dIE?PDU--{Hh-7SN3Bgcl
zH9Vp4|J^Fdigr^KGncH*MFj`^azE-6=4Ven?gD@s+WQd&d=ibqWd6vnZj9^?w|Dk7
zL_q*&r+r=lUY7wtwkMHv&}abK@@Urr1R{+h16Ke%L=6hrQ*#p#oD{8uQ1*Xx3D5xG
z5VIsb4Sgw~9D1Qf9Q8k(x&r^x67elu5MBVhn$Ru~Kw!i6(yw&15@V7@b%TDlaBht2
zV2qVTupLa9Pz#oqEt4yhUgym$h>Bc{xISwW(_SCX;5g>3x*Mvkjya|@1#x`6s^N6w
z-E9ANECF$5S6KgcPxw}rvp(||JNcdY>WHw3s6!tK3gvLTm>iabyQDzcG5}2vU&s;W
z*kP@pbht^I0LK!`TUMZdt$%)bWiZ-xabw2EFNQIV?{?J0a!}~3)jBJY+*v9HtZf37
zWHgv?bvP)#Nr5FJ20u~))?C03&-RaGv&^1)^D2Xpd<j^S%7u|fm+PH<+3u*uaqeti
z!^Le4Hyq_xaRuW_V_9Px%#Na=_Lq2g;b4Y%j*uYO#vITZshCMawb{UP>GDFQyvg&c
zb3;<&y?HCDxPRJQwQf2Yr>1-(MWY+%y*kz6r$*%Ajex6F789<?63iyn#T&9{iuJ_Z
z;Pm+t&gpxrMn~zW`W1!Of?(znm{uv1skz4UrRqI0iTjaCaHbI}$@0UiHvKAyZrGx-
z1W^!y>E+5-V*Fvh;FyKkIvH!1a~Vr{LT?PNaBAZ?x}&h}8KV<leIO*OPRI*+@tk>;
zW&01ai!n=J(#02>X46|62xs+}AJ=}}&hN6FcItB8KgwGWI^p%4utl8|rZbdsWsj6C
zr3#t0IMyW%*Ff8r*rSV`#lAYST+5J)ysmwIM?(ObILkY#0f(s*I%65jLRuiR$E3X{
zqmw!>H0#<mPIF?(T4*b8v&Wk73hm8J(?8>Jr}rKqJg!d=<I<$WTj$Y*Ji7R@0Lzjt
zSfukV%nS-7{ID!fG&9OI$(71Zs}~gf7~$R_E{!$EUD7%3%JSFAq)X#!-IQ2lSN7bD
zQsPtaZqWyqqQ3SQtiHU7(vF3B#cS+-_CEcMiS(TAdJjP8MG(k&Y}F?--!vAB-#4D%
zVaVV&PJNI|UF*k2;E4No4|iN0l(iRoP=S$9JG<~1*ZvvffxV!N#FM(rHtJe;XaXf3
zV#OFOmJeR{B}I2QpOU)vP@t%tqTEmmDvIeBFjhGU?sAaEQqjKHR+=)J{_uc!1G%9f
zmI;C%5k=HAC3!;AoXrQ^<Z13pv6%qSxMSaUe@sxS^4D|cY3&%9q^hS2xS~*~?)87>
z=i5eprSq0-U${v#CUI=#e}GjjiyKWN>C%?HxMRjB=I}Bcd~&;He!PXUq%8A^QV89c
zS-<ysvCWc;%SRESm@oBwu$BW)x{|mSiw?R2Y&e8z`-4}fZ!Ry+n3%9X?vBLQJ~A~W
z%X{0Se7LHZZ3l@x0XSckY{i2__xciW4JB^w5Z5X%&K!efIY77MFWQY9pY1~K(kU=Z
zsQk$<FlMdxJ^cftSh@5a-hsl>53y494Vu>vIpb$K^n6R|T#%h=KL!-X#yaQ@Y`^u3
zDsPZ=LEPVvo;W-TJm%~Z+cd)~J%wCwL6Lr$g|Xt&J|#AV4C<W~E1Z#PqVm<`=FKkh
zW#kP*_*mT&wQ@Ri$5%H<1zc*({R9GSm*NtsvS}nCr|_!{rQUkz^O+r8dkkE7fe$_*
z5ku-tHlK<<eF8VTf4<1*sN(Ix7-itE<Nmx_vRogf$1`Z)$s^9nTLGkTX>m<v<^~6h
zL85$3WrXa6T?)>o$`+!KCOBxa(70WW`i!L4_U6sOc<Z$7zbS3{kURrB!?2KD*NoZ0
z4P&ajVYg$u-#@!u>nZkuN8hV-g6w5w%KAbV;L$(-blvwlUB7YuvjCdye@`}W)A3_L
z+f61mZ5o4-5lAsCnQD<e)6kR+#0shKAP`cwOU$YWhPg+=dAHO2poonjG8rbky!eF%
zZ`qM>%WkpTmW=Jr`xZ6Tmc?6&V!MVhRRW`Agt_Ggwe5vti3_&w5SkBJ^EuWzVP?Ee
zmC+Vv*?#_o;G)zpqy5U1e@}<Zu*BM$K7ETcv;AK+h8sT7cuFe-Ul~>BK=4fM?h@T~
zPmq_v#KWh=XS-Odc+y1Dyb&BvM_76gXdAX@28gyv?hdT%grE%fu*trGOM&Ysy5eA=
z6*q(VwrR+UV(E5UO#e+{Sk_@LxMT(XH*73nSC2x<R}gXH-=Ge7yH*5a2peCt#NPYF
zx5-OfaCGwz>+I}>q{6V}v2L0*OP=MzV}<JYP-kSCtl(s6=8A5Rgh~)$KSFG0jfQ~k
zmQ*O!N)#8GD*Ti_6dvz4?lj<^xAEk9_Ur|vaBQRR#2w~q@W^&G-mw|czOsrDF0e<P
zc495gtTWD84_ZEXi|!H@ysc0>o;5M8!9rWbrJ~rSD)x*O7Hr1t!h5Dkw@i%vdPnqK
zzt9hbFD!+&RDtn$PF)Q=zAu?fdz(y03LW3l1P_OH`t3ouz<UXf=?MWRCw_F*@ZTP{
z<DVS`054;*Kik%y-*q?hmh+7u{;BbxM8*0xgRT3?ss6hg!&dIa4e$Bg`+Sono<7IU
z40|o!I$*JXgQm!mlMQL8Y@P1X{HgtYLomjObl*_@8o{=w$g3WC)!gK$6fl?(oXJEn
z{WyKi&5Ao(<}5!fIM58-G)opM6VwAdPIaAR{*auU7oP<eJg(S(c_7~sb`9UlO3_IJ
zx3AkaeJ+%fdG2CLR##?z|C+4ZktX!@;q)d>l@V#PAL1~wU{*^G7v&s7V;j46otKip
zgm8Go22lA{TU&v{H~$}dO7&N#j+oS1JX!4qM~m2ueb=trQR9dK##^v?20ySEyN~VT
z^@RGHt>zcm_K+%+C$;byIwHZX$xYqq@pd;IOH)aGOnP|j6xO{L9NCxDaQ{|eX|Vcy
zkz3twjb<%$Wtb=80Q%17)d|)HUYvsfkM#&wj#TG1wikY}9ar5Kx`qLOFX8r3X3&Et
zvG(gwWPXpe+^Pu|@#<3k00z-CFq-=A<f*Mv`OiEbbIn%s+W=t8Cr!i*z3Jh&5*Got
zo5^R(Dilh!Od$rqE{7dIABO7|mfW-q-I49Qb!%_vYU_@&`N;HP?FVZ+*hP^c7t<fA
zZ3Z6?mgo6`uD<gQZgfJoPyB$1VE0|j>BbLwcFCtxtZJ3k>K-nm4TW~fZ^AVW-`HPQ
zNO+EtCOp9g5G?Oxg);)cv)cw~Fs9h;2e-QHkC7;r%bv-YW8L%z(Ook>2hGon)Dkn@
zXr^}-iQV#P@edtBrIZbjt|yfRlWs>-Rd;u^e}{e0{qctXW}%d#k27Ut=+pmbz#g55
zk4Gd~H9y!E>ELlY4uAXMw~tVFI2M_XitCPP=HV?pQenP_hQQ0O>-@iurc&@j_{G4w
zo`=6B5=R7Trf|81j=hLEwI`8zkoJ%2X~;Z2Ds4P))!uSAW#o^6MQcaBIkA16z;AGW
z%KC$EdLx(k_R4NqWy&uDl*ar>b;MOoBFs;7WDt7&KrUA0?xqx_(e|QGkMmjO>z9A5
zSax7nc>@mtCuYAW@of?)SZuS(+ni39VqPX3ggYu+JB%C{vuWC5eT@?e=I)T5*H#R^
zZ0o4s+U;Zu-G9M-m({MuQ{IDWH_Yp6rH$shFaMf6Lfg_6m1^|{d=f`giogE)k=vIz
z0|6A3f~k?oXtR@1nKWti;&<aJ(w<E=h$o*bbDx<^Xd^U`r*kcaZ#dK)RomWh@eKAM
za$rQc6LU#oqXzwgz2{lYp1_lyu~6HhWPiy|U>=Eh<L$U}UDMgtGq)NL+jfiHz0Wca
z<Ea*$`~$!h+O{eQK89S1X(R>luVwj_?E3vdRvJ_4WNOozj<;!gf3wK|nQCOyK;I_Y
z*jah0?m}jZ%_+j4#^;zpo71Wad!{$!*KJN<=n^SLXYDdC-xDAj2fsfW`aE(xNXr%$
zXls!sZslNY%qa{^YSBDDb@f#IPa8<O1Bts+sj&u+?<lBCLA&s8)?9ZaXMTR8vn#K!
zbz|qT<Bg3+jt~zGSCG9wEZp*ZUe>yz`1*$Br@0sHxzb4V{QkFDRL(OoJk1Kl9!@1(
zzG77yOH>R}E-ZbZ$($N(&VuUT^tVZE3Ni+j^pHBrX4l{icAgdcUM8dBzk|!Wb&zt6
zDSw_FU|B0mKB-0CFnbHL-ZdnNGR@E{y{;Ln6FL((o<@9v?*jYu!1|h16^Sn_0y?`m
zQLM7*qDes)^5;p7r73nodzg;%&W3M4TAo_8t1f=f>Za-o;zzUZXert{LTRX!ZAh3P
z`pLi~y9%<;`k2j1&D75LbN2}*!h_MyGMF-9Zh)n;b&9tiEM!+lx8(3{gXV2aLWcOW
z)C*PX5=*692&{d!GRmPTH=GIVYuoiuNl)n{*8cN;p>OCVH9-a45^FQZyl0{X_G7T3
z*||_yz(hv6($;w*fBASW{|8F+luJ>57~Ms}hdX`37fKtw3%kwSJATtT=uF>$&r~-C
z#7`?8<-jkH=FbPr2N*-_RSZ5cvZe#nUi7LxGMKLuXMX&7fAP)fmzeo6vp_UWYReI*
zy$oaACNb&znr^2Bj`4Y3655b;BUR~{?cxvi6TG+*jojG$?(6*PPmJ~>d%1zbk)I6;
z?)@~oc<aK3vi|9)lgOWRI;H_Le{Uf_E?!{9TrP2ntIJuO1_@QJ-Cc0l4)%WG5h8@J
za3k_fvhXT)@xrYm?T`K)xlwVl@dv#AksCNOmo|m2cLF8Gfzk2zrnuF#Or~(d)6W9|
zl40Z2Cz?{?H*fMBPT!r<++O6!QJFps-hIlB{+;k*yK=C_Pc87(L;IqU&GAn?kMZ#(
zZ4Ev5eK$RuXvDjkw}Dpw42xOsYYdr1bjoQe?@=K+J(Iombsl+Zg9IKFKV^pPTvg63
z3<)BhIiaJV;dqg`-?01G4?h3yxljCA!;J5RKVK3A9ht;4uZDIuS0SVwqO9GbYX=}>
zJEB-D8uLv&-07s%wK2kVt2=|lbX|5Gx!CB}F|F%uTp=V}lCg}z6@9`(yXD4`c1Pg~
z`yqTRbIGIfU?rLJaSZQ+zEwB3-O+)+u*GJahUJ~Cq9YK-ot`oaF7<~hnU3xD_Aah)
zes=9UjHKcQp1tQO-WYjPbskdGDgCQ$we`mWu0`QKWPy|ZMSv=S6eFGO_V8!8LCHCP
zHl~<$m%5Q*|9l!sggZkK4>Itixxxb_$aLd0@kSwjjISJyXKE!6o`)0jjGFhY!oCXB
zOQ2`<;-jk(PeQ9dpc9mWZbAQ~wb?<XJ|{l76?6u^JBP>KX@@+PfN_XOk%Zk224<7Y
zIVG^2^zS>6bgljOM_PvVl3*@WXE8fvqT#b-KGwncrEbqk&Ya-L3!zeZO!r}!eLAD#
zOKM<)e>#nHADtx4b~Xssw(T9bW<TM;2r?8LM|sQ?CA_^bM9GtvjKVi=%+%T~J^n0#
zpl=aKw06S~wKHKukyzu|b`1-|koG_C>9g-)e&{l8hL!PoM7{k4G02#PJr9z$IQGgs
zoP3)3m>;jszrO9>XRf5A!<YUR4~ET)$sYr4>$~H&_dmSUPWk7A;RNbZOWZ_qlZ3eH
zWht#F=ZCkxW>Dp{-eT33(`xt956CDh60t2SKCdsVUJ=ZpJ!i;A{q7eb4?KifDJk@k
z;}f@9pyPK_#gK&VF`hyoQA~Nt3UBKnTdh=VhjBH?Z%w@?K8BNZpg<5*asHJrCG6y=
zLnZef{%H#Rwyg8US0#7ZkS=>!K6#{2ydZO42T=km`rP_1_f)aCeaT+HsX$JD!mF;%
z=!Z^^Y!`Ha$w)T-_qdtZN!ywuW)>D&N)!vuGsUz&vg33ajIWJL21Yr-2E^s-mX-Qe
zte{b7@M9tLnghm2(ng561i<5)htjGFtg)OKM6%8SjznlLOof!v0B>C6{<>@I^1j@X
zNVBU%8gl0sz~ghtWU4himef6)JniXy??#$YWk5pT!y4O+nP6Tt;R#}nJD0As%5qH&
zat6({%)+lZm>NM|Za5nZ1!!$tocSE6<1ZOCWnp|NpddROo7U}RMNUpfUf5@k2{QF#
z`=_72DJec{TO>iSd=OYTm~Q-UaDfI?p{#R;{<~@;x=*?(A#U)w1I^grcY`NO!aNaK
zl_h3!)~vX_Vc)mpOKrLTnr->B(+GE3`|%?CA;15M<dZBS+hdFLuN&{2!GN~~JU#rO
zBKb>+d%f`cAa8xCE>6l>y7Ke|vL_gm+$kR{D2J)4>k<~6f~{y1SJy(rw%<eXjA3b1
z4?~M82i>;@Z*C~VX<WQUOwgn2y<Q!jI9UzP;j_U!8aqf3SY^cbWSXwaRekf5{B?)z
zWW5a=4_|Sk$Fu3gM!33plY^<dGHp}yx$CQ8ai(=UP)p+W-5S$f5fg+DQ3Axz2;H!$
zCnSBE&F0e4nV&)-`r!?I#<sx<yyg`=t1y~2^^<i&$zNh)1{%gXav>0}yUJLF>>N)^
zxFU)3KsOY?#9a}!k4|R9Su33He4JQioP1mwLp+a+94Ou>IfSxJ7~xqJoWqJCX*dK-
zxy3m%or~jFUZUD#*~&NHX9ZqqgQx6?_SXGwwNfRqqxoMw1jNcH)%$d|M5Npb`G%Y$
z>M>Tx@O+H1>`6Coin??A1szdmx<%!h^pSaV`(rmrKE-dNHm+v(uo2!022c5i<!gE(
zuL!wWifpKcqoFiV68MDe1a}M%CIi3XD(3IUM7T&mWH49MHjVF8wS!V3PGJSEHSJyK
zSH7cm7qM@f=31icu)3T<wB_6M)MPB~!S_0sm^TumV~ywDtUhrX7H1F*NrZjXYFSYq
zTUM*w?EABop6#<ol$EVrrW-__HICmLCEk>oa`SoVuz3oR9dG4K{l(lP(G~Vvp-J+3
zeU>c`+5Kz*?t47z75iZ{QB`bLzot^1ytcByD*r1iO>f8+iX0t{=mX*D5@v-_>L(b9
zg2|4>;j8N&oE@i=6I%Q~^Nxo5n=!fbuXS95A15<N&gQY~^ZYxHjfo>%qU##}a;s<j
zt->f)4JVyg3vU@ombg|K8N7jIXIeMU#fCe?@e4Pxt=;(xzwdT!wje=c%Y^1L+T&Lz
zDt2`jmzQ|p#z{nF;!Jg<e)oqdleW)NrP!mr?A;&VYo~px_HFn!??FvCU~s6uSw96M
zcQ&iM;tgZA^3&*T*)B$HP_e;M&!(_51{)XD49<wBl*HJY-ZLP41~Iuu&r^CdrgNQ(
z&Z~_ckI4;*9S@49h2>`U2flWCHS=r6?3m9${NCI>|I!?!(KR(s=k1Mq26HgboR%4<
z*GlIc<~OlJHTTpbnyfxwP1^g)V+F697f!pP4He`JD%wpJ96$?>8xkQq@|C~vZzhk)
zj2t0}ja@o7Xm$unGx67JwR_h)$K9-LNmO&bu56tIC9Jexlnx~{%)K^Cw@OnMBbh29
zHSszYs-+`h`tEq+g|3imBSxTeaCgyZzw@fUoRPrIBHTe|i>A4w_c`Jt?K=x+Y`(3k
zhId3^Uhu!#2QOS>x+Oc)V(-l6Iajn??OZeJ{uQR@r+;ZBeOCbl`#VFu^_s&{<As*z
zr()66wef~A<R7k$=|jkREb^-p{Drdhu~JEBqu*!m+6{^0r3((hXqxx$%%(frhyQU1
zy9E<Z+tW=Hm?hhN>aRJur)Kc0Tt&kW?t)fSv>bNnh5};_-+&buUZ;E?wFr8(R{QFT
z_~~F?eeadWr_bc4M2=|TmzJ73#0|PMvJz{~n!enZOYL&2zy2cwWh8o*{cRR{TJfoq
zYI;=C6J=2dNx8fHLwEVE^Q1jYt&t;MYpxg^M%&3fY&+kj3*3vG*kDGRIuFhxV$urp
zChc~@$W?d8*!CXcJovWz(y6CHChp;rEn!*n0Vn~?bi5TCmuzggn9}wF9!X4cPOoI-
zf2FQ^?lVTFS?cH;r=}+mH@dG=u3u}&S<VOs`KOro-l2yS>{L)T%16TElWt>lP1l?x
zc0OBD`6A3&e-juGZbkOrQ&FuzfJrtG>OjP|9?IN%%1ri!B!1-FTN$n|UNI=N91_)|
zD<^j&Xeb!3qK_lM7KX!i5u~X$gtiEb{@j)q2dUbqo&X(X<qv(eU!{EUFZCpe(OYSs
zof;rJD|Ke`?u?re;t@hG^iwgGA;H!EXr%ny^`X}+3F#m^>SatJE;FQ2eT&e;G3K>e
zw0z6^_Rkl;s)>!hZd7+3a?-YH)R2}i?fNI13+482k?qRn`w7hldPabTYPH*y{9_;W
zYE~2AR7vVvII~?%c8>#i^52g@-@;KFpG{HWj(&)_(NSN`D*yfVd&qECvM^=-VImkz
zZL|R!F6iL9Y>9|($r3*aThECF>*%l5+GAC=v)v3|me&>`&D5j^R_arge#VlwzQa-f
zz5kk?dG>6LzbwABI8!>Uu*2EK@K~V!%Q?)GPM*$;=4jse`U_v;j{Cb3r2P|Hui2xH
z)3-IsbA|FifSY$?mYYOJ`y~DzN9^AZg|NhRA+ECBVtW&EDXo14E8k(WN!!*0pQF)|
zE_#e>tch*gX`?Pr+iF9SDqKH`DUvn0C8uT3^1Ze$?)?JJbi0kV)Q-)U4L{8x>2yJG
z%etZxfuH{fA)gL!k=7o2Wb)75rqwh*^kJ?SRYxAoI$!%y+2}PFhi$RZwpXS!Mhj)W
zhxiL@TlQ-Qq44cTgR%s=LD9Rn8DVSro^kx(D=j5kfc6e_{^whYGO88lZ#He=33C+L
z1cm8hM+v}=v5chuG?od5m#(YrB%@2<m}0oN{A~Ja)oRv<A$vsVm1Nkn?QICbM)u(n
zS@a>sOUM;d)c6J_^D1WKZ0<sddwe`&a=9e?P3=s`#JJc?mKeT$9451fDGoFTx-Ba;
z!<SGwXBmqR4eIqV_%zANsAn@PLkFWmAL43rbLmxZ`)!xT!~fa5-mkz5Y>zUzFYCDC
zzxp*>oMHWsJ4PLW&1I^%81F!?G1{yflv&%Np9NLsM4&Gcb2A|0c?f94v2aWqHl+cB
z#WdVM0)q#UblLL{`%Oy-XvJc0G+Z8xNmaUdtlL5eAn`d#^`9#Tb}g10yKnL!An+(V
zVnYmM0+rfGn6-kH_og*V7#?hdD8czE<-6MX_(rG@F*|*?T*Xq>(>uh7g3)b&R;{aE
z#bC5Z2WYGwXvPq9=yjOsmW4djP|(GdjiZfXS2+XMHTBoBwjP$?-fphB0}0Qi??Rz=
zOb<mLD5IG*`WsnaYz)ZnG~Zrk4Lv_3HqgG5bucLQwk^G&x1z4MQOsk{$A4OnT7Rsg
zMAYt_BZc)@FF_Ujhv;@MJzp9gYk7*w@1ocs1a$L85-%*M?S*BxlUMiPqhIqyhtc@l
zNn1R63r2G)U0`TU(=*Qt{%G`W!lj?_g49TQ3RC*Hcslo$pASs$dOT#p2ujm#L|B^G
z?lJNFiO9dKsFX0WG70;PO2JokK~HSUwk-{78wkIafD8U@dwiE_WD_aZ|7hds9vH%p
z3C-?p##_OcmJt@YdF^PVQP=*t{tkTJ@(BH7cLQ*s)~S{vE{7sXYrDhzbq?;{qSXko
zle{MHWs{lv<oid6m+dy@NA4jd5=^B*R<9ARNIJAfsR2?hG%BcDmNgkXzR(GwBOMs4
z(R5S@Wco{k{k9mqwA_v?|Ix{=+)|0VExA$=@JxG?pGCKJ#JXt$HlH?)1>LPgY&KLV
zK5b#*l1_UR<Iw;&{Ih7}knD`wF#5sRP|M*9VcAa#g>(${!pn@H$2X`cfhNCC?fUpa
zK1es-%Cf0aHGopnU*3RFx-2m#H=2u9w@*HnJV`@QYqQPXq6!SE#d|fXZJ{HBbw8^~
zbXhq|Nf~lc%jE>+aRl{u(Zr~~45r@S2htW^|HIrGJuiCo@pcP(v+e<Gqm>ebA^q__
zTKbvhsNq|6cq92l1F#&{rksg?`wwI@HXnf+=lfJiN#!o<J^b~fFcIm`4uopJOIY%2
zzMZ4H3SMORT-w-|y9}edT%9sZWD(^ne)8dZ8EZ?-{rH1}+`JCqr-z*N4AAI63xlA&
zn#a=AW3z{I!-QL=ZFTeU@WACoG0bh^>4T}k?(F-??g@FsCPn5Yl&86m)?CXwX%p5h
zCnU>W(n-9iZ^h^zDgqM0+>2#9Nivtue1ESbs|-F4O;@uyB#>5$>$0cY+BaLJ4G!|E
zr3b6ZeTZSMH%~~y46Yhz<=Bdc9c47Q-V!iIn^(b;W?}x)U<pd}zO48buEn(fj*J<x
z!?B8OS_+9R;QEQrpZ)t6hc?Fpt~95u)Bug)!1i~gN!6f+0)Tjh@4C@so0u)8Q7W*s
z^er@h*EAr2u>#{$TMW9sd*=|*Q(dZxSIKPy#m64*yE=lFd!*p(`APDA#8+PJaL7?_
zZQXr)ll@{dFEHwwB7dhfp!K!3$B?7BFFT!i!RyN#8)HGbE?L{C8=>Yb>r*V+<F$3M
zLy(rUBXMXys;ka?3*?iM5_59fJgA?X%SqdXjHD5KsRxunAoJgNzt|&6wRecuRkN+2
zkMHtasWgMZazs2}cPOy@nDvF)n*<v+B~6HI5ME-*u}n{u{Q6`u-P2x0@C6V1hhCWK
z2#wYQ4-{;k(BlRpruP<<;gi2|m7-5KfNF{;zOr1s2C>F_m-YMIjaN*kqmhbsb-xjj
zW^1}K%k0IlpsOujg4D_eQ|KDHlfGrxf5~J)fFN|9|1KotAvQPVR24it#~jgp&bBVn
zF<~W5G!&`1NKK4w1RPNF=am0T!MZTI;WiNerM-nS^j<>X2sPOX<hB`C8F0)yIn-|o
zhg<S-#hZ)EHA8AH$pggC-u1TAJ?O*AFaB6AZF~0cKt4;k$hL}WgE+MsRDw*b+9Tzs
z{piI~#WMve00_R8{Uh<aNJ#<IjudEC0tIBW(s{-buj^mDf>=lW@&t1jv$C{{Z_-AT
zE3SyAouWm>Z&&(h)0HFJM9ng<gzZQZsD=x~^@!0)3#A4D0?tgpR&LbE(~2_-V4}LE
zDI-CDOQ8HEgq0#mJzp<I#>5x3s?|TYz}^GGh^o?5lfm$&gJvLC<$(5)mguR%%0e!I
zp?^nLL(1Xd8%0};B>vIcVa-wCQ@7L9<$IqdeRU^PSWb%8<zxHa?D>3-FFD0_gqWq&
z)j<rW?5&JaCU61LwJZqcd)L-c6H7<f(obF1UP43tY26YYYQP5J?Ro6^){v`BO0B-2
zQwgNYg<_R;&J0!KI{0Yy<JE9H)HC+>6Y|9FO`Bgth@t1{Hup(SzFkzl?sw2SoKpry
zF`sXe_p^UoY9eE2(b=oIGq`PWfsJM89{9-wrTLGCqE5a@e&=sm8k6Pqhej|x9DO<O
zgG9#z=lG`Ba|+pV&1&GR++hN^G*qgAz0sg)q^DkRmgIkEzxTWMOt$}(%6@U>wnXVQ
z$ohy%REhv6G`&}@?ne?D!xmMjahaDYoF8U&aPMo*Jr2M2LUxI+xo&2BY^yiYIk|@Q
zdw8VdpZ-6e>HJSR+Vx?mbV9z1#rg~vuov5E9aIB8jpjFJd7f3TU)lZ|w0b75^k>vT
zCVCGc?xfwsb(xPhaBN#aiT|?!7oZ!g%$>W}!FuX`JSJ8zTaGR3T!N<uGuFRPFBq)K
zG{~IQPa&RLZ&a!u({vV~8X~3NG#o~<aP~4272>iEB=E`AF^T&3MI<!!%KPDxr4p-*
zdk5|Kn}n4icfy|T+{=Ca6#3luIo0zFa9V0=D)k5sQc$$FqHh|T9+XWmIi$Y3Rqtzd
zNxCEmDW5Y}*EA@idTINq*ttmUd;3lHP3TX$V}^>Qz=-;9JOk-0adeN0>C|f7<hwVi
zaOw#oF@gEkg-Xs|*c}xC^TY#00yc2lhkawax4jt1B%MNgyov^jj&7^l!7-d3*~ps)
zdT*T6{GpVILfSLGHfT(SvNBpYwZ%c&J8trg!?*U$ISBB+1gL@g$$iguF|c`^wlL2d
zaMcveornX8a?ByEH5*Ch7SuPZi&Kx}?HwH3Ly?!0w9dFXJufC9_DDcOuFB={+&g?E
zG?fzH_S!}C)a|1goPCOQ3YWgB^&UAd-SpNr*8XE-uKm}k`&Qv8&R?Z|G?wpIotB&g
zQJD2c6tEl2MMp$m>cvBoG>4iGzm|aou?sY7FtL!x{lgoCSk+kZSWR0;Ym9QP;;~X|
z2>z!XcXs=<a{XN_xQ_}2@bpJFGXuq`nrInMvG!8>@yk-wb8}Sbg73;(Uj*n#>Rt`_
zka8+Wx;p}<74Hylz9`MEs0$E^S6AlhowmWOJu6Gw9HNptAq8GrYG3%Flpszs&cXI6
z!o{-EJ27lU8#{!&jXm;}5Rv$lpfukUX8c<aXZefvjM=^S_slOrD~cW>c+>#G2Vx!F
zjGXRE*fL&!nX@kFZgVa7VDc;OrVS+;yDBKZXMR&xb7obzmzSDX<RXgN$5C-6i?1r4
z4}Me;i$K=tAIWowktFm9ie-l9Hl&W>>SUud*!I#|YeLla8i}g;gC9#q#B*xxJJlt0
z+u!i-*0-bk_xGa$WR7DkIixO!KmeUOSEy@jmwEc}4N04Bwyko<&Rhu#ZaL~4-(s&<
zWh$=eRz2a+$ITsZ;j52418?R>7m{PD%)++(cSiwW#%PPC>VBl@d{?(^WSc*4Y$U^x
zMTWEXQpJ|#s*S3DNFRRTC^a%sY*}N?@=ZE4)S4<KdM^(h3mC5?p#dPBa|$>^W_Bq<
z8uq8gB~*SQ!S8g9O3DuTbYFoQ))?kHAH1v|#>)GU!dS+o?Pzg&h)^4bf+UaYccb1X
zS)I(yK1zeJeI2uT7H18Nt(&aXA*KmQZTF-VL4FS_8+!wtTQPsP^~Y{xq0iXAq91sX
z?p9K|o7H8qrOsc)plN7Lm7AkO<<(>*MfYhE;flmW<Gh=sVZ#X1g!=62U2xlOZTPk@
zMM`>IBWrjTUmvzx%;0GI5_~GH&V0A9eH>9UAQ^C=okU2A=U7ZOI6_`3>gO@ti<y7Q
z+u)yWIKVC++eUD+J?C746l?lHVYxA8@edAn1}}+khwOsC@?j;rb6=QUUBBAv9iAgW
z?A$flK>(B0fJ;`XRo4FXa?x3dd4i<QgD1ZlC>mCui5oDJn^w?&yuiLdg(wUv!EmjE
z%l7H^OWY2`y{UDf5PKWpF)Kq4WB6aZLJQ;7J<jfMg{%-kiB~)Da0!~}%+gg1$?UGc
z(7^rOgEsgB#X4HbiM*T<1@KJYhuMLwba@@>&Qsu<wL93us#E$7@);{yY0Bg*!3@fi
zNY`btLm^gDGx;s_6jS~OZm2LtKyGf<;rGfLxkKc0#V{8R_4BJ)GNUOPH*f`4ir}L@
z9H66-JC0~Vq1ECXJM-4eM)}5Ecten5VjbMzRDNW+rvY@)H4BFHQIJ92&%jtQJkgr=
z$5gh;?T6%;!^MtT*+-JkZaxKO$T!RmojA^Ux6AWmEIjVkF+z$Jy4?yd_4KxF)99aB
z&b<RLs!wQ8-qvl*OgQ2p7`DILw$p5EaP>jAZH`>1u8BVfvS9>U9WZXQazN8|GOxEI
zt|U*eU)bSlCw@rLv{Q7nvMLfPf4I0z%G$fSkm35->13=YHFEz%?toTWR)~&p%146*
zJKO1u%7b0B9O&)7;1gtRCgcQu?t`tksj!ltX5a;qCNC0hPR=2j$(E@E+6;49-dy+m
z^G(ph*9^E?Sc`3}bTO#0!_VnAPpEo}5W+5xvj+G;!!LN4!=qDI?-SC%cFr~~pz2MY
zcqlW9+IOtsRa=l;=kJLA7SizdJ+r{}ZmrlHhdrMm6sF?2H(s$T<Y#noDKW-4<Si3g
z<uA*CzZ_kHKBTejATOtvkm<6&C>cTa?P{XmL)B5Hg=LFCJunjWc8|o*FCjgfS5WCn
z9TXNpChV?ptvGxOMK{l<<>~q<F0+qCWVw#G29OCbvVx({{Z|q!95JNxo|LPCA0FaT
zT^Gj3Te(DR+N0d<GILLM<2%cRPz{q)reme0AO7}62=IO%9COWg;#vkVG5mjpZ0{?T
zcF~q9rD1U}m-@}hea^0bWQ#})=g5Fs`A=|}N>$dr;(fl2o7<v%{h80J`<t{lP0a*>
zgxk}2n;=G)bl)3fiX4_Zme!O1p08^l>Bic+(8nDxri#3)pv@43tQkpo;gnOAtz3zz
z@=SD*ePuFA^z0g4q!ktp+xI{(xgmEqoTzkdH2LMO-f_??b2CS=yvFbB3*sXUxqsqe
zw?Tbv4aNhdB3V6t-ia4a3?5nep5u6kI}6o;hzqN5&f=iDCPoZVd&@^Qx=uyxO@&ya
zQ!`!&r${x3xg{#<#dh}f7(}!dnrY>IHvitg^n9cBMf(I=?BlL2%ytcQx@}!eo(!*j
zGRe-f?Z=S}OuL8GC)t1|x5C?=drA-#OjVEa@tdh|OjPHgpU2n@k8>Kj#5hteF*}}2
zi~c#Ih8S=%NjcWO$F*=<Rou8X6WviKop#vPA>RmZ(&k0GKrn5DSIadTcczC;xZ}po
z6J=tgSSns_@S|>SZ#djC^le15TiiKPAEh|(of49yqkcut@d#4iaclmG2!A5MD8G)x
zDKeX8w5glL%B)8yOa{=HjgFTbbTo83ntt<SK;7J~!WY?6$+|Be3`ylgE=F~=Z>Xsc
z)$3Ug$d&MHN3x;$sV3(J>dY0L=2=-bd#CFU>>Rk>Rdn2Ex_LKCrfzm2Z>#PPE6p^R
z?!vzin)7T-lf?G=En5ZRke_CH*}W3)Ty_%yI&qBUX4(<Nd*j8!g2wCKGI3Is(xZx4
zndvd-i14pibrQs9UY9<<MJ#WL7d8(<MWGKL;bIFLY}8=%Z9-`Uo;Qp5v*MJ5kMBOu
zWm#(;g}ak}pezMFQuA&j9q7E3;7DWR;<5R4wKYy)QqjG<5yUieXyz?Z0mblNVzh5z
zOi*4O8UX94rOyx3(WV@NPgtCnv1hZ2Z8c|K_O_b5$N9%6=l#H*Bb$zF+JW521Ydi9
zk*mk;l%}ToF%@_<dGc#(uLA_G%mrhFb-_|Vwj{Xyd51vZb#1uHU5w&xMaARoGlk1e
z4r!$R11PgV*G3!D87W4WC-GSTx*9UR3H)`ZyTBJPU#RTjJPUaUmsJ+O-xL*()RP6U
z;$pHYRrQGZE*Mc3qDkp4lU#)&pFm_)_iaf_uN9N|%s!nm__4`99U^ry()V<{#Jeb2
zS_4kJ@kU#fBC_G~stMgn%?J$EtAJ-PJM^ee@Qq=f#MP{L7s6pVYR#X$hYz16>t;8d
z;2-NQ)%>N;%|z$;L>6S(wUDc<aD-e{rji%6+o|>5vLl)`W}!6<_MGCFT@dJPOXfuo
znEhMjKEKP*XuRi<@icm`p%I}~GDttZ{`rf+Yn>_P&a!!HU&IZbCE%$g&@MK@M(!gt
zK}n3IxTR>5)~x29lqgTZ#F#v^ZTkkKm#UfKZbFhX^>@%~Tdf5>MFonDl5v${#B|H<
zpY=Mn64kdzVc6oJ=Xu1<68>rvVsw*8aK4qE(Rgl?X<ES!pHu)x)raxLZPM_w*Nz+y
zBSY3DCi^u5`~|AHD<NTVclKw`73}yT<6!stsDyE#YR#cz+Z)Uuv&q6@2iDu;Uppfo
zR^K6&g86>!L}NXx?%yANu??P?F*3->ZvEl=!^V|DvV#0sp=6Y9G|dWhT6A^$=PTfv
zCl2bNClwN)GphSrcO~N9ttQ?Xpk`ZX-ag6kim!+N`0+dDQ#+Z3*m{7Wg4{7iQ4G~U
zzK7AquxAv;TCXEA#y&jK_4T2a>kZE%@l|O^Ejaz7oYooH=Dj=SJd?+BPfu?yDo0Z{
zr#VhK$44XMCd_=CikhqK0*2(Nb-A-u;;qM<7n}z^xdEey);l;JASq|4>Z=oG>QP;x
zr?^Ukfl3n#kSH(m;YS5NvwNNw-F7D5UX})>hR-i|y_{CCdZ|m@hPOVQ?YCu-y{O-#
z(ulzI@@3?%+@l=gv)g}gT7O%ux~S9S!EVuuXfa|tXXxI~bQHFgK_#-U{?QlU7Sev5
zN029B_LtnQ6tRrXe7C~<mTNoPzsOZ@Z{d6Gi_sg1v=Sy8-}53pr^3(udyGYCK~Trc
z3}qR0JI6v8yL~WJQ>jBN2k8q*s}mACc1ni^1{^E7Fk=OJss=>>{A+vRX{YfHfqTK0
z6LxKH;@jZL^(V^Zko8GQHZ=_rxht;^-tA}xF_vNN-lc@(-vn8$9o3E%Kj5kJwX|?s
zrh;!Qqyg$wTy|)h`f9UFlM1zDAMM@a&t`Zo5NRJ+TBTlVEI$;dGJGsUecWL{CU0^y
zyWO$oT?KvlCxPv22QvfDkX`f1PWfr(xhFH(1QeC42PK8pyRF&UTlS<ZR;U5HpOPmN
zbb4&j{4&~v)_!T|g9T78r1&!Z>9=1&!_w7%ghD7bu}Ax(%q4v$<9Xla+&_7^yUCHJ
zg>HEpzlig3Ql63~gL;!q<>NEI4jXUfEv8=_ptYSi;NWi+icXm$z)@j-I1Sz5ilCaY
z_c(`XOHRsnmT!?<n`@J~_f7=p;U9>1{1rKy%+zUerD|DTq~!&sXq=UJu_`V-cKyDm
ztYB;vCaJWftuudP@%wK<v^Tqd;doFw%Q@$=t3Xc5UMBHDOR5pw)v_a%>8vKmE8Lqi
zpoqd9ryCUyUmvSA{Bzk_AwB9l>1)S>Rx4k0^D6*zGw}R%#f=Db^wMYWlHtJ%)QkSP
z`s(szB6K%RUOG<`Cmxr6v0@4hB|zB_<|2hO1b^C4xa+jW?Cv-H=YN2mLCVG2vg?dt
zrVYK?-Wth19YP&qP(k_N;$Q7cW3##9KOBFW%#6Y;yHgYg=IW%L+e6uoPz=H;y;kZw
zd);&fe-kdRsHmUFmVW(}d{_LsZ$^^(_t*TU%vPNNzdxQ0-si7@zimF(N=pAxr?Ad{
zz}vyj-eY}75{N*wGYv_s91qg7{GP(gH(}imGg!OIgDWJ!5*7dGmN-K!tYr?wDm{gn
zR{0gkF;RT))Lr6fsogFed{+$f-CfD0UcL#4QnowA$lhdkDC}s+u9sms!Tj?8DVqn9
z7)6T7q%TQVaqVuOKAj~?NN)-CZ?waNEfL9E!B}TE(chn|HzP3M_fOuBevJ2^1ukLx
zmv}0FUYO{ErdzsnL4p*jb#)_6R=6Kd^$mDz7T`wz$^7H~xYlX=v*cp5hj(&u<2l8^
zHY&XCYGAeCU>?{;Gf(cu<0$EVG-nk(S>2^Z7dffngeo0NOlbF%#8%}g9VnP$wpQe?
zUx|+XcJ{boMAK#kR>77bjq<Yg&vqrOI`BwhH)ifD^Eo5u1dcga$G;0F-_3_Un1*tz
z6?6P1B=^*FuaMcp(jUeVt%2O(q%d8D>%p@H{@v0i`H}Kh3keOfZ@@cB5vV*~mf;<x
z0DrsZGUt=>h7S_X1Y+C7@U5(UO8%CmV-ewT%{lf<t~1hmm_64c78IVgGY8NuYmUv|
z(PD4-Ma-Af`?GT{$$i$j@E}gp{J|@RupjN8(T$mlK!EX7oVJ)|wHy0;$Q(;{%Mmvg
z_EMO+`_a3oUV$}ZxvU5+c%zkAyH!kXa#3*7Zqj#zn`obo#V-AuHwa#!l+OsHWw^(m
ziFH6)i`N}2S5qD`{bMT!Aah#W;uidZm~9nyIq`<urA8nUMU^})6CS2#^8e9v)^ANP
zZWmuSFkl-a1|yUjrF3qzAkv5+Qi_un86bi#s4-?db`u7o_`oC5!baPGf=EaigOL_U
z?e+V^`%m20x$bk$=eRlwfOH?ak=@BOP1Jcy_Ne3Bo^%52Mle&?GRDomUO9>9OpJ}M
zCgMYLNS(E$#?2u4BQtLH%{IbW80Wj+l#9$<F{3wxJ5v8XA2u$3EhRNro<dhLDO8B*
z(+&-5PYq>dK$hxejBP-zc}Dxj8;UAgfcYZF5?fZ=a@7&YRu;9vbKa`epL!HLQk#r|
z=PbfCsKN;pDxhrI*#jt$y_)gZ$rrU6Qh86m`ufPMkvN8R!Yi=C<c$)_H#~~7>V7cA
zpJD8@9V{kx*P=))@QFJA*lA&AEhzWvWu3b=fAi)g1;`_3C&em9obaJT?1=4?wQ%`1
zc}t2*ebhN8$hUyX)&l(rh^}8bAyQw&f->QMrOL%~AROx-;QFshKpnq*8+=(3u2u%^
z&DJM#cl~@dl2`duVlkNxl1hWpPQ3knQX#;J!u2<<w^D$@mMQc(9w$GUID4{hgDzPI
zv8*f8AYG2(uIQRH8Nxs!?p}-m3d(YLx_ON05y2z?zdPd6q_uoDa-#mK{&cY{Wo+;n
z$JU{2yS<7EEK;X73^BONKiJV!>M%5eYxL4G&X!9fFHrd`&fYW0m(I`Zvm~4pRbrEh
zuH1SuB_dV5hgg~)I{L3^ufNdyswu)XOa&O7A31hd(<}I)k@3R0J~2);6qIhMe}|&?
z+X7&-{%GAsO9pID7EQ?`5*q*A?Yq(7jBx_~J5Wf@E)<3fBblk^c(FR~Th?HNE}5LJ
z<azkDVm^VoEj#O+X}#8J{bKGui~0Ho$~0KRM?jTvVaWx+WTMP<XStFq2)FLbqC8z(
z;~myNG2a&4xBoR}M8Q&)CwBS{U~NUa6%Pi3ZzvIItYLEC@QGs1AS_e09UfL9ZJwF<
zdG@|ECpxqvw|&R-25iJgHgpU%&)Z|{4Mp=Ig$uCv9S_XU;lVwg<#)R_COlJHV&lqM
zFLZbEl3)GyZCNT++FIs$S*nVpOFx0VOlf`BU&&N4LxB+n4QEfKE)Kzj@%)AxQjNuA
zITt3{e<|GNZOU)A4jpOt#`}tcXU{o+w+tJPYBle~tt)Qg_!k1KNY6h;A64G9U8nIO
z+c`8Nx2Gsy8wHV7weE*n7KuKeY}3c7Oww*I%aG+lHysKAwqB{)r%<+TH*6u2!B&B%
zhizP{p>0Cy!eNG;%$+_|KKeJP2gME8X%kcRFD2BN&^F-_K&a54xW|ESM@Xi}p^r=`
zM4FW_4a613!3=Yz!626qGqNwo5__-qIz6MtM*dd{^98WmC7X=({*o)fJKzg|a@pW8
zisw`F#<PH><<xjz<0Elp!E&e5gVzSjM`SYwW-cOZoO4oOrRNC;+9~OHnttt{)^W}K
zp>Cyh(k!t#YXK^5sP>HwaI9>yRBkc>4G;qLrA)q`t0vQ)ENrxopMy*g?u=7a8rQwU
zOb{eRr|TXH*aYR|ak?R{?{j^9#MPfjHjr}Q!eO_CPl*0MT`?su0%FPnUiS=w8qqyL
zbi^pH$rd6CGCf;OSbFMP%w4qVEj-<sr|}F^=avIl28I1Cw%#z{WDX5C8fK(x^<qcT
zEj<!WkQDZsYHdMflrgPI)TBHJ->yfDw6z*$ASaNyZ;jN;u0Yr}LDf<E#XG5RxK7=5
z%X<0ex;--SF<e1p+NnZ*Lo^Rsy&qsfeiCY&C3Q8{7wjR{*;1;A<8Hg~dt2bfhbhwF
z&R-e2{=Ts=3Ce!ZfVU{e(-bR}1h2LLCzbtNZM&gpz~H@)*$zh>AS^vM6G5pFheitj
z)eTA0&hG9CGX(Rz|B=lF7y3d9q-Vi3FgU$&W8)*jp>1yePcq*P*Lb-c>)740dVtzk
z|9!tS!#iR1q$(@b%@mhz+|;SBy6)4>;4V)figopPd+Qb4N}Dh2nC}-D5VWZcLmww^
zpU>vNEf1&n?F)U3Mc#{&nk(5o`%7qbRv}`?TVP7GR76W`s$C)8m{;|hd?k~GpcLg|
zieU5spt25@BJkCLs2~okb;$K?p3}}g32n*_E~xyFewkS)O@?5k3T`oV*1PkYWD4?F
z^LgxukD|LKgh|CyYM6qYow6beT|I<-tn^AkxuBHpKp1}Zo79tn7{EE6k8I@czi>ha
za@4kjO*?XnPtAz?OfG|jrXhfhZ7IKp<f%0wa!HL{GIusOQw|J&aagyDDLLKPPO@d`
zm=ngNHt9C<&$`cPG$XI=biJkft9PfVh8c0E*Y_p;mcBp=pYu^@+|=SH08VA}MSaT-
zO76}k+!0?#^D->+($%!TZ@;-^DET1LRCL&=Y!`2Raqr^!P#R24CPc@^R<x5<Ga4Zp
zKy1X5#s!mw#Qn$n*aXhWWLHy4v+zL#_~X?ZF;3v1-eS`eI@5C~PeJF?=07MK22hrX
z&d66$fSL}q?XwfEs%s1y8h;0O^f$lWYN{9gG1|(y0RdH2Dl<$~1`;3c&F}f7#Jf;v
zn8v#t2hItAVHn)5u4u%fVqO=-&^EJf39ysFpQ$7tTyjxM{57uGw0SD4J!Yj%B9kl6
zt#K7VKWS<0k{Z4)H<mUc#ZhS5(w_bugi--k^ACJTO}&TPZryBD_Mx*_e=whzevv;L
zM77rK`o7!jYvP#h7Jg#+0*@^)7}piH?JAk5qFHmc4fn1r{{&~}t+7$>atI!PQ+-?)
zOUvjicL4||@YAU@clT4@h1ivvoIY1N^F(wGY&NvdJ}9xQu%FnVJLD6@tRtDnMY&xo
z(;b&H38C7lmOy1B`Os(?W3zKhZg)txZsEhJmId7$^<V1@b}IyI7u^ti$Np=}c!_j3
zQ^_kxnqNhQ!FvVblyck{*~lc`iB^5HfoPuF3Si9tXh`L3AyPBk^e&kL^m)JuNUMP}
zar7t+<crY<D%WdV%ESu&Gv51c(t2Dd#4Bh+&#YQDRzv1d@6%Zq$n~*XLw05WG>Jh}
z&f@>`EN365U!r*`ani4oBm7CU`BJ>Qj+5S&!T|zKaKNOdPo=^~hkf&KqKnrHo}OuU
ziX{fCuzqQ^DEGhtNW>z2_33?S!u$+rGz;@!@LA~DJf4pNPkMtB?3SFr5rq$7ja7B4
z@^etmYygZXN1gaVy#*se06MV1d{T})+eQUAh#>A%-wk|2y87waU4p(K2_v#Hhy{t1
zD4k(Q#LN($mGsDlqLrHUND<f@QO-a?x5+iVFU7h&G80Z%t^HmcmLIUO1*gCrZ33E7
zzH#4qVG}iHz_?yrzq;V5KH=m!TDd8h*n0x71;%dvxU=yQ3_Ug})e9p60(JN<rV*Pe
zsugXB>UjzL!hv|5<GQTP<ik2wqx{om#txnhHU$v0UfQrtL7jXJdCC_=Tt*~eSAMc3
z-}f${^PNefsO>>(&SQR7d`3>#@nJB!VHT=v9GA7K<9c%H{ON0edf7>Jb5H9l$B(<w
zfcqh(b18SP>9ibI{mY1HQQ0e{vXui{2fkyq;by;fd8Aecq|V#>i{g1fIIp|6DN(J6
zD2aHRXxk%zOJ^57yAaYE5mQZx)Yp6DKT=STB9HoP=l4*s*?H>3J09Gp6|TLi<F?Ix
zM7B!PygDppk7WL$?mwR${<}pg37zvp=+_`!Q8*C&p0cdXGsxS1-fguzv4s*1;okys
z5Tvw25kD$Cn#HLp8-$$gM3_Cx1=~U*Q=P`6eZ1R~DN$HvYTY1jILc8;esqqmXTPj;
z3f3&P3{<XESmIw|7>cD`Z<{u@j*G!?RedN?^z9cv`MPi<xz-XT|3qvsp&}?tx!d*I
zc|&clO^R{4f1uARtROn68P0G#9@xg3YFT5IjZh}oKuy+YebZ<Avx>iOd`5D;XG|rI
z+$8ufzhvW7s6tE?0`{wq+oM}P53h-65ATlT&7sX!$GP8TS+-i{@?ei`8O_7Cuo|kV
zWy9T~p;mvmCu8Nz&W4^ac{xLs9g%8<0a_OiB`qa8Yh410{4K>y;28oBf*AUQf2x*r
z<C4p`zi91Vy2a>_Ym;>5y8v0ylDsGxQMH;)y;Kex3biTI$@2R*+nCkgXADzjq+8_g
zd<BQN^e`HoD;@qib~RuAWZ7JD3nnMulb@FVs&jS+>BhQsW`*AalwYvhVU23v;_shV
zT;C?*;HURCXrcY-;Dw)Mv%B`~w|!hug>MaO^SKul6&~!X7~gVw_%C(@EzvdFcYr8Z
z01&l<Zd!iczkFiyo+jDEPm{JFg~o+FqKZr^HReS_Z7ELGhLR$>%lYG~>)XDBO5x~-
zK18k0txt>O=Gy5wxHb(k{hXBNea+>X(8~RwtRCkfA|&aZ=w)P>^Up{233{RQqa`xB
z!Z2rnD4s4(PSu~vlELSt%J&G<8Rqc(0uT$DL1GWr4Lr0eL4fu25ss<wXPUkD$D=aB
zdnBw=5MPF0_9#C7t5%J}HbL{mmrt|G^R=Gakg@-|5|Ik*5&dRlX#i-|Q{_x<0pQ{v
zn7s=)u|w#)U&qJtE(l)D9Z)t0z0`pm?h02+(|`Xm(a-~H=?4+w6S^v=q)lb}03X<q
zq#lUMev)#5X&SK47v*=jQ}T`qDL54R=fsgm?sdDnRS~R{FWcB<c=tUd)!U<`gr7dK
zK&KxPdExyQ^FB;{L<3Q53^UkiaI-B)PBlSUbrfXlj6nmb5RXJzprK&W;p*%u;y(Kk
z1uZbwjfhb3R>6e@sMC$Ap1A`qplI95stoq)dAto*(G6ej{Q#;C*!Z!>&JVEoVIb`#
z4#DauxxYFT^}V6sSQk5M)y8joJ@CbMdfJkzcBSvTGmYKjnNvze4-vg4v8#Qo^}vcs
zjo>Tgbt9!KR~oI92t;n1?!Qm}R$wD^e=_6337w8kc%D5~(O`L}Ez6D=31%p>-}iF7
zM&T^sP-!DSnXCx3z|Dv%-mE2{7q^)f?$t$lqYTVu9@Q=NJLtGztb|)OUf3g7Wta-X
z*#&OonPNC|4RbP`j9uqid`tDIx07Lq6Kcn54UW4*z?3~wVpo*o$cPEZC|w?fPtAtV
zhJMc{D(wVjasdWTq=$%v1ki@NOs)zr=~%Q}+V7x(6LAoP7=dtqhgC+sTchgC{1}-U
zL>Rd{5<S#aE++9oS=)pnL~c7ut6=X&*Y+9pdWKculP2RpT;WJtn4<_A^FRx{mptmJ
ztonFnFCa!yr6O>07NrLG&rKyAs%6<`|Db;+55Pl9J*`()jOB${Ja;jMOqZ$TyJ+O5
zR*Xs;!jyde_x3O=MD04OqJ@$p^>)hbBn&B8sK%pva8YU4YEJ`?5u~?Cdu{{#=qfG$
zp62)GT;<|6uA*dRNPHV}A>+hh%GQuB%lj3dL?9HjCVbkgr4)KS?R5XqLH1KcSTu^d
zB@%gTfx;5{a&Qk*+{5+6I_8IRhBZFglBF><PhACKoSc+$e}rK{Yvw7dwsa^p-ZmLf
zlxSEGCNir&7%&=ALUf>`&4{2@5;Qn;+QIj}Cic)7v!RurK2<$S_u&6(5n1C}Z_~QI
zS<q{J1u*hTRFI<k=Tmmc*wxhFkVSmS%h!U1qdznp!h&a_wXLot+*;%;;zi5FnoG(v
zOwM-mRrQky{o=cOWrnJRNAeTZpLs~qTqm-z-@gX}0GQ=34<|qq7-Nxov+mGM!BU@m
zBUNpc<3`G-0{7Dub}UMbk|Zh|spMObePVsLYsxk-!p%Usi>sic`}BO74_hYLwEBoC
z01$W+bV)vTy-d3xLQV=9!(%m9Jpc(!AUr!DSUAr`UnU9}&~;o*9hv7Ux4o%%t{+9n
zC*oUzG^9KYLJf8Fwx=D)-~9654k=4({%s~4kQDP@&~p_{>+dMOQPUimtcB7m+_QhR
z3oWb3PYiwz!cwhT6P#-r`U`M{o=ATF=SR6G_A38WURsytgb)pz$R+cuyIm{`D*R@^
z4u;L=Fs+}D(YuY_sXJF#f;?pE{P9a@^Fk_N(JreoEq{4gxAKu`;}p35_npFXF{8J-
zq1tbEcd8$pHe+n-c!g2-H8Iw)cU20V>Bm3mKo9htpj2Y?@qK`0CXG)4{a&bF`m`PW
z)*n)`PxGwaD%<raHM^SbL#vg(WU9RggRn{&z}2hqIo`ZSTJ`IJ(JnRDxJ1ZS=s)(=
zHGwI3Q&rvk@7F6Kq{1GVAL+-Aw1h)UbMByZfkO$OlNj3U86Zd|34|Q^_?Y$P?D9;k
zG@N)Qp{hUIR1pou!?bKh-rR~iB#j`ZB9X+%k%+^7yJd*~r6e4V9>JhbrW{e0lF5#$
zdU6vfZAy}s`<ND7ax?{tK7k*3b8SRcYZa6xEl<or);u|EgCmZ!q>mEc?Qis6OFx0$
z77R3fJ80{vt}8>{@kkbQBjNCdh7u8}d5<&priCaky@Tii<QnVaZX}?U@g_&KMk40t
z2+})=$Yf&RdSj!RIMZ(OKUjx}!XQb#lo6JWK_Ao9fH2;gB%sqQS2mS~3?_P%{hkA*
zKij4qUf3r}x0^!ar?q|q6CWwZ38lXf-y**fMY;>O#$G{MJ}2+L_4;-DLTD=nfIpMs
z(qbn5k>$N2YLO%>{5yxdyONefeseuctka?kn<>1tP`8eKWjo`8EMNrQN^5-kZbMo-
z_4MHn8Az(#>u<+f_sphSZkXQwy5en!Bpx?*I<<YVC255$-zx2)B7Ku6-qEsSENLZM
z4TjA?wic*u0HoF5W#h7l^FG<g4^8XY<2sHx8Xu)mCmc0fjPXBGZ+`=~U(J->Q8T`h
zHEv0glfHZS>LujulW%|67FDpHQV4(}TUlz8Ex*ySNi9QJdb3OKHlkY`PGI-882XL1
zj-CG6qKIsT;At)Il3*n4v)0!wMXe|~!<Gp2xBH<(Jz|Y>iD($1rTC1?>)SX~%WgX8
zGK~ADQyh%VOjmZHGnIReKavb`(}!crTJJqPK;$xX^zLvZL2`0^8Ib?n-k(c_@29Ph
zu6u~jWPs$;(NZvJHkcC|6Vxc1tr^SkBA*b>?7V<ziTodA)H?<Dq%i!fuZck4{E-xv
z?gKhwLXhiZra}-z*-CV!OrsaOxVcfu&=8u{drC7!ZgHDrm^kpYW_05l5^*Rn3q>;#
zj7NHRHXQ_sERCVq9TD`Bk6_~zr+lrkoF4JJYp~f0RuAGb=o=&#Qj6?yGI5b^a?y!&
z_21zRA|?2ON$)1e6HMn?*R<!HHbA!h{fp0~hYT8O1<oO%_3>2q-*^6YUP5S)dzvzi
zS75XZMMW)mP;!s{3)tBy{Yh7llc+%ZzbSGx&755$SFgT&=&hX-R-RDL{N9G0uBrj3
zO9qmH1-Iowj;~H(M#+z356*Mu;_E`~;j*b17YN`Q-1nCw?=1LO1)sf{YxrqL)Y}bU
z`d(Liw1YA3ALn#g;ws%FF)0^sd2~k;NC`VUg){X;fVOK#aZ2D&nM*I8vAdd(i_w58
z;FyDSdm($%IB%iL&)~$4Em;0P4xFfaZAZHPDodyNXL#8uhC%~AsO(sJZwa#y_mr#<
zdeENJ`{XeMzU>2#2}2~xdOYRcGV;d2V#b4FPjA`}4%oS*-8s+<DuT&=-{C87>yLo-
z1}n9%n(HYz9;0*^7qCAg_)=3tj!7*ye87>=;J*Hx+TaESi9(>(IysD==ZsRoTH4o*
zhAG<c|4O;$VPQAtqc4)}1kcLKL0b1;?mAK)Ss%cVKK0wMOOfDyI|%@A$T`vScv!k*
z_X}I3GZj*DCN$^zQ=^~&>yq(m$(ls%&liT2str^vb;25F^ZS4efDogv05WS@*D3Kq
zP|JLz_XO(ge&Voe7o7SJ>QR(;nNp55K9m3<h+M+4KWjdN6C%`~zDRDRu%}2t&XmVc
znc9f!tanIb4$@S1@!7xE9pwK@uAqnODCIW+Tv(11rQ28MTHdw3iAStCo-s;=wqDK~
zFL_!h6Vd&TT`n;So5UFL525b>p0xCB<^}qTMs~H~^bVBSq`laNvr|xgxY7AIWR>rZ
z;$4e<VJw++>fd(?-x4m0HuPOgDpN<6xeHQ1m%vf4RRr8TJ!RHX)oncd{SXxh$U5nn
zcQE$@jzpV3;9A~ZaBJj%*FZuuaJ!^06RWFs93FYhdAo<RE>AI}FnSzJLUW-ezkiqm
zmK`prH(9+*(dOgS=t+WhTMU(``;ziP7@7RFWT2(C#sKHzu~s^;9ULgTxM)!Zv4RSZ
zLCauYpEC`9sx*HWdN|)lpEGm0tO@xR9}!*dKdXN+zaM#<6xtpEx=jLk_aUNRC8d%r
zh)Zs%yu3VsxU7z3A}!z*jPy-M=R}hnc>%2T==l!!E+ml2_Ppo(otg&s*e_iDd}yah
z|GQlP-s5=nrN3=5fSSQw86$=xf6q+arNT<rh-nx2#I1&c!T;dK*8g_z+ap4LY=6R(
z-4{OT4uec4Xn!-!^8%a$>&G7)@9dLo4w3^-CvWmHFl9Gh3*y#j_w-?QsI`hQSispE
zSx(#hC(<|aFh3wxT@3jcA83r#2L{r&`ZE;_JT2A11b;9IrtGm;N)oOPfDZFwF}xJ)
zereqWCq!Ms?zCH7=+LOo`2v4A`mD%PPWmMkuiFDWQf=rTpm!7{pW%D<90rzu6zN*K
zK>2-3K^?O@sOZ$bP16G;wqr@+IYcP!A^l#HQ&wrzlFZL<+=E&ayTJo^<*I5jaOGB^
zV?Fcosfpxc_a%s#vXjxk%FQ?RP&5KxcQ-IA_?j{z*<;4FQTfJ|d~=eRI*dI9kp>@;
zyT)_F@-fCCOcZuhCHzUHi`CVyX=@JZM<cEzZ-H|(1GOVCr2YU%(P3jZH`Z0*9)}iC
z8FN!jn{uV+7V<)PNa)Lpg1pY1@KWW?5-(kzFP-bjJE!<j$=3Eb;sUCW)-Ek=I13cD
z@(<dXbGqrzbYe=oZf(P{x?N@>W$)Y~!+`%q`kBU~B#+KMpy97Lzy@4N6?^iglB$RT
zlqGzxgH2gPNPe4rGMS(0Ys8%eH%V8!VwFyT1(m-*j9{@{SBT$Jm(dAVVkbDXI{QH*
z3`*4~aD+>d4X%F-d5=Iqk+{O}_!lZy9HrVEWkO}|jbv`K1?!;4-Ydk}(6mrp-5?+a
z7=aAh-K|7$rFEFy*+X_6;YxUkI)#DCJepPlOy|+9f|Jo}qfnj;u>vvO6{;@>^GES3
zI9=bO`Ka{ny8!eTj;)RVihv>sOm$L*8Ul^wRT00znZ@n0b0tpieRTTPV#~&Bw<!^r
z%DX{srlMNuw*@ditV&l5c19KO914?i8bd2~QKi8$#|nDgm-1tL<z(0{3@|$LQB#i%
zFi1UFRLo;}JAaMuNB_D4xMBhyn9<|nPRXTX6Owb(o~NpZ0c(a^aeT*MD^Own{+2qA
zGDTC+FTh^AbsgggCGSQcsoea$(%G4pP>jGcerJZm2bN@A;MSb`yA{?0?U9{RQ~V?9
zkup6zpLq5m5QXxCK>QdTg|WAR)6VNcP@_Bmuo#H_%cK73X{WPa{<R81JtTV_mMU8f
zhBM7lk?kku6T4R~2+xCWoP>a3y2G5za3TYaxZ{ec&z<U6EPYzAN4m>Z#=m2~@7;~5
ze*9D8w7z)2*kiU7CuZ*(dahe<p+ZR1DId|=qT~2{%Xc~Er7JLkyfgoVQUf;8X~Kor
zYt!gsTIBfwq9twVdbIr`AXDX{f1xDTD59vZkOs1SXP%;J3rdCA2Eu#)vN$zBx63DN
z!@(>aWW8#GoPo<3DY=lt6;1<9)#3wqHu<@$R7W)e0j5EKjYne@&S)07WAY(anSL#Y
zmn5zUhs2G}?@&OYqt*A6pZwZ=&?LTSmvT=y&OiBVEQmX!6nU)I1w15hiEpbCRwqf*
zu%3LCt6_4NndG8I;CE|_>tjRcQeB-5;)c=&fd{yzA7`!q)UAlF8T+qX-W#=MT6N@c
zS?2L11K$3>nQMEBr}FSNiqB*5aKJ!{qYPqi%@gfNcX#;yU8mXB-BJg9OvC<mDC#4t
zT$ENllmJ&%Z<mM9a6vc;bQ5NLqtEc;^BbI#JA>~?3@8}j%-1c6M59+xo~2DcHFh)m
zY<hNqM1s_D?1tt<OdJ3m6n%&ZxpY?Zgs2Pq)SYUrnYo;gmdV7t`k076%pEd)pAQ(x
z;%bG8Ds)-u8iep`sj>%8+!8WVq!1ZuW+~A;5)LAOcBmONsY8<n-ie|LL(h0M6=<<j
zGw1`0e<uO*G#;LA*QRR%Egpjk!-5<wnBa-~*u(YC8dNNku>NyMnEB|1h>P^*Uhz$H
zsvaM~^`d-tEAh`-Fu)iavtE-IGyX_`9ozX8<XOCC#y@E-QQW2VtRB`ut%57b20$E)
zf_oHqu$+{5uH4W@-|pb|k(0d?wwPN6Eyzj=AS$oQ&<h;&wa0UBi)G7!4)k+!#26S?
zrMg>BITcfQST_DLP#`jS`$J_gTnT$uo#6d;CmHud<KK1v9`!l?Uj{snpIj!oca|Th
zRI=;!(3z>Sz>*+zPi%09Ng>deg7DIKcF=M|ji3|v9CP30FkU{!y93dYJKi!cj*aWY
z%t8=Gmp@hHo`W3JeZdK0NKLp!h<Upq^bfnlj=FE$+-Zh;rBpLd3V;UXPrfTKm042h
zyFpQLbqADpwjYCAnB8#(FOSRek4u1Cd|PX*i#uQuP5&Eu?zr#;*1MOa(n`7CC)_^F
zg$C=m?@@_bQ8V<4f(iu^tz3-8wJ=0{qi6gl9nwjsZD1|3D>#=xkl@xcT;~gH>QxM9
z`bdK?`<Cp8y(+bCtD(ILk4<TXkevlCO9RXh)Hph+crr1ThjS8(Pe1b8-JdYd^D^_L
z$=Om1A=tyP4b&v!8%5?3ct!vgtR9Ul5uWD4OVkz5FTRjVD?z3V%C>T%DO)p+N?%8?
zgY0>^yMaUZ{w=>uZ>P0HGi}-q0fDW>(bYkuBLzY1l00)%AmRh|cl=nc>ncdJTUnNS
zmlK&~)|TFzO%BUEmK~}koJJmu8Y_p$yG(pwmE$X=o~X?)XoY}|7J2)dJU?h$1EAx(
zAE!CFRa(&9gfn#T{$tR~daq{Wg!_h#$3}>v1tn#h8;Heu_6X_=@c}2ID0s%gc<_@&
z?BlCCt}~RY<sN5P%L_EJ;myASVw)>=T~STPL``L;dMg5P6Ci&gf3`{1eAMlX6)4;#
z%SUC2?Fjq+Lpmpy9r8#nkk*>$uOfLFIESph>N1zWXiB}o<wQN={!|0m*|g=CXjOo`
z(m_{QC#2<$w#)vZgKk#J#TUvuXnJZnHi$HJeCy;qUU)*rH|ir$m$T`;ntsrmaTBL!
z49)7E_0Rn0g7}C9t@p0)fNo}6I;wmG0xrz_1{My=vVrgYvEbdSil3t&hN|ek%-ODl
z(|!+zCG5g_V$Xa?xUd{K##Q@_e#7^SEh;@d8#Ws6s%xC;B4uu;7RE~8%mmu5Mxh%g
zm^Vw#d_sE|EI{i#7=LVUdAW#Iv?dU8&ndgXT~hd?5IS0RBGpG#M40z-_C6`ha)6B_
zZdcO)ld)K1Bk;`xp~lfr4b?|LOT=iTS^(37h`D3tdDMFE=f+U1lzhEo<8_!y2k7W~
zB~pH4ixba+SgCSGbmzL2-urfghdTCdm67fFd!-9mnRDr<MDQH4T?f`%Y_T?`9@!?5
zTsT)h>Z=P*ILGYa;kgNbW?4|Pv8T4^=a46TkU+WRl1EmYZ0j0Ap@yfn&QmO^v52?V
zi5yP`SLEqb=%i~4O2^>}%q?X0rtC<to!?t6@SYVX+8X9)aApsmNJrTs<+~5r8W-Q&
zQBShnE&CL3C%-Pdc>NZjtKi-LMh?1QQcP$aYxRUKkdZMfhCrX?eH}WTF(5vS(pKFM
zr^~dn$%$zGl_0_@a|-<2KFhGzZb>WE^0|Yh>vK_36_0v@@b0i!<vMRRh053`f$cW!
zOVq*c+S7f&IQTwMSK5C7FsQ1LSXz{FD(y>A{cJ`BItqB9Z8v;VIt*azqZq2iTElss
z+1j2uUvl<|a<A<0v!APja*gp+GfkPtOyz8J9El=+$gv+ANE^%#-?UtFbcK{n<b9g6
zkq2mt>c;hlewK{WFJl`<8(n2qU1Q25lJ+j?PghGn4v>z-z7WoUHrtvMoVeX$@Q=H{
z+bTgZcbQY#KBPt+;2q>7*Qh!{`RhJ%B=<<?Q7pIYjC99woHGcbMlGt}<e_*Wh$zGh
zkVS>_p&$mdx!B=-l(Y8@pFrN~wsM(uATyT8&rKSX1kb(ndHMGL*AGsgY04ehoC^!S
z*{(l(TD7PitNQIz4A4PKcTU$y2R^6IoWVNqwmEKQ6uw$8umQeECMGPOvDAIV{pNB;
z-T9YGE%d!d`|MnBSp!C2rcU<-OOf9ftb`@COAl3tT5!$$>x~c3_S!oqT{$izx_-(H
z>oWu1uXorzxQwo9nIBbBFTNYGOKZhocilMM9(y6Ovfeu3;}?R8png@6bVG_|Jy(42
zPT7r3Ag*ZYeeMV<!y)LGkFTEuPsV{khdT8u7&YJnSs!>AgAA>LyJ+Z|vcnT++X)5d
z<P1b_-$Rj$+w#zUp~CT*W&O|@C>5Pu{?@JyL<MU-)Lo4uwsxTZ<L?G5Spkm2x_!o1
zb7$j#XF$DNp!n;W4FgA0_rUhVCOAx>3)9@YonD9?oF@z~47*PA!UyaS$VlOVisMAF
z9to>2+dIWWUm@&9g<8b=$4Y#Ik=X`O>cd}U6K1ZO0=EB+pdFc%!6ya0_2u?Ow98O>
z8;whnlRXH0aOXW{SL0gKXUtv*Ak9ecyXcN8x9#E%IH(g{{VPD0qNv$TVjXbh*uIt%
z+l*Agn)eAsV6096Fy=?W<`OIs-he=Se7A;=1ty2O7oaAP*P2wafr}1>Y~~({3ui4M
zbh8U)wUr_??!wqft#s{Vjy+amEXe?Z9|csv(_S?i1s<5_&1;0P;7wU#Y1J!ib4b&r
zdpz(lbKs_~X_<;fNZ;EaM`s(_xpLQqrMCHFI1ZFoKdshs`BIat>aVYwre|l&`c#Ee
z<+lMFATX9QsrC&C62ty2&y@~wl0UZ3n0!(odTha%{dTcHj;6cHo%&rHul5|uPk}B#
zU5y|r8OnTIZl=gw8eo8yiKu5R_1DQJCLK}WCK=#v{*qGbhIkc@v|>?CoHmF>%A%$0
z1-6??UE>KryrR_J)FzQLnf?=X(dcBM2fkCiYDv=X(sa4Pg0;S(l=9_5?6+5b+wfsr
zFp~sSmGpX{3E5Y*r%gsUMqH+In%GKj=T}s5Kxen&eTz%%hm7;GBHA&~t&0V{3$X+B
zs=%p<mcxa9^m?~v4>UE9?__*LgN@7Bi)1;Tf>fJi{a1&IKHq(X^G6|FKBmzf68{VK
z;2JYs;WmNpSzLNo&k=&Ie}Z01?JfpfK(LdJLJ}URDALFvowFEuU}Zdxb0*}>oB)1E
z1flx3fLjt654ri7S2Hn8_`P|#nvdkGX{xpq#6;uE_LH3Z&$b2@wNw@;v1l2t8qO(N
znbFrmar(m`0`*Md^+Xl(K=_m>q(U_q@E(gOM*vhLx`v!tgJpm*;7ZO=!R`r@JllE$
z*8%Oge2mv|HQ%OdZxS<y&Q{>i$BBVHqYh~`y)4nb`;*1o6NRn^3udR43smNJllfP@
z%cT*4+P){HhYFpNAGDeyyvDy)<PG@8!7A*Q!Y)rb|1feze3itOIlcGSdGbo)7uu;m
zp0H(F*U1}I#{kf&X2XimCN%;2e)kVHngPn`$KBfI5pd>twAK^m0V@0W1ln{|^k8QC
zq}6)XFrrae^T%b`U=u+^U=~#xBjRcrS*=B|Lhk(uyvH2BtJETFY;k#_;h-N2;TGIW
z1~m#_Tr791>Q#K>GhsiStZ+kq!c+FOyYiumm44ycUB75u3%=zc2SauGgDKE^(_x(u
zm`GPOEMr7NhZv#srab^Us>9T45wGEzBTg8rzq_9h5Jy2DH}|`NhIPP(U^5Y_E=w_{
z5yio^IE2t~%uy2@<|GY<5|O31zs${mTYAS+)ree`I#r-kA$V;WkU{@sydbHffD+rq
zy-_2-UI(yu0bMy+9*k8>ssW)i;FHh2fZH0FOfEFy>GXZ=nI-`DFMM6@Bl!`4py4l?
z{WAIXpJ=V)uSMf~=`UQ9owJuz^!vv1Ak~V1BZ%o#)0LbRQQX$=5C3fD=4Rq#4!VHD
zh!4+@%(@9yd*}F<FY43T7Y+_9A9<OrwQBvY=@?jlDWNozX{lKz(zEG0oAa)2=bUEV
zPBZ9|y{v!gy4v*&PH{lMUa@v)s)k36jND#iTstbtJ_*|VG!yS|5;MrJk+1dndo;v`
zqGxZ;W_)(5FX>m7`6k+0bCVK{@k!6N?a@D8yDYk*Wkm$oPOhemh5`VVQ`q+?X^Ld3
zi$@uQuuZMr$?#u1Z7L?|TN=nrA)4d@O1fn*ionU@7;Mrj9@*J8r7!L$3?ZAeAfLE@
z_Q9}4*%v(7jxm|or{o2PqjK<|HRlt~+mal)kvyej@8BZsXW=`1>NIWgvzPqNGOY~?
z?9j~AUQk&jOW+%TK2|D=uLyB=1kr>`C13xR29QcSdsRo|5R6XPp$w6+uJ|AzzHh|f
zdSFZ0LHeP7Gu#Et(5|0cqvn_IchCG&h7}X^Uuy~1;}D4rkV|l-884pfQ>pUY%m&PX
z;zYNqWS}dQ?&3g{nNz*2eQ0LlwB6|p8I$Q#sLT2W$QB_-Ay#LmblS?wI`vP5frshR
z%1kaW>vG~%eh@GQSf<7FRi~p*rZ#07Y5q1in=nrme-;x40+b{024h+-rhlh5$UQdi
zv-O7dC5KtCj3OU2@w_}4gza)*Ck2muneRj$u?ZJ1Z#_CxW9EI$Dh5HzpYiog+UWy+
zP$t^_c0<W)#~1CN=GTCc>}zhJ`o1jdsy+QeIwZ~4Vg{gXIt8NwyDv-n0$<Z2?_axD
z!URdVd&=2LU3j3>GBJ^go_omAk$d45WHerJ09dSnVQu*sJ6GRx?f9_mw|PZOsYEXa
z_0*e9IE4x6{_VCyXCfV~^h~o&9KdrkrE1xyZOHVAoq4uNfH!!Kk*?_CDrvKJxAx9!
z(tAw<{6;tnp0G|{x~)9_qV6$ZI5$K6medL`U+7tXn=2A`oyH3gowArn6?N@LpvF~)
z0Z(6Dnzu&DotR0y`C%X6F+?ykgIn&qM_2T4JK#xYc}P6^`QaxIGa*z66+pEtp_O))
z7yPa6D%$fN9LG=LWy^bJvBiEx&xS<O(0;8$5tDG!wX56Kh;N|s<B(_DGQSe|r^koR
zp>;U016VngTT0K&Q=btC7k}-OgG|U4q=_iXhqt?~lIp24O%N!&gS8&jhq*HAL)|sb
zFLr*)RycvQrQN9=5*bF7WlmNJN?eRa`H}@yLgMXqh%J5QM_*IHE?gGXM%%8uTgnEM
z?s*&>29or?FW$AyX-SF2BW+8K{#Y$;y0XJkOpb9#kI)yJ`5v1!bK}^7=K+8%zzcUq
zUApKzsuZ4sDpgfka*@dz6b-cxd%cd<+~K_ZU7yp3+)B3Ua~WSBXun|qFc0Bf^0R49
zUX_a_&Xj{dbcb|kp`n?ED$!zkgS}92si9FQk^woQ2dYT!N=XJNQtn2tPty#8+vYUU
zesOmLVo_To*c&>?BVKbZXR&9BJbmN8d0@+B&yOOz)ScdcRPTmTp_U2QB((!OJF1<a
zhWb@Vpp~*;l;IWXBk`-Ht^I4pvPL-y_D$BOkQJOvL_UZI8Vam;r9}y;#=xk>iU=fL
z`${OHop9sQpEtSY-Lzk2ZUf7mHZ-M?7)!qz?k~&Ec%)16L(g7)iUfQ@eJ^m9)>l5e
z^k1!y*PP9tH)|fHP84V_L@*PWQ=v#TqIN;-p)G+=SB-RAh9O<f_6KIe6|bo?vt%Xz
zq4|#5RG&8l+0Wd6Njur1)^vK_Ft5j@9i@3X<G#-4zbQTX9r@pWO@e#LGS7TaJL%{r
z({jko*ty&Lf?ZluzP;%47mU3kh|&^vG3G=TLGpHxRFs40;6-tw7f-yt`XJ0#3+Vse
z&RZT)qUctr0muf5TsN7e`W~;;dT)6Mo`QnIWxQO|HV3O~#NOxhS3auuMd<d}OkA({
zm0`oDptB*VC3i!(@_|PmA%KrXSQa{)Jk*iPZ4=J;Fi?S{jDM_k?c!%GfF~`)%B=PM
zj0Y(hv$$nVdw!;zQE!tEu$m`DJ}lPfMNEIs-S@l~?1<3qdZ5UztGJXScbZE>^b!p9
z%U_fpj}<8E2l@xSRzM4=bJtZY<(s3xwLnK>AkVtbIx*nkOtw;^1j2k=?_K{$IFodb
zaMKzR?xh97KAceE$1XMI6*_gii%K<840*s^Sy+$ROxLb`?;H=`5F{ORK`c>aI+jtw
zSbzM3Gs=$KS%&;ZvjHfk`u8R2JmbLBk2AkeZjfqMzHGBl7F3)05!)N8g3rU*fSX47
zf-@g1zsLR<RgGz3ms!NVA2(*;2l}h<zh=lSP}>Z*mbFj=f{fA7T0|O@GaD-YNEnkt
zQZ4vMD~o2|m+4^R8l=p>As{EQqVILq`=qC8hj8)C6WoD!HNUA3trKDzY=5AA3~RXw
z_xe6r4=b1Bp|U$TTj1Iz&6V7GLxv7@r#|wXtNiA9at4Ia=^>jpE_{i_?<#DBaKoAd
zbu6!>#b%zJH5d{cx&%8Y`lVKL^g(*Gy#DH!rjCfrhnc0@-9-K3#4=)n)>3?CJ;EJF
z0%Xd*lafv7&RA@UFd>lcD{G|f)Lr@upu42EsTAE*;xB^l3LOh&t*1u5*$PX2$Q`yn
z)KB;@Uu^!wA+~yxf<I!R%q>Nyp?gB5@a@dTVD8Z7L=(B5-IOd+vf9az59u8$7h5fA
zVOiYVYHYt+2Cd2vJF}Yd3D`hht=}B~-980$Ws{GG+ELgKYMZ)SdNrHY)PKK^eQ<hK
zY`jJI7e_16>-38Q+|{4J5B-N2Ub>WG8Pw!+W<MnKh7_m%Vz0d7>z~(wAH7rM0=F9%
zKlqd{*|-JCt`xd<2lb#pPzdx?D6XNw$Ah75-hotrX&mKY>5GG#NKXmi=s&w4GQ5r*
zTYz8Op3rNuY*cULKY;HAfDUkd@sH$!Yej=+G+~trp$DkVt*P&J;VSJ~EbI4CKwAs-
zU&nu~^lt0Q>rC;-f80L51EJ$Qb=6<6;5?ey?UW)1X0fkIYX7bg`3s#yg(QK{RP;^#
z816Ss@DJ;OAtPu2prK=}Jg%ytG2NRhPBjNwf#deKcoaJNto|&V9!z5yh$vPd1}hWi
zH=yWw=vRyCw0w^K8X=C%s1xmnNJWF6GH(8~?I5I|e8G30$<(KzvPMpWzz8nLil%eS
zC7iC@2T`_p(ZcgJ=Eg;EnESAlQ2&Zg!Fmx&RYNaVB@#={F7i{z;_L1BW+(Fl5Bo|F
z{SiE*^G}|HCIYHAxx53I^+bQn>@ajLR=4+xRd++TDHeUDdq`^M1vh0&y}9x&42Xce
zD>aIZ%Y5${0B27DPilz_-V54xT(#Rg1R1+z{RLLN?_e(CT){+$4KazxYIW=N&cLS1
z0F)IzxsSPVBt}!Mb-yN@94ZFg>rF?-*NP_=i?UFPZ)VOBCcnN}D0O%4rZWEe!<rq$
zyMOtY?(E<CDtSgAW4>Ym^r%+Qr;RKxQ)vZ+h?@u)mC87?HN@Jg)v$`Aq<-5hKL)kc
z8>+;(7`qbjfh4=Y4oeW}4#{y>?!?X)y(_tFp>ntm%ALYfbfbvzJ{)F%4;ppyfydM@
zWvf4oZxi;Zn6aOK-bzIT@n}nNt<cnMOQ({@7n?vO2NR^A-9Qzthoe*8B~;JxAG|Lm
z{qgO>&r}HhbM(_CT(cu)W{-&1({5G4Ds^+RxWFzbDsm@*A;oHnlrKZBE4TEF1<3uY
z(Kz0H;DY=zpx7YQ^?*vM`#B$Z%7vjV4+>OvY~D4auN^Y8L)iXf@<YUQC#v4PM(+>W
zxT?hQ=bOOxn`Z#Dd!d+arv?7nU!R<Kaq=!evA}0ZOcuH9bkgd~9l`Jam-w~7Ns9vd
zP^_bT%daqEU6bkLycIP46L@L1XjbK?_Ff6d-?>ma)SqXM4?Dv-Vdsv`RULYfeT*Cn
zHkunr6yk+pn!agtDsXsokU8|?+gp<HD#11-=!`OLra`$0%f5xdaNpb%IIyn(|Il1S
zrdUdc`P0s(U#5plLU#~vxM0nsqr*HeV97`IOU&o;etjc<fiavtuQTtC#t~(HhLI-`
z9uT*TP#gm0UdE5;WxF(QZR(H{1B&p$9qZ!Bsy=sS-8V7{cH-9c(<?1^4<8mtLy9u)
zI`zu|ThAgh$bN)fhgKb{?xtmZmPqpT_v=eP{1di;fa#VFe!@s;s9*-He%#vNk`cWU
z$+H(hxjT$g44|Q}0#g4ul`=Q09mcr+{TO0q7ETBo8N5F_lcurmZtRRL_$hF(bP2lt
zeM2G%GI+}B^#3!*0n}QW-qv}qfl|iSeDUSd=1I<`pGe1K`Fk867X%1`j6XIP*g5CP
zS?xFwS9|TC#_`wJH=8Zk(zLmY>y4|({yH6CdEhAqsETb7;`~G@?`Y$?B)26URmE9o
z(5!m;Vqwm<g5h0te)CIHAUu%aRt4PZVK`L(QQqlV(?!;Ig4eFsjc;lGw_XKa!2I`T
z;lDM|MipqGdbKGM-b5HNo-1WBes^&UoJ$5V4GIO)avS~adkUD-)YKolnnWY617gKi
z)r2)OG7w!el!~gG4U@t`Yc*5uNkKdhT5iY0=-a>1kSz;B>%W~jaalB=EDvqE1LtHw
zu+JhDT7R^A*#~l$@6Lu~c;5IRV`NSIovZXLww)*@DyDOchT85*9dC5Qs#MfAh47)L
zC+j<D{qL21v0)0&MJEf4N+V|TUkXzDuaZvo^*6T{&k`J+<v-Tqsy!NZn-u91oSj0Q
zQCp|-GzTK;_BOQlyjkNW6jJNHZR7s2reqid%&z$TItg#m6|3Xo0ilf2Rae;OZ!YR|
z*}6{y;T7m_IGH&Z&FW*;0(o2=?5*bW5-1}7niO5Toq?kzC%bLv3WbxW--$F2ls;o4
z0ma5T#k9W^Kw?t8(6|VD5@UU!vDjUi{fRg|u&X!-OMD2Dx7hC%lo1i^8m#+pm(F2O
z)DeqEX*x;EPeV@KDOZb=qi8YWstm>^_?Axopu}KWiuv?)$d>r}z9$^2Nlvb6ELL^P
z07Ikcq!?IF%tI9hd=Mq={p~XdQ#S9@bo*U70dnk(vmi!EYr;8oR#R4<qN}<rMG6uz
zaAv$Ph+7{?Z%5CNGVO32o<^55HL$8O|AX@vxs~X7j2!$2sG#z)&AEzF45{9@1Ns!=
zH7Dwt%1GxP;$Op4FjUrZ8O$ISQ3<`s?oK<mcl+i(FHUyFq(;aVjJk$v#cgzp%?t`5
zI~pryA<H^@$0^C7G`^9UGK($etl6Y&Rxwap4}?zrN|+>3MqKr+wz9g5ct-`>ef{^Z
z+V}jmT;}2u%|!<LB@%7ej{iL0c*%#P-I21yp7UA)XKvU&n(#6;`RD`W2&krW*3y1!
zYrR7ouf5z-v1q@*XV10YsMN+Enk(1~QRj-T6?B99t$M)#aEYNmb2XsU-naf!#e{fU
zP%>8MemEl34T5Gs-neEARy{l*@hRp0F#aHkOda#s+EIBZXX>I3{JsFniluhw8JT{?
zYAS)x_Y<A(s-~%RgA%))q&ngI*FK4SzZ%sB`yM_qy^}uPSVmwHU@;lMMw8+&X<hGb
zII*iSJ^Hds0la0xt)9}e(HQbT(-OlmjC{xNmYs8&n)yPoa{NJ1C=C3{=^EXN*wvD&
zL=|<epo;HG>G{q9#396u0j6OwAN{Vuev_G5xs|iDh#cmy4Ysg_h@79&@_=PPHJrNm
zJ`drsd`QJ|?O*7+JOGIHLCCc%_-V>7a;=+0R*1)N$Vi9$<EOA9LL#!<PEb_5TMvM8
znb?PD4A(1)a?i@&7piOUzNSicY-nWkVmJOL6Tg=ul(%rzEA&0i_xIz|OJpa*Cj75=
zDIOR$!auY-?6MTZ^RlN_z(!w&iLO{`Itl$u25(gDQ6$Duna8^)A)ST8TL`;-5mkm{
zu}rp8clS;K(0SFqR8)>H#K74sm9aA(7)>p7AC%fICyO3|QLz<<H`}4Y2*E^ze(v9^
zmy9)d6?i%zR-VYa|7Vcu2owxC0$e0QL%h=C{Xlqyr47n{!<M1c^h%6mGYCbJC2Di>
z*rFKD3&m8pyPS_$N(k~S-r@B&BlEHKkv5?mRly{vyrYX)%U==oKK60e&7jCrvf#ai
z*dXSbHACU=TUEJ0_3Q&($vHIJlM#ni6L-J;F<tx^4Sv%7v?tjMZR+=aYQ}U=hT8eU
zdB;ZM#PZG@Rpy-Ta*#k4j+%{1HjX>3<StmO48hvM0~k`8Z=&Hq(T#fzm8j~2U$2I{
zM08ox3j*_GB+Gkph*%~q<U7Kr;yeKO#>?+%ii?ZD8!N}m;P3kP8X2SMTlbfebOG?|
zp}WbJEFc{Eu5)XD=I?f@ik!VKd&P^7e+)GG<9`+Dm5&HndAKdac%QuNVCY5M^8Fne
z-zKvs_BMj51*B<(d)e!%7~UIsO<sf^@#;-s6iW*8dSwNjB|OL8e(BU)r%S}7SN3Q4
ze?Q)cG0ZjE`PG(3bp0W3RHGXI=<iET804ID2U}YK6Mq&QP5gWs-EN7%!*lz811}U~
zd#qMg<j)+3if-M9iOwDXi@30ivgB0m0nF{MTu+seOV@NVTor<%QPlv|$j6lz51R;b
z0l8ZHs(%*Ea&BPGF=CA4-{40@Fyq;_{_`O&;=0s5Unox+3^K_#u4M4DEk6`bfd0~F
zd-r<D-o2s;8{6~#H2wfY=D3;`*XT{fGDv4v4Rl&FIiP5@{i(@!M?;!iveu7TWi~Er
znepx8BVKSD8`z?ykG=f<{O1r@i%lwG`wzyPSZkYgEVZWiZZn(Y1xVurfQg$`+`7*n
z?x~2O@iG$vb`CCHt{3U6O5cy2kglk}isjAH9!$g=972Dxi6=Uo9H={EGH)^xnVN{>
zSw<CQ>@%lvhjn7#Fvm~Gl128j;vWoQ%><~ViMWFK#g2+R)^=h7WXhIr8&T-I)b`9;
zcEY^!F|YBzCTF}(gr;0Xgf85~Do|hzA7yVJd^PiFKT&_rPhD?Et-qY^fTej)M2MD&
zpp{?%o|uOxd~x1BF^FnJ(_~T1vZzUqnuP<k&`OLFLEdqf@)CE*P*$q!FbC*}Xn|=Q
zTeFi^sgBrAw^MKTyFL9@p-m5m&UsB*^vIux9%zdZgPa_LBc@L+Nfn}U<b=%0@l<ix
z_<SNOmtJ^q3f`~V%RP!N=8AVQJld%=+j1j+%Ra{UPmuUJ)>N$}mg;WqMhc~@41_<t
zLKVT4^c+0&e(Cna>WZ-0FIm{<zhFlj=A~)6pPyq<^a#)OIf|^a(Ck`phg@UT<Ck%^
zS_B!ySe1uJY6o{wSFBjb+e%spkOFKM$<Qp@7znF3jQQHLrA^hIE}2=7#D%tw+)Av;
zJjmU0$mQ}&sKeXQ#pbh(<O_^$mQ^1u)|Bz^-EmQTl1moi|0p{5N2b3&j_+<}V`FCS
zbHCrp{no~YTx#xe%cZpB7KS2?p<SA8y6WPRLMqB#F?ZFcnv&!a(Pb>5a*5*W`zO4A
zIq!2`ujk|OTu1dm@PHYEcg>6{`EUI5v#sDbwBBlH^B`~|)1ZGl#y_$Y(k<(s$7vbU
zl<m30r$j@Qi0o*kz8|wa-+Tn!|N1vxRabe@e}N_0%a)i4v-PdGBlcRn{Xn{<Z$m6t
zPPq%hclmd*b5sdPhQF3p`%US*xU}c*Cj&%-@`M%79y~09U>+7%hhHSUOoTXJVj#%J
zz*ZdBTO)4%gF-86|0^JLd7lYK%v?W6HtUSu5B6eW>nSZ}{*?_8S#WdyK5lQv1Nk&f
zv0F;E!hU#B8kV_k^k9DnHMM+Z-59x^P1o{K9Sn$0@-2F{6TK3~T?6*%b#rEqH0VvT
z*Jv!1w~;1J^r3``dRBQK`y3SBdH<&e@I8CPZz%gFmvroYt75$Zb&2+3r_WA>Owdr0
zSkx?m04Kd_JOh%R9aN=K4^&Q}nb}Ik{()2fEY$-fm|;<!{(%%_XQ7sapqj6Lca`}v
z@9EPXwL`R*=4xP|`bt-}C+$6c4rV)`K*s)P49sh&UVRC(cpp&X4?R```%KWejQT+0
z5;Q-&2~CS6#S(P!&aZI)O+*H&c-#gA46#REPgBn8B4gf1a6eu<kZwYkYylwc5eidX
zkm0wke_0-wH%_sHDjK^YiKqyy`e(94%ezv$gBK36H%ZmAC&i?ATsB1DLBOF`#@~eY
zMrb9uDMX1?hXYX0ax)yv{>X5&Y-=~_+=a1WWFfXpl-^xKMs*4v`>-SPfzI3yt2O`}
zs@58OQV`xy?@&8>6gXk@>T@VbBcM*A&DMvny?s?Z=R63Ru2Cr0SX#1-d3P>a?6|Y;
z_epxd1a5R)j9_5Xl_t-wzlG@ugYWNV90%U<xAU{2B4<0L_9u$lZOpdrvMHe^eC!y~
zIIW)cx&@T$L1svpr+`k@M%U-ui%dImxAR>|JB_E&FTm!PG*tDCYuJTw%805&Ba7IV
z31&7Lcsjb>J0tm#ydn}SO385;#@69ggqwd#b2Q++N}c-9B>*p~({>+(r)i3lz?Pe3
zpK<()WH2JojFFLN-KB5o>I%l{*j%S&ZN!?Xh{m4MD3J(?BEIGj`epir6rD}_oG>V{
zh=ysfw?3sis2eVIvL0MF0e2B88EM}0E{P}V{_(?&Efs#0ISEsoni9HiML>?@O3kKo
z4dH3nQ?Dc3;IK}d*5OWAwYy))P)1<EbD3(|eIYaQSZkBJ_ykqT2O^2WL5sg3C5VXE
ze#OkGXWs9@{g=v;Ji<TS-mG14O}$qu1Pz-vBTe^(!akY~ZwD4*06F(fS{bEmhV1HC
zs;ocQyZU|SmTkhI(g~>d?ArOQ!E^@rOD2Q^wAaYa$qhJcAZc%!is-;;BF-(TizXzn
zjn0ZB(3z9#PsgApVl8h>rH^PKcv$rGUen<Wq|S&Inz2qZGzkeA->oVZM-m~9E2l_M
zYToVC8tucyE)Ew1u+eno6rfyeC#mbQ+pGz^aZLQES_)lB)e55wEt<|ZY?HJY4MDPi
z&lQvCdu%z4MhJscqdh0VNr`WzI1E|kEf!3w<~hX3G8UK}EG~hF2V?v776+0q$D%Jg
zni9)`0=9&cqvKgi{!$sp%|4e+)7dZ3o^;7`<VpJ=`qB6{#Z5D{cj6ORu{1=<UWhT=
zBBtLx@xIx!vWD;Av?^n@K95ZCMHcw@>+s`}Gb1}a`oPDsmWO>HTg)$@)J*29AeOIB
zyjEzbiG1dN2O6g~KwayH=`N9C8_%*I9?!87TOG-bYe#t5FE7A7uC8t}yG&WjzjPss
zgv<0mqbPz%k(GQosma~g!dQe^_Jk&_c^4gBq0bf!=9(_P;pjD2mOUNVJfyme0(fe<
z+PNW9U?nlV9@kh{I5G+_p>n=I(dFq4dZ&x_o9U?*;b;{=<_c!0nId<&-9|7yI3x+E
z<5<?<ZD5Le8B3!fv)kUNLC+~m&fR}gw|6?_0?o<EJcGhY8^CSUb-S7}*J=4$T(kE#
z&^``P5Kpv$lWz{lb|P4?YKlRN{_B55v}<=uuxam>)SQ|Wv`hHS0qB#Zo{84?UWo69
zw~U15uMjZBmFUE`Tp!vLPIfHmsz>Zrz+_&6P5FM-=!5hN$Ahpb5{F-ReHJW04ZC;9
zKK@Kr6F)y)z_K2SwBV6+Zr0k45&s5qy(GXc`t1oSOH1sz!5oO;;akQB9;x}CHAADL
zJ@%-t&JO70nCg80JF}gFgk`27cPz}T`qw(-Oi8_De`|xL{JN)LN|AGo+pAC~5!=N!
zP0HKB+J1L^k~y$#Fg(&nc(spqK?i>91MyW1t1ouO`|M+Jh+#;XCUUnMUu<H#@Z?HP
zqEN3h-}N6c6W+S8Cwl~(>TB^F{)M{--r{0Jtdf4{l7h1ZSb>c4d%fR2z?uRzou1Dz
z6M@Z!EGLvf62!`1GYn=e?5KvrO?25Q<|?|ERO%1!4LcDiJ6|!0YhBoVc}%WDYM@zS
z_Ovp^=4C}wlNHBbGcQE5`5(S}^Z9kcc|cDRP<4%khgh}Ub#PkbV~U!5R+0SP9GQhQ
zxXxFBxWbC;3c}2cTCeY0Q>9vxfx6k|8AskZs^iPW(+<6CUO$RZxUC+y5s^FHe+SMa
zA|?L_5<~92N{5?6`|v!7iY8;sw}|B6flx2|?ZVIRbC%>*L}9$Y1*MUwjrlk{1ga_J
zVqW)>Fhlt11Y>x_Kb}9K2^h|cypvHWUsmE>`fLYmk|yzb^kP>eCv62S-X$In{rlkg
z1dEF2I3q$iLPpxyS5`o%GYYv3DcJVwX}W*{Dv#}ZBfj}VoI|o&gu94w!%Ra{;}gHv
zyhqO?u`PQ#=GPjIj@k;J&T{?bD00-6D?1!v#2%!u*!7xinP$)KJfgQ@C|tR1Q*%bB
zrD7gckXOBfy~r;6q_?N-L7ToRZnHXHf%z5gEIZ_c$htR8{gmsBEd6`--T=^bj8;(y
zRF1LvXA+rNDq+nrv~|Hr2(S(Kye>5ZyRt+N`eW&*D<DW`f8_LR1$hh-Z3K<n98e}2
zMjhGoW(w>#YGsQIunD@i|47s=VrnnI!&El#iHpt3&^CpT&Trz@bG`+ejZR>37sCrZ
z%-N1bg%Q}FhCd1-B-q7NxZ;88yxI5Ov<Dal!1xD=e@j@Tz+(=_uwiB`S)`<Bmxu4%
zvSg+6oqYTBcpN>q5Iu$hOmQv2H1~(#FHV~A`>*mKB(4@zI+pLr5byOpJ%T9qqmI_H
zeP?0dAAN^R`-nQiR_FgFUNfeJ*37NPvl%k8nd|80QpkZIr4$dgUNe!Q9>m`WsRn?>
zVkhMp4D_-R;CFcl`dnvSb7-Nmj>T%;2<JS&{zl%pQ9<6Yk9$F{Z_k)<|H?=Gp<r~l
z8y5s9o~IUlcOoe!IXCT%6Nz9!?>0K>%yNbZ{sBJ{6g{4%`rskFFt<>yJz2Bs_dz<D
zmmIjqt1e7Wc7#U3GVbB-=6eu}6-PI?DshUM!k_PjED}y_Rl|HRYR8gDUf49D5R002
zF-L@(k4T@=4z9Z5a|w~OAQ8m3{iuae8?s&<cHQaJ?u2i6a_qaA0`Oubn+o}o8C?<J
z=O-l#MY7&GI+gX2G=Yevin5W4cG(U3lt(8gJ7qTWeq`TG{yE0PP3iZ}`W7TJi0<|L
zTrtZTB)cLgwDN5Enlq?l&H4L&3q<qpUIi!QW~pARL`sgO-R$oiCtq)et*er;`lj26
zig$NRnqnK^H3=USB**dHT#vi#;;ks*=?qo3B}pFA&lr`mXCK)UQjwgLjt9;`vF(d<
zzjg?oLpP9Gx@)ZP(-68M16OtiI?i-~zr+eJ&F3nHn7vyk^dxzN$mJVh25C038c0A-
zSZXBRg5JGFp#rXCpG{0CFVXi!h2#LcfJ^EMrO&eiPfX``QRW|bmVWQJ#aIjP(t+|G
zv5Dmy{JR-4&-Xy&*tsRcR}-u}U69cj6cnt+X`Ap3mj#px|8=d%j<d=#|IkAlMpx2o
z0iaZHirU;34C*0g5zAiSh!wzGnE5gb)zfS4*h%xuCK9`;t80%X5PASB0EPHg2|$(D
zo?WM%kSJl1)7BPIAXacm?)sq61Af|ANxtgcR9A<hdy;NPtw_}--Br#;N5B1IQh=8v
z&y{Tc2-)TH-MN43!*aYh?KVPAV~-*)aB01e_{gLyVs;Vr*%9q4Bps#R($EK7+_d`Q
zT~u;@#M^fe6rxGkr<+|dEC%l<aE_vyBt64QkcC;2NN9}hoV>zKx%~~;Y{f$pRlev^
z^P<iTFUi)CVLo1`R@OL^n`0o5RSNl_GuBC$c+S?o)#paJRS7p8JVbJ-wGf_6xc6o<
z_7MOtrFo9EcB^TK?KRFj@wu3rD~)|j@AgP1rFI@1kETokY5o$uTl6Uj`Z#mbAa(Mg
zpBKQqQ0DiL$B^qtPwkfTUQr0!!2bdR)%aOvi2o7p227-41Uw?=zX+bfO)V8-h-rCE
zfY)$CY&4i_stnmW_N;8}cg~5a>-3zGX<iT+;V|Rv!$p6}Z4a51SuUTp(WR?=rdPQw
zPYD$-uUu+&p>c_Q((qC8al>nnBW|Z&G@AzbpGnvd{`cvFyK}?PN4~^Uw6v}m@4ep1
zB7()mQuj2nuYbDZW0s{1bzXe{Ezh{4n~k|%C=Ru+ysWtQW-$M$6dJFQtKOY(Hn;tU
z+a<D;a3A2w)N4QCF;D#|_HXjov>^xBjt>fjPlG9w(6rr!@VD?wZzTze=%PwHKb#Gk
z7V8~$6jU$eU7y&X%$A%>y~o+RO?bC%1eJweIDA(zWd6G`wIuuY*BOk@t99{9MA*IA
z>91IG|62RLm(i~9wCvW}jT_SwMiPw!oxEG0v~^V+m60^X5T5Ugm39ef=rjB#F}fGV
z*gyJvwp(ScwkE94KQye-Ve|8vaF;f>AZcrp)Oy=`xnfE*b61;JkhNWu*8-Eh7$Ftf
zZK-i4V4b~qk1gnh2Tk#t_l`-tWO)F+ik~z2!Mf90gEYEoww4fjP(3Sj0J5aTaq@Gh
zzd<1}-fs)GIPuKTaZod3IY@W#o^z4Ww=<OU)nmRYvs(d3an4rDmbL$2rA2e07CIg#
z{UKkc5ro`&L$?qq6Js2@ubNw=0;e<;1->6cls@XX+r^a14iEQFr2(HnB_>J@;fWsp
zi7Xo`@xO1U|B9qblMZ1^H1Ut~+<cDu5|dME*BU6U2Wrp$=Q=>8e_l>aZ|^fn8hdd7
zj6R@-<b{7{??YTc_qIH)FSvBAFy=hSWP8RgZ|j#DRkgiHF<dI7mKDvUA*o;#HfG<9
z;%n9iu1`^y(3Kd^kT=1o{D1@`PDG??OgHcDuu={_4c=Zt%D#UiX?Q(@#+6AZqBY#$
zNU2RlaF48+uK2}$*j(vrk<FPdKE64PHD!CFTaUi)T0HwCyjoF(y=c^l4nU;u0_sNQ
zj-1t7wJ4TePUvW}3yr5=D}F>icN@W-VHaBZWMs$<4HLC1UeU}|b(Py^mX&Axa@O^r
zt+3cgFh$~elve6GIb}bigz#onpw=~#&4GEBF{noWy8Oo<x=?kDvw(ISlfh}YVUqBu
zW55BSKgCoadVZnY0JYab81{ftM%h33z{tluvfJT^a;~(N5~1`hU#vDqGH^+I6hvsm
z^3Z1_z$jOe&2zJXGzVR!`n1rLc?eVKQqtYlGao^T>kA&(KSBtbB8}{G`U_g~B3cat
zA>+_`5saBVoIoD8N_7rniY%d1XeA+g^0r=k`KJ<dG!%>w`d@gY{0y{1#U%n6rX&#y
zcZV{q;m-opV={ZaumW)J>BAsmU)m?{i+8`rNT?tAaUN{v;^`a2;p@i9Ht2g)ux5H1
zuX5yJC_?D7GZTRqBoA=?^E(~nkV<U-IY^)mf%@)&9-dwJP*nt)xy*??f7Wf0yDx4J
zg<5(f4#!pix1M{(edDnBuY2phoEjBwkmPBXL`}n;Ffv!cN#R@Z4o*zTP4U$IqWz$K
zOT$rQp~%PnFWC#}^MqpMt=2F5Qw07RL#g}CKH}*}Z2+}bf2{F~1;)-Ct?D?CZVl`F
z1{cp{IMed0PuzQU2f@r#3SJgy<hmrO1aTtZ15<cLLJ!DO?D2xF3tB8cg<LgHY%|zF
z-_tMN2SZMIOu9kjJPw=jGHElwQM5_uKt0!T1xA{@cC`7b-S$7EeS#q^e(4Q%r3XYu
ztklUR`g%H5|DS&<p(W(R-XYhr=MRrond%*%OB0U%@D(eemH#z%JDU#pR<dmafkP%n
zyi1Wn@h)~hX$;D`UP<y=etdQIl3(0oyaPOjyxq-0xYS(q{=f^tPwYLt9sH}2HR>)*
zBdk)?_m~o_9E=Q-bNko&<IH|TGC;|*g$;`9r?I4<GN3^<LPUnxJx7P;4AvppwvgUH
zP(NkeW`{70g;X1qvHR;q1-qoLoW5+x<ByytA!Q$m;cK&p9D__3!#B+N#D3s%nOpWN
zF!?e;Z|U2sFEnaJ;FB+jjLMDM%r#uo$bi(ThqCO%6Dm!9KZWJCE99Nljkm5#2Y{5&
zOhV#0Vk#QvBVggQOh?{5f_dt$q6SR?qjy~-ElTSA>K~w{#cm<ya4OS0>+iBkLl>wm
z35g;-jxAtR@N!K_d#|zrAy`TG;xXM+fWW^&1k@+l0Is+L5&`wm_mz?dhmX{Vr2+}@
zuZCb#W&Jo@XyyHk6hDvDjxENxm~nUiY@AeM4h=pEi>X9MI&)D0y%;B9+5?Qz2+HN2
zjMZ%Et*@<07`Wn!#c4D3ku}d1XO~J@<?nYH4}wmaE*t;?^y=$-`s#xI<anYlRp$?@
zZ%G)2{!BYNp`B|KD$)rBES+_XBl<v6Nj|BP0lHJz|E}o_@%@A;1~$@u@55O62PKym
zZ-hK_RxR7#Au+r8GRWX0M609#aDq}$9H#h5ob##21h^<?hO<-h%D{?Nl&pkL(La6y
zeTyH7>4mr|KN1uZ^bo0Fu(tsAIJIol7(1;0ep7e&^YG;<Cg*4u*2T{M$?+s3b<=+u
z$`DD(0}<Tb)(7l-DI=RyD4i0N;Mj2Fl&<uyRjJE~Z`aVXZgn63GuwJKJ3M>eKPGDm
zy_-^O<uo;zQ#_9BP?Fd#K(NwguX%*ZCaakTFRJZ*@VR@^y6H9buz{|wiY(#L^(Xr+
zMJmdn`}S0d&?*fh5muo$91p|ZhoVaDo%gv^8cEwwA{V8MnNm<D{VPh-zM<~+`7-NE
z)FOAR;qd7FnihC6R;{GsRDzxV;uhwo$NTnb$lbEJG+cd^mgVoJ$A9L=EEP4|nf<Q-
z7GNX@Q3gFo3puH4rM|-U*$2AzfZ17wDUMC)7Wt53)-4ryb|;~I_WkQH(~!y-gj9k{
z+M#7ai_&f6+TjT;YsIR5nbsclE<Y?f)&h51{PP{RH^wUJ)#xmE+oh;&Ing3K)w&IR
zoa9vfPNIN+piG;~ya(<tbE(u2p7+N@b$@CbD*xO0(X3LuR5J?xmeX~YK}zHv+chEs
zu#9p8w02%@7_yv1NVJP$!Zaqrz`<QRZ4;_s8J$_5Irc#<YgxzZAQ&NN7Y80<+A1el
zQO9*WYy<qLwAl8IDvXc+09{U0cFA{{6~A%yVutCck{SON&&dr}StWTb@35P;8$nv)
zPP2q_64LSfh?G!cHuXh0OiWMveK)_S{EDeia`DxktXpKY64i(#W#aZ>XonW-s*8~J
zYw0d|!Fwo8@-50ho;dYyk0gxA(Pz;4_RRgCiT2wxeJ(`ZQQ=+KVu7x01}34;vpfoT
z^x>rolBQ%i#Zs{*XnMNG!Bp|)BNn&cq=Jm1R@Lr7+7ASBVR3c(v^#I#!6RgoN_)B4
zWnlIP@VXCk<Av5=Vf`z|BQt_cTV5O<sEbEeAfzc`!hVd0kw88B=PQv`hSY~C+vc(7
zNL6dS34eKpL%`w^X1eAoZ)}$l7w*b@*ZBqDyEQG&y@J*gu|L9D;6X0uCiL_fIsKge
zlAoq6Cz1uAU5vryK86hO{y!C{%|{lZ`eULSk%1^Zcl*Oa_x!_T0@qtIr}F%{8mtP)
zI5#K3DyKH#^Y)GNbp3VcfycB*M42aHXz~cKx2Lu0>}(E;3CTS-ux|F~vfvx9xqJVH
z_K`+DQxOPzlJiPoZH~*-w90T7lkW7lFLp*VxP;dO1H)s!FPRsZ#3`QA2%9;?eC+rv
zn0Q|*5RbE~jUHuQF=&>a-%eJ@FnMi!Xa(R>nL?-h_s}n|WA>i8zW{h9js>337*NB{
zqza{VqrBRL``U%kMg0ivvuMyBP8hMy_&3)XtSjf|`z{&%&!N7%YK1>L8DOJIiGnl=
z+h0#SUEbGMrY}gE+F&b}xAv>Hmyald2AINqr#Y8q$Qt)VH@|{r!1B99@YU&&5pdcR
zm}EB3MH;*qjP@&Jwdt)<!MVT_FW?>x5V_yvy)&9sj-;BS?4+A;s1@76(sH<i#D?1W
z($#?I@Mb7h&%Wy(7HDjkCt*8#<ke3`3|1mzaZE8^1PRyEIwn*(_PI_?j4G7(6Jmmd
z;^$EhT|<RHuhbjbbM3I?A047`jISzSJusQh%fo*@aevDjY*4oKqpc3KgZSCUy*0ub
ztITvx4%05OOeWbc=_N%FXyP=9eG=%f4w5%CBOvrBR{h#RTiE@*kK5pv+O-rTThMw=
z=j@utByC_hIN;WbDLn%U%%CUpPJsR@V&}sP7>0vWq<!~)OV^u?Y=~@QwkHR01o6Xn
z1n|2gmkimxqr=5H^0@8IXL`TZP2#q)tg+Uq;{7>2-v30Zu8gb`AdCL7Gztu?+MKh8
zzu+9F3Ou<*c;YL-i67}fmTC&ZYai|n8EOC7rWN)Hmw!Kpt~h3?r6}Yyp(IGJT}-t>
z>i)k9D1am%i0y(>C*Vmg*WYhkmOWw_SfY)skw=A<00j{For%nhYP<;7THj2`P4cn<
zwMKs;w3by3nu<^Hh*?^N2W=y+jVbah8qR@So>)*uKtO=!BEJi&Xlwe2t9qQH<@n@)
zRDO;{Fz8e&uw}af7$UOyLFL~rz2^hFj9S^e`RVD_*0W!G2iNXJi1iAUSGz&~F!S(A
z*iQNr=+w$im#+bCXBq$P66jA!r)LLc8srYspq?_;UBmhjNv?ZTjI}dRo6HRieMw})
ze@;?|gACq0&`VaFx69~w2lFWq3u$SMluJ*5bS=B!krzbL^N|Egj8&@iJer)TA!TN%
z0oaYWl1F0&k1MsETp=3DUdhdeUVd@#<|HZ`+HxLoGKg2_ROSz{9}fW=#dzoYf~d6X
zvfhTDbQw<?MMj7{`S(^_ch^*f=tn90e^O*Wc#w1a=m_<a@Pc~7#Y{|-I_EGy7;6qn
zf31a!D?Wsd=b5*T4F}Xw%l{#=QrIQu#_&28c8l+jcPA1(T>G5e>~3L;isRDtD9J-9
z04psm*BAFstSFf#z*FOu-CQGplqKaymPvodb@5tl038&z(JCTQsC)DB(|6-8nVT_}
zjY8@_#Hl~pJr4f<IvJg65(@y*a5>*ebYq-_`BqR6Ng~AD`dj!ZH_ts$x-HuNR>5HB
zX}>9{c3o-3C6<!WcKx=7C1SImxzq_#W%nx(0XiDsJoVk<EZ_w5fld&k$B7`O0-+G}
zP-2GR9I0=ugtN|gX9+~WBz01)ObgJowBmIg?J(RWt!515J4}g<W(K`N0<Uo`+If8O
zFzr{l3Iy3<#3l6|<TsW-H-Ii>Ud)G{L^e35WQ>eEiI<KSgeW6nni*8h1vUg~y7pKX
z2mrA2ITLd+LM)e{L?Op<4Q({frmET2YKwo}6v<t>0X$K<<%n>&&G0}Jq0gf~BB;sf
z3;@u!n~0ac^4H5X_EQc!BC2VZcl<QFe*d+TSPwrP$Hyp;=<>I{eqMeSk|)OTSzctp
z1$^5heDmIEy2>e`am%H??kQZ2)UGzr=Xe%EIy!}T$DE6fmYWZ;kMe#ZWy>XqJF#P3
z38O%Pej+$qrsuQGT6)-1K56Rg@e=ov_hLwhwBTA5Tq@-`RFUxk4t|}bsz2%gG0E5J
zG)(JuTJH4$^go<cuF4gY-YeYST*zV86)qLD*#qfv&#tem$+gyT&fgtV$UEiDksEFN
z$Q9R&z-ih`UhD!>w&vY)rpvZAbLK!1D5b|eW*Hkl+ZlgUmC_|FH=ili$D6#CYVAe5
z#X<c4QL=();td!6%ogzYzsEkeeaSjzwKwLQlMK+_?GE?LDe<!WPac2fkB6cQf~Uo^
z_KSCQLTgZBI6^X&`2cCajl5A%0uE=bAyaP>ZO}yqxdx^r<&lyxQtJqd`VKj@yz6ua
zU}V8FxQY2wS$K1>{(Ro%``?b=uTjs!9gdzE#8@nNa?3doG5q&;pIA<6Z>nXOMvXQA
zB92fgxMbGX@iiiqJbO0}c{!s0&`t$&uoGTQ<@VmukBa5=>=ovsh;Gce@KX3V+M7y{
z>?dlz5bLuPf8m8+8$bOa{OEyL_GxMKTM`Rg)C~O<fi1Ol66fU4v%Xhq>}$?}VBvcB
z0NHf*Y{);cc5f@f!FBMcH-tyr(||FUB$hi82W41SN1Ag0y%!GQ*?ntsXU~>E?*6r^
zv~uJ5kAGz=*gU68iWC*EB9dPfB#8oh<T#OC_O|pNlkENa!OU~lC{x1MFLSVA&t;Jw
z6d~}Obr9)U!y#G8i9JTJC&*!oD0C~OZdwk6Rj#fxb~<mbbUr^X*YOd1WUb?_7j~lA
zP<EeBcL(K6lG_IW1Cl;If|is1uhNAvH1A@)VabG!l#fGmg<1R)BT~gv>cMSZmeZST
zRi5}s8@bZFw{>lH=NF6^;#`X?XlX{OD_G|zLM9rwU!-0?{x%FO9QqGOT~|l+29t0o
zJ~6cd;i@4{gRpiL)6GQ(ZW~bSu}2JVt978!e)=n_MN)8FXljl1ut-<TtV09ZhKX0a
zzTUdwbWR2O58LmA?wUqaS|A>fZzxR48-6Ur)@5R?x<oUA-W-%Fuhwv@@2vS<YwtNH
z8Cr>!wqv6z!Z2OjP4xV}60_tE;+4jp{_0N)tx}d9B?fK3y*l8v4ilxb5+DnQ+nQ6}
z%i$gM%5Q!U`1$b#cU3x0%0)S6k&BUI#lvl5>MBwD-@pGF$i7+N2tWyZj{Ght0rD*&
zD=eM;wsm8X`Mz?D_LfOm?xmi_NX?9NbEoLf3(Ctt&Pq;<+sVIU^28d%`x<pq^N0XK
zrKBu-GbgqZ4gSn?g11h6uO;ds^@cEspq}WXeE6=}fuSQ&A6|t^H7ZS?UOz&8O@qIH
z%5WdTRo{p`7C!9d-jZBPs>!A1%t-NEpG=kaSC0xE&-N|3FG12Zj&M(fP;+t{htwe_
z_CU`_V2Vh>C$~;Mi~}Pza<A;6!KJ=~p*4#`Udq53S8P+bYXEYUwA`UTeg-dmHQTP!
z2%zlXIQAzHoogzM%wvx)&ca-H1rkD+eMQ@;y_qd%CdRChTqcP{_DjrzS)`a4u@&db
za2y5L=cY?9uiWC06j>m9bUL(EgdYef11i6hR;V<E95v)Bz_4a^36`Od%VjjKaiDYQ
zs!xHoL#x!iAOL~}J_q&&i8Y@Xxf5ghDOTOp08r9d*4hROMhf^Ftq)!XDOom_sBw5*
zWYAJjVKod(?;9;Czznek6?}SUcstL{)5J5uOlRUNE0^qs-La3bb3_N#@A}O(OgZ+^
z0Jd&QM%NQZlHGlZ9Tk}Kd~;z29FT=OnpeJ%gf_TZlMnvuLKgPau9Pekaq^KAsViiL
zs&|d8$<U2T9Y82=9*bDkqeIs2UXh6fwpwUf>Bn`e%i>!xT0teufy4eLPLhMeYWoa8
z(c){cp8T&0+%WR-qm`CLu5#4xxAaE=w|wCzUNve6_5#y|hiZzj*!+CpgKHz|avtwk
zj}Aa97!S&KwLW<<<4V^}IFft6LL8ls0krP<1OF%;H`Hhf%PF61D1h}-G^2BUqq(HF
zB~1afEN5Xnhw(W+>#z1WnB@y%tYZUo<fAkDK$j4@&LFg*A-WKjlm-jD0A&=%N{J~6
zn++9MUqAAg%;b4Q1=y7QN&2+|5C06s6>n3oja2Mnf3lL|?PhmbpFRbxL<7WpEwiNe
z7nP)LZTa&ulccLu(p-RTzS)>)X$8%8Rwn}!Tz`D3wy;Nspel*iPa;c+U$gauU=yXW
za!wUx;B}lv-Q_u8FVW5%6-!N8@xlFRwLcfHJKba&Yq|!{)@mo@$;Q8J5nq117bqs1
z)oNgOdfv9(Y@%OG?i28#jB>=DYp*c4T8XrCY#DkiCFeNnW0PG6-Hag(2BnI@rePEL
z;Zp7Q>@H@>U##}FXYRP~u$EK{^Q<(*l|B7X81HUmPS-Z_^Nq+-+N=V*>R)fJ&EGl(
zZLYBtJ6CtpE&@oiOU=?3x}^kP2t@mhp~5ZhRo&MU{L<tyPOYUOTTeS}rJj=(AgA#x
zd2HbtBuR)<&eJ6LhB=N$YV^eKyB<+}?-8Yj1sf!3SGK4JYZ{na9QeF?_xg#UItXeC
z-qWJc^GhJ+pYh=(I<M4m!CLILYI6e@gsO)g5@PN@g8Vkr=D8OA5*Nx{IOggKa5|PQ
zqU*TgTalCGLysLR`*kDI3Ff@Lx+jUU2Bz<YGfkU=D?$F+0CG}gyX%4eQ&aOFPc8mi
zy3{M2yh4-MHGZ+_%33<DlBtMiHHj>JmlP@-m>qc8ct(J!8h)i45e{|NPPl*HTYxfP
z%v?8zp50i9W1irv#j+394jZuA@=+UGbiPj`HEXr3(fmX`D9s@rw7IFB*860O(yY)4
zw(+V@)&^F(s12@fzwM2l(4|H2%?rVhOM_|brh`wCf7v$csikJ9{b)~kA$rP<aiuZG
zp`yKl6<G#Ud<_#PA&cC2EP|ugcu9EKe}S4lEt*cW;4+nL;h|ZTR<i9Ht&K_!xa41R
z{q8$>&)lr!Abv=b{CoZt4D)DfE93f|JG710Z2VytfT}ZOS#_|_6b~UC7YT&Af$ka(
zJ;F1J_es!By5Bb_-7A^$A}w*w#d&9$H>oP)C0yo<?#=s80Bv$f&r>CyanbBwA_9Y}
zOZ=&&-dPxI{H(p*xeO!FJ7^RIUDp4lhkdG?tJ(Q`7AHJJRK+CeEIgitB4TqM3{xw7
zlnu(93*VO(RTtSuyBK5@0&wS*o;f?K&UIfcluF3Va)us;Up`;g&y3j1^JQLeEDs;P
z=Z<g9xM?-#H~4OSDOL3jcfBMq?pnYQya1zop|&5NK$0<7MRV(_Pc$kl#2pLEn-POb
zpp3o!+!I;TMlqgr4{KjSPFK*BjCZRm;p)?9-XO_TpDR)`R7{{TjvE{fEtYI8VbmRe
z&2wF6ZoI)lw9V@Sp2<;OV|7lJaWbqJ7wN|7Arc{N>rlH4dd2oqEQIKYs&K(S_00c$
zx<s?B`626tEer*z+Hcxe|2s!4n4q$qmjl&Z%w#huwED|$);gV|ffo_2fx6+(fiMQL
zSu0zS)wpJ)L~Vh#KBS(R)_efDgeD<q&kBzSSktpEQ}BM{->N@Z{tG;>g;-GCL({kF
zdkyV%Y69$>TquRvGEL9&gB2}#^k+QEbHexg-aW+^#hxy;Ivh$+Jw1Irm)=MDxJ>^T
z>wE8`-()L#eC}#}|DM)cOl&O1Br-0BzWaFJW2YPq<YPpJ#dnFS5$m4X0QLv%mmdz<
z#^p$QQM9>G|MLkZBG5%P4^_~M@0%t-tDjX@x*=R}lEt=N)MCG&si#44>f!1JTpAjB
zL=J;Bg}(ebrLC?oc2S6ZPM{?bPo;)T##0T<%cQ9BT!1Af!OOrEpS}m`VSZ>+SXoW`
z-oIhY4JWq*&w0%EJLBl`9H8rg4{l&<7icx(Sy|~G;d}3ha#*N7<sM5+m>UNx%eP`F
zH(93XJ*J6rrtjUNAyD_uDGZwF)qMZ2u4HF6(&CRJXutNQ9-l99;tFk08#We<(n(x3
zd6kVZ3w*h0F0O$N;b#~kEXJUxdLOUpRc>YlK_65Gel*sK(g>J-c{b10)<yQ_4r|L3
zPpK^o`4S%|^66k=RcN(>akcBveMB}j<C|SVcaW^TlVA=Ua3#Tbe2k}JEp+xIyV29j
zygwnXPn<OnAf)9DTeTuGcchW?;bKHtBR|$the_0(O7;H$Ua^h1gwp`OaLGV_Fe^c_
zOdz{>9=$b|`Ja;PUcC{UffOh^z?#{%;`CKuKz5ZxGPAXUC8~3Vx*m{u#=q~V_HHp*
zH`KG2@_lU8aDK&%!Og*|2sjDp-@}Q=;?HJ+d34u{;##tsC;!%VQccj$(|wn55wdVn
zmVYVh-j)Y2KEc$`&K;7hX=j_<{)v}M&`1{N2H6F})1|GCma~<!TJ(No{os@stRSVk
z=z>%@={xgp3p{Mi=acN+b610hxW3+FF8ePh5Aia_)e(LPyZz|K$ow3F_d8aF)#-X~
zDg$5hUKPTGKkR>)bBNjj$wbr%SC#Uo$V)JQGK8+&ESVdB$X7AugYr$?aQ{7xko|sg
zi@Gh{Zz?rR=Mim|i``u{W(H}<Wwuh^eH9CIvw0a>SySJonLRtRJ_QB8pTIUpaJQr&
z4jBsF1#y%2Sp`Ea5%jy;Jk4)3%ftIvix2w;^Q&08M#+Pe7Nr(=-50j<e5gH5U5WKj
zBoSG34|gr<Oq@PeO@Fwrwe$TT!W1KQ*~`1!za&gP=2=j>YhmXc8s@GKhY)L~zAOH^
zk)>S*YCdfL#-P=^SpM*n4)k4$Jp%S%uev4GP+BsQu2eYhBYAXLghdgfIYKWq%bCcS
zZfe?$@9&3zwluT*-v~Q}=qc67R58*EJT1UAc6*a=dK!?L+anb$LAq#4v~#W$dd5w=
zrNZ1lm6f%y&$6gPRPYW>SE{a3X=Qw>J?~Ft^;B*TO+U)}=%?m6boJ;X^N$^KR$o{;
z2+^)1!$`2Gj4bx3{EA(~g$YI!-P8#t<vyh4?v2pmf+VX+GYS65U$_%Z6E1dD$vvIu
zoUM`FDUpv%{sQt;S45vbP;&kWmRvDv`39TP<f)`+zehG=AI_~wjkI@uYB8IimDn7&
zTqF)5$|A5cTcuNNc(A%=Me};c#;XkZ?rOk)qFc>%OPbF=wHAm!a8poUS1ljtVm=p(
zu@R(7!PaV9g5{AFaSFxDF6mvZsK+WOMuTcPhJ58NHx(!0Did!+D+!2U%u5WS{kZuT
zAHN9#82XQQS8A(37^W|`-ZY_7cQI<yHzhmPf4m#S6XljaADC4;!G7*|*#is!RK!Cy
zbC2kCK#Y3Yhewy04r=Nhc^}^foxDTnR>+zUN<UDg3GwMamvqz!k3)BKKw5OsWnOKl
z%q?mP;Z=FY81%QclZ$Q{%VVxtzk3BY^aS6r9b$XrGZ+=(^#Z#6IZn<`6RHokPilrO
z1z;C+OGzK8v>3zOf{7gA>CQfc@3swH-d|~c<BpOzMw=h(qoxR71NJl@EV^FAt$s}0
z;h!HwR8){OFcb2U-g!g*9tS$3F=cCc=VxOO#Xv4UUYuf85yc-P#&RnI-#|ldHRiv_
z4nY2q6iS!}%hWm+yyTwHy(r>b^7Wlmy;B*fcn{_EQj5(xBM}jPa!A9C#5e^muMRuh
zMtI%}xAxw&9UKbt6JricO=5v<36%6l=H&=PD0$<E1^SUGi!h*zcu;Z>`yM;AAGg)P
z-45~5@VJx;Q-A9Kf44>AKZDpoEwoU-LIbkAp|9y+kh(b3b@eR!5&WViVL<IHkWh5{
zUaq9m7lJ3}HMRFI{5`qOPnz&0&-80<#@fTeyxx~90NS=%>^uARr^;!JTNC7L3VCl3
zRSf-7vOvbQE_%}E1R>?LQqG@rOpmf`v60BKcjelZHj@EZ#(%9%Q-BULq)4(N!~J?5
z!H7M8YRL^=zBM&(5>YZNzG5LCJuGT^4QQU}2jK6_T5a9yI70?%l)O#15=My+P)WBn
z%{Z??;aN_?k{j)Wam+d-8~a%bIIvXl)rc-lEaV*`*OT#Y?~0*w8>Q#>%`{?62C2_F
z_w+fbN&73hzdU~C%Yvj`M&3acq46-+`2aSJI4+yIRKdvf0=61qg8R|aAvX|YT}kp-
z^zBm*s!t++K3%Si0MN#EJ0C#1s@otrda3sJs*6tzDoEyPqEj8Dy@me%rIUc?ooVUd
zK&gjGA*t*7N}myvf&t112@40DU=<<<sG7R(HjfGi-POMx*EXewdu1GKgZD47SMMBy
z>xY)h0HzRZ87Y%_IA3<5@L`Zzv{l`KP?Mj+<S5h2NKIc|f+lYy&s-`nB1FE?V``fH
zt+LNl%Uwn|3e>{)>%vc%Fk<-c{>hP<EeFYTeH2l13WXO64)!?{QDdk23Ky}75bfM!
z7ZCJ?(x}^0{V>9dv=0GuP)GVnZnA_6e2>D!v+h^Am)IjWzXNlWa~SCN075yZ^Cq8g
z(CpuCix-7TG0buou3y7czRKxA@HzJLNg(qLgxmW0(ER}9;k)@DMCuJw4*J~zzQlvi
zSlmg8_nyI;oA}mV)$ebT>sV`>A@t+C6G9AnqI`Y#?{(pCTto!>;OC6Wa6rUtsMcTL
z3a~y8kFU`N1=lNEYV=oyPB3U$vYW6iv$a0A_lMNPMQ6R>HXr7z)7YpFJSDA{1?44l
ztP?l1z1b3tyvD^#hXRezLWm=F5T~_(epcfByX_$rj`qew$~wG<zFzdcy0z7U9+E|#
zMuMI003I9pI4RkE8hO|CQgu^-t%8QUafUSN`$j6Z@dbFaEPVIKk_36f?73POSl>*b
z)@k;0p8-@FF10!+9&ipxt81y2Uaa!O@*bm=N{#n=9p{Bvl1-A1VJ!WTRK+BuHXRwe
z0p`zm*zu4PSs)KygY}UmE(-661@pncNl!53>7x2|G>m})dwzN!_|fuhKJeAF)U@(B
z$uo-@JIjP032*seYuAes*lN&!z6fG~Rs6$L9i$)qmFNtZv6{p93<RrLF^)9fi<V*{
zf%3<52qd#&pa$jSOaN&AlY1{)iSW(w)+?CbAn5Znza35;y=9H1Fu(tsrX4e?aME<@
z1s)wu(W_2;vMT5UF`V<lN75{<GgLRncy2_+(IH6hljql3tf>-auUc1sDpAehtGL%}
ziW^)o<`Y8xru<7;%9Bq`l`uw|UWL_@N!8f7poj?XQ~E*H2_cYj-y}Cmkl&qLIo*+O
zyV}<oR-jS6O|skoX4JBsQX`S)?Pv4jA-ctJsVzAT0bFCxc8Ly=fNS6Zq?B-Po=b6t
zROg`l$qnEVxoNC`t*^JtV!tR5sR1{laPVgY<NCxz&fI7>k+}fc+Lb;^MS3ffY`;E1
zGQzPjE54@tsLJ1&S9$>nScg&TU1t318)lltJ0M4#&ye)@qy^eT@a?+4P?%FD_2)0j
z(7_Z480`17B&pnkTsILlCgz1!Ht>Kl)IYmSbfRZMW^EQzVqSP*oei$;DoX~;v<~uU
z{;Lh<T6YBM;^qM3NQV0;FH@3I|4`8yZ5&_28a6qM!LF686PtB<9#i1Y3&>|zpS^Cp
z&x-db_Be<JVVx@+tGmJ%q_=65K+t!v*eO6eNgz7foa%Q{nMO(lV^agUR&dK);vqx2
zgRn`0FG>haJph4;WOLT5o;+3SNew+IB`J|=W6(bDlpiMY7k9&3kSE`ai)BM_E>gxm
zz%Yq67hPh_6~Nh?mMBEHMg8pV=ilg{q3xNeMxjVInB9s=fum5pV^ay{ZX&oi3PQB;
z-37YlW=H!~nAjY`{}<T~D15O`WbHiYM3F_b<lxX@-(-PDH^24iA19_Mt`13SWHmA8
zFxyh_UP<TRm2N4jGDks0rSRQ}T`7E;lzx?BP_`Q#;Uft+A?p1cqAPG#;XLGz)Vxx7
ztkmm&`3jm3lXmV6;i!n#09~#{TnC-hv5@w}UlT2~cqdod6>$g8;L-@gT)C^SL+~Zp
zoqB_<y8WgDvY>?CouEHkC*c=cQIK^$rF8E3kN6eXf|dxaymN0VR=J*9J0gObYaUhC
zn@;y0_1;Q`(0Xoe5SrVFw6hH1O8vcN<kA4+U$-~ywZa%$G}9uZF5Xen(Sl{~BmPX-
zPC<<qL$BnR_UR3CPdESV($YQOYu1^}m0@NAIgMyy%qdfEbN{;Z@PbUjaVz)WXPpih
z^KkF_+H$C>c?qchkG;mL1PN@F{7bz>X)KrXp!$TA{^kkF(VSWCCsUijWNG^1*k^TY
zGD6=*c;}_>-#3b}-Do>zGMiT*wX<_9yjM?4TT2qcTa{V5u2~|#gs)?|Q1_*1s)yuT
zp#YkP`Qzq~U7g<Dg41@~>HHkY+LQ(=D*laR3BE=?s)aVJE<l}G17DpwXW=jv+7&+&
zmGz)*%~^F%fI0lKI{<$g-XZIV$6N{T8WplmmR6>hhXXCt?o7!5#A3LaF?z}=B+x^W
z`4pt?P|7Lt8wWejQri**^5t&fiHB+P9$HxRSH|ZEF!VqrKV7bbC_E@<Gm<<T(&M)1
z_MG7`M7r*S-5*#2-PV&=kJOuf?Ydr-^Rol4Z*OAA?6mu+T=x`;HI6|Nf#s;5Hip9?
zN(vq%5T-c*LD}QSFvUz<NjNF~u~-PXk@Y5fwt<m<-2dVT4Z)uWTor!m<MVU9_mOiN
zJ8SIB4#Q|qh*59eBqEuRRO#KK&yj+xFjW$A)_zsD_G#wk#^Bcj!XNO-uMxs8TbS|f
zWYsfbG9yY(>c+-h!p=jV&ueYMl?EIF56pwUo`>xP%l*J1l(H|px=MrEd1V+}`%V=P
z7Ht+?V7Nh`pDB)6(``VZ4^76jHXFr|BxTGC^kcbSE!7Nl=P0#8dS0{vW)QU-`c9(^
z^3KQa@A%L7R*iPqW&oQe?|76(0A@)w@kiLrm`Js}{+1g#9J{H-ie?#zc1=kKPz53_
zj6FnNdgEghx79&Y%8eLNyNkEV{Ip4W(@G_I`8E@phx94gMmSA)zUYMVol41^a4!eH
zUfm3nJRiWF>45(-78cA(8ktWSzI5r*xVY~rKbXxKUJ5lWc_=vwn11-!GrD^k7SK5D
zlS0B$?SCKF4=S`C<<`2gy8P$s!9di<bKAodh!QtHl=!}a5CtQoOWTe}_K3gvc5nxo
z84X)t0Mjy#YUtMWN<=nN(CD~mvKZwEQMy2X&yS&l?Kt3cKP6N}xgX0UQGY>kW9?$K
z8hBYHjU?|KWws!IiX$Y{MFvi586jU$w?(uv`3EN54wWp9%g95{38`D39}S%HQlx2z
zoXN8LcNk#PQo)TldGhy7-CQ(8vl$mfT#Rwj!-5*N<W{Mg9B&+ps?FVvmQrp%l|H5m
zwU#xUrNac?sS4a6fTvv;@j5YYfsxD3#b+qqpf;cwAI&B9!Xw&%OdD~18@3=y6@=9Q
z8pw(t%>%WjgA%qFoCrFA7Sz_4?IACJHs8Vkr3c(8C#J4@J3-Mq|Fzv&y3QH*MK~@P
zXs`gRm4jgRA$<Rd5f8D3)+aNUgY#VnwGKgubQ!1pvTq&v+=S&oUbxk;-bm}!U#|=*
z@8t7Sq{7yGfyPBl3E)^pLP<d|SS?v_=?z;@MdO#ODt*~66KUN)V$ucy%b<L)Kaj7m
zyBV=AKuM4S!sk03EBTJJbgJ|6d9|MI{A+D@1|YdQh;Y_^_Jv19$z9pRv8^pffZGm+
z=MIJD9xxyvxoba?aLQrqlH<ToN&x5jo3$PB1b#e0`xsV%H9eA^s{z_BJ1;*cMLO>*
zXzw@4i0+`p`CNd&+6-VfDucsp_g)9_v7O-Jk#|Y~?;~(LV(Vgi+1eg8tMa&b)P9bF
z?q1+d=IGYoIvU5Bf3gtFy3i;`+zH3TE8pi+m>j@Mrk#R+-KO}?MJ526)pZ-_TPD2G
z=Xb`>s+M=*QZiEbpQ@{_wjgG<qyMpV&!-V};3onQdJ)F1j(69tQmRat8r!u)kY&Fn
z<lui7c1maMTyb&-K5aWlnC@e`JanfTLHXb$OJHrp(MLR9iVxWjXS@5|2MquqU1YNp
zWYZS6G3g$p>UcoQR&M5VoMNbgldUA>$0cZ0$s%*!Twj^cIIXOLAQ_8rz&)as4{c>5
zKX4?%HZ|2iQ97IxntKdLR?98eMSu&VLE}{x;tV;9>T7(XPqtGT*w0Wo|8s!H$&cIa
zSD*glo~K!)heGFYkk&4xi;k5U`c4kEM%5Lu#j6%-srCH)sU}146|kEcP=Cs}7Ys)v
z1<`U`RP}^51M*e|=K2^5Fylc&m?7HBr86}!xtG=34mc<4M^)Yis5cZ&LEHupnR_Qn
z%dD~U06hvfWQWu1d#yK&53()b{dmB-9pFdcw~KtktAwOXyfWS2d(>bF_|w_1F1X>t
zRq{RhJK%y|L0E)Zt_H<sd29iobxpAY#XFYu!1Ax;Mmt0^$H-5FK5SR?y>q-DlOD&7
zD_5bcaZljvhDXIMK5$XBd5sp<{42V`7BD1JUBCCQQf;2xQ@;kR8Bj={X2YO$EW_@M
z$8#?CCUK*%>s`4Txnem!^UK#D5mo5QoxXf+#KoSbTQq-4=i{|Sy)@UxPL3I;KsN8?
zQ&O+^9cAy%X_Rf+easVaAMs+Pn|w{glQ8Sc>i}|2iA_}7_1^O*>}<kk;FbWZKPqo&
zM|M0l(M4jtCZnKhTZJYf2ndOGvKdWY({&TyHGN|0UAgedbEX5L29RV>FFar-x47$f
zI#(Ima(i%_OZ;<K5NhlLomPa89)7duswl1Zn#fDAmuk?6fc{VnLByU!l|q8|^M>~I
zFs+jzHPj|<Qp2PhXCbExnp?tTsDG~{E&d=l<DpV-+WZr9q}U*eH5){79iOs4ODypX
zDWO5aE?F!p?1S$85z=itbxNeWRAW$K1MF0tz|D0g{2AXjFR~INnFwz0#2tlzqo=^O
zvEDFcc(}6DRrN;awUd2OL`iFnlp}%G&VG93zXEao(WLVb#`4`QyV<;YA0$&qm`$G^
zyS}xRNl?Qc+Skfe{-CsIvm^P``jRNb+Z^g@Zw70cPb4nQy|8(i?twgBlnHm9$D@BW
zIZ4EX_dL{}yPB*)?Nmh^|0(<?9$`mb^;g39i%Spr6KR0reuw?3BLq#zjYCEL#6)Qz
zy(oArxK)Ce5|?ZbG+j*fd!oK`)p>gC0qL!T^IvcR(u_~yT{CQdwZcJ7!yf4k)ciFV
znS-80rKz+_qGhwF8Ei?OOA$MF4q8{{-71O#3Nlu0xxEhGSy2c)+v(rirI1?m&|i>x
z9}w8*o!<ny3I>I9Fm(<8rxr+HIEcl9g4ax{q4rn1h1Y&=k|L&6Q)T;!x-^lWac}9^
zu9`XM&AV-Y8t8WQ2N)C>QgjTMsiYF03ne`I&fQyafwJT%q1lY&BxUEQV7=cO_`+95
zT|!y;nz-jSOPZN|tiIP0ni)2dvWSYngR!?lDCw9X&|34XUS}|_N7_@OY6I6}D#2WN
z+uaQ-j+BSqx_>2Tu!8Xh2+ltO9C3%W&pd>BbBzF=5wi@rpj?nS@CSP}gs)>5=1y0%
z(Ml_nEc0ExN!X^J&B>NIrlQVLUAa8@H7m=mnt7Y#<p0%m=I>Cp?;pQs?lJc?gRzg@
z*g}l4jBOBOtXZ>Xh%qw^W@{EpB0G^%J*`?$X;n#<RD??9DXol#N>7U#(js{t)qH*a
zfbaFo_0x48*H71Rp4ahyzuvvqZkx<K3DzE}&0J1OrBv(ueEdTrYSj`CY`a|p_Ztu_
zp>OBhW`QP~7wmmqSPD*$%Djnn_BXkBRxWPF?nAj|i_MXJFa_o+&KYb*sJ+OGt7re&
zc3*B3wfr~@5AR22kc`$J_p|@%BF_O!6wccQJwD~WlH2wLo?U<ZP8ZUXFA-X}Nb`r{
zN0Z<|PZ4v7{5(a32<7RGf`q$zMntG6TBj-OT0Qw(Q*PAzA06mylV96jUDcgEw;T2;
z_b=TW2Po^WHY2oMsUp{!3BC0@B{daBGsd$}vNop4-1=7EgB5u}f|lBKt4Fn((f@6m
zy5Xk_?~ZzI=;5mG-!>r1MQH7N*=Zx1A^V1U$n)g-F3Utzv&VN4rjFl`b4C59F3n`w
za4gQ|jl(L>!(rd^K*PM*K(ts3sUlX9YCSJQ^W>|q>t9C;@^xw>PN#au9dy%s$ji1{
zw{~5kT-ox9i}D|4UFj`6Y>%Jz@Ziy{y_&Q})C+xq#`cEOO=h=MJ`9(fFEw7(Wa%E0
zQeW4T<6A$YVd)x$)>Jb7GEBM9e{$7z-`UbPx<SJf<=x0e;8Dzo*Ikpl%z4N9G63+q
zyMGthP>aGlXW^ci!1A=~Yc921LT)tk{e4>78~?qadd6-I>-9_2*X5GB$Nl5mmX?se
z@YbPKKoG{*$+dL4w9aKm+}FTQRabXS?5wZn?)s<h;0M1GN($_RnT&qTuf@;)?%j>F
z#e;WO2aQ<G@%m{cyGpjaL44}Kpgy7B_*3d+IBn_TXXLS(VF%Plw9QW~s4e+L4Z9Q(
zFEk_C1#53p%#5HDu3Y`f{2^Y|fFd`eQs+~?jxknjPaou))3Aa_cho;uO{_yWPL~==
zU!6*g2~U;S%qWS8IX!L4VdaCi+rC=k^Y6tC&FlWH1^FWCTiUFbc<we$V2%X{tf8zP
z3{m>DLOl-+J8QC~UnxwjS;;#WTUFZ|_tqTR@)S-@Q#+Pg9(tmQ(1d+Rl);T|ov6Dq
zx`&v(K&h|)IO>%Sr@7#%XX+;qc3Mj|WBD4KfloMg>^Xy?iQ+|xMeRt*BYR~urX_Cg
zUx{TA*Z8IL!*LOHGTCdSx<mfM+N;!!JjE_Ba6CV@WLY7O#144~Ov`ZbrrYEP#p;AU
zqQ6k3^qnGPJcv-EQUiaY{QUKC`!A9Ua;snY*8IC)Pml%A_J53mm$vwA@%iWb(Wnw>
z(^aM46FMPhEw|GyJknB5-}{EN-dDCpV&;$RK?u%%xb@@rAURG@5m7Oy9u28g*>)qI
zbT4F=X(?250w(ANw;t%etkuc5I>CNb;uO3qKcVD5S=Sw6+Fa?9c+Ix|DrC6i+4`pQ
znx!9PX1>qoO|K128|nr8qw?opNvqrxtd!-K?I<gvcD$&C2lprOsC-$MUsApugunJ$
zYr!|+Y7A2H(BYTL8|twFGnRWc?5djuP*k{noG~-=`_GELCtd!24lL7A{%1ZBNZy<D
zeRE0jkGh@1TLW#DQlgUCvT-olvn|&E>M0z!V4Ab-+t-;_g*!}I+NV;s{g$A3`JceJ
zY!i7Oa0DcKhdS5z!OT8m0&Ihc`t>Atz4b;v400cX;V2st^vud^CzfAdFe9gHe4aPR
z{yid(LOzs-@Gt03UYn|YQ=_Its#(FUekJ`XTC6_$A6ua)HmM7Ehbr092y~$bFRPC@
z-V?+>Pg_Ld@iSEx+KzL>@)K}<X^Wru*83<gilAxf=pEHKmCuh3>5s5|bbJBNG!23m
z_@`T=6*CHXnVV(`@>wfnmg4Sr#yJQ8EC*rKA;>Ohv6WVY2K5RYRwRqXuF?{TW+|=$
zQw?ne$CPX9O&T!1__RmGwu@>}E7T|xBuoi}0E0X?N_^M@Q;n?wVOwC_C>4&?vqd%4
zzzwe9Pr>bHKV?>oM%XvDzWxELw5!499BP$g9KdzQJO7xJ^dgZMeOFMNk~cvZt*Ulz
z!Dv9HQC}2!AjOaB9}pN69I`GnEIcA|rOD*~j){$nPe|O5L{DchSs9t^tn3^Pm&X@u
z5{iIDg+eUJ&C4&??BM9+OmcB`bN8?%0)Rv8g(4Un1_zr~N~GQzkMACykqPh?pC8^B
zxQN~IW6hoFAk9FB)3CjPiv6DyzoiFCvM&DguWP3zj3;k1Q*X%Gv+2OfQN`~a)Ph!1
z)RmBQOXEe~4&R&WlQynCJKXg#MU6NXqvgL+{SCbIee2!jryt%wm^K}Q+=i-Eo-fR4
zB?au?_eY`h@t-qG$LD`d!1<ZAVQap5$Vyl4tWa#KHlrWmD!ae??f<Fo#F^2Tp=qJl
z76sS)`|cDsTK{LI*jlb={#5BO|4hlKChpO*iFXHO@0Yf;n6To{H%BWJxBSg)7WOOF
zP*0ivb<U${&oSPgt>s%;yZ=_+S+tP+IHjU8viLOr^?SQNT0azulbeq>tD_>yierAd
zd?Vku_GEm`uBTPtzoj=2%IZ3x(yA3<)?4Ts0;7gQqOsb`ek!qvYt0mvOnW$E{~;_8
z5|wL~C4lg~qkj~1CR4}~i2xo;%%zKRv_z70EPlBgcSp^CoG#%gXVS&2JbHokmgT{z
zz&Kvc`#c^%-WVJk8^tYLCcdCZ#B9DWYqMn*pQr6dHd+27%VHS#06_t<cuNrsZ|!LB
zpwhW@PJxaSv4jLlCW|MwIYD%=_kfKZT0W1n4(5w+5Edqb$F--(#23Q2*XE>rMlwJJ
z#biPlBD1}}vr7zEkN5jW!~jelBwIVyi%-dgJ8<w!{+%pR=hR}ZIKz)jB-#)iEE)P;
zW4wMpF_6y5Y2D0HeGH0|M6|!rj@-}JZx*(RUVUHyv4O>&Ty4tlsvBu-`T3~^IcHey
z10jGvMNl}zr86`INCCsu*~y+Ut{D4V9LSgOm{WH6`2NE}Z-;!#l~MUYS0z3p*O8_C
zBZ^9#4NUDN22xUO@opXu+?+H@yq9&9LhvCWnhq2z-D1yKe29*7F^ic+$B&_hUb+s6
z`8nqK_R+KnMDCd3YIiReZT7`SllZ6iGCfZhe$=6T#B1NgGu{a7(c3?FWx}=r5oY03
zv5?-)@76BAleHF~F=J}$=up{z>5D^ny5LWs7Kh+35peu4(m|G1aC3&1HH<a^SoM_U
zh#AF>>JgboCBJ6JdYAF}H~GBn+^iMkWL1Z0F_f`C3jpZ+$)0I0ldU4)(I1HD+sSA=
zefo~dJ~W!bVR1V|<o6rdOX+;RAKOV(Akq%8m*$*AYil_<bn`or`Cq=UQqYkIo`^R6
zINeV5lr5M+=3tkzG9^N~iiqEbUc>e5ib@T_yW-6#W}33eG5sgsyLp`WTyAIg<3lH%
zCq=1-vKL@u&<VVk(GKCg<?Sc^vR`?XrHTt8)^K{bYx|;baoqOM_KUIcm3=YBP*!Ny
zd658BQ0kvqSl&+RU_Qi$YOPkLxgPY@q7N7kSevyTJFY~>?4m;BfBj_9s9W=n<ZQ-E
zL?7>|&Z_(grbclX&VFaM(KnW+zf9rWTs_MXWYMxyR3dsFt+ro@S-0FR64_px8f9dy
zXE94@jN@GMX`Ysj|5rhqc31p2oOrNR-sR2d&S>KBmw=BzI3H<VNXTVqLY9YQ$;Yp9
zRW@Wb)&@Sv)=CaC;DK%rE%n<TAH2UOf-Fs78)y;z3Q>4RQ(bUS)WXe3_3z@Y3Jp6X
z_Lc1;RMc0K16-a+(FQE<BJ1lKRlomaZIZBT@CGcVUh`$O!HKo3KLVX3`Vf*XytgVr
zw7WA<ZO^W?n%b^+d#!|ZcWJJ7C&O$!&gs2a)|8&65qMh&gh(3aJXf=IM;1km)}niN
z_pT5Q`?9RWWkHZJ&0ueOp_EQD%TznSXPVkQUgK_?)JV<oPJF@6ROY;7A1l0AIBFgZ
z<%u9JRB1@OlSuWMziodjJy?m#W4_p@T~VUC_b69Axf?6wKVaErx(aA#vXTOs&rLb7
z!iI*IcKQ|F!x>i{ftUhKdOo>S<4LO&A0k|P@zRF#V`E)^yE_Fgc2z3p(j=_4`QCWD
zWp{7y;4B_f=}vD+e1tbj)Qcyakmdnm+~q+~c4FaQNg%#`AaRi3EadA&-fS1-XfOzZ
zjqHdXjBcP^2EmaM;k?@@(YEqHZMq2xDN`E{;bC5+4bks8!J=p)<9Lodg}KV>g=8(z
z=Z_@5*Od|4_7%>>0|6!IvU2_z59J=?!N+(2n$)PLy6RC4>Kqu=+$N?WpqtoP)sUjd
z5~qS3EfNid>A?$c&2<s%TMTHwJmJA82X4CU)MtdUr!z>xM$S-<7p=>{%X&T30tZ6_
zEJga-0ycYUhAQ|5te3Xprniz5;S#hCM<XPOhcYml^|CmEH;mx#R=c#{o-Z`cd}Q(H
zw)t7sdnVSET$ixVPv06VEq8+^&oFHOv3h*=Ol6^iQ~q4SwxX3DILi)|LlDrey*@Mz
z^Wo<N=+o6`2PCD;j}5eixo56ji2UXh4W^b$JKnGy&|(5is?Vp~Em<~sw6G0iAU5&U
zZ1+{Nr&0hiI#EeE<wn|<bedIR03P4-P-_ifTJZAD?l0v9&}QBA0`Z69pB|crQ<TCY
zDgFWet6C-*Idi}oVAUu4tX&h_O9o0PJn9rtJu^=?<3;|J&BcFbd6?~+3tXl-dK4qf
zXcV|VRoKni5a{Qu?cfIMWOwV7<aT-k4SC%=!U!(`vobC=ee<>E!O{>z<;~Q{aHX&F
z^;HL>8R=pbzsSf~uP0|df9HkUheY^=An$aOPlxjZ@agD;=1Z5fHMGAtTwd*E`N}n>
z>n)jn+mdAweUEbQ7Aw<}{`CCa$Msx1KT?Y+yp(1-H2n!tYRrKK5)tco!tlHsmvN4E
zbiQU*43*UZNMk}CSdIQXV;j0U>Z33>MILO>`tK5BQOqAcS30C^)0Mr>F84qV;esv8
zfPlrcb)ATmlM55|Z?>O^eOKGy)Av^Q{FHYxDJ0R>ooA{$Ic4vB=RL(w755Q7CT6_}
zy?k<9&@J@MXQ7TlDe3+t3U^LEU{MGZ0n_}AN~N9{E}i$@cD0~%tabYs5NXjvNcL_U
zD$lySs?p9+=7=^`g-vjCa*TQWy{fPnS#su)QlS~=a-!usKQbe^f|h3PO$;7H>=?FW
z-fKYgmPsTG3v>W<i^oL+NJp;qgss<$J}rDH-n~H1?cTFl$Y3=FZsq0`vQz_?<_s;I
zUAb)WW>%j@`^lX`C;RBk=r{M`1Q($5$Lp=Q?7xcR!ULj1sxuQUIoP1(&Fn$Iw0?Wr
z-X_GWw=W;(v`X9El^k7>Wr?f7wnv9BPT6bL{axcS0PyjvCc7;hQR#poFEB=V_s#9Z
zJki2BmGTWP3oWQIimZSS&yGTMv7URA?};9tw)AiO%1#83a%uilw1p4G9BZ8q&Q_*m
zJCG1g`C!YfN)0+9EG+Rxy1!G}QBVHBe4ha&I%@4setrRy&G<wOkHYZwChcKmQ>fq8
zd`ZW8MO!Lu*el~TM~bcE{2>W*dV0=anP>0h01zBJ%Iq5$#NSrrxQNh*$b^W)!IUV3
z-7WS>q%eT4MzGf7eGx{ixDZvtbn0R$sxjdNxTn-6c8hm}wPvFExEd)uNyn_tXt6ya
zmE!G!j?h8dWfF9w^|eBnQnpt)HCV4i*mWc2$`T~@t~2zn`Ro%arK=s`L_5WLZ(v2s
zuK6~HH$seDtNoc6LsR3WFmLydPJieI3}e4_A}uFZCr1*=Za{ZB9v#bc8q*nzSW~1K
z9Whc_Sov0ah2nLrsA~7~AGwZuqx|EZbKdjnB88V~N-<XFpRsuwx&gxLLVgZbaQt$$
z5+|XGnhy^HvN(iOnHCs$n&w|Zd~CYNX@E7*xQYH@7Km2En+divhpPI`)Rg|IFkN}R
zrzq=`P4Qmdz`fhdh7Qv<h#E0a6Qmb?FjRLBUZ*zZ*q-D%{ux5>c1}lPGy{zfe?k{f
z%K+)4V3P%7198;P^#nk<Y=s)A!(!eMSGvD@ojZi{3^nLK6%t8C*jq*>U?W;?C%q1d
z2x^L(G_Bv4M0>$-)^N{T4^qnDqYE}=eyvLP{bQeyF3rUe8XLluD{!*=MRSaLNOU{N
zV{*9K7|A_CYtj&<+l;ZSD0`D~UMr1eT4>u;4P5G9;4)nRH02cWS#ouk6WWLXA(6D#
zVTZl+)&{W6pDCG`^=DM%zkar<4VS?kMz1o{M*LchsvbC>gs`p^{qQf$TgyQMMk#AV
zW?#~+gnsL7o-VHs8nQQI>8aoW`#yKL%2#V6scvP`hqyO*<tg<1@h+As0m;qUp|6^5
z6aR$Ttzrw2Y{ZPFh;|FICiTO6WIep6I8lH2L-z4dHNkG;S7bRQ+aW1JLo%JHHc%<}
zmAMKW#Sa33%MDIVLj)sh-Xh_A`pr4*bWv0-)#-^zhUaqGk^C@k#%We)1-ITc+s9G-
zOro>g#}zDyaT|nHT43SWJLwY~=2Z(NmJ&7)B%mDDvp;kO-#<OL77f}Vve7)s9eX`1
zwkHe>L+UXbVw0I1ErXjBTlJHDty#S~^PnUS%YANn%^W8>R-B_DLqy4-Dpj!hkA<hP
zRL0B2K$ei5Dgd|ueU(PRe>4*Kl)*n$sM7%E>bwF5b6fN~>Mb`owV;FOixe_DaIXwb
z;l`(Qo~blm-0pT9VsMBu(wQj3%mYdwi4@+gmKy|a+*G4Y3V*uez|o6`T0bVYfzmHO
z6rCw&v%Ly4*MM(j^+GlD-yT*pvw|H(7&m+Z1!K87B5l8s0SpJ)d}IGyJZ_CK*-e50
z>MHOGBOc%R>ER=nbg@D&&~JDDUDt4LcL)I3Yhi%AN#D|J!RlOYDxMJx`bTu2KPj&-
zfw)?oFgZHHVimlH;*jXAGZk=eq9X;C0DkdJkos1yCZ0&hl3*^2PsA+_QJZ{VKtN1G
z2Q+4zkQc-;I<X_|7Jpk%DM%ZdtMCjy2#z$k?F2hMAHH#^Vdv(ZK>+BM__WA21YD;@
zLqTY=T_PUTBrRVZA>TM+>x%^qno@sH-ou=0N;3er97jCN-QU560#A%9gBn-nsvz8d
zCqcdWYC^MosNJ)D9Jq2q@2$uOynf*BQ2d|?430pc5N@fIawF8xFA&#~JOoEy{cr_*
zaMWvg=8<R3$br$3l4+6e-=HERWl<D<*9!yQ9M3sNnRAn2P~$|ao53dHYPfO{5tC0U
zCzUsBc~tVh{dGl@m^hm&+vEmiy$R*NAB~kgykrYIWsv^L3SvDajqHDUs`%pURAa0B
zP<JP`A7T#AOu{uc>Y9J~I?^Ac*AaA8K72}TtW)0QZVI=J3TpX*g*hXt9>nR~{PfR-
z<(u4u_s*4gO-WGW1<};VH<QI6D{IZbpzmW}%DJF{rUzW<W=hFMHev1gB{<9rZ%C#H
zb8YfqFUbx-w0{UXYe`|!>llupyQ#oHB&3X0xApR)UL1Kh)^5%fFF`*+i)Hz~l0#PA
zZ!=bM#O1vY+gpA&f`|jn56r=3gTk(pifc3OQ#6Dx6$W->LVCfm)PJ|bA$Kv*GjD6}
zYxSW=%_!$zf2D4y^RQ=569}GxG|U%MGo=uylm|hceQhu6aG2iupR;p1q40~;Ni{5Z
zL5}>0(eg8}qc3678KDQMm=cTv$U4N6tLb5oAf%$&GDvAC;`)=m>f)reKLLIGQ)sE}
zSFVw|%9XGvsNRMY-jU3=|10%yq;DtUSr5+g0lu7Yb^y9Ns=Y1zDQQe;($VqQ1VQ}>
z)aNk^@rXISdBQ1&1tRpTB%%AlRF}{WBDrA*A`*lnyQDlN3}V&9kWWSLzVLBe19bP4
z)8C3q-4|OwLbs-8zk5K&s0yoDWvh!lkk8@BetWIn&sZo6)Rd*bv^VTyO~7@{&GhhH
zb2=<j8@Ps&I$Zvx(b`q8;?Pe+>DO7PPHMiqSONyRDF7LxD|uWp1%C@QU0#GdHljPK
zCfhxa8XAzXMt0DPgPAH*);^Hu*%*kBJ{Hg*3$fn>UEc;>8}cqB?Z>%agyy|&kTXRe
zj~Y=%aDo3oE@59(Qm82ldkiB*;OcAOxI`uV)g{_}(D{@U(jIk9c>}&rcfwxT@F7>#
zuv61{+=LBEx#2#}d)Cj#fY&h(;u(3{=Z4~dpr)H!5`ajC?9r&i(;tknOj}L?Xx&X0
z3??x>pa;94^$e_AbSox-{p@E6rc*w1n*8&?$P-XScX?*~;V7u5YmG$S_a7eSv75}g
zKLaQLF%mYYm-~6u#hR8-Y|HJT6fk8RM4889i;v~61W9(H_Padtvb_ejspy#Jfzm+O
zzp*ppw<kt1;3Ni%{$A7=l{*f3u7GB!Apr0~-M8?UU(kJb`Wf5F*SeX8nSco+_mqe0
zRG0S|&<tbId=}t!`#!^b=@wv|Nc)|G$0e9k=I)r+K4U7b!BR)_Ef_cR2e?@bX016U
z04Gj)N_rCF2L*#+62_EELL?{-g83w4m<ajWGVJXlj079-z}3qKkF~JG7D`gamt8PK
zFd2&_Vp4u;pWkUxPL@-_lG~hdF%}h3m_Q=BluN>+Gca^4l~3NNJccR2sz+X|Ps8>O
zVEcU7!`PXJxexlAFlR`qFs#qSkt;brso>q9@>N8fo64Ax`v`>b#@<YEP8=sjV$!e!
zqZnD*RB4A>zbgatpUFA7`*b+qx%0y_teTH(fRji23)AdwqD;Ghk=r|*@4{Z84PowM
zea_QVAt~l176sC-Hu=If=55_+SG;FNF2#X9kEvZBx4*(1kW$~cWgDvBd}}rt0J_$8
z$s?pcEl#=Fk$;lzJ8RVoR@^Vp6W}<5JQFCTKL;ZJC2nFDw|)#WI9_LL0&OX}kTY{A
aJJq(+IulZJ{-1Dg#SaVo@00KUU;hWfvWUL`

diff --git a/pc-bios/pxe-rtl8139.rom b/pc-bios/pxe-rtl8139.rom
index db7d76d9ca41889cb993fdfd73a9f260f0debbd4..67c77fbf73135d9f81467cb36d3d1c64362ba8c5 100644
GIT binary patch
literal 61440
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%0AxHYU0<m07bzW9bYL
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
K|8M^%8TcRg_~}Lf

literal 56320
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

diff --git a/pc-bios/pxe-virtio.rom b/pc-bios/pxe-virtio.rom
index 6dde514c79304041837ed0de99678149844d9419..b1ec909628998aa9289b915e59416717e718a618 100644
GIT binary patch
literal 60416
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%0AnSMLox`{(uy#H~ef(<aZ
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

literal 56320
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
Xf6_VudT;)pA`bw(f&b{V|A+T~iG=>J

diff --git a/scripts/refresh-pxe-roms.sh b/scripts/refresh-pxe-roms.sh
new file mode 100755
index 0000000000..14d586070f
--- /dev/null
+++ b/scripts/refresh-pxe-roms.sh
@@ -0,0 +1,99 @@
+#!/bin/bash
+
+# PXE ROM build script
+#
+# 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
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# Copyright (C) 2011 Red Hat, Inc.
+#   Authors: Alex Williamson <alex.williamson@redhat.com>
+#
+# Usage: Run from root of qemu tree
+# ./scripts/refresh-pxe-roms.sh
+
+QEMU_DIR=$PWD
+ROM_DIR="pc-bios"
+BUILD_DIR="roms/ipxe"
+LOCAL_CONFIG="src/config/local/general.h"
+
+function cleanup ()
+{
+    if [ -n "$SAVED_CONFIG" ]; then
+        cp "$SAVED_CONFIG" "$BUILD_DIR"/"$LOCAL_CONFIG"
+        rm "$SAVED_CONFIG"
+    fi
+    cd "$QEMU_DIR"
+}
+
+function make_rom ()
+{
+    cd "$BUILD_DIR"/src
+
+    BUILD_LOG=$(mktemp)
+
+    echo Building "$2"...
+    make bin/"$1".rom > "$BUILD_LOG" 2>&1
+    if [ $? -ne 0 ]; then
+        echo Build failed
+        tail --lines=100 "$BUILD_LOG"
+        rm "$BUILD_LOG"
+        cleanup
+        exit 1
+    fi
+    rm "$BUILD_LOG"
+
+    cp bin/"$1".rom "$QEMU_DIR"/"$ROM_DIR"/"$2"
+
+    cd "$QEMU_DIR"
+}
+
+if [ ! -d "$QEMU_DIR"/"$ROM_DIR" ]; then
+    echo "error: can't find $ROM_DIR directory," \
+         "run me from the root of the qemu tree"
+    exit 1
+fi
+
+if [ ! -d "$BUILD_DIR"/src ]; then
+    echo "error: $BUILD_DIR not populated, try:"
+    echo "  git submodule init $BUILD_DIR"
+    echo "  git submodule update $BUILD_DIR"
+    exit 1
+fi
+
+if [ -e "$BUILD_DIR"/"$LOCAL_CONFIG" ]; then
+    SAVED_CONFIG=$(mktemp)
+    cp "$BUILD_DIR"/"$LOCAL_CONFIG" "$SAVED_CONFIG"
+fi
+
+echo "#undef BANNER_TIMEOUT" > "$BUILD_DIR"/"$LOCAL_CONFIG"
+echo "#define BANNER_TIMEOUT 0" >> "$BUILD_DIR"/"$LOCAL_CONFIG"
+
+IPXE_VERSION=$(cd "$BUILD_DIR" && git describe --tags)
+if [ -z "$IPXE_VERSION" ]; then
+    echo "error: unable to retrieve git version"
+    cleanup
+    exit 1
+fi
+
+echo "#undef PRODUCT_NAME" >> "$BUILD_DIR"/"$LOCAL_CONFIG"
+echo "#define PRODUCT_NAME \"iPXE $IPXE_VERSION\"" >> "$BUILD_DIR"/"$LOCAL_CONFIG"
+
+make_rom 8086100e pxe-e1000.rom
+make_rom 80861209 pxe-eepro100.rom
+make_rom 10500940 pxe-ne2k_pci.rom
+make_rom 10222000 pxe-pcnet.rom
+make_rom 10ec8139 pxe-rtl8139.rom
+make_rom 1af41000 pxe-virtio.rom
+
+echo done
+cleanup

From bcec36eaa0f8570d455214512f1d6382410c509e Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Fri, 15 Apr 2011 17:32:47 +0200
Subject: [PATCH 232/386] s390x: Prepare cpu.h for emulation

We need to add some more logic to the CPU description to leverage emulation
of an s390x CPU. This patch adds all the required helpers, fields in CPUState
and constant definitions required for user and system emulation.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/s390-virtio.c         |    2 +-
 target-s390x/cpu.h       | 1022 +++++++++++++++++++++++++++++++-------
 target-s390x/kvm.c       |   17 +-
 target-s390x/translate.c |    2 +-
 4 files changed, 864 insertions(+), 179 deletions(-)

diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index d429f10d56..48fb0d05c2 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -82,7 +82,7 @@ CPUState *s390_cpu_addr2state(uint16_t cpu_addr)
     return ipi_states[cpu_addr];
 }
 
-int s390_virtio_hypercall(CPUState *env)
+int s390_virtio_hypercall(CPUState *env, uint64_t mem_, uint64_t hypercall)
 {
     int r = 0, i;
     target_ulong mem = env->regs[2];
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index e47c372fbd..a84b3ee184 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -26,24 +26,35 @@
 #define CPUState struct CPUS390XState
 
 #include "cpu-defs.h"
+#define TARGET_PAGE_BITS 12
+
+#define TARGET_PHYS_ADDR_SPACE_BITS 64
+#define TARGET_VIRT_ADDR_SPACE_BITS 64
+
+#include "cpu-all.h"
 
 #include "softfloat.h"
 
-#define NB_MMU_MODES 2
+#define NB_MMU_MODES 3
 
-typedef union FPReg {
-    struct {
-#ifdef WORDS_BIGENDIAN
-        float32 e;
-        int32_t __pad;
-#else
-        int32_t __pad;
-        float32 e;
-#endif
-    };
-    float64 d;
-    uint64_t i;
-} FPReg;
+#define MMU_MODE0_SUFFIX _primary
+#define MMU_MODE1_SUFFIX _secondary
+#define MMU_MODE2_SUFFIX _home
+
+#define MMU_USER_IDX 1
+
+#define MAX_EXT_QUEUE 16
+
+typedef struct PSW {
+    uint64_t mask;
+    uint64_t addr;
+} PSW;
+
+typedef struct ExtQueue {
+    uint32_t code;
+    uint32_t param;
+    uint32_t param64;
+} ExtQueue;
 
 typedef struct CPUS390XState {
     uint64_t regs[16];	/* GP registers */
@@ -51,17 +62,42 @@ typedef struct CPUS390XState {
     uint32_t aregs[16];	/* access registers */
 
     uint32_t fpc;	/* floating-point control register */
-    FPReg fregs[16]; /* FP registers */
+    CPU_DoubleU fregs[16]; /* FP registers */
     float_status fpu_status; /* passed to softfloat lib */
 
-    struct {
-        uint64_t mask;
-        uint64_t addr;
-    } psw;
+    PSW psw;
 
-    int cc; /* condition code (0-3) */
+    uint32_t cc;
+    uint32_t cc_op;
+    uint64_t cc_src;
+    uint64_t cc_dst;
+    uint64_t cc_vr;
 
     uint64_t __excp_addr;
+    uint64_t psa;
+
+    uint32_t int_pgm_code;
+    uint32_t int_pgm_ilc;
+
+    uint32_t int_svc_code;
+    uint32_t int_svc_ilc;
+
+    uint64_t cregs[16]; /* control registers */
+
+    int pending_int;
+    ExtQueue ext_queue[MAX_EXT_QUEUE];
+
+    /* reset does memset(0) up to here */
+
+    int ext_index;
+    int cpu_num;
+    uint8_t *storage_keys;
+
+    uint64_t tod_offset;
+    uint64_t tod_basetime;
+    QEMUTimer *tod_timer;
+
+    QEMUTimer *cpu_timer;
 
     CPU_COMMON
 } CPUS390XState;
@@ -69,24 +105,174 @@ typedef struct CPUS390XState {
 #if defined(CONFIG_USER_ONLY)
 static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
 {
-    if (newsp)
+    if (newsp) {
         env->regs[15] = newsp;
+    }
     env->regs[0] = 0;
 }
 #endif
 
-#define MMU_MODE0_SUFFIX _kernel
-#define MMU_MODE1_SUFFIX _user
-#define MMU_USER_IDX 1
+/* Interrupt Codes */
+/* Program Interrupts */
+#define PGM_OPERATION                   0x0001
+#define PGM_PRIVILEGED                  0x0002
+#define PGM_EXECUTE                     0x0003
+#define PGM_PROTECTION                  0x0004
+#define PGM_ADDRESSING                  0x0005
+#define PGM_SPECIFICATION               0x0006
+#define PGM_DATA                        0x0007
+#define PGM_FIXPT_OVERFLOW              0x0008
+#define PGM_FIXPT_DIVIDE                0x0009
+#define PGM_DEC_OVERFLOW                0x000a
+#define PGM_DEC_DIVIDE                  0x000b
+#define PGM_HFP_EXP_OVERFLOW            0x000c
+#define PGM_HFP_EXP_UNDERFLOW           0x000d
+#define PGM_HFP_SIGNIFICANCE            0x000e
+#define PGM_HFP_DIVIDE                  0x000f
+#define PGM_SEGMENT_TRANS               0x0010
+#define PGM_PAGE_TRANS                  0x0011
+#define PGM_TRANS_SPEC                  0x0012
+#define PGM_SPECIAL_OP                  0x0013
+#define PGM_OPERAND                     0x0015
+#define PGM_TRACE_TABLE                 0x0016
+#define PGM_SPACE_SWITCH                0x001c
+#define PGM_HFP_SQRT                    0x001d
+#define PGM_PC_TRANS_SPEC               0x001f
+#define PGM_AFX_TRANS                   0x0020
+#define PGM_ASX_TRANS                   0x0021
+#define PGM_LX_TRANS                    0x0022
+#define PGM_EX_TRANS                    0x0023
+#define PGM_PRIM_AUTH                   0x0024
+#define PGM_SEC_AUTH                    0x0025
+#define PGM_ALET_SPEC                   0x0028
+#define PGM_ALEN_SPEC                   0x0029
+#define PGM_ALE_SEQ                     0x002a
+#define PGM_ASTE_VALID                  0x002b
+#define PGM_ASTE_SEQ                    0x002c
+#define PGM_EXT_AUTH                    0x002d
+#define PGM_STACK_FULL                  0x0030
+#define PGM_STACK_EMPTY                 0x0031
+#define PGM_STACK_SPEC                  0x0032
+#define PGM_STACK_TYPE                  0x0033
+#define PGM_STACK_OP                    0x0034
+#define PGM_ASCE_TYPE                   0x0038
+#define PGM_REG_FIRST_TRANS             0x0039
+#define PGM_REG_SEC_TRANS               0x003a
+#define PGM_REG_THIRD_TRANS             0x003b
+#define PGM_MONITOR                     0x0040
+#define PGM_PER                         0x0080
+#define PGM_CRYPTO                      0x0119
+
+/* External Interrupts */
+#define EXT_INTERRUPT_KEY               0x0040
+#define EXT_CLOCK_COMP                  0x1004
+#define EXT_CPU_TIMER                   0x1005
+#define EXT_MALFUNCTION                 0x1200
+#define EXT_EMERGENCY                   0x1201
+#define EXT_EXTERNAL_CALL               0x1202
+#define EXT_ETR                         0x1406
+#define EXT_SERVICE                     0x2401
+#define EXT_VIRTIO                      0x2603
+
+/* PSW defines */
+#undef PSW_MASK_PER
+#undef PSW_MASK_DAT
+#undef PSW_MASK_IO
+#undef PSW_MASK_EXT
+#undef PSW_MASK_KEY
+#undef PSW_SHIFT_KEY
+#undef PSW_MASK_MCHECK
+#undef PSW_MASK_WAIT
+#undef PSW_MASK_PSTATE
+#undef PSW_MASK_ASC
+#undef PSW_MASK_CC
+#undef PSW_MASK_PM
+#undef PSW_MASK_64
+
+#define PSW_MASK_PER            0x4000000000000000ULL
+#define PSW_MASK_DAT            0x0400000000000000ULL
+#define PSW_MASK_IO             0x0200000000000000ULL
+#define PSW_MASK_EXT            0x0100000000000000ULL
+#define PSW_MASK_KEY            0x00F0000000000000ULL
+#define PSW_SHIFT_KEY           56
+#define PSW_MASK_MCHECK         0x0004000000000000ULL
+#define PSW_MASK_WAIT           0x0002000000000000ULL
+#define PSW_MASK_PSTATE         0x0001000000000000ULL
+#define PSW_MASK_ASC            0x0000C00000000000ULL
+#define PSW_MASK_CC             0x0000300000000000ULL
+#define PSW_MASK_PM             0x00000F0000000000ULL
+#define PSW_MASK_64             0x0000000100000000ULL
+#define PSW_MASK_32             0x0000000080000000ULL
+
+#undef PSW_ASC_PRIMARY
+#undef PSW_ASC_ACCREG
+#undef PSW_ASC_SECONDARY
+#undef PSW_ASC_HOME
+
+#define PSW_ASC_PRIMARY         0x0000000000000000ULL
+#define PSW_ASC_ACCREG          0x0000400000000000ULL
+#define PSW_ASC_SECONDARY       0x0000800000000000ULL
+#define PSW_ASC_HOME            0x0000C00000000000ULL
+
+/* tb flags */
+
+#define FLAG_MASK_PER           (PSW_MASK_PER    >> 32)
+#define FLAG_MASK_DAT           (PSW_MASK_DAT    >> 32)
+#define FLAG_MASK_IO            (PSW_MASK_IO     >> 32)
+#define FLAG_MASK_EXT           (PSW_MASK_EXT    >> 32)
+#define FLAG_MASK_KEY           (PSW_MASK_KEY    >> 32)
+#define FLAG_MASK_MCHECK        (PSW_MASK_MCHECK >> 32)
+#define FLAG_MASK_WAIT          (PSW_MASK_WAIT   >> 32)
+#define FLAG_MASK_PSTATE        (PSW_MASK_PSTATE >> 32)
+#define FLAG_MASK_ASC           (PSW_MASK_ASC    >> 32)
+#define FLAG_MASK_CC            (PSW_MASK_CC     >> 32)
+#define FLAG_MASK_PM            (PSW_MASK_PM     >> 32)
+#define FLAG_MASK_64            (PSW_MASK_64     >> 32)
+#define FLAG_MASK_32            0x00001000
+
 static inline int cpu_mmu_index (CPUState *env)
 {
-    /* XXX: Currently we don't implement virtual memory */
+    if (env->psw.mask & PSW_MASK_PSTATE) {
+        return 1;
+    }
+
     return 0;
 }
 
+static inline void cpu_get_tb_cpu_state(CPUState* env, target_ulong *pc,
+                                        target_ulong *cs_base, int *flags)
+{
+    *pc = env->psw.addr;
+    *cs_base = 0;
+    *flags = ((env->psw.mask >> 32) & ~FLAG_MASK_CC) |
+             ((env->psw.mask & PSW_MASK_32) ? FLAG_MASK_32 : 0);
+}
+
+static inline int get_ilc(uint8_t opc)
+{
+    switch (opc >> 6) {
+    case 0:
+        return 1;
+    case 1:
+    case 2:
+        return 2;
+    case 3:
+        return 3;
+    }
+
+    return 0;
+}
+
+#define ILC_LATER       0x20
+#define ILC_LATER_INC   0x21
+#define ILC_LATER_INC_2 0x22
+
+
 CPUS390XState *cpu_s390x_init(const char *cpu_model);
+void s390x_translate_init(void);
 int cpu_s390x_exec(CPUS390XState *s);
 void cpu_s390x_close(CPUS390XState *s);
+void do_interrupt (CPUState *env);
 
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
@@ -97,173 +283,673 @@ int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw
                               int mmu_idx, int is_softmuu);
 #define cpu_handle_mmu_fault cpu_s390x_handle_mmu_fault
 
-#define TARGET_PAGE_BITS 12
-
-/* ??? This is certainly wrong for 64-bit s390x, but given that only KVM
-   emulation actually works, this is good enough for a placeholder.  */
-#define TARGET_PHYS_ADDR_SPACE_BITS 32
-#define TARGET_VIRT_ADDR_SPACE_BITS 32
 
 #ifndef CONFIG_USER_ONLY
-int s390_virtio_hypercall(CPUState *env);
+int s390_virtio_hypercall(CPUState *env, uint64_t mem, uint64_t hypercall);
+
+void kvm_s390_interrupt(CPUState *env, int type, uint32_t code);
 void kvm_s390_virtio_irq(CPUState *env, int config_change, uint64_t token);
+void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm,
+                                 uint64_t parm64, int vm);
 CPUState *s390_cpu_addr2state(uint16_t cpu_addr);
+
+#ifndef KVM_S390_SIGP_STOP
+#define KVM_S390_SIGP_STOP              0
+#define KVM_S390_PROGRAM_INT            0
+#define KVM_S390_SIGP_SET_PREFIX        0
+#define KVM_S390_RESTART                0
+#define KVM_S390_INT_VIRTIO             0
+#define KVM_S390_INT_SERVICE            0
+#define KVM_S390_INT_EMERGENCY          0
 #endif
 
+#endif
+void cpu_lock(void);
+void cpu_unlock(void);
+
+static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls)
+{
+    env->aregs[0] = newtls >> 32;
+    env->aregs[1] = newtls & 0xffffffffULL;
+}
 
 #define cpu_init cpu_s390x_init
 #define cpu_exec cpu_s390x_exec
 #define cpu_gen_code cpu_s390x_gen_code
+#define cpu_signal_handler cpu_s390x_signal_handler
 
-#include "cpu-all.h"
+#include "exec-all.h"
+
+#ifdef CONFIG_USER_ONLY
 
 #define EXCP_OPEX 1 /* operation exception (sigill) */
 #define EXCP_SVC 2 /* supervisor call (syscall) */
 #define EXCP_ADDR 5 /* addressing exception */
-#define EXCP_EXECUTE_SVC 0xff00000 /* supervisor call via execute insn */
+#define EXCP_SPEC 6 /* specification exception */
 
-static inline void cpu_get_tb_cpu_state(CPUState* env, target_ulong *pc,
-                                        target_ulong *cs_base, int *flags)
+#else
+
+#define EXCP_EXT 1 /* external interrupt */
+#define EXCP_SVC 2 /* supervisor call (syscall) */
+#define EXCP_PGM 3 /* program interruption */
+
+#endif /* CONFIG_USER_ONLY */
+
+#define INTERRUPT_EXT        (1 << 0)
+#define INTERRUPT_TOD        (1 << 1)
+#define INTERRUPT_CPUTIMER   (1 << 2)
+
+/* Program Status Word.  */
+#define S390_PSWM_REGNUM 0
+#define S390_PSWA_REGNUM 1
+/* General Purpose Registers.  */
+#define S390_R0_REGNUM 2
+#define S390_R1_REGNUM 3
+#define S390_R2_REGNUM 4
+#define S390_R3_REGNUM 5
+#define S390_R4_REGNUM 6
+#define S390_R5_REGNUM 7
+#define S390_R6_REGNUM 8
+#define S390_R7_REGNUM 9
+#define S390_R8_REGNUM 10
+#define S390_R9_REGNUM 11
+#define S390_R10_REGNUM 12
+#define S390_R11_REGNUM 13
+#define S390_R12_REGNUM 14
+#define S390_R13_REGNUM 15
+#define S390_R14_REGNUM 16
+#define S390_R15_REGNUM 17
+/* Access Registers.  */
+#define S390_A0_REGNUM 18
+#define S390_A1_REGNUM 19
+#define S390_A2_REGNUM 20
+#define S390_A3_REGNUM 21
+#define S390_A4_REGNUM 22
+#define S390_A5_REGNUM 23
+#define S390_A6_REGNUM 24
+#define S390_A7_REGNUM 25
+#define S390_A8_REGNUM 26
+#define S390_A9_REGNUM 27
+#define S390_A10_REGNUM 28
+#define S390_A11_REGNUM 29
+#define S390_A12_REGNUM 30
+#define S390_A13_REGNUM 31
+#define S390_A14_REGNUM 32
+#define S390_A15_REGNUM 33
+/* Floating Point Control Word.  */
+#define S390_FPC_REGNUM 34
+/* Floating Point Registers.  */
+#define S390_F0_REGNUM 35
+#define S390_F1_REGNUM 36
+#define S390_F2_REGNUM 37
+#define S390_F3_REGNUM 38
+#define S390_F4_REGNUM 39
+#define S390_F5_REGNUM 40
+#define S390_F6_REGNUM 41
+#define S390_F7_REGNUM 42
+#define S390_F8_REGNUM 43
+#define S390_F9_REGNUM 44
+#define S390_F10_REGNUM 45
+#define S390_F11_REGNUM 46
+#define S390_F12_REGNUM 47
+#define S390_F13_REGNUM 48
+#define S390_F14_REGNUM 49
+#define S390_F15_REGNUM 50
+/* Total.  */
+#define S390_NUM_REGS 51
+
+/* Pseudo registers -- PC and condition code.  */
+#define S390_PC_REGNUM S390_NUM_REGS
+#define S390_CC_REGNUM (S390_NUM_REGS+1)
+#define S390_NUM_PSEUDO_REGS 2
+#define S390_NUM_TOTAL_REGS (S390_NUM_REGS+2)
+
+
+
+/* Program Status Word.  */
+#define S390_PSWM_REGNUM 0
+#define S390_PSWA_REGNUM 1
+/* General Purpose Registers.  */
+#define S390_R0_REGNUM 2
+#define S390_R1_REGNUM 3
+#define S390_R2_REGNUM 4
+#define S390_R3_REGNUM 5
+#define S390_R4_REGNUM 6
+#define S390_R5_REGNUM 7
+#define S390_R6_REGNUM 8
+#define S390_R7_REGNUM 9
+#define S390_R8_REGNUM 10
+#define S390_R9_REGNUM 11
+#define S390_R10_REGNUM 12
+#define S390_R11_REGNUM 13
+#define S390_R12_REGNUM 14
+#define S390_R13_REGNUM 15
+#define S390_R14_REGNUM 16
+#define S390_R15_REGNUM 17
+/* Access Registers.  */
+#define S390_A0_REGNUM 18
+#define S390_A1_REGNUM 19
+#define S390_A2_REGNUM 20
+#define S390_A3_REGNUM 21
+#define S390_A4_REGNUM 22
+#define S390_A5_REGNUM 23
+#define S390_A6_REGNUM 24
+#define S390_A7_REGNUM 25
+#define S390_A8_REGNUM 26
+#define S390_A9_REGNUM 27
+#define S390_A10_REGNUM 28
+#define S390_A11_REGNUM 29
+#define S390_A12_REGNUM 30
+#define S390_A13_REGNUM 31
+#define S390_A14_REGNUM 32
+#define S390_A15_REGNUM 33
+/* Floating Point Control Word.  */
+#define S390_FPC_REGNUM 34
+/* Floating Point Registers.  */
+#define S390_F0_REGNUM 35
+#define S390_F1_REGNUM 36
+#define S390_F2_REGNUM 37
+#define S390_F3_REGNUM 38
+#define S390_F4_REGNUM 39
+#define S390_F5_REGNUM 40
+#define S390_F6_REGNUM 41
+#define S390_F7_REGNUM 42
+#define S390_F8_REGNUM 43
+#define S390_F9_REGNUM 44
+#define S390_F10_REGNUM 45
+#define S390_F11_REGNUM 46
+#define S390_F12_REGNUM 47
+#define S390_F13_REGNUM 48
+#define S390_F14_REGNUM 49
+#define S390_F15_REGNUM 50
+/* Total.  */
+#define S390_NUM_REGS 51
+
+/* Pseudo registers -- PC and condition code.  */
+#define S390_PC_REGNUM S390_NUM_REGS
+#define S390_CC_REGNUM (S390_NUM_REGS+1)
+#define S390_NUM_PSEUDO_REGS 2
+#define S390_NUM_TOTAL_REGS (S390_NUM_REGS+2)
+
+/* CC optimization */
+
+enum cc_op {
+    CC_OP_CONST0 = 0,           /* CC is 0 */
+    CC_OP_CONST1,               /* CC is 1 */
+    CC_OP_CONST2,               /* CC is 2 */
+    CC_OP_CONST3,               /* CC is 3 */
+
+    CC_OP_DYNAMIC,              /* CC calculation defined by env->cc_op */
+    CC_OP_STATIC,               /* CC value is env->cc_op */
+
+    CC_OP_NZ,                   /* env->cc_dst != 0 */
+    CC_OP_LTGT_32,              /* signed less/greater than (32bit) */
+    CC_OP_LTGT_64,              /* signed less/greater than (64bit) */
+    CC_OP_LTUGTU_32,            /* unsigned less/greater than (32bit) */
+    CC_OP_LTUGTU_64,            /* unsigned less/greater than (64bit) */
+    CC_OP_LTGT0_32,             /* signed less/greater than 0 (32bit) */
+    CC_OP_LTGT0_64,             /* signed less/greater than 0 (64bit) */
+
+    CC_OP_ADD_64,               /* overflow on add (64bit) */
+    CC_OP_ADDU_64,              /* overflow on unsigned add (64bit) */
+    CC_OP_SUB_64,               /* overflow on substraction (64bit) */
+    CC_OP_SUBU_64,              /* overflow on unsigned substraction (64bit) */
+    CC_OP_ABS_64,               /* sign eval on abs (64bit) */
+    CC_OP_NABS_64,              /* sign eval on nabs (64bit) */
+
+    CC_OP_ADD_32,               /* overflow on add (32bit) */
+    CC_OP_ADDU_32,              /* overflow on unsigned add (32bit) */
+    CC_OP_SUB_32,               /* overflow on substraction (32bit) */
+    CC_OP_SUBU_32,              /* overflow on unsigned substraction (32bit) */
+    CC_OP_ABS_32,               /* sign eval on abs (64bit) */
+    CC_OP_NABS_32,              /* sign eval on nabs (64bit) */
+
+    CC_OP_COMP_32,              /* complement */
+    CC_OP_COMP_64,              /* complement */
+
+    CC_OP_TM_32,                /* test under mask (32bit) */
+    CC_OP_TM_64,                /* test under mask (64bit) */
+
+    CC_OP_LTGT_F32,             /* FP compare (32bit) */
+    CC_OP_LTGT_F64,             /* FP compare (64bit) */
+
+    CC_OP_NZ_F32,               /* FP dst != 0 (32bit) */
+    CC_OP_NZ_F64,               /* FP dst != 0 (64bit) */
+
+    CC_OP_ICM,                  /* insert characters under mask */
+    CC_OP_SLAG,                 /* Calculate shift left signed */
+    CC_OP_MAX
+};
+
+static const char *cc_names[] = {
+    [CC_OP_CONST0]    = "CC_OP_CONST0",
+    [CC_OP_CONST1]    = "CC_OP_CONST1",
+    [CC_OP_CONST2]    = "CC_OP_CONST2",
+    [CC_OP_CONST3]    = "CC_OP_CONST3",
+    [CC_OP_DYNAMIC]   = "CC_OP_DYNAMIC",
+    [CC_OP_STATIC]    = "CC_OP_STATIC",
+    [CC_OP_NZ]        = "CC_OP_NZ",
+    [CC_OP_LTGT_32]   = "CC_OP_LTGT_32",
+    [CC_OP_LTGT_64]   = "CC_OP_LTGT_64",
+    [CC_OP_LTUGTU_32] = "CC_OP_LTUGTU_32",
+    [CC_OP_LTUGTU_64] = "CC_OP_LTUGTU_64",
+    [CC_OP_LTGT0_32]  = "CC_OP_LTGT0_32",
+    [CC_OP_LTGT0_64]  = "CC_OP_LTGT0_64",
+    [CC_OP_ADD_64]    = "CC_OP_ADD_64",
+    [CC_OP_ADDU_64]   = "CC_OP_ADDU_64",
+    [CC_OP_SUB_64]    = "CC_OP_SUB_64",
+    [CC_OP_SUBU_64]   = "CC_OP_SUBU_64",
+    [CC_OP_ABS_64]    = "CC_OP_ABS_64",
+    [CC_OP_NABS_64]   = "CC_OP_NABS_64",
+    [CC_OP_ADD_32]    = "CC_OP_ADD_32",
+    [CC_OP_ADDU_32]   = "CC_OP_ADDU_32",
+    [CC_OP_SUB_32]    = "CC_OP_SUB_32",
+    [CC_OP_SUBU_32]   = "CC_OP_SUBU_32",
+    [CC_OP_ABS_32]    = "CC_OP_ABS_32",
+    [CC_OP_NABS_32]   = "CC_OP_NABS_32",
+    [CC_OP_COMP_32]   = "CC_OP_COMP_32",
+    [CC_OP_COMP_64]   = "CC_OP_COMP_64",
+    [CC_OP_TM_32]     = "CC_OP_TM_32",
+    [CC_OP_TM_64]     = "CC_OP_TM_64",
+    [CC_OP_LTGT_F32]  = "CC_OP_LTGT_F32",
+    [CC_OP_LTGT_F64]  = "CC_OP_LTGT_F64",
+    [CC_OP_NZ_F32]    = "CC_OP_NZ_F32",
+    [CC_OP_NZ_F64]    = "CC_OP_NZ_F64",
+    [CC_OP_ICM]       = "CC_OP_ICM",
+    [CC_OP_SLAG]      = "CC_OP_SLAG",
+};
+
+static inline const char *cc_name(int cc_op)
 {
-    *pc = env->psw.addr;
-    /* XXX this is correct for user-mode emulation, but needs
-     *     the asce register information as well when softmmu
-     *     is implemented in the future */
-    *cs_base = 0;
-    *flags = env->psw.mask;
+    return cc_names[cc_op];
 }
 
-/* Program Status Word.  */
-#define S390_PSWM_REGNUM 0
-#define S390_PSWA_REGNUM 1
-/* General Purpose Registers.  */
-#define S390_R0_REGNUM 2
-#define S390_R1_REGNUM 3
-#define S390_R2_REGNUM 4
-#define S390_R3_REGNUM 5
-#define S390_R4_REGNUM 6
-#define S390_R5_REGNUM 7
-#define S390_R6_REGNUM 8
-#define S390_R7_REGNUM 9
-#define S390_R8_REGNUM 10
-#define S390_R9_REGNUM 11
-#define S390_R10_REGNUM 12
-#define S390_R11_REGNUM 13
-#define S390_R12_REGNUM 14
-#define S390_R13_REGNUM 15
-#define S390_R14_REGNUM 16
-#define S390_R15_REGNUM 17
-/* Access Registers.  */
-#define S390_A0_REGNUM 18
-#define S390_A1_REGNUM 19
-#define S390_A2_REGNUM 20
-#define S390_A3_REGNUM 21
-#define S390_A4_REGNUM 22
-#define S390_A5_REGNUM 23
-#define S390_A6_REGNUM 24
-#define S390_A7_REGNUM 25
-#define S390_A8_REGNUM 26
-#define S390_A9_REGNUM 27
-#define S390_A10_REGNUM 28
-#define S390_A11_REGNUM 29
-#define S390_A12_REGNUM 30
-#define S390_A13_REGNUM 31
-#define S390_A14_REGNUM 32
-#define S390_A15_REGNUM 33
-/* Floating Point Control Word.  */
-#define S390_FPC_REGNUM 34
-/* Floating Point Registers.  */
-#define S390_F0_REGNUM 35
-#define S390_F1_REGNUM 36
-#define S390_F2_REGNUM 37
-#define S390_F3_REGNUM 38
-#define S390_F4_REGNUM 39
-#define S390_F5_REGNUM 40
-#define S390_F6_REGNUM 41
-#define S390_F7_REGNUM 42
-#define S390_F8_REGNUM 43
-#define S390_F9_REGNUM 44
-#define S390_F10_REGNUM 45
-#define S390_F11_REGNUM 46
-#define S390_F12_REGNUM 47
-#define S390_F13_REGNUM 48
-#define S390_F14_REGNUM 49
-#define S390_F15_REGNUM 50
-/* Total.  */
-#define S390_NUM_REGS 51
+/* SCLP PV interface defines */
+#define SCLP_CMDW_READ_SCP_INFO         0x00020001
+#define SCLP_CMDW_READ_SCP_INFO_FORCED  0x00120001
 
-/* Pseudo registers -- PC and condition code.  */
-#define S390_PC_REGNUM S390_NUM_REGS
-#define S390_CC_REGNUM (S390_NUM_REGS+1)
-#define S390_NUM_PSEUDO_REGS 2
-#define S390_NUM_TOTAL_REGS (S390_NUM_REGS+2)
+#define SCP_LENGTH                      0x00
+#define SCP_FUNCTION_CODE               0x02
+#define SCP_CONTROL_MASK                0x03
+#define SCP_RESPONSE_CODE               0x06
+#define SCP_MEM_CODE                    0x08
+#define SCP_INCREMENT                   0x0a
+
+typedef struct LowCore
+{
+    /* prefix area: defined by architecture */
+    uint32_t        ccw1[2];                  /* 0x000 */
+    uint32_t        ccw2[4];                  /* 0x008 */
+    uint8_t         pad1[0x80-0x18];          /* 0x018 */
+    uint32_t        ext_params;               /* 0x080 */
+    uint16_t        cpu_addr;                 /* 0x084 */
+    uint16_t        ext_int_code;             /* 0x086 */
+    uint16_t        svc_ilc;                  /* 0x088 */
+    uint16_t        svc_code;                 /* 0x08a */
+    uint16_t        pgm_ilc;                  /* 0x08c */
+    uint16_t        pgm_code;                 /* 0x08e */
+    uint32_t        data_exc_code;            /* 0x090 */
+    uint16_t        mon_class_num;            /* 0x094 */
+    uint16_t        per_perc_atmid;           /* 0x096 */
+    uint64_t        per_address;              /* 0x098 */
+    uint8_t         exc_access_id;            /* 0x0a0 */
+    uint8_t         per_access_id;            /* 0x0a1 */
+    uint8_t         op_access_id;             /* 0x0a2 */
+    uint8_t         ar_access_id;             /* 0x0a3 */
+    uint8_t         pad2[0xA8-0xA4];          /* 0x0a4 */
+    uint64_t        trans_exc_code;           /* 0x0a8 */
+    uint64_t        monitor_code;             /* 0x0b0 */
+    uint16_t        subchannel_id;            /* 0x0b8 */
+    uint16_t        subchannel_nr;            /* 0x0ba */
+    uint32_t        io_int_parm;              /* 0x0bc */
+    uint32_t        io_int_word;              /* 0x0c0 */
+    uint8_t         pad3[0xc8-0xc4];          /* 0x0c4 */
+    uint32_t        stfl_fac_list;            /* 0x0c8 */
+    uint8_t         pad4[0xe8-0xcc];          /* 0x0cc */
+    uint32_t        mcck_interruption_code[2]; /* 0x0e8 */
+    uint8_t         pad5[0xf4-0xf0];          /* 0x0f0 */
+    uint32_t        external_damage_code;     /* 0x0f4 */
+    uint64_t        failing_storage_address;  /* 0x0f8 */
+    uint8_t         pad6[0x120-0x100];        /* 0x100 */
+    PSW             restart_old_psw;          /* 0x120 */
+    PSW             external_old_psw;         /* 0x130 */
+    PSW             svc_old_psw;              /* 0x140 */
+    PSW             program_old_psw;          /* 0x150 */
+    PSW             mcck_old_psw;             /* 0x160 */
+    PSW             io_old_psw;               /* 0x170 */
+    uint8_t         pad7[0x1a0-0x180];        /* 0x180 */
+    PSW             restart_psw;              /* 0x1a0 */
+    PSW             external_new_psw;         /* 0x1b0 */
+    PSW             svc_new_psw;              /* 0x1c0 */
+    PSW             program_new_psw;          /* 0x1d0 */
+    PSW             mcck_new_psw;             /* 0x1e0 */
+    PSW             io_new_psw;               /* 0x1f0 */
+    PSW             return_psw;               /* 0x200 */
+    uint8_t         irb[64];                  /* 0x210 */
+    uint64_t        sync_enter_timer;         /* 0x250 */
+    uint64_t        async_enter_timer;        /* 0x258 */
+    uint64_t        exit_timer;               /* 0x260 */
+    uint64_t        last_update_timer;        /* 0x268 */
+    uint64_t        user_timer;               /* 0x270 */
+    uint64_t        system_timer;             /* 0x278 */
+    uint64_t        last_update_clock;        /* 0x280 */
+    uint64_t        steal_clock;              /* 0x288 */
+    PSW             return_mcck_psw;          /* 0x290 */
+    uint8_t         pad8[0xc00-0x2a0];        /* 0x2a0 */
+    /* System info area */
+    uint64_t        save_area[16];            /* 0xc00 */
+    uint8_t         pad9[0xd40-0xc80];        /* 0xc80 */
+    uint64_t        kernel_stack;             /* 0xd40 */
+    uint64_t        thread_info;              /* 0xd48 */
+    uint64_t        async_stack;              /* 0xd50 */
+    uint64_t        kernel_asce;              /* 0xd58 */
+    uint64_t        user_asce;                /* 0xd60 */
+    uint64_t        panic_stack;              /* 0xd68 */
+    uint64_t        user_exec_asce;           /* 0xd70 */
+    uint8_t         pad10[0xdc0-0xd78];       /* 0xd78 */
+
+    /* SMP info area: defined by DJB */
+    uint64_t        clock_comparator;         /* 0xdc0 */
+    uint64_t        ext_call_fast;            /* 0xdc8 */
+    uint64_t        percpu_offset;            /* 0xdd0 */
+    uint64_t        current_task;             /* 0xdd8 */
+    uint32_t        softirq_pending;          /* 0xde0 */
+    uint32_t        pad_0x0de4;               /* 0xde4 */
+    uint64_t        int_clock;                /* 0xde8 */
+    uint8_t         pad12[0xe00-0xdf0];       /* 0xdf0 */
+
+    /* 0xe00 is used as indicator for dump tools */
+    /* whether the kernel died with panic() or not */
+    uint32_t        panic_magic;              /* 0xe00 */
+
+    uint8_t         pad13[0x11b8-0xe04];      /* 0xe04 */
+
+    /* 64 bit extparam used for pfault, diag 250 etc  */
+    uint64_t        ext_params2;               /* 0x11B8 */
+
+    uint8_t         pad14[0x1200-0x11C0];      /* 0x11C0 */
+
+    /* System info area */
+
+    uint64_t        floating_pt_save_area[16]; /* 0x1200 */
+    uint64_t        gpregs_save_area[16];      /* 0x1280 */
+    uint32_t        st_status_fixed_logout[4]; /* 0x1300 */
+    uint8_t         pad15[0x1318-0x1310];      /* 0x1310 */
+    uint32_t        prefixreg_save_area;       /* 0x1318 */
+    uint32_t        fpt_creg_save_area;        /* 0x131c */
+    uint8_t         pad16[0x1324-0x1320];      /* 0x1320 */
+    uint32_t        tod_progreg_save_area;     /* 0x1324 */
+    uint32_t        cpu_timer_save_area[2];    /* 0x1328 */
+    uint32_t        clock_comp_save_area[2];   /* 0x1330 */
+    uint8_t         pad17[0x1340-0x1338];      /* 0x1338 */
+    uint32_t        access_regs_save_area[16]; /* 0x1340 */
+    uint64_t        cregs_save_area[16];       /* 0x1380 */
+
+    /* align to the top of the prefix area */
+
+    uint8_t         pad18[0x2000-0x1400];      /* 0x1400 */
+} __attribute__((packed)) LowCore;
+
+/* STSI */
+#define STSI_LEVEL_MASK         0x00000000f0000000ULL
+#define STSI_LEVEL_CURRENT      0x0000000000000000ULL
+#define STSI_LEVEL_1            0x0000000010000000ULL
+#define STSI_LEVEL_2            0x0000000020000000ULL
+#define STSI_LEVEL_3            0x0000000030000000ULL
+#define STSI_R0_RESERVED_MASK   0x000000000fffff00ULL
+#define STSI_R0_SEL1_MASK       0x00000000000000ffULL
+#define STSI_R1_RESERVED_MASK   0x00000000ffff0000ULL
+#define STSI_R1_SEL2_MASK       0x000000000000ffffULL
+
+/* Basic Machine Configuration */
+struct sysib_111 {
+    uint32_t res1[8];
+    uint8_t  manuf[16];
+    uint8_t  type[4];
+    uint8_t  res2[12];
+    uint8_t  model[16];
+    uint8_t  sequence[16];
+    uint8_t  plant[4];
+    uint8_t  res3[156];
+};
+
+/* Basic Machine CPU */
+struct sysib_121 {
+    uint32_t res1[80];
+    uint8_t  sequence[16];
+    uint8_t  plant[4];
+    uint8_t  res2[2];
+    uint16_t cpu_addr;
+    uint8_t  res3[152];
+};
+
+/* Basic Machine CPUs */
+struct sysib_122 {
+    uint8_t res1[32];
+    uint32_t capability;
+    uint16_t total_cpus;
+    uint16_t active_cpus;
+    uint16_t standby_cpus;
+    uint16_t reserved_cpus;
+    uint16_t adjustments[2026];
+};
+
+/* LPAR CPU */
+struct sysib_221 {
+    uint32_t res1[80];
+    uint8_t  sequence[16];
+    uint8_t  plant[4];
+    uint16_t cpu_id;
+    uint16_t cpu_addr;
+    uint8_t  res3[152];
+};
+
+/* LPAR CPUs */
+struct sysib_222 {
+    uint32_t res1[32];
+    uint16_t lpar_num;
+    uint8_t  res2;
+    uint8_t  lcpuc;
+    uint16_t total_cpus;
+    uint16_t conf_cpus;
+    uint16_t standby_cpus;
+    uint16_t reserved_cpus;
+    uint8_t  name[8];
+    uint32_t caf;
+    uint8_t  res3[16];
+    uint16_t dedicated_cpus;
+    uint16_t shared_cpus;
+    uint8_t  res4[180];
+};
+
+/* VM CPUs */
+struct sysib_322 {
+    uint8_t  res1[31];
+    uint8_t  count;
+    struct {
+        uint8_t  res2[4];
+        uint16_t total_cpus;
+        uint16_t conf_cpus;
+        uint16_t standby_cpus;
+        uint16_t reserved_cpus;
+        uint8_t  name[8];
+        uint32_t caf;
+        uint8_t  cpi[16];
+        uint8_t  res3[24];
+    } vm[8];
+    uint8_t res4[3552];
+};
+
+/* MMU defines */
+#define _ASCE_ORIGIN            ~0xfffULL /* segment table origin             */
+#define _ASCE_SUBSPACE          0x200     /* subspace group control           */
+#define _ASCE_PRIVATE_SPACE     0x100     /* private space control            */
+#define _ASCE_ALT_EVENT         0x80      /* storage alteration event control */
+#define _ASCE_SPACE_SWITCH      0x40      /* space switch event               */
+#define _ASCE_REAL_SPACE        0x20      /* real space control               */
+#define _ASCE_TYPE_MASK         0x0c      /* asce table type mask             */
+#define _ASCE_TYPE_REGION1      0x0c      /* region first table type          */
+#define _ASCE_TYPE_REGION2      0x08      /* region second table type         */
+#define _ASCE_TYPE_REGION3      0x04      /* region third table type          */
+#define _ASCE_TYPE_SEGMENT      0x00      /* segment table type               */
+#define _ASCE_TABLE_LENGTH      0x03      /* region table length              */
+
+#define _REGION_ENTRY_ORIGIN    ~0xfffULL /* region/segment table origin      */
+#define _REGION_ENTRY_INV       0x20      /* invalid region table entry       */
+#define _REGION_ENTRY_TYPE_MASK 0x0c      /* region/segment table type mask   */
+#define _REGION_ENTRY_TYPE_R1   0x0c      /* region first table type          */
+#define _REGION_ENTRY_TYPE_R2   0x08      /* region second table type         */
+#define _REGION_ENTRY_TYPE_R3   0x04      /* region third table type          */
+#define _REGION_ENTRY_LENGTH    0x03      /* region third length              */
+
+#define _SEGMENT_ENTRY_ORIGIN   ~0x7ffULL /* segment table origin             */
+#define _SEGMENT_ENTRY_RO       0x200     /* page protection bit              */
+#define _SEGMENT_ENTRY_INV      0x20      /* invalid segment table entry      */
+
+#define _PAGE_RO        0x200            /* HW read-only bit  */
+#define _PAGE_INVALID   0x400            /* HW invalid bit    */
 
 
 
-/* Program Status Word.  */
-#define S390_PSWM_REGNUM 0
-#define S390_PSWA_REGNUM 1
-/* General Purpose Registers.  */
-#define S390_R0_REGNUM 2
-#define S390_R1_REGNUM 3
-#define S390_R2_REGNUM 4
-#define S390_R3_REGNUM 5
-#define S390_R4_REGNUM 6
-#define S390_R5_REGNUM 7
-#define S390_R6_REGNUM 8
-#define S390_R7_REGNUM 9
-#define S390_R8_REGNUM 10
-#define S390_R9_REGNUM 11
-#define S390_R10_REGNUM 12
-#define S390_R11_REGNUM 13
-#define S390_R12_REGNUM 14
-#define S390_R13_REGNUM 15
-#define S390_R14_REGNUM 16
-#define S390_R15_REGNUM 17
-/* Access Registers.  */
-#define S390_A0_REGNUM 18
-#define S390_A1_REGNUM 19
-#define S390_A2_REGNUM 20
-#define S390_A3_REGNUM 21
-#define S390_A4_REGNUM 22
-#define S390_A5_REGNUM 23
-#define S390_A6_REGNUM 24
-#define S390_A7_REGNUM 25
-#define S390_A8_REGNUM 26
-#define S390_A9_REGNUM 27
-#define S390_A10_REGNUM 28
-#define S390_A11_REGNUM 29
-#define S390_A12_REGNUM 30
-#define S390_A13_REGNUM 31
-#define S390_A14_REGNUM 32
-#define S390_A15_REGNUM 33
-/* Floating Point Control Word.  */
-#define S390_FPC_REGNUM 34
-/* Floating Point Registers.  */
-#define S390_F0_REGNUM 35
-#define S390_F1_REGNUM 36
-#define S390_F2_REGNUM 37
-#define S390_F3_REGNUM 38
-#define S390_F4_REGNUM 39
-#define S390_F5_REGNUM 40
-#define S390_F6_REGNUM 41
-#define S390_F7_REGNUM 42
-#define S390_F8_REGNUM 43
-#define S390_F9_REGNUM 44
-#define S390_F10_REGNUM 45
-#define S390_F11_REGNUM 46
-#define S390_F12_REGNUM 47
-#define S390_F13_REGNUM 48
-#define S390_F14_REGNUM 49
-#define S390_F15_REGNUM 50
-/* Total.  */
-#define S390_NUM_REGS 51
+/* EBCDIC handling */
+static const uint8_t ebcdic2ascii[] = {
+    0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
+    0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+    0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
+    0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+    0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
+    0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
+    0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
+    0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
+    0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
+    0x87, 0xA4, 0x5B, 0x2E, 0x3C, 0x28, 0x2B, 0x21,
+    0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
+    0x8D, 0xE1, 0x5D, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
+    0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
+    0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
+    0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+    0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
+    0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+    0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
+    0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
+    0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
+    0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+    0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
+    0x9B, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
+    0xAB, 0x07, 0xAA, 0x7C, 0x07, 0x07, 0x07, 0x07,
+    0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+    0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
+    0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
+    0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
+    0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+    0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+    0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07,
+};
 
-/* Pseudo registers -- PC and condition code.  */
-#define S390_PC_REGNUM S390_NUM_REGS
-#define S390_CC_REGNUM (S390_NUM_REGS+1)
-#define S390_NUM_PSEUDO_REGS 2
-#define S390_NUM_TOTAL_REGS (S390_NUM_REGS+2)
+static const uint8_t ascii2ebcdic [] = {
+    0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
+    0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+    0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
+    0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F,
+    0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
+    0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
+    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+    0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
+    0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+    0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
+    0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
+    0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D,
+    0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+    0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+    0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
+    0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+    0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF
+};
 
+static inline void ebcdic_put(uint8_t *p, const char *ascii, int len)
+{
+    int i;
+
+    for (i = 0; i < len; i++) {
+        p[i] = ascii2ebcdic[(int)ascii[i]];
+    }
+}
+
+#define SIGP_SENSE             0x01
+#define SIGP_EXTERNAL_CALL     0x02
+#define SIGP_EMERGENCY         0x03
+#define SIGP_START             0x04
+#define SIGP_STOP              0x05
+#define SIGP_RESTART           0x06
+#define SIGP_STOP_STORE_STATUS 0x09
+#define SIGP_INITIAL_CPU_RESET 0x0b
+#define SIGP_CPU_RESET         0x0c
+#define SIGP_SET_PREFIX        0x0d
+#define SIGP_STORE_STATUS_ADDR 0x0e
+#define SIGP_SET_ARCH          0x12
+
+/* cpu status bits */
+#define SIGP_STAT_EQUIPMENT_CHECK   0x80000000UL
+#define SIGP_STAT_INCORRECT_STATE   0x00000200UL
+#define SIGP_STAT_INVALID_PARAMETER 0x00000100UL
+#define SIGP_STAT_EXT_CALL_PENDING  0x00000080UL
+#define SIGP_STAT_STOPPED           0x00000040UL
+#define SIGP_STAT_OPERATOR_INTERV   0x00000020UL
+#define SIGP_STAT_CHECK_STOP        0x00000010UL
+#define SIGP_STAT_INOPERATIVE       0x00000004UL
+#define SIGP_STAT_INVALID_ORDER     0x00000002UL
+#define SIGP_STAT_RECEIVER_CHECK    0x00000001UL
+
+void load_psw(CPUState *env, uint64_t mask, uint64_t addr);
+int mmu_translate(CPUState *env, target_ulong vaddr, int rw, uint64_t asc,
+                  target_ulong *raddr, int *flags);
+int sclp_service_call(CPUState *env, uint32_t sccb, uint64_t code);
+uint32_t calc_cc(CPUState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
+                 uint64_t vr);
+
+#define TARGET_HAS_ICE 1
+
+/* The value of the TOD clock for 1.1.1970. */
+#define TOD_UNIX_EPOCH 0x7d91048bca000000ULL
+
+/* Converts ns to s390's clock format */
+static inline uint64_t time2tod(uint64_t ns) {
+    return (ns << 9) / 125;
+}
+
+static inline void cpu_inject_ext(CPUState *env, uint32_t code, uint32_t param,
+                                  uint64_t param64)
+{
+    if (env->ext_index == MAX_EXT_QUEUE - 1) {
+        /* ugh - can't queue anymore. Let's drop. */
+        return;
+    }
+
+    env->ext_index++;
+    assert(env->ext_index < MAX_EXT_QUEUE);
+
+    env->ext_queue[env->ext_index].code = code;
+    env->ext_queue[env->ext_index].param = param;
+    env->ext_queue[env->ext_index].param64 = param64;
+
+    env->pending_int |= INTERRUPT_EXT;
+    cpu_interrupt(env, CPU_INTERRUPT_HARD);
+}
 
 #endif
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index ae7dc561b3..2643460722 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -182,8 +182,8 @@ int kvm_arch_process_async_events(CPUState *env)
     return 0;
 }
 
-static void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm,
-                                        uint64_t parm64, int vm)
+void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm,
+                                 uint64_t parm64, int vm)
 {
     struct kvm_s390_interrupt kvmint;
     int r;
@@ -218,7 +218,7 @@ void kvm_s390_virtio_irq(CPUState *env, int config_change, uint64_t token)
                                 token, 1);
 }
 
-static void kvm_s390_interrupt(CPUState *env, int type, uint32_t code)
+void kvm_s390_interrupt(CPUState *env, int type, uint32_t code)
 {
     kvm_s390_interrupt_internal(env, type, code, 0, 0);
 }
@@ -237,7 +237,8 @@ static void setcc(CPUState *env, uint64_t cc)
     env->psw.mask |= (cc & 3) << 44;
 }
 
-static int sclp_service_call(CPUState *env, struct kvm_run *run, uint16_t ipbh0)
+static int kvm_sclp_service_call(CPUState *env, struct kvm_run *run,
+                                 uint16_t ipbh0)
 {
     uint32_t sccb;
     uint64_t code;
@@ -287,7 +288,7 @@ static int handle_priv(CPUState *env, struct kvm_run *run, uint8_t ipa1)
     dprintf("KVM: PRIV: %d\n", ipa1);
     switch (ipa1) {
         case PRIV_SCLP_CALL:
-            r = sclp_service_call(env, run, ipbh0);
+            r = kvm_sclp_service_call(env, run, ipbh0);
             break;
         default:
             dprintf("KVM: unknown PRIV: 0x%x\n", ipa1);
@@ -300,12 +301,10 @@ static int handle_priv(CPUState *env, struct kvm_run *run, uint8_t ipa1)
 
 static int handle_hypercall(CPUState *env, struct kvm_run *run)
 {
-    int r;
-
     cpu_synchronize_state(env);
-    r = s390_virtio_hypercall(env);
+    env->regs[2] = s390_virtio_hypercall(env, env->regs[2], env->regs[1]);
 
-    return r;
+    return 0;
 }
 
 static int handle_diag(CPUState *env, struct kvm_run *run, int ipb_code)
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index d33bfb1f31..2cb893f219 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -36,7 +36,7 @@ void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
         }
     }
     for (i = 0; i < 16; i++) {
-        cpu_fprintf(f, "F%02d=%016lx", i, (long)env->fregs[i].i);
+        cpu_fprintf(f, "F%02d=%016" PRIx64, i, *(uint64_t *)&env->fregs[i]);
         if ((i % 4) == 3) {
             cpu_fprintf(f, "\n");
         } else {

From 3110e2925489c571901e945e315942ce84fe696f Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Fri, 15 Apr 2011 17:32:48 +0200
Subject: [PATCH 233/386] s390x: Enable s390x-softmmu target

This patch adds some code paths for running s390x guest OSs without the
need for KVM.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 cpu-exec.c            |  8 ++++++++
 target-s390x/exec.h   | 11 ++++++++++-
 target-s390x/helper.c |  4 ++++
 3 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 5d6c9a8a1c..d57afef642 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -346,6 +346,8 @@ int cpu_exec(CPUState *env1)
                     do_interrupt(env);
 #elif defined(TARGET_M68K)
                     do_interrupt(0);
+#elif defined(TARGET_S390X)
+                    do_interrupt(env);
 #endif
                     env->exception_index = -1;
 #endif
@@ -560,6 +562,12 @@ int cpu_exec(CPUState *env1)
                         do_interrupt(1);
                         next_tb = 0;
                     }
+#elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY)
+                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
+                        (env->psw.mask & PSW_MASK_EXT)) {
+                        do_interrupt(env);
+                        next_tb = 0;
+                    }
 #endif
                    /* Don't use the cached interupt_request value,
                       do_interrupt may have updated the EXITTB flag. */
diff --git a/target-s390x/exec.h b/target-s390x/exec.h
index f7893f3877..7a87fffca6 100644
--- a/target-s390x/exec.h
+++ b/target-s390x/exec.h
@@ -31,7 +31,16 @@ register struct CPUS390XState *env asm(AREG0);
 
 static inline int cpu_has_work(CPUState *env)
 {
-    return env->interrupt_request & CPU_INTERRUPT_HARD; // guess
+    return ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
+            (env->psw.mask & PSW_MASK_EXT));
+}
+
+static inline void regs_to_env(void)
+{
+}
+
+static inline void env_to_regs(void)
+{
 }
 
 static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock* tb)
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 4a5297be18..629dfd9708 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -82,3 +82,7 @@ int cpu_s390x_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
     return 0;
 }
 #endif /* CONFIG_USER_ONLY */
+
+void do_interrupt (CPUState *env)
+{
+}

From 8103b4d161d7c00ea3ff89ffe66bb2bc2c67de5d Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Fri, 15 Apr 2011 17:32:49 +0200
Subject: [PATCH 234/386] s390x: Dispatch interrupts to KVM or the real CPU

The KVM interrupt injection path is non-generic for now. So we need to push
knowledge of how to inject a device interrupt using KVM into the actual device
code.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/s390-virtio-bus.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index 175e5cb3a0..bb49e393ec 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -43,6 +43,8 @@
     do { } while (0)
 #endif
 
+#define VIRTIO_EXT_CODE   0x2603
+
 struct BusInfo s390_virtio_bus_info = {
     .name       = "s390-virtio",
     .size       = sizeof(VirtIOS390Bus),
@@ -305,9 +307,13 @@ static void virtio_s390_notify(void *opaque, uint16_t vector)
 {
     VirtIOS390Device *dev = (VirtIOS390Device*)opaque;
     uint64_t token = s390_virtio_device_vq_token(dev, vector);
+    CPUState *env = s390_cpu_addr2state(0);
 
-    /* XXX kvm dependency! */
-    kvm_s390_virtio_irq(s390_cpu_addr2state(0), 0, token);
+    if (kvm_enabled()) {
+        kvm_s390_virtio_irq(env, 0, token);
+    } else {
+        cpu_inject_ext(env, VIRTIO_EXT_CODE, 0, token);
+    }
 }
 
 static unsigned virtio_s390_get_features(void *opaque)

From 8d5192ee15bc519f83741f5e413ebba5d57a6abd Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Fri, 15 Apr 2011 17:32:50 +0200
Subject: [PATCH 235/386] s390x: virtio machine storage keys

For emulation (and migration) we need to know about the guest's storage keys.
These are separate from actual RAM contents, so we need to allocate them in
parallel to RAM.

While touching the file, this patch also adjusts the hypercall function
to a new syntax that aligns better with tcg emulated code.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/s390-virtio.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 48fb0d05c2..698ff6f345 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -82,13 +82,12 @@ CPUState *s390_cpu_addr2state(uint16_t cpu_addr)
     return ipi_states[cpu_addr];
 }
 
-int s390_virtio_hypercall(CPUState *env, uint64_t mem_, uint64_t hypercall)
+int s390_virtio_hypercall(CPUState *env, uint64_t mem, uint64_t hypercall)
 {
     int r = 0, i;
-    target_ulong mem = env->regs[2];
 
-    dprintf("KVM hypercall: %ld\n", env->regs[1]);
-    switch (env->regs[1]) {
+    dprintf("KVM hypercall: %ld\n", hypercall);
+    switch (hypercall) {
     case KVM_S390_VIRTIO_NOTIFY:
         if (mem > ram_size) {
             VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus,
@@ -128,8 +127,7 @@ int s390_virtio_hypercall(CPUState *env, uint64_t mem_, uint64_t hypercall)
         break;
     }
 
-    env->regs[2] = r;
-    return 0;
+    return r;
 }
 
 /* PC hardware initialisation */
@@ -145,14 +143,9 @@ static void s390_init(ram_addr_t ram_size,
     ram_addr_t kernel_size = 0;
     ram_addr_t initrd_offset;
     ram_addr_t initrd_size = 0;
+    uint8_t *storage_keys;
     int i;
 
-    /* XXX we only work on KVM for now */
-
-    if (!kvm_enabled()) {
-        fprintf(stderr, "The S390 target only works with KVM enabled\n");
-        exit(1);
-    }
 
     /* get a BUS */
     s390_bus = s390_virtio_bus_init(&ram_size);
@@ -161,6 +154,9 @@ static void s390_init(ram_addr_t ram_size,
     ram_addr = qemu_ram_alloc(NULL, "s390.ram", ram_size);
     cpu_register_physical_memory(0, ram_size, ram_addr);
 
+    /* allocate storage keys */
+    storage_keys = qemu_mallocz(ram_size / TARGET_PAGE_SIZE);
+
     /* init CPUs */
     if (cpu_model == NULL) {
         cpu_model = "host";
@@ -178,6 +174,7 @@ static void s390_init(ram_addr_t ram_size,
         ipi_states[i] = tmp_env;
         tmp_env->halted = 1;
         tmp_env->exception_index = EXCP_HLT;
+        tmp_env->storage_keys = storage_keys;
     }
 
     env->halted = 0;

From e87b7cb0f0e04d7c4510564530ab00ed4db37a45 Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Mon, 18 Apr 2011 06:39:52 +0000
Subject: [PATCH 236/386] Remove unused function parameters from gen_pc_load
 and rename the function

Function gen_pc_load was introduced in commit
d2856f1ad4c259e5766847c49acbb4e390731bd4.
The only reason for parameter searched_pc was
a debug statement in target-i386/translate.c.

Parameter puc was needed by target-sparc until
commit d7da2a10402f1644128b66414ca8f86bdea9ae7c.

Remove searched_pc from the debug statement and remove both
parameters from the parameter list of gen_pc_load.

As the function name gen_pc_load was also misleading,
it is now called restore_state_to_opc. This new name
was suggested by Peter Maydell, thanks.

v2: Remove last parameter, too, and rename the function.

v3: Fix [] typo in target-arm/translate.c.
    Fix wrong SHA1 object name in commit message (copy+paste error).

Cc: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 exec-all.h                    | 4 ++--
 target-alpha/translate.c      | 3 +--
 target-arm/translate.c        | 7 +++----
 target-cris/translate.c       | 3 +--
 target-i386/translate.c       | 7 +++----
 target-lm32/translate.c       | 3 +--
 target-m68k/translate.c       | 3 +--
 target-microblaze/translate.c | 3 +--
 target-mips/translate.c       | 3 +--
 target-ppc/translate.c        | 3 +--
 target-s390x/translate.c      | 3 +--
 target-sh4/translate.c        | 3 +--
 target-sparc/translate.c      | 3 +--
 target-unicore32/translate.c  | 3 +--
 translate-all.c               | 2 +-
 15 files changed, 20 insertions(+), 33 deletions(-)

diff --git a/exec-all.h b/exec-all.h
index 496c001c03..29fd322347 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -77,8 +77,8 @@ extern uint16_t gen_opc_icount[OPC_BUF_SIZE];
 
 void gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
 void gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb);
-void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
-                 unsigned long searched_pc, int pc_pos, void *puc);
+void restore_state_to_opc(CPUState *env, struct TranslationBlock *tb,
+                          int pc_pos);
 
 void cpu_gen_init(void);
 int cpu_gen_code(CPUState *env, struct TranslationBlock *tb,
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 96e922b569..456ba51ac6 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3367,8 +3367,7 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model)
     return env;
 }
 
-void gen_pc_load(CPUState *env, TranslationBlock *tb,
-                unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 {
     env->pc = gen_opc_pc[pc_pos];
 }
diff --git a/target-arm/translate.c b/target-arm/translate.c
index fc9ff8d9e8..e1bda57e81 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -9551,8 +9551,8 @@ static inline void gen_intermediate_code_internal(CPUState *env,
      * This is handled in the same way as restoration of the
      * PC in these situations: we will be called again with search_pc=1
      * and generate a mapping of the condexec bits for each PC in
-     * gen_opc_condexec_bits[]. gen_pc_load[] then uses this to restore
-     * the condexec bits.
+     * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
+     * this to restore the condexec bits.
      *
      * Note that there are no instructions which can read the condexec
      * bits, and none which can write non-static values to them, so
@@ -9817,8 +9817,7 @@ void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
 #endif
 }
 
-void gen_pc_load(CPUState *env, TranslationBlock *tb,
-                unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 {
     env->regs[15] = gen_opc_pc[pc_pos];
     env->condexec_bits = gen_opc_condexec_bits[pc_pos];
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 1c03fa5fb6..e2607d64c0 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3604,8 +3604,7 @@ void cpu_reset (CPUCRISState *env)
 #endif
 }
 
-void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
-                 unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 {
 	env->pc = gen_opc_pc[pc_pos];
 }
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 7d1340ed01..199302e517 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -7890,8 +7890,7 @@ void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void gen_pc_load(CPUState *env, TranslationBlock *tb,
-                unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 {
     int cc_op;
 #ifdef DEBUG_DISAS
@@ -7903,8 +7902,8 @@ void gen_pc_load(CPUState *env, TranslationBlock *tb,
                 qemu_log("0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
             }
         }
-        qemu_log("spc=0x%08lx pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
-                searched_pc, pc_pos, gen_opc_pc[pc_pos] - tb->cs_base,
+        qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
+                pc_pos, gen_opc_pc[pc_pos] - tb->cs_base,
                 (uint32_t)tb->cs_base);
     }
 #endif
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index efc9b5a856..51b4f5a814 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1212,8 +1212,7 @@ void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
     cpu_fprintf(f, "\n\n");
 }
 
-void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
-                 unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 {
     env->pc = gen_opc_pc[pc_pos];
 }
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 038c0af3ef..9e5578d455 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -3113,8 +3113,7 @@ void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
     cpu_fprintf (f, "FPRESULT = %12g\n", *(double *)&env->fp_result);
 }
 
-void gen_pc_load(CPUState *env, TranslationBlock *tb,
-                unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 {
     env->pc = gen_opc_pc[pc_pos];
 }
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index bff3a11bc8..b47b92e909 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1940,8 +1940,7 @@ void cpu_reset (CPUState *env)
 #endif
 }
 
-void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
-                 unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 {
     env->sregs[SR_PC] = gen_opc_pc[pc_pos];
 }
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 953c528068..4eaa8261c3 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -12737,8 +12737,7 @@ void cpu_reset (CPUMIPSState *env)
     env->exception_index = EXCP_NONE;
 }
 
-void gen_pc_load(CPUState *env, TranslationBlock *tb,
-                unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 {
     env->active_tc.PC = gen_opc_pc[pc_pos];
     env->hflags &= ~MIPS_HFLAG_BMASK;
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 3c3ee24c95..a943dbcf8e 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9367,8 +9367,7 @@ void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void gen_pc_load(CPUState *env, TranslationBlock *tb,
-                unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 {
     env->nip = gen_opc_pc[pc_pos];
 }
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 2cb893f219..4d45e32616 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -54,8 +54,7 @@ void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
 {
 }
 
-void gen_pc_load(CPUState *env, TranslationBlock *tb,
-                unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 {
     env->psw.addr = gen_opc_pc[pc_pos];
 }
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 88098d7c23..93c863650d 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -2069,8 +2069,7 @@ void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void gen_pc_load(CPUState *env, TranslationBlock *tb,
-                unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 {
     env->pc = gen_opc_pc[pc_pos];
     env->flags = gen_opc_hflags[pc_pos];
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 883ecd2d2f..3c958b26d6 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5080,8 +5080,7 @@ void gen_intermediate_code_init(CPUSPARCState *env)
     }
 }
 
-void gen_pc_load(CPUState *env, TranslationBlock *tb,
-                unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 {
     target_ulong npc;
     env->pc = gen_opc_pc[pc_pos];
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index a6ba991e92..98eaeb3d43 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -2098,8 +2098,7 @@ void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
 #endif
 }
 
-void gen_pc_load(CPUState *env, TranslationBlock *tb,
-        unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
 {
     env->regs[31] = gen_opc_pc[pc_pos];
 }
diff --git a/translate-all.c b/translate-all.c
index efcfb9adcd..97668b2c8e 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -157,7 +157,7 @@ int cpu_restore_state(TranslationBlock *tb,
         j--;
     env->icount_decr.u16.low -= gen_opc_icount[j];
 
-    gen_pc_load(env, tb, searched_pc, j, puc);
+    restore_state_to_opc(env, tb, j);
 
 #ifdef CONFIG_PROFILER
     s->restore_time += profile_getclock() - ti;

From 618ba8e6a1313df6a8366ac8ffee47e3f885ac90 Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Mon, 18 Apr 2011 06:39:53 +0000
Subject: [PATCH 237/386] Remove unused function parameter from
 cpu_restore_state

The previous patch removed the need for parameter puc.
Is is now unused, so remove it.

Cc: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 cpu-exec.c                    | 2 +-
 exec-all.h                    | 3 +--
 exec.c                        | 9 ++++-----
 target-alpha/op_helper.c      | 2 +-
 target-arm/op_helper.c        | 2 +-
 target-cris/op_helper.c       | 2 +-
 target-i386/op_helper.c       | 2 +-
 target-lm32/op_helper.c       | 2 +-
 target-m68k/op_helper.c       | 2 +-
 target-microblaze/op_helper.c | 2 +-
 target-mips/op_helper.c       | 4 ++--
 target-ppc/op_helper.c        | 2 +-
 target-s390x/op_helper.c      | 2 +-
 target-sh4/op_helper.c        | 2 +-
 target-sparc/op_helper.c      | 2 +-
 translate-all.c               | 3 +--
 16 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index d57afef642..395cd8cf90 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -808,7 +808,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
     if (tb) {
         /* the PC is inside the translated code. It means that we have
            a virtual CPU fault */
-        cpu_restore_state(tb, env, pc, puc);
+        cpu_restore_state(tb, env, pc);
     }
 
     /* we restore the process signal mask as the sigreturn should
diff --git a/exec-all.h b/exec-all.h
index 29fd322347..7c2d29ff98 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -84,8 +84,7 @@ void cpu_gen_init(void);
 int cpu_gen_code(CPUState *env, struct TranslationBlock *tb,
                  int *gen_code_size_ptr);
 int cpu_restore_state(struct TranslationBlock *tb,
-                      CPUState *env, unsigned long searched_pc,
-                      void *puc);
+                      CPUState *env, unsigned long searched_pc);
 void cpu_resume_from_signal(CPUState *env1, void *puc);
 void cpu_io_recompile(CPUState *env, void *retaddr);
 TranslationBlock *tb_gen_code(CPUState *env, 
diff --git a/exec.c b/exec.c
index b1ee52a4d0..c3dc68ae09 100644
--- a/exec.c
+++ b/exec.c
@@ -1070,8 +1070,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
                 restore the CPU state */
 
                 current_tb_modified = 1;
-                cpu_restore_state(current_tb, env,
-                                  env->mem_io_pc, NULL);
+                cpu_restore_state(current_tb, env, env->mem_io_pc);
                 cpu_get_tb_cpu_state(env, &current_pc, &current_cs_base,
                                      &current_flags);
             }
@@ -1179,7 +1178,7 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr,
                    restore the CPU state */
 
             current_tb_modified = 1;
-            cpu_restore_state(current_tb, env, pc, puc);
+            cpu_restore_state(current_tb, env, pc);
             cpu_get_tb_cpu_state(env, &current_pc, &current_cs_base,
                                  &current_flags);
         }
@@ -3266,7 +3265,7 @@ static void check_watchpoint(int offset, int len_mask, int flags)
                     cpu_abort(env, "check_watchpoint: could not find TB for "
                               "pc=%p", (void *)env->mem_io_pc);
                 }
-                cpu_restore_state(tb, env, env->mem_io_pc, NULL);
+                cpu_restore_state(tb, env, env->mem_io_pc);
                 tb_phys_invalidate(tb, -1);
                 if (wp->flags & BP_STOP_BEFORE_ACCESS) {
                     env->exception_index = EXCP_DEBUG;
@@ -4301,7 +4300,7 @@ void cpu_io_recompile(CPUState *env, void *retaddr)
                   retaddr);
     }
     n = env->icount_decr.u16.low + tb->icount;
-    cpu_restore_state(tb, env, (unsigned long)retaddr, NULL);
+    cpu_restore_state(tb, env, (unsigned long)retaddr);
     /* Calculate how many instructions had been executed before the fault
        occurred.  */
     n = n - env->icount_decr.u16.low;
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 9f71db4c3a..4ccb10b0f4 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -1374,7 +1374,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
             if (likely(tb)) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc, NULL);
+                cpu_restore_state(tb, env, pc);
             }
         }
         /* Exception index and error code are already set */
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index ee7286b77a..8334fbcf6d 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -90,7 +90,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
             if (tb) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc, NULL);
+                cpu_restore_state(tb, env, pc);
             }
         }
         raise_exception(env->exception_index);
diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c
index be9eb06fd0..34329e2a60 100644
--- a/target-cris/op_helper.c
+++ b/target-cris/op_helper.c
@@ -77,7 +77,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
             if (tb) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc, NULL);
+                cpu_restore_state(tb, env, pc);
 
 		/* Evaluate flags after retranslation.  */
                 helper_top_evaluate_flags();
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index a73427fe45..fba536f0fb 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4835,7 +4835,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
             if (tb) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc, NULL);
+                cpu_restore_state(tb, env, pc);
             }
         }
         raise_exception_err(env->exception_index, env->error_code);
diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c
index e84ba488be..c72b1df47b 100644
--- a/target-lm32/op_helper.c
+++ b/target-lm32/op_helper.c
@@ -95,7 +95,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
             if (tb) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc, NULL);
+                cpu_restore_state(tb, env, pc);
             }
         }
         cpu_loop_exit();
diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
index 07111073f8..9b13bdbcc2 100644
--- a/target-m68k/op_helper.c
+++ b/target-m68k/op_helper.c
@@ -68,7 +68,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
             if (tb) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc, NULL);
+                cpu_restore_state(tb, env, pc);
             }
         }
         cpu_loop_exit();
diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
index b7cd6b288f..c7b2f97d96 100644
--- a/target-microblaze/op_helper.c
+++ b/target-microblaze/op_helper.c
@@ -60,7 +60,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
             if (tb) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc, NULL);
+                cpu_restore_state(tb, env, pc);
             }
         }
         cpu_loop_exit();
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 8cba535a32..b8e4991f32 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -54,7 +54,7 @@ static void do_restore_state (void *pc_ptr)
     
     tb = tb_find_pc (pc);
     if (tb) {
-        cpu_restore_state (tb, env, pc, NULL);
+        cpu_restore_state(tb, env, pc);
     }
 }
 #endif
@@ -1972,7 +1972,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
             if (tb) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc, NULL);
+                cpu_restore_state(tb, env, pc);
             }
         }
         helper_raise_exception_err(env->exception_index, env->error_code);
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 28d40ac9aa..d5db484b4a 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -3741,7 +3741,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
             if (likely(tb)) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc, NULL);
+                cpu_restore_state(tb, env, pc);
             }
         }
         helper_raise_exception_err(env->exception_index, env->error_code);
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
index 402df2d85e..be455b9de2 100644
--- a/target-s390x/op_helper.c
+++ b/target-s390x/op_helper.c
@@ -61,7 +61,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
             if (likely(tb)) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc, NULL);
+                cpu_restore_state(tb, env, pc);
             }
         }
         /* XXX */
diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
index c127860cd9..b909d18bc4 100644
--- a/target-sh4/op_helper.c
+++ b/target-sh4/op_helper.c
@@ -32,7 +32,7 @@ static void cpu_restore_state_from_retaddr(void *retaddr)
         if (tb) {
             /* the PC is inside the translated code. It means that we have
                a virtual CPU fault */
-            cpu_restore_state(tb, env, pc, NULL);
+            cpu_restore_state(tb, env, pc);
         }
     }
 }
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index 854f168c60..ffffb8c0bd 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -4375,7 +4375,7 @@ static void cpu_restore_state2(void *retaddr)
         if (tb) {
             /* the PC is inside the translated code. It means that we have
                a virtual CPU fault */
-            cpu_restore_state(tb, env, pc, (void *)(long)env->cond);
+            cpu_restore_state(tb, env, pc);
         }
     }
 }
diff --git a/translate-all.c b/translate-all.c
index 97668b2c8e..2ca190ca8f 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -112,8 +112,7 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb, int *gen_code_size_ptr)
 /* The cpu state corresponding to 'searched_pc' is restored.
  */
 int cpu_restore_state(TranslationBlock *tb,
-                      CPUState *env, unsigned long searched_pc,
-                      void *puc)
+                      CPUState *env, unsigned long searched_pc)
 {
     TCGContext *s = &tcg_ctx;
     int j;

From 5bc95aa2461f3b9f70ecbb2a9ec22f939fc33d6d Mon Sep 17 00:00:00 2001
From: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Date: Tue, 19 Apr 2011 18:56:45 +0400
Subject: [PATCH 238/386] Implement basic part of SA-1110/SA-1100

Basic implementation of DEC/Intel SA-1100/SA-1110 chips emulation.
Implemented:
 - IRQs
 - GPIO
 - PPC
 - RTC
 - UARTs (no IrDA/etc.)
 - OST reused from pxa25x

Everything else is TODO (esp. PM/idle/sleep!) - see the todo in the
hw/strongarm.c

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 Makefile.target     |    1 +
 hw/strongarm.c      | 1598 +++++++++++++++++++++++++++++++++++++++++++
 hw/strongarm.h      |   64 ++
 target-arm/cpu.h    |    3 +
 target-arm/helper.c |    9 +
 5 files changed, 1675 insertions(+)
 create mode 100644 hw/strongarm.c
 create mode 100644 hw/strongarm.h

diff --git a/Makefile.target b/Makefile.target
index d5761b72f5..9e4cfc055a 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -352,6 +352,7 @@ obj-arm-y += syborg.o syborg_fb.o syborg_interrupt.o syborg_keyboard.o
 obj-arm-y += syborg_serial.o syborg_timer.o syborg_pointer.o syborg_rtc.o
 obj-arm-y += syborg_virtio.o
 obj-arm-y += vexpress.o
+obj-arm-y += strongarm.o
 
 obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
 obj-sh4-y += sh_timer.o sh_serial.o sh_intc.o sh_pci.o sm501.o
diff --git a/hw/strongarm.c b/hw/strongarm.c
new file mode 100644
index 0000000000..de08bdf674
--- /dev/null
+++ b/hw/strongarm.c
@@ -0,0 +1,1598 @@
+/*
+ * StrongARM SA-1100/SA-1110 emulation
+ *
+ * Copyright (C) 2011 Dmitry Eremin-Solenikov
+ *
+ * Largely based on StrongARM emulation:
+ * Copyright (c) 2006 Openedhand Ltd.
+ * Written by Andrzej Zaborowski <balrog@zabor.org>
+ *
+ * UART code based on QEMU 16550A UART emulation
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * Copyright (c) 2008 Citrix Systems, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "sysbus.h"
+#include "strongarm.h"
+#include "qemu-error.h"
+#include "arm-misc.h"
+#include "sysemu.h"
+#include "ssi.h"
+
+//#define DEBUG
+
+/*
+ TODO
+ - Implement cp15, c14 ?
+ - Implement cp15, c15 !!! (idle used in L)
+ - Implement idle mode handling/DIM
+ - Implement sleep mode/Wake sources
+ - Implement reset control
+ - Implement memory control regs
+ - PCMCIA handling
+ - Maybe support MBGNT/MBREQ
+ - DMA channels
+ - GPCLK
+ - IrDA
+ - MCP
+ - Enhance UART with modem signals
+ */
+
+#ifdef DEBUG
+# define DPRINTF(format, ...) printf(format , ## __VA_ARGS__)
+#else
+# define DPRINTF(format, ...) do { } while (0)
+#endif
+
+static struct {
+    target_phys_addr_t io_base;
+    int irq;
+} sa_serial[] = {
+    { 0x80010000, SA_PIC_UART1 },
+    { 0x80030000, SA_PIC_UART2 },
+    { 0x80050000, SA_PIC_UART3 },
+    { 0, 0 }
+};
+
+/* Interrupt Controller */
+typedef struct {
+    SysBusDevice busdev;
+    qemu_irq    irq;
+    qemu_irq    fiq;
+
+    uint32_t pending;
+    uint32_t enabled;
+    uint32_t is_fiq;
+    uint32_t int_idle;
+} StrongARMPICState;
+
+#define ICIP    0x00
+#define ICMR    0x04
+#define ICLR    0x08
+#define ICFP    0x10
+#define ICPR    0x20
+#define ICCR    0x0c
+
+#define SA_PIC_SRCS     32
+
+
+static void strongarm_pic_update(void *opaque)
+{
+    StrongARMPICState *s = opaque;
+
+    /* FIXME: reflect DIM */
+    qemu_set_irq(s->fiq, s->pending & s->enabled &  s->is_fiq);
+    qemu_set_irq(s->irq, s->pending & s->enabled & ~s->is_fiq);
+}
+
+static void strongarm_pic_set_irq(void *opaque, int irq, int level)
+{
+    StrongARMPICState *s = opaque;
+
+    if (level) {
+        s->pending |= 1 << irq;
+    } else {
+        s->pending &= ~(1 << irq);
+    }
+
+    strongarm_pic_update(s);
+}
+
+static uint32_t strongarm_pic_mem_read(void *opaque, target_phys_addr_t offset)
+{
+    StrongARMPICState *s = opaque;
+
+    switch (offset) {
+    case ICIP:
+        return s->pending & ~s->is_fiq & s->enabled;
+    case ICMR:
+        return s->enabled;
+    case ICLR:
+        return s->is_fiq;
+    case ICCR:
+        return s->int_idle == 0;
+    case ICFP:
+        return s->pending & s->is_fiq & s->enabled;
+    case ICPR:
+        return s->pending;
+    default:
+        printf("%s: Bad register offset 0x" TARGET_FMT_plx "\n",
+                        __func__, offset);
+        return 0;
+    }
+}
+
+static void strongarm_pic_mem_write(void *opaque, target_phys_addr_t offset,
+                uint32_t value)
+{
+    StrongARMPICState *s = opaque;
+
+    switch (offset) {
+    case ICMR:
+        s->enabled = value;
+        break;
+    case ICLR:
+        s->is_fiq = value;
+        break;
+    case ICCR:
+        s->int_idle = (value & 1) ? 0 : ~0;
+        break;
+    default:
+        printf("%s: Bad register offset 0x" TARGET_FMT_plx "\n",
+                        __func__, offset);
+        break;
+    }
+    strongarm_pic_update(s);
+}
+
+static CPUReadMemoryFunc * const strongarm_pic_readfn[] = {
+    strongarm_pic_mem_read,
+    strongarm_pic_mem_read,
+    strongarm_pic_mem_read,
+};
+
+static CPUWriteMemoryFunc * const strongarm_pic_writefn[] = {
+    strongarm_pic_mem_write,
+    strongarm_pic_mem_write,
+    strongarm_pic_mem_write,
+};
+
+static int strongarm_pic_initfn(SysBusDevice *dev)
+{
+    StrongARMPICState *s = FROM_SYSBUS(StrongARMPICState, dev);
+    int iomemtype;
+
+    qdev_init_gpio_in(&dev->qdev, strongarm_pic_set_irq, SA_PIC_SRCS);
+    iomemtype = cpu_register_io_memory(strongarm_pic_readfn,
+                    strongarm_pic_writefn, s, DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, iomemtype);
+    sysbus_init_irq(dev, &s->irq);
+    sysbus_init_irq(dev, &s->fiq);
+
+    return 0;
+}
+
+static int strongarm_pic_post_load(void *opaque, int version_id)
+{
+    strongarm_pic_update(opaque);
+    return 0;
+}
+
+static VMStateDescription vmstate_strongarm_pic_regs = {
+    .name = "strongarm_pic",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .post_load = strongarm_pic_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(pending, StrongARMPICState),
+        VMSTATE_UINT32(enabled, StrongARMPICState),
+        VMSTATE_UINT32(is_fiq, StrongARMPICState),
+        VMSTATE_UINT32(int_idle, StrongARMPICState),
+        VMSTATE_END_OF_LIST(),
+    },
+};
+
+static SysBusDeviceInfo strongarm_pic_info = {
+    .init       = strongarm_pic_initfn,
+    .qdev.name  = "strongarm_pic",
+    .qdev.desc  = "StrongARM PIC",
+    .qdev.size  = sizeof(StrongARMPICState),
+    .qdev.vmsd  = &vmstate_strongarm_pic_regs,
+};
+
+/* Real-Time Clock */
+#define RTAR 0x00 /* RTC Alarm register */
+#define RCNR 0x04 /* RTC Counter register */
+#define RTTR 0x08 /* RTC Timer Trim register */
+#define RTSR 0x10 /* RTC Status register */
+
+#define RTSR_AL (1 << 0) /* RTC Alarm detected */
+#define RTSR_HZ (1 << 1) /* RTC 1Hz detected */
+#define RTSR_ALE (1 << 2) /* RTC Alarm enable */
+#define RTSR_HZE (1 << 3) /* RTC 1Hz enable */
+
+/* 16 LSB of RTTR are clockdiv for internal trim logic,
+ * trim delete isn't emulated, so
+ * f = 32 768 / (RTTR_trim + 1) */
+
+typedef struct {
+    SysBusDevice busdev;
+    uint32_t rttr;
+    uint32_t rtsr;
+    uint32_t rtar;
+    uint32_t last_rcnr;
+    int64_t last_hz;
+    QEMUTimer *rtc_alarm;
+    QEMUTimer *rtc_hz;
+    qemu_irq rtc_irq;
+    qemu_irq rtc_hz_irq;
+} StrongARMRTCState;
+
+static inline void strongarm_rtc_int_update(StrongARMRTCState *s)
+{
+    qemu_set_irq(s->rtc_irq, s->rtsr & RTSR_AL);
+    qemu_set_irq(s->rtc_hz_irq, s->rtsr & RTSR_HZ);
+}
+
+static void strongarm_rtc_hzupdate(StrongARMRTCState *s)
+{
+    int64_t rt = qemu_get_clock_ms(rt_clock);
+    s->last_rcnr += ((rt - s->last_hz) << 15) /
+            (1000 * ((s->rttr & 0xffff) + 1));
+    s->last_hz = rt;
+}
+
+static inline void strongarm_rtc_timer_update(StrongARMRTCState *s)
+{
+    if ((s->rtsr & RTSR_HZE) && !(s->rtsr & RTSR_HZ)) {
+        qemu_mod_timer(s->rtc_hz, s->last_hz + 1000);
+    } else {
+        qemu_del_timer(s->rtc_hz);
+    }
+
+    if ((s->rtsr & RTSR_ALE) && !(s->rtsr & RTSR_AL)) {
+        qemu_mod_timer(s->rtc_alarm, s->last_hz +
+                (((s->rtar - s->last_rcnr) * 1000 *
+                  ((s->rttr & 0xffff) + 1)) >> 15));
+    } else {
+        qemu_del_timer(s->rtc_alarm);
+    }
+}
+
+static inline void strongarm_rtc_alarm_tick(void *opaque)
+{
+    StrongARMRTCState *s = opaque;
+    s->rtsr |= RTSR_AL;
+    strongarm_rtc_timer_update(s);
+    strongarm_rtc_int_update(s);
+}
+
+static inline void strongarm_rtc_hz_tick(void *opaque)
+{
+    StrongARMRTCState *s = opaque;
+    s->rtsr |= RTSR_HZ;
+    strongarm_rtc_timer_update(s);
+    strongarm_rtc_int_update(s);
+}
+
+static uint32_t strongarm_rtc_read(void *opaque, target_phys_addr_t addr)
+{
+    StrongARMRTCState *s = opaque;
+
+    switch (addr) {
+    case RTTR:
+        return s->rttr;
+    case RTSR:
+        return s->rtsr;
+    case RTAR:
+        return s->rtar;
+    case RCNR:
+        return s->last_rcnr +
+                ((qemu_get_clock_ms(rt_clock) - s->last_hz) << 15) /
+                (1000 * ((s->rttr & 0xffff) + 1));
+    default:
+        printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
+        return 0;
+    }
+}
+
+static void strongarm_rtc_write(void *opaque, target_phys_addr_t addr,
+                uint32_t value)
+{
+    StrongARMRTCState *s = opaque;
+    uint32_t old_rtsr;
+
+    switch (addr) {
+    case RTTR:
+        strongarm_rtc_hzupdate(s);
+        s->rttr = value;
+        strongarm_rtc_timer_update(s);
+        break;
+
+    case RTSR:
+        old_rtsr = s->rtsr;
+        s->rtsr = (value & (RTSR_ALE | RTSR_HZE)) |
+                  (s->rtsr & ~(value & (RTSR_AL | RTSR_HZ)));
+
+        if (s->rtsr != old_rtsr) {
+            strongarm_rtc_timer_update(s);
+        }
+
+        strongarm_rtc_int_update(s);
+        break;
+
+    case RTAR:
+        s->rtar = value;
+        strongarm_rtc_timer_update(s);
+        break;
+
+    case RCNR:
+        strongarm_rtc_hzupdate(s);
+        s->last_rcnr = value;
+        strongarm_rtc_timer_update(s);
+        break;
+
+    default:
+        printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
+    }
+}
+
+static CPUReadMemoryFunc * const strongarm_rtc_readfn[] = {
+    strongarm_rtc_read,
+    strongarm_rtc_read,
+    strongarm_rtc_read,
+};
+
+static CPUWriteMemoryFunc * const strongarm_rtc_writefn[] = {
+    strongarm_rtc_write,
+    strongarm_rtc_write,
+    strongarm_rtc_write,
+};
+
+static int strongarm_rtc_init(SysBusDevice *dev)
+{
+    StrongARMRTCState *s = FROM_SYSBUS(StrongARMRTCState, dev);
+    struct tm tm;
+    int iomemtype;
+
+    s->rttr = 0x0;
+    s->rtsr = 0;
+
+    qemu_get_timedate(&tm, 0);
+
+    s->last_rcnr = (uint32_t) mktimegm(&tm);
+    s->last_hz = qemu_get_clock_ms(rt_clock);
+
+    s->rtc_alarm = qemu_new_timer_ms(rt_clock, strongarm_rtc_alarm_tick, s);
+    s->rtc_hz = qemu_new_timer_ms(rt_clock, strongarm_rtc_hz_tick, s);
+
+    sysbus_init_irq(dev, &s->rtc_irq);
+    sysbus_init_irq(dev, &s->rtc_hz_irq);
+
+    iomemtype = cpu_register_io_memory(strongarm_rtc_readfn,
+                    strongarm_rtc_writefn, s, DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, 0x10000, iomemtype);
+
+    return 0;
+}
+
+static void strongarm_rtc_pre_save(void *opaque)
+{
+    StrongARMRTCState *s = opaque;
+
+    strongarm_rtc_hzupdate(s);
+}
+
+static int strongarm_rtc_post_load(void *opaque, int version_id)
+{
+    StrongARMRTCState *s = opaque;
+
+    strongarm_rtc_timer_update(s);
+    strongarm_rtc_int_update(s);
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_strongarm_rtc_regs = {
+    .name = "strongarm-rtc",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .pre_save = strongarm_rtc_pre_save,
+    .post_load = strongarm_rtc_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(rttr, StrongARMRTCState),
+        VMSTATE_UINT32(rtsr, StrongARMRTCState),
+        VMSTATE_UINT32(rtar, StrongARMRTCState),
+        VMSTATE_UINT32(last_rcnr, StrongARMRTCState),
+        VMSTATE_INT64(last_hz, StrongARMRTCState),
+        VMSTATE_END_OF_LIST(),
+    },
+};
+
+static SysBusDeviceInfo strongarm_rtc_sysbus_info = {
+    .init       = strongarm_rtc_init,
+    .qdev.name  = "strongarm-rtc",
+    .qdev.desc  = "StrongARM RTC Controller",
+    .qdev.size  = sizeof(StrongARMRTCState),
+    .qdev.vmsd  = &vmstate_strongarm_rtc_regs,
+};
+
+/* GPIO */
+#define GPLR 0x00
+#define GPDR 0x04
+#define GPSR 0x08
+#define GPCR 0x0c
+#define GRER 0x10
+#define GFER 0x14
+#define GEDR 0x18
+#define GAFR 0x1c
+
+typedef struct StrongARMGPIOInfo StrongARMGPIOInfo;
+struct StrongARMGPIOInfo {
+    SysBusDevice busdev;
+    qemu_irq handler[28];
+    qemu_irq irqs[11];
+    qemu_irq irqX;
+
+    uint32_t ilevel;
+    uint32_t olevel;
+    uint32_t dir;
+    uint32_t rising;
+    uint32_t falling;
+    uint32_t status;
+    uint32_t gpsr;
+    uint32_t gafr;
+
+    uint32_t prev_level;
+};
+
+
+static void strongarm_gpio_irq_update(StrongARMGPIOInfo *s)
+{
+    int i;
+    for (i = 0; i < 11; i++) {
+        qemu_set_irq(s->irqs[i], s->status & (1 << i));
+    }
+
+    qemu_set_irq(s->irqX, (s->status & ~0x7ff));
+}
+
+static void strongarm_gpio_set(void *opaque, int line, int level)
+{
+    StrongARMGPIOInfo *s = opaque;
+    uint32_t mask;
+
+    mask = 1 << line;
+
+    if (level) {
+        s->status |= s->rising & mask &
+                ~s->ilevel & ~s->dir;
+        s->ilevel |= mask;
+    } else {
+        s->status |= s->falling & mask &
+                s->ilevel & ~s->dir;
+        s->ilevel &= ~mask;
+    }
+
+    if (s->status & mask) {
+        strongarm_gpio_irq_update(s);
+    }
+}
+
+static void strongarm_gpio_handler_update(StrongARMGPIOInfo *s)
+{
+    uint32_t level, diff;
+    int bit;
+
+    level = s->olevel & s->dir;
+
+    for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
+        bit = ffs(diff) - 1;
+        qemu_set_irq(s->handler[bit], (level >> bit) & 1);
+    }
+
+    s->prev_level = level;
+}
+
+static uint32_t strongarm_gpio_read(void *opaque, target_phys_addr_t offset)
+{
+    StrongARMGPIOInfo *s = opaque;
+
+    switch (offset) {
+    case GPDR:        /* GPIO Pin-Direction registers */
+        return s->dir;
+
+    case GPSR:        /* GPIO Pin-Output Set registers */
+        DPRINTF("%s: Read from a write-only register 0x" TARGET_FMT_plx "\n",
+                        __func__, offset);
+        return s->gpsr;    /* Return last written value.  */
+
+    case GPCR:        /* GPIO Pin-Output Clear registers */
+        DPRINTF("%s: Read from a write-only register 0x" TARGET_FMT_plx "\n",
+                        __func__, offset);
+        return 31337;        /* Specified as unpredictable in the docs.  */
+
+    case GRER:        /* GPIO Rising-Edge Detect Enable registers */
+        return s->rising;
+
+    case GFER:        /* GPIO Falling-Edge Detect Enable registers */
+        return s->falling;
+
+    case GAFR:        /* GPIO Alternate Function registers */
+        return s->gafr;
+
+    case GPLR:        /* GPIO Pin-Level registers */
+        return (s->olevel & s->dir) |
+               (s->ilevel & ~s->dir);
+
+    case GEDR:        /* GPIO Edge Detect Status registers */
+        return s->status;
+
+    default:
+        printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
+    }
+
+    return 0;
+}
+
+static void strongarm_gpio_write(void *opaque,
+                target_phys_addr_t offset, uint32_t value)
+{
+    StrongARMGPIOInfo *s = opaque;
+
+    switch (offset) {
+    case GPDR:        /* GPIO Pin-Direction registers */
+        s->dir = value;
+        strongarm_gpio_handler_update(s);
+        break;
+
+    case GPSR:        /* GPIO Pin-Output Set registers */
+        s->olevel |= value;
+        strongarm_gpio_handler_update(s);
+        s->gpsr = value;
+        break;
+
+    case GPCR:        /* GPIO Pin-Output Clear registers */
+        s->olevel &= ~value;
+        strongarm_gpio_handler_update(s);
+        break;
+
+    case GRER:        /* GPIO Rising-Edge Detect Enable registers */
+        s->rising = value;
+        break;
+
+    case GFER:        /* GPIO Falling-Edge Detect Enable registers */
+        s->falling = value;
+        break;
+
+    case GAFR:        /* GPIO Alternate Function registers */
+        s->gafr = value;
+        break;
+
+    case GEDR:        /* GPIO Edge Detect Status registers */
+        s->status &= ~value;
+        strongarm_gpio_irq_update(s);
+        break;
+
+    default:
+        printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
+    }
+}
+
+static CPUReadMemoryFunc * const strongarm_gpio_readfn[] = {
+    strongarm_gpio_read,
+    strongarm_gpio_read,
+    strongarm_gpio_read
+};
+
+static CPUWriteMemoryFunc * const strongarm_gpio_writefn[] = {
+    strongarm_gpio_write,
+    strongarm_gpio_write,
+    strongarm_gpio_write
+};
+
+static DeviceState *strongarm_gpio_init(target_phys_addr_t base,
+                DeviceState *pic)
+{
+    DeviceState *dev;
+    int i;
+
+    dev = qdev_create(NULL, "strongarm-gpio");
+    qdev_init_nofail(dev);
+
+    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+    for (i = 0; i < 12; i++)
+        sysbus_connect_irq(sysbus_from_qdev(dev), i,
+                    qdev_get_gpio_in(pic, SA_PIC_GPIO0_EDGE + i));
+
+    return dev;
+}
+
+static int strongarm_gpio_initfn(SysBusDevice *dev)
+{
+    int iomemtype;
+    StrongARMGPIOInfo *s;
+    int i;
+
+    s = FROM_SYSBUS(StrongARMGPIOInfo, dev);
+
+    qdev_init_gpio_in(&dev->qdev, strongarm_gpio_set, 28);
+    qdev_init_gpio_out(&dev->qdev, s->handler, 28);
+
+    iomemtype = cpu_register_io_memory(strongarm_gpio_readfn,
+                    strongarm_gpio_writefn, s, DEVICE_NATIVE_ENDIAN);
+
+    sysbus_init_mmio(dev, 0x1000, iomemtype);
+    for (i = 0; i < 11; i++) {
+        sysbus_init_irq(dev, &s->irqs[i]);
+    }
+    sysbus_init_irq(dev, &s->irqX);
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_strongarm_gpio_regs = {
+    .name = "strongarm-gpio",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(ilevel, StrongARMGPIOInfo),
+        VMSTATE_UINT32(olevel, StrongARMGPIOInfo),
+        VMSTATE_UINT32(dir, StrongARMGPIOInfo),
+        VMSTATE_UINT32(rising, StrongARMGPIOInfo),
+        VMSTATE_UINT32(falling, StrongARMGPIOInfo),
+        VMSTATE_UINT32(status, StrongARMGPIOInfo),
+        VMSTATE_UINT32(gafr, StrongARMGPIOInfo),
+        VMSTATE_END_OF_LIST(),
+    },
+};
+
+static SysBusDeviceInfo strongarm_gpio_info = {
+    .init       = strongarm_gpio_initfn,
+    .qdev.name  = "strongarm-gpio",
+    .qdev.desc  = "StrongARM GPIO controller",
+    .qdev.size  = sizeof(StrongARMGPIOInfo),
+};
+
+/* Peripheral Pin Controller */
+#define PPDR 0x00
+#define PPSR 0x04
+#define PPAR 0x08
+#define PSDR 0x0c
+#define PPFR 0x10
+
+typedef struct StrongARMPPCInfo StrongARMPPCInfo;
+struct StrongARMPPCInfo {
+    SysBusDevice busdev;
+    qemu_irq handler[28];
+
+    uint32_t ilevel;
+    uint32_t olevel;
+    uint32_t dir;
+    uint32_t ppar;
+    uint32_t psdr;
+    uint32_t ppfr;
+
+    uint32_t prev_level;
+};
+
+static void strongarm_ppc_set(void *opaque, int line, int level)
+{
+    StrongARMPPCInfo *s = opaque;
+
+    if (level) {
+        s->ilevel |= 1 << line;
+    } else {
+        s->ilevel &= ~(1 << line);
+    }
+}
+
+static void strongarm_ppc_handler_update(StrongARMPPCInfo *s)
+{
+    uint32_t level, diff;
+    int bit;
+
+    level = s->olevel & s->dir;
+
+    for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
+        bit = ffs(diff) - 1;
+        qemu_set_irq(s->handler[bit], (level >> bit) & 1);
+    }
+
+    s->prev_level = level;
+}
+
+static uint32_t strongarm_ppc_read(void *opaque, target_phys_addr_t offset)
+{
+    StrongARMPPCInfo *s = opaque;
+
+    switch (offset) {
+    case PPDR:        /* PPC Pin Direction registers */
+        return s->dir | ~0x3fffff;
+
+    case PPSR:        /* PPC Pin State registers */
+        return (s->olevel & s->dir) |
+               (s->ilevel & ~s->dir) |
+               ~0x3fffff;
+
+    case PPAR:
+        return s->ppar | ~0x41000;
+
+    case PSDR:
+        return s->psdr;
+
+    case PPFR:
+        return s->ppfr | ~0x7f001;
+
+    default:
+        printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
+    }
+
+    return 0;
+}
+
+static void strongarm_ppc_write(void *opaque,
+                target_phys_addr_t offset, uint32_t value)
+{
+    StrongARMPPCInfo *s = opaque;
+
+    switch (offset) {
+    case PPDR:        /* PPC Pin Direction registers */
+        s->dir = value & 0x3fffff;
+        strongarm_ppc_handler_update(s);
+        break;
+
+    case PPSR:        /* PPC Pin State registers */
+        s->olevel = value & s->dir & 0x3fffff;
+        strongarm_ppc_handler_update(s);
+        break;
+
+    case PPAR:
+        s->ppar = value & 0x41000;
+        break;
+
+    case PSDR:
+        s->psdr = value & 0x3fffff;
+        break;
+
+    case PPFR:
+        s->ppfr = value & 0x7f001;
+        break;
+
+    default:
+        printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
+    }
+}
+
+static CPUReadMemoryFunc * const strongarm_ppc_readfn[] = {
+    strongarm_ppc_read,
+    strongarm_ppc_read,
+    strongarm_ppc_read
+};
+
+static CPUWriteMemoryFunc * const strongarm_ppc_writefn[] = {
+    strongarm_ppc_write,
+    strongarm_ppc_write,
+    strongarm_ppc_write
+};
+
+static int strongarm_ppc_init(SysBusDevice *dev)
+{
+    int iomemtype;
+    StrongARMPPCInfo *s;
+
+    s = FROM_SYSBUS(StrongARMPPCInfo, dev);
+
+    qdev_init_gpio_in(&dev->qdev, strongarm_ppc_set, 22);
+    qdev_init_gpio_out(&dev->qdev, s->handler, 22);
+
+    iomemtype = cpu_register_io_memory(strongarm_ppc_readfn,
+                    strongarm_ppc_writefn, s, DEVICE_NATIVE_ENDIAN);
+
+    sysbus_init_mmio(dev, 0x1000, iomemtype);
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_strongarm_ppc_regs = {
+    .name = "strongarm-ppc",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(ilevel, StrongARMPPCInfo),
+        VMSTATE_UINT32(olevel, StrongARMPPCInfo),
+        VMSTATE_UINT32(dir, StrongARMPPCInfo),
+        VMSTATE_UINT32(ppar, StrongARMPPCInfo),
+        VMSTATE_UINT32(psdr, StrongARMPPCInfo),
+        VMSTATE_UINT32(ppfr, StrongARMPPCInfo),
+        VMSTATE_END_OF_LIST(),
+    },
+};
+
+static SysBusDeviceInfo strongarm_ppc_info = {
+    .init       = strongarm_ppc_init,
+    .qdev.name  = "strongarm-ppc",
+    .qdev.desc  = "StrongARM PPC controller",
+    .qdev.size  = sizeof(StrongARMPPCInfo),
+};
+
+/* UART Ports */
+#define UTCR0 0x00
+#define UTCR1 0x04
+#define UTCR2 0x08
+#define UTCR3 0x0c
+#define UTDR  0x14
+#define UTSR0 0x1c
+#define UTSR1 0x20
+
+#define UTCR0_PE  (1 << 0) /* Parity enable */
+#define UTCR0_OES (1 << 1) /* Even parity */
+#define UTCR0_SBS (1 << 2) /* 2 stop bits */
+#define UTCR0_DSS (1 << 3) /* 8-bit data */
+
+#define UTCR3_RXE (1 << 0) /* Rx enable */
+#define UTCR3_TXE (1 << 1) /* Tx enable */
+#define UTCR3_BRK (1 << 2) /* Force Break */
+#define UTCR3_RIE (1 << 3) /* Rx int enable */
+#define UTCR3_TIE (1 << 4) /* Tx int enable */
+#define UTCR3_LBM (1 << 5) /* Loopback */
+
+#define UTSR0_TFS (1 << 0) /* Tx FIFO nearly empty */
+#define UTSR0_RFS (1 << 1) /* Rx FIFO nearly full */
+#define UTSR0_RID (1 << 2) /* Receiver Idle */
+#define UTSR0_RBB (1 << 3) /* Receiver begin break */
+#define UTSR0_REB (1 << 4) /* Receiver end break */
+#define UTSR0_EIF (1 << 5) /* Error in FIFO */
+
+#define UTSR1_RNE (1 << 1) /* Receive FIFO not empty */
+#define UTSR1_TNF (1 << 2) /* Transmit FIFO not full */
+#define UTSR1_PRE (1 << 3) /* Parity error */
+#define UTSR1_FRE (1 << 4) /* Frame error */
+#define UTSR1_ROR (1 << 5) /* Receive Over Run */
+
+#define RX_FIFO_PRE (1 << 8)
+#define RX_FIFO_FRE (1 << 9)
+#define RX_FIFO_ROR (1 << 10)
+
+typedef struct {
+    SysBusDevice busdev;
+    CharDriverState *chr;
+    qemu_irq irq;
+
+    uint8_t utcr0;
+    uint16_t brd;
+    uint8_t utcr3;
+    uint8_t utsr0;
+    uint8_t utsr1;
+
+    uint8_t tx_fifo[8];
+    uint8_t tx_start;
+    uint8_t tx_len;
+    uint16_t rx_fifo[12]; /* value + error flags in high bits */
+    uint8_t rx_start;
+    uint8_t rx_len;
+
+    uint64_t char_transmit_time; /* time to transmit a char in ticks*/
+    bool wait_break_end;
+    QEMUTimer *rx_timeout_timer;
+    QEMUTimer *tx_timer;
+} StrongARMUARTState;
+
+static void strongarm_uart_update_status(StrongARMUARTState *s)
+{
+    uint16_t utsr1 = 0;
+
+    if (s->tx_len != 8) {
+        utsr1 |= UTSR1_TNF;
+    }
+
+    if (s->rx_len != 0) {
+        uint16_t ent = s->rx_fifo[s->rx_start];
+
+        utsr1 |= UTSR1_RNE;
+        if (ent & RX_FIFO_PRE) {
+            s->utsr1 |= UTSR1_PRE;
+        }
+        if (ent & RX_FIFO_FRE) {
+            s->utsr1 |= UTSR1_FRE;
+        }
+        if (ent & RX_FIFO_ROR) {
+            s->utsr1 |= UTSR1_ROR;
+        }
+    }
+
+    s->utsr1 = utsr1;
+}
+
+static void strongarm_uart_update_int_status(StrongARMUARTState *s)
+{
+    uint16_t utsr0 = s->utsr0 &
+            (UTSR0_REB | UTSR0_RBB | UTSR0_RID);
+    int i;
+
+    if ((s->utcr3 & UTCR3_TXE) &&
+                (s->utcr3 & UTCR3_TIE) &&
+                s->tx_len <= 4) {
+        utsr0 |= UTSR0_TFS;
+    }
+
+    if ((s->utcr3 & UTCR3_RXE) &&
+                (s->utcr3 & UTCR3_RIE) &&
+                s->rx_len > 4) {
+        utsr0 |= UTSR0_RFS;
+    }
+
+    for (i = 0; i < s->rx_len && i < 4; i++)
+        if (s->rx_fifo[(s->rx_start + i) % 12] & ~0xff) {
+            utsr0 |= UTSR0_EIF;
+            break;
+        }
+
+    s->utsr0 = utsr0;
+    qemu_set_irq(s->irq, utsr0);
+}
+
+static void strongarm_uart_update_parameters(StrongARMUARTState *s)
+{
+    int speed, parity, data_bits, stop_bits, frame_size;
+    QEMUSerialSetParams ssp;
+
+    /* Start bit. */
+    frame_size = 1;
+    if (s->utcr0 & UTCR0_PE) {
+        /* Parity bit. */
+        frame_size++;
+        if (s->utcr0 & UTCR0_OES) {
+            parity = 'E';
+        } else {
+            parity = 'O';
+        }
+    } else {
+            parity = 'N';
+    }
+    if (s->utcr0 & UTCR0_SBS) {
+        stop_bits = 2;
+    } else {
+        stop_bits = 1;
+    }
+
+    data_bits = (s->utcr0 & UTCR0_DSS) ? 8 : 7;
+    frame_size += data_bits + stop_bits;
+    speed = 3686400 / 16 / (s->brd + 1);
+    ssp.speed = speed;
+    ssp.parity = parity;
+    ssp.data_bits = data_bits;
+    ssp.stop_bits = stop_bits;
+    s->char_transmit_time =  (get_ticks_per_sec() / speed) * frame_size;
+    if (s->chr) {
+        qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
+    }
+
+    DPRINTF(stderr, "%s speed=%d parity=%c data=%d stop=%d\n", s->chr->label,
+            speed, parity, data_bits, stop_bits);
+}
+
+static void strongarm_uart_rx_to(void *opaque)
+{
+    StrongARMUARTState *s = opaque;
+
+    if (s->rx_len) {
+        s->utsr0 |= UTSR0_RID;
+        strongarm_uart_update_int_status(s);
+    }
+}
+
+static void strongarm_uart_rx_push(StrongARMUARTState *s, uint16_t c)
+{
+    if ((s->utcr3 & UTCR3_RXE) == 0) {
+        /* rx disabled */
+        return;
+    }
+
+    if (s->wait_break_end) {
+        s->utsr0 |= UTSR0_REB;
+        s->wait_break_end = false;
+    }
+
+    if (s->rx_len < 12) {
+        s->rx_fifo[(s->rx_start + s->rx_len) % 12] = c;
+        s->rx_len++;
+    } else
+        s->rx_fifo[(s->rx_start + 11) % 12] |= RX_FIFO_ROR;
+}
+
+static int strongarm_uart_can_receive(void *opaque)
+{
+    StrongARMUARTState *s = opaque;
+
+    if (s->rx_len == 12) {
+        return 0;
+    }
+    /* It's best not to get more than 2/3 of RX FIFO, so advertise that much */
+    if (s->rx_len < 8) {
+        return 8 - s->rx_len;
+    }
+    return 1;
+}
+
+static void strongarm_uart_receive(void *opaque, const uint8_t *buf, int size)
+{
+    StrongARMUARTState *s = opaque;
+    int i;
+
+    for (i = 0; i < size; i++) {
+        strongarm_uart_rx_push(s, buf[i]);
+    }
+
+    /* call the timeout receive callback in 3 char transmit time */
+    qemu_mod_timer(s->rx_timeout_timer,
+                    qemu_get_clock_ns(vm_clock) + s->char_transmit_time * 3);
+
+    strongarm_uart_update_status(s);
+    strongarm_uart_update_int_status(s);
+}
+
+static void strongarm_uart_event(void *opaque, int event)
+{
+    StrongARMUARTState *s = opaque;
+    if (event == CHR_EVENT_BREAK) {
+        s->utsr0 |= UTSR0_RBB;
+        strongarm_uart_rx_push(s, RX_FIFO_FRE);
+        s->wait_break_end = true;
+        strongarm_uart_update_status(s);
+        strongarm_uart_update_int_status(s);
+    }
+}
+
+static void strongarm_uart_tx(void *opaque)
+{
+    StrongARMUARTState *s = opaque;
+    uint64_t new_xmit_ts = qemu_get_clock_ns(vm_clock);
+
+    if (s->utcr3 & UTCR3_LBM) /* loopback */ {
+        strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1);
+    } else if (s->chr) {
+        qemu_chr_write(s->chr, &s->tx_fifo[s->tx_start], 1);
+    }
+
+    s->tx_start = (s->tx_start + 1) % 8;
+    s->tx_len--;
+    if (s->tx_len) {
+        qemu_mod_timer(s->tx_timer, new_xmit_ts + s->char_transmit_time);
+    }
+    strongarm_uart_update_status(s);
+    strongarm_uart_update_int_status(s);
+}
+
+static uint32_t strongarm_uart_read(void *opaque, target_phys_addr_t addr)
+{
+    StrongARMUARTState *s = opaque;
+    uint16_t ret;
+
+    switch (addr) {
+    case UTCR0:
+        return s->utcr0;
+
+    case UTCR1:
+        return s->brd >> 8;
+
+    case UTCR2:
+        return s->brd & 0xff;
+
+    case UTCR3:
+        return s->utcr3;
+
+    case UTDR:
+        if (s->rx_len != 0) {
+            ret = s->rx_fifo[s->rx_start];
+            s->rx_start = (s->rx_start + 1) % 12;
+            s->rx_len--;
+            strongarm_uart_update_status(s);
+            strongarm_uart_update_int_status(s);
+            return ret;
+        }
+        return 0;
+
+    case UTSR0:
+        return s->utsr0;
+
+    case UTSR1:
+        return s->utsr1;
+
+    default:
+        printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
+        return 0;
+    }
+}
+
+static void strongarm_uart_write(void *opaque, target_phys_addr_t addr,
+                uint32_t value)
+{
+    StrongARMUARTState *s = opaque;
+
+    switch (addr) {
+    case UTCR0:
+        s->utcr0 = value & 0x7f;
+        strongarm_uart_update_parameters(s);
+        break;
+
+    case UTCR1:
+        s->brd = (s->brd & 0xff) | ((value & 0xf) << 8);
+        strongarm_uart_update_parameters(s);
+        break;
+
+    case UTCR2:
+        s->brd = (s->brd & 0xf00) | (value & 0xff);
+        strongarm_uart_update_parameters(s);
+        break;
+
+    case UTCR3:
+        s->utcr3 = value & 0x3f;
+        if ((s->utcr3 & UTCR3_RXE) == 0) {
+            s->rx_len = 0;
+        }
+        if ((s->utcr3 & UTCR3_TXE) == 0) {
+            s->tx_len = 0;
+        }
+        strongarm_uart_update_status(s);
+        strongarm_uart_update_int_status(s);
+        break;
+
+    case UTDR:
+        if ((s->utcr3 & UTCR3_TXE) && s->tx_len != 8) {
+            s->tx_fifo[(s->tx_start + s->tx_len) % 8] = value;
+            s->tx_len++;
+            strongarm_uart_update_status(s);
+            strongarm_uart_update_int_status(s);
+            if (s->tx_len == 1) {
+                strongarm_uart_tx(s);
+            }
+        }
+        break;
+
+    case UTSR0:
+        s->utsr0 = s->utsr0 & ~(value &
+                (UTSR0_REB | UTSR0_RBB | UTSR0_RID));
+        strongarm_uart_update_int_status(s);
+        break;
+
+    default:
+        printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
+    }
+}
+
+static CPUReadMemoryFunc * const strongarm_uart_readfn[] = {
+    strongarm_uart_read,
+    strongarm_uart_read,
+    strongarm_uart_read,
+};
+
+static CPUWriteMemoryFunc * const strongarm_uart_writefn[] = {
+    strongarm_uart_write,
+    strongarm_uart_write,
+    strongarm_uart_write,
+};
+
+static int strongarm_uart_init(SysBusDevice *dev)
+{
+    StrongARMUARTState *s = FROM_SYSBUS(StrongARMUARTState, dev);
+    int iomemtype;
+
+    iomemtype = cpu_register_io_memory(strongarm_uart_readfn,
+                    strongarm_uart_writefn, s, DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, 0x10000, iomemtype);
+    sysbus_init_irq(dev, &s->irq);
+
+    s->rx_timeout_timer = qemu_new_timer_ns(vm_clock, strongarm_uart_rx_to, s);
+    s->tx_timer = qemu_new_timer_ns(vm_clock, strongarm_uart_tx, s);
+
+    if (s->chr) {
+        qemu_chr_add_handlers(s->chr,
+                        strongarm_uart_can_receive,
+                        strongarm_uart_receive,
+                        strongarm_uart_event,
+                        s);
+    }
+
+    return 0;
+}
+
+static void strongarm_uart_reset(DeviceState *dev)
+{
+    StrongARMUARTState *s = DO_UPCAST(StrongARMUARTState, busdev.qdev, dev);
+
+    s->utcr0 = UTCR0_DSS; /* 8 data, no parity */
+    s->brd = 23;    /* 9600 */
+    /* enable send & recv - this actually violates spec */
+    s->utcr3 = UTCR3_TXE | UTCR3_RXE;
+
+    s->rx_len = s->tx_len = 0;
+
+    strongarm_uart_update_parameters(s);
+    strongarm_uart_update_status(s);
+    strongarm_uart_update_int_status(s);
+}
+
+static int strongarm_uart_post_load(void *opaque, int version_id)
+{
+    StrongARMUARTState *s = opaque;
+
+    strongarm_uart_update_parameters(s);
+    strongarm_uart_update_status(s);
+    strongarm_uart_update_int_status(s);
+
+    /* tx and restart timer */
+    if (s->tx_len) {
+        strongarm_uart_tx(s);
+    }
+
+    /* restart rx timeout timer */
+    if (s->rx_len) {
+        qemu_mod_timer(s->rx_timeout_timer,
+                qemu_get_clock_ns(vm_clock) + s->char_transmit_time * 3);
+    }
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_strongarm_uart_regs = {
+    .name = "strongarm-uart",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .post_load = strongarm_uart_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT8(utcr0, StrongARMUARTState),
+        VMSTATE_UINT16(brd, StrongARMUARTState),
+        VMSTATE_UINT8(utcr3, StrongARMUARTState),
+        VMSTATE_UINT8(utsr0, StrongARMUARTState),
+        VMSTATE_UINT8_ARRAY(tx_fifo, StrongARMUARTState, 8),
+        VMSTATE_UINT8(tx_start, StrongARMUARTState),
+        VMSTATE_UINT8(tx_len, StrongARMUARTState),
+        VMSTATE_UINT16_ARRAY(rx_fifo, StrongARMUARTState, 12),
+        VMSTATE_UINT8(rx_start, StrongARMUARTState),
+        VMSTATE_UINT8(rx_len, StrongARMUARTState),
+        VMSTATE_BOOL(wait_break_end, StrongARMUARTState),
+        VMSTATE_END_OF_LIST(),
+    },
+};
+
+static SysBusDeviceInfo strongarm_uart_info = {
+    .init       = strongarm_uart_init,
+    .qdev.name  = "strongarm-uart",
+    .qdev.desc  = "StrongARM UART controller",
+    .qdev.size  = sizeof(StrongARMUARTState),
+    .qdev.reset = strongarm_uart_reset,
+    .qdev.vmsd  = &vmstate_strongarm_uart_regs,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_CHR("chardev", StrongARMUARTState, chr),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
+/* Synchronous Serial Ports */
+typedef struct {
+    SysBusDevice busdev;
+    qemu_irq irq;
+    SSIBus *bus;
+
+    uint16_t sscr[2];
+    uint16_t sssr;
+
+    uint16_t rx_fifo[8];
+    uint8_t rx_level;
+    uint8_t rx_start;
+} StrongARMSSPState;
+
+#define SSCR0 0x60 /* SSP Control register 0 */
+#define SSCR1 0x64 /* SSP Control register 1 */
+#define SSDR  0x6c /* SSP Data register */
+#define SSSR  0x74 /* SSP Status register */
+
+/* Bitfields for above registers */
+#define SSCR0_SPI(x)    (((x) & 0x30) == 0x00)
+#define SSCR0_SSP(x)    (((x) & 0x30) == 0x10)
+#define SSCR0_UWIRE(x)  (((x) & 0x30) == 0x20)
+#define SSCR0_PSP(x)    (((x) & 0x30) == 0x30)
+#define SSCR0_SSE       (1 << 7)
+#define SSCR0_DSS(x)    (((x) & 0xf) + 1)
+#define SSCR1_RIE       (1 << 0)
+#define SSCR1_TIE       (1 << 1)
+#define SSCR1_LBM       (1 << 2)
+#define SSSR_TNF        (1 << 2)
+#define SSSR_RNE        (1 << 3)
+#define SSSR_TFS        (1 << 5)
+#define SSSR_RFS        (1 << 6)
+#define SSSR_ROR        (1 << 7)
+#define SSSR_RW         0x0080
+
+static void strongarm_ssp_int_update(StrongARMSSPState *s)
+{
+    int level = 0;
+
+    level |= (s->sssr & SSSR_ROR);
+    level |= (s->sssr & SSSR_RFS)  &&  (s->sscr[1] & SSCR1_RIE);
+    level |= (s->sssr & SSSR_TFS)  &&  (s->sscr[1] & SSCR1_TIE);
+    qemu_set_irq(s->irq, level);
+}
+
+static void strongarm_ssp_fifo_update(StrongARMSSPState *s)
+{
+    s->sssr &= ~SSSR_TFS;
+    s->sssr &= ~SSSR_TNF;
+    if (s->sscr[0] & SSCR0_SSE) {
+        if (s->rx_level >= 4) {
+            s->sssr |= SSSR_RFS;
+        } else {
+            s->sssr &= ~SSSR_RFS;
+        }
+        if (s->rx_level) {
+            s->sssr |= SSSR_RNE;
+        } else {
+            s->sssr &= ~SSSR_RNE;
+        }
+        /* TX FIFO is never filled, so it is always in underrun
+           condition if SSP is enabled */
+        s->sssr |= SSSR_TFS;
+        s->sssr |= SSSR_TNF;
+    }
+
+    strongarm_ssp_int_update(s);
+}
+
+static uint32_t strongarm_ssp_read(void *opaque, target_phys_addr_t addr)
+{
+    StrongARMSSPState *s = opaque;
+    uint32_t retval;
+
+    switch (addr) {
+    case SSCR0:
+        return s->sscr[0];
+    case SSCR1:
+        return s->sscr[1];
+    case SSSR:
+        return s->sssr;
+    case SSDR:
+        if (~s->sscr[0] & SSCR0_SSE) {
+            return 0xffffffff;
+        }
+        if (s->rx_level < 1) {
+            printf("%s: SSP Rx Underrun\n", __func__);
+            return 0xffffffff;
+        }
+        s->rx_level--;
+        retval = s->rx_fifo[s->rx_start++];
+        s->rx_start &= 0x7;
+        strongarm_ssp_fifo_update(s);
+        return retval;
+    default:
+        printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
+        break;
+    }
+    return 0;
+}
+
+static void strongarm_ssp_write(void *opaque, target_phys_addr_t addr,
+                uint32_t value)
+{
+    StrongARMSSPState *s = opaque;
+
+    switch (addr) {
+    case SSCR0:
+        s->sscr[0] = value & 0xffbf;
+        if ((s->sscr[0] & SSCR0_SSE) && SSCR0_DSS(value) < 4) {
+            printf("%s: Wrong data size: %i bits\n", __func__,
+                            SSCR0_DSS(value));
+        }
+        if (!(value & SSCR0_SSE)) {
+            s->sssr = 0;
+            s->rx_level = 0;
+        }
+        strongarm_ssp_fifo_update(s);
+        break;
+
+    case SSCR1:
+        s->sscr[1] = value & 0x2f;
+        if (value & SSCR1_LBM) {
+            printf("%s: Attempt to use SSP LBM mode\n", __func__);
+        }
+        strongarm_ssp_fifo_update(s);
+        break;
+
+    case SSSR:
+        s->sssr &= ~(value & SSSR_RW);
+        strongarm_ssp_int_update(s);
+        break;
+
+    case SSDR:
+        if (SSCR0_UWIRE(s->sscr[0])) {
+            value &= 0xff;
+        } else
+            /* Note how 32bits overflow does no harm here */
+            value &= (1 << SSCR0_DSS(s->sscr[0])) - 1;
+
+        /* Data goes from here to the Tx FIFO and is shifted out from
+         * there directly to the slave, no need to buffer it.
+         */
+        if (s->sscr[0] & SSCR0_SSE) {
+            uint32_t readval;
+            if (s->sscr[1] & SSCR1_LBM) {
+                readval = value;
+            } else {
+                readval = ssi_transfer(s->bus, value);
+            }
+
+            if (s->rx_level < 0x08) {
+                s->rx_fifo[(s->rx_start + s->rx_level++) & 0x7] = readval;
+            } else {
+                s->sssr |= SSSR_ROR;
+            }
+        }
+        strongarm_ssp_fifo_update(s);
+        break;
+
+    default:
+        printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
+        break;
+    }
+}
+
+static CPUReadMemoryFunc * const strongarm_ssp_readfn[] = {
+    strongarm_ssp_read,
+    strongarm_ssp_read,
+    strongarm_ssp_read,
+};
+
+static CPUWriteMemoryFunc * const strongarm_ssp_writefn[] = {
+    strongarm_ssp_write,
+    strongarm_ssp_write,
+    strongarm_ssp_write,
+};
+
+static int strongarm_ssp_post_load(void *opaque, int version_id)
+{
+    StrongARMSSPState *s = opaque;
+
+    strongarm_ssp_fifo_update(s);
+
+    return 0;
+}
+
+static int strongarm_ssp_init(SysBusDevice *dev)
+{
+    int iomemtype;
+    StrongARMSSPState *s = FROM_SYSBUS(StrongARMSSPState, dev);
+
+    sysbus_init_irq(dev, &s->irq);
+
+    iomemtype = cpu_register_io_memory(strongarm_ssp_readfn,
+                                       strongarm_ssp_writefn, s,
+                                       DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, iomemtype);
+
+    s->bus = ssi_create_bus(&dev->qdev, "ssi");
+    return 0;
+}
+
+static void strongarm_ssp_reset(DeviceState *dev)
+{
+    StrongARMSSPState *s = DO_UPCAST(StrongARMSSPState, busdev.qdev, dev);
+    s->sssr = 0x03; /* 3 bit data, SPI, disabled */
+    s->rx_start = 0;
+    s->rx_level = 0;
+}
+
+static const VMStateDescription vmstate_strongarm_ssp_regs = {
+    .name = "strongarm-ssp",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .post_load = strongarm_ssp_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT16_ARRAY(sscr, StrongARMSSPState, 2),
+        VMSTATE_UINT16(sssr, StrongARMSSPState),
+        VMSTATE_UINT16_ARRAY(rx_fifo, StrongARMSSPState, 8),
+        VMSTATE_UINT8(rx_start, StrongARMSSPState),
+        VMSTATE_UINT8(rx_level, StrongARMSSPState),
+        VMSTATE_END_OF_LIST(),
+    },
+};
+
+static SysBusDeviceInfo strongarm_ssp_info = {
+    .init       = strongarm_ssp_init,
+    .qdev.name  = "strongarm-ssp",
+    .qdev.desc  = "StrongARM SSP controller",
+    .qdev.size  = sizeof(StrongARMSSPState),
+    .qdev.reset = strongarm_ssp_reset,
+    .qdev.vmsd  = &vmstate_strongarm_ssp_regs,
+};
+
+/* Main CPU functions */
+StrongARMState *sa1110_init(unsigned int sdram_size, const char *rev)
+{
+    StrongARMState *s;
+    qemu_irq *pic;
+    int i;
+
+    s = qemu_mallocz(sizeof(StrongARMState));
+
+    if (!rev) {
+        rev = "sa1110-b5";
+    }
+
+    if (strncmp(rev, "sa1110", 6)) {
+        error_report("Machine requires a SA1110 processor.\n");
+        exit(1);
+    }
+
+    s->env = cpu_init(rev);
+
+    if (!s->env) {
+        error_report("Unable to find CPU definition\n");
+        exit(1);
+    }
+
+    cpu_register_physical_memory(SA_SDCS0,
+                    sdram_size, qemu_ram_alloc(NULL, "strongarm.sdram",
+                                                sdram_size) | IO_MEM_RAM);
+
+    pic = arm_pic_init_cpu(s->env);
+    s->pic = sysbus_create_varargs("strongarm_pic", 0x90050000,
+                    pic[ARM_PIC_CPU_IRQ], pic[ARM_PIC_CPU_FIQ], NULL);
+
+    sysbus_create_varargs("pxa25x-timer", 0x90000000,
+                    qdev_get_gpio_in(s->pic, SA_PIC_OSTC0),
+                    qdev_get_gpio_in(s->pic, SA_PIC_OSTC1),
+                    qdev_get_gpio_in(s->pic, SA_PIC_OSTC2),
+                    qdev_get_gpio_in(s->pic, SA_PIC_OSTC3),
+                    NULL);
+
+    sysbus_create_simple("strongarm-rtc", 0x90010000,
+                    qdev_get_gpio_in(s->pic, SA_PIC_RTC_ALARM));
+
+    s->gpio = strongarm_gpio_init(0x90040000, s->pic);
+
+    s->ppc = sysbus_create_varargs("strongarm-ppc", 0x90060000, NULL);
+
+    for (i = 0; sa_serial[i].io_base; i++) {
+        DeviceState *dev = qdev_create(NULL, "strongarm-uart");
+        qdev_prop_set_chr(dev, "chardev", serial_hds[i]);
+        qdev_init_nofail(dev);
+        sysbus_mmio_map(sysbus_from_qdev(dev), 0,
+                sa_serial[i].io_base);
+        sysbus_connect_irq(sysbus_from_qdev(dev), 0,
+                qdev_get_gpio_in(s->pic, sa_serial[i].irq));
+    }
+
+    s->ssp = sysbus_create_varargs("strongarm-ssp", 0x80070000,
+                qdev_get_gpio_in(s->pic, SA_PIC_SSP), NULL);
+    s->ssp_bus = (SSIBus *)qdev_get_child_bus(s->ssp, "ssi");
+
+    return s;
+}
+
+static void strongarm_register_devices(void)
+{
+    sysbus_register_withprop(&strongarm_pic_info);
+    sysbus_register_withprop(&strongarm_rtc_sysbus_info);
+    sysbus_register_withprop(&strongarm_gpio_info);
+    sysbus_register_withprop(&strongarm_ppc_info);
+    sysbus_register_withprop(&strongarm_uart_info);
+    sysbus_register_withprop(&strongarm_ssp_info);
+}
+device_init(strongarm_register_devices)
diff --git a/hw/strongarm.h b/hw/strongarm.h
new file mode 100644
index 0000000000..a81b110e23
--- /dev/null
+++ b/hw/strongarm.h
@@ -0,0 +1,64 @@
+#ifndef _STRONGARM_H
+#define _STRONGARM_H
+
+#define SA_CS0          0x00000000
+#define SA_CS1          0x08000000
+#define SA_CS2          0x10000000
+#define SA_CS3          0x18000000
+#define SA_PCMCIA_CS0   0x20000000
+#define SA_PCMCIA_CS1   0x30000000
+#define SA_CS4          0x40000000
+#define SA_CS5          0x48000000
+/* system registers here */
+#define SA_SDCS0        0xc0000000
+#define SA_SDCS1        0xc8000000
+#define SA_SDCS2        0xd0000000
+#define SA_SDCS3        0xd8000000
+
+enum {
+    SA_PIC_GPIO0_EDGE = 0,
+    SA_PIC_GPIO1_EDGE,
+    SA_PIC_GPIO2_EDGE,
+    SA_PIC_GPIO3_EDGE,
+    SA_PIC_GPIO4_EDGE,
+    SA_PIC_GPIO5_EDGE,
+    SA_PIC_GPIO6_EDGE,
+    SA_PIC_GPIO7_EDGE,
+    SA_PIC_GPIO8_EDGE,
+    SA_PIC_GPIO9_EDGE,
+    SA_PIC_GPIO10_EDGE,
+    SA_PIC_GPIOX_EDGE,
+    SA_PIC_LCD,
+    SA_PIC_UDC,
+    SA_PIC_RSVD1,
+    SA_PIC_UART1,
+    SA_PIC_UART2,
+    SA_PIC_UART3,
+    SA_PIC_MCP,
+    SA_PIC_SSP,
+    SA_PIC_DMA_CH0,
+    SA_PIC_DMA_CH1,
+    SA_PIC_DMA_CH2,
+    SA_PIC_DMA_CH3,
+    SA_PIC_DMA_CH4,
+    SA_PIC_DMA_CH5,
+    SA_PIC_OSTC0,
+    SA_PIC_OSTC1,
+    SA_PIC_OSTC2,
+    SA_PIC_OSTC3,
+    SA_PIC_RTC_HZ,
+    SA_PIC_RTC_ALARM,
+};
+
+typedef struct {
+    CPUState *env;
+    DeviceState *pic;
+    DeviceState *gpio;
+    DeviceState *ppc;
+    DeviceState *ssp;
+    SSIBus *ssp_bus;
+} StrongARMState;
+
+StrongARMState *sa1110_init(unsigned int sdram_size, const char *rev);
+
+#endif
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index e247a7ade0..d5af64465f 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -363,6 +363,7 @@ enum arm_features {
     ARM_FEATURE_V7MP,    /* v7 Multiprocessing Extensions */
     ARM_FEATURE_V4T,
     ARM_FEATURE_V5,
+    ARM_FEATURE_STRONGARM,
 };
 
 static inline int arm_feature(CPUARMState *env, int feature)
@@ -393,6 +394,8 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
 #define ARM_CPUID_ARM946      0x41059461
 #define ARM_CPUID_TI915T      0x54029152
 #define ARM_CPUID_TI925T      0x54029252
+#define ARM_CPUID_SA1100      0x4401A11B
+#define ARM_CPUID_SA1110      0x6901B119
 #define ARM_CPUID_PXA250      0x69052100
 #define ARM_CPUID_PXA255      0x69052d00
 #define ARM_CPUID_PXA260      0x69052903
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 12127dee74..bf843353e0 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -214,6 +214,11 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
         env->cp15.c0_cachetype = 0xd172172;
         env->cp15.c1_sys = 0x00000078;
         break;
+    case ARM_CPUID_SA1100:
+    case ARM_CPUID_SA1110:
+        set_feature(env, ARM_FEATURE_STRONGARM);
+        env->cp15.c1_sys = 0x00000070;
+        break;
     default:
         cpu_abort(env, "Bad CPU ID: %x\n", id);
         break;
@@ -378,6 +383,8 @@ static const struct arm_cpu_t arm_cpu_names[] = {
     { ARM_CPUID_CORTEXA9, "cortex-a9"},
     { ARM_CPUID_TI925T, "ti925t" },
     { ARM_CPUID_PXA250, "pxa250" },
+    { ARM_CPUID_SA1100,    "sa1100" },
+    { ARM_CPUID_SA1110,    "sa1110" },
     { ARM_CPUID_PXA255, "pxa255" },
     { ARM_CPUID_PXA260, "pxa260" },
     { ARM_CPUID_PXA261, "pxa261" },
@@ -1553,6 +1560,8 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
     case 9:
         if (arm_feature(env, ARM_FEATURE_OMAPCP))
             break;
+        if (arm_feature(env, ARM_FEATURE_STRONGARM))
+            break; /* Ignore ReadBuffer access */
         switch (crm) {
         case 0: /* Cache lockdown.  */
 	    switch (op1) {

From c64b21d519a6ecae12f65625fa60f3035ed88644 Mon Sep 17 00:00:00 2001
From: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Date: Tue, 19 Apr 2011 18:56:46 +0400
Subject: [PATCH 239/386] Basic implementation of Sharp Zaurus SL-5500 collie
 PDA

Add very basic implementation of collie PDA emulation. The system lacks
LoCoMo and graphics/sound emulation. Linux kernel boots up to mounting
rootfs (theoretically it can be provided in pflash images).

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 Makefile.target |  1 +
 hw/collie.c     | 69 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+)
 create mode 100644 hw/collie.c

diff --git a/Makefile.target b/Makefile.target
index 9e4cfc055a..0e0ef36b97 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -353,6 +353,7 @@ obj-arm-y += syborg_serial.o syborg_timer.o syborg_pointer.o syborg_rtc.o
 obj-arm-y += syborg_virtio.o
 obj-arm-y += vexpress.o
 obj-arm-y += strongarm.o
+obj-arm-y += collie.o
 
 obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
 obj-sh4-y += sh_timer.o sh_serial.o sh_intc.o sh_pci.o sm501.o
diff --git a/hw/collie.c b/hw/collie.c
new file mode 100644
index 0000000000..156404d9f3
--- /dev/null
+++ b/hw/collie.c
@@ -0,0 +1,69 @@
+/*
+ * SA-1110-based Sharp Zaurus SL-5500 platform.
+ *
+ * Copyright (C) 2011 Dmitry Eremin-Solenikov
+ *
+ * This code is licensed under GNU GPL v2.
+ */
+#include "hw.h"
+#include "sysbus.h"
+#include "boards.h"
+#include "devices.h"
+#include "strongarm.h"
+#include "arm-misc.h"
+#include "flash.h"
+#include "blockdev.h"
+
+static struct arm_boot_info collie_binfo = {
+    .loader_start = SA_SDCS0,
+    .ram_size = 0x20000000,
+};
+
+static void collie_init(ram_addr_t ram_size,
+                const char *boot_device,
+                const char *kernel_filename, const char *kernel_cmdline,
+                const char *initrd_filename, const char *cpu_model)
+{
+    StrongARMState *s;
+    DriveInfo *dinfo;
+    ram_addr_t phys_flash;
+
+    if (!cpu_model) {
+        cpu_model = "sa1110";
+    }
+
+    s = sa1110_init(collie_binfo.ram_size, cpu_model);
+
+    phys_flash = qemu_ram_alloc(NULL, "collie.fl1", 0x02000000);
+    dinfo = drive_get(IF_PFLASH, 0, 0);
+    pflash_cfi01_register(SA_CS0, phys_flash,
+                    dinfo ? dinfo->bdrv : NULL, (64 * 1024),
+                    512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+
+    phys_flash = qemu_ram_alloc(NULL, "collie.fl2", 0x02000000);
+    dinfo = drive_get(IF_PFLASH, 0, 1);
+    pflash_cfi01_register(SA_CS1, phys_flash,
+                    dinfo ? dinfo->bdrv : NULL, (64 * 1024),
+                    512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+
+    sysbus_create_simple("scoop", 0x40800000, NULL);
+
+    collie_binfo.kernel_filename = kernel_filename;
+    collie_binfo.kernel_cmdline = kernel_cmdline;
+    collie_binfo.initrd_filename = initrd_filename;
+    collie_binfo.board_id = 0x208;
+    arm_load_kernel(s->env, &collie_binfo);
+}
+
+static QEMUMachine collie_machine = {
+    .name = "collie",
+    .desc = "Collie PDA (SA-1110)",
+    .init = collie_init,
+};
+
+static void collie_machine_init(void)
+{
+    qemu_register_machine(&collie_machine);
+}
+
+machine_init(collie_machine_init)

From 756ba3b0127fea2bfb538d256c76f19aec126732 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Tue, 19 Apr 2011 16:32:34 +0100
Subject: [PATCH 240/386] hw/arm_boot.c: move initrd load address up to
 accommodate large kernels

Newer kernels are large enough that they can overlap the address
where qemu places the initrd. Move the initrd up so that there is
enough space for the kernel again.

Unfortunately it's not possible to automatically determine the
size of the kernel if it is compressed, so this is the best we
can do.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/arm_boot.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/arm_boot.c b/hw/arm_boot.c
index 41e99d1332..bfac982e65 100644
--- a/hw/arm_boot.c
+++ b/hw/arm_boot.c
@@ -15,7 +15,7 @@
 
 #define KERNEL_ARGS_ADDR 0x100
 #define KERNEL_LOAD_ADDR 0x00010000
-#define INITRD_LOAD_ADDR 0x00800000
+#define INITRD_LOAD_ADDR 0x00d00000
 
 /* The worlds second smallest bootloader.  Set r0-r2, then jump to kernel.  */
 static uint32_t bootloader[] = {

From ec444452b8753a372de30b22d9b4765a799db612 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Tue, 19 Apr 2011 17:30:55 +0100
Subject: [PATCH 241/386] target-arm: Set Invalid flag for NaN in float-to-int
 conversions

When we catch the special case of an input NaN in ARM float to int
helper functions, set the Invalid flag as well as returning the
correct result.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/helper.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index bf843353e0..62ae72ec27 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2551,6 +2551,7 @@ float64 VFP_HELPER(sito, d)(uint32_t x, CPUState *env)
 uint32_t VFP_HELPER(toui, s)(float32 x, CPUState *env)
 {
     if (float32_is_any_nan(x)) {
+        float_raise(float_flag_invalid, &env->vfp.fp_status);
         return 0;
     }
     return float32_to_uint32(x, &env->vfp.fp_status);
@@ -2559,6 +2560,7 @@ uint32_t VFP_HELPER(toui, s)(float32 x, CPUState *env)
 uint32_t VFP_HELPER(toui, d)(float64 x, CPUState *env)
 {
     if (float64_is_any_nan(x)) {
+        float_raise(float_flag_invalid, &env->vfp.fp_status);
         return 0;
     }
     return float64_to_uint32(x, &env->vfp.fp_status);
@@ -2567,6 +2569,7 @@ uint32_t VFP_HELPER(toui, d)(float64 x, CPUState *env)
 uint32_t VFP_HELPER(tosi, s)(float32 x, CPUState *env)
 {
     if (float32_is_any_nan(x)) {
+        float_raise(float_flag_invalid, &env->vfp.fp_status);
         return 0;
     }
     return float32_to_int32(x, &env->vfp.fp_status);
@@ -2575,6 +2578,7 @@ uint32_t VFP_HELPER(tosi, s)(float32 x, CPUState *env)
 uint32_t VFP_HELPER(tosi, d)(float64 x, CPUState *env)
 {
     if (float64_is_any_nan(x)) {
+        float_raise(float_flag_invalid, &env->vfp.fp_status);
         return 0;
     }
     return float64_to_int32(x, &env->vfp.fp_status);
@@ -2583,6 +2587,7 @@ uint32_t VFP_HELPER(tosi, d)(float64 x, CPUState *env)
 uint32_t VFP_HELPER(touiz, s)(float32 x, CPUState *env)
 {
     if (float32_is_any_nan(x)) {
+        float_raise(float_flag_invalid, &env->vfp.fp_status);
         return 0;
     }
     return float32_to_uint32_round_to_zero(x, &env->vfp.fp_status);
@@ -2591,6 +2596,7 @@ uint32_t VFP_HELPER(touiz, s)(float32 x, CPUState *env)
 uint32_t VFP_HELPER(touiz, d)(float64 x, CPUState *env)
 {
     if (float64_is_any_nan(x)) {
+        float_raise(float_flag_invalid, &env->vfp.fp_status);
         return 0;
     }
     return float64_to_uint32_round_to_zero(x, &env->vfp.fp_status);
@@ -2599,6 +2605,7 @@ uint32_t VFP_HELPER(touiz, d)(float64 x, CPUState *env)
 uint32_t VFP_HELPER(tosiz, s)(float32 x, CPUState *env)
 {
     if (float32_is_any_nan(x)) {
+        float_raise(float_flag_invalid, &env->vfp.fp_status);
         return 0;
     }
     return float32_to_int32_round_to_zero(x, &env->vfp.fp_status);
@@ -2607,6 +2614,7 @@ uint32_t VFP_HELPER(tosiz, s)(float32 x, CPUState *env)
 uint32_t VFP_HELPER(tosiz, d)(float64 x, CPUState *env)
 {
     if (float64_is_any_nan(x)) {
+        float_raise(float_flag_invalid, &env->vfp.fp_status);
         return 0;
     }
     return float64_to_int32_round_to_zero(x, &env->vfp.fp_status);
@@ -2645,6 +2653,7 @@ uint##fsz##_t VFP_HELPER(to##name, p)(float##fsz x, uint32_t shift, \
 { \
     float##fsz tmp; \
     if (float##fsz##_is_any_nan(x)) { \
+        float_raise(float_flag_invalid, &env->vfp.fp_status); \
         return 0; \
     } \
     tmp = float##fsz##_scalbn(x, shift, &env->vfp.fp_status); \

From 1f1f0600aa8a233ceb1b90e9f47386849bdb11ed Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Wed, 1 Dec 2010 21:54:04 +0100
Subject: [PATCH 242/386] vmstate: port adb_kbd

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/adb.c | 40 ++++++++++++++--------------------------
 1 file changed, 14 insertions(+), 26 deletions(-)

diff --git a/hw/adb.c b/hw/adb.c
index 99b30f6bc7..fbf5080167 100644
--- a/hw/adb.c
+++ b/hw/adb.c
@@ -261,30 +261,19 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
     return olen;
 }
 
-static void adb_kbd_save(QEMUFile *f, void *opaque)
-{
-    KBDState *s = (KBDState *)opaque;
-
-    qemu_put_buffer(f, s->data, sizeof(s->data));
-    qemu_put_sbe32s(f, &s->rptr);
-    qemu_put_sbe32s(f, &s->wptr);
-    qemu_put_sbe32s(f, &s->count);
-}
-
-static int adb_kbd_load(QEMUFile *f, void *opaque, int version_id)
-{
-    KBDState *s = (KBDState *)opaque;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    qemu_get_buffer(f, s->data, sizeof(s->data));
-    qemu_get_sbe32s(f, &s->rptr);
-    qemu_get_sbe32s(f, &s->wptr);
-    qemu_get_sbe32s(f, &s->count);
-
-    return 0;
-}
+static const VMStateDescription vmstate_adb_kbd = {
+    .name = "adb_kbd",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_BUFFER(data, KBDState),
+        VMSTATE_INT32(rptr, KBDState),
+        VMSTATE_INT32(wptr, KBDState),
+        VMSTATE_INT32(count, KBDState),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static int adb_kbd_reset(ADBDevice *d)
 {
@@ -305,8 +294,7 @@ void adb_kbd_init(ADBBusState *bus)
     d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
                             adb_kbd_reset, s);
     qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
-    register_savevm(NULL, "adb_kbd", -1, 1, adb_kbd_save,
-                    adb_kbd_load, s);
+    vmstate_register(NULL, -1, &vmstate_adb_kbd, s);
 }
 
 /***************************************************************/

From 2b2cd5928d9fcad9f1941225f8b9598a2a954e11 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Wed, 1 Dec 2010 21:56:35 +0100
Subject: [PATCH 243/386] vmstate: port adb_mouse

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/adb.c | 43 +++++++++++++++----------------------------
 1 file changed, 15 insertions(+), 28 deletions(-)

diff --git a/hw/adb.c b/hw/adb.c
index fbf5080167..7499cdcef8 100644
--- a/hw/adb.c
+++ b/hw/adb.c
@@ -427,32 +427,20 @@ static int adb_mouse_reset(ADBDevice *d)
     return 0;
 }
 
-static void adb_mouse_save(QEMUFile *f, void *opaque)
-{
-    MouseState *s = (MouseState *)opaque;
-
-    qemu_put_sbe32s(f, &s->buttons_state);
-    qemu_put_sbe32s(f, &s->last_buttons_state);
-    qemu_put_sbe32s(f, &s->dx);
-    qemu_put_sbe32s(f, &s->dy);
-    qemu_put_sbe32s(f, &s->dz);
-}
-
-static int adb_mouse_load(QEMUFile *f, void *opaque, int version_id)
-{
-    MouseState *s = (MouseState *)opaque;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    qemu_get_sbe32s(f, &s->buttons_state);
-    qemu_get_sbe32s(f, &s->last_buttons_state);
-    qemu_get_sbe32s(f, &s->dx);
-    qemu_get_sbe32s(f, &s->dy);
-    qemu_get_sbe32s(f, &s->dz);
-
-    return 0;
-}
+static const VMStateDescription vmstate_adb_mouse = {
+    .name = "adb_mouse",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_INT32(buttons_state, MouseState),
+        VMSTATE_INT32(last_buttons_state, MouseState),
+        VMSTATE_INT32(dx, MouseState),
+        VMSTATE_INT32(dy, MouseState),
+        VMSTATE_INT32(dz, MouseState),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 void adb_mouse_init(ADBBusState *bus)
 {
@@ -463,6 +451,5 @@ void adb_mouse_init(ADBBusState *bus)
     d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request,
                             adb_mouse_reset, s);
     qemu_add_mouse_event_handler(adb_mouse_event, d, 0, "QEMU ADB Mouse");
-    register_savevm(NULL, "adb_mouse", -1, 1, adb_mouse_save,
-                    adb_mouse_load, s);
+    vmstate_register(NULL, -1, &vmstate_adb_mouse, s);
 }

From aefe2129315c023413e7780d962016bda19f7f3a Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Wed, 1 Dec 2010 22:03:06 +0100
Subject: [PATCH 244/386] vmstate: port ads7846

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/ads7846.c | 41 ++++++++++++++++++-----------------------
 1 file changed, 18 insertions(+), 23 deletions(-)

diff --git a/hw/ads7846.c b/hw/ads7846.c
index b3bbeaf68e..9c58a5f59f 100644
--- a/hw/ads7846.c
+++ b/hw/ads7846.c
@@ -105,35 +105,30 @@ static void ads7846_ts_event(void *opaque,
     }
 }
 
-static void ads7846_save(QEMUFile *f, void *opaque)
+static int ads7856_post_load(void *opaque, int version_id)
 {
-    ADS7846State *s = (ADS7846State *) opaque;
-    int i;
-
-    for (i = 0; i < 8; i ++)
-        qemu_put_be32(f, s->input[i]);
-    qemu_put_be32(f, s->noise);
-    qemu_put_be32(f, s->cycle);
-    qemu_put_be32(f, s->output);
-}
-
-static int ads7846_load(QEMUFile *f, void *opaque, int version_id)
-{
-    ADS7846State *s = (ADS7846State *) opaque;
-    int i;
-
-    for (i = 0; i < 8; i ++)
-        s->input[i] = qemu_get_be32(f);
-    s->noise = qemu_get_be32(f);
-    s->cycle = qemu_get_be32(f);
-    s->output = qemu_get_be32(f);
+    ADS7846State *s = opaque;
 
     s->pressure = 0;
     ads7846_int_update(s);
-
     return 0;
 }
 
+static const VMStateDescription vmstate_ads7846 = {
+    .name = "ads7846",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .post_load = ads7856_post_load,
+    .fields      = (VMStateField[]) {
+        VMSTATE_INT32_ARRAY(input, ADS7846State, 8),
+        VMSTATE_INT32(noise, ADS7846State),
+        VMSTATE_INT32(cycle, ADS7846State),
+        VMSTATE_INT32(output, ADS7846State),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static int ads7846_init(SSISlave *dev)
 {
     ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev);
@@ -151,7 +146,7 @@ static int ads7846_init(SSISlave *dev)
 
     ads7846_int_update(s);
 
-    register_savevm(NULL, "ads7846", -1, 0, ads7846_save, ads7846_load, s);
+    vmstate_register(NULL, -1, &vmstate_ads7846, s);
     return 0;
 }
 

From fd484ae494bbb38f832fb89a89c979ca6790b531 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 00:16:33 +0100
Subject: [PATCH 245/386] vmstate: port m48t59

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/m48t59.c | 36 +++++++++++++-----------------------
 1 file changed, 13 insertions(+), 23 deletions(-)

diff --git a/hw/m48t59.c b/hw/m48t59.c
index 9f39d6bbf0..537c0f7b16 100644
--- a/hw/m48t59.c
+++ b/hw/m48t59.c
@@ -585,28 +585,18 @@ static CPUReadMemoryFunc * const nvram_read[] = {
     &nvram_readl,
 };
 
-static void m48t59_save(QEMUFile *f, void *opaque)
-{
-    M48t59State *s = opaque;
-
-    qemu_put_8s(f, &s->lock);
-    qemu_put_be16s(f, &s->addr);
-    qemu_put_buffer(f, s->buffer, s->size);
-}
-
-static int m48t59_load(QEMUFile *f, void *opaque, int version_id)
-{
-    M48t59State *s = opaque;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    qemu_get_8s(f, &s->lock);
-    qemu_get_be16s(f, &s->addr);
-    qemu_get_buffer(f, s->buffer, s->size);
-
-    return 0;
-}
+static const VMStateDescription vmstate_m48t59 = {
+    .name = "m48t59",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT8(lock, M48t59State),
+        VMSTATE_UINT16(addr, M48t59State),
+        VMSTATE_VBUFFER_UINT32(buffer, M48t59State, 0, NULL, 0, size),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static void m48t59_reset_common(M48t59State *NVRAM)
 {
@@ -696,7 +686,7 @@ static void m48t59_init_common(M48t59State *s)
     }
     qemu_get_timedate(&s->alarm, 0);
 
-    register_savevm(NULL, "m48t59", -1, 1, m48t59_save, m48t59_load, s);
+    vmstate_register(NULL, -1, &vmstate_m48t59, s);
 }
 
 static int m48t59_init_isa1(ISADevice *dev)

From c7298ab251019b33d55a2ec9ff1880a9aabe33f8 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Wed, 1 Dec 2010 23:02:56 +0100
Subject: [PATCH 246/386] vmstate: port mipsnet

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/mipsnet.c | 53 +++++++++++++++++++---------------------------------
 1 file changed, 19 insertions(+), 34 deletions(-)

diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index c5e54ffc35..26aad51eab 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -202,44 +202,29 @@ static void mipsnet_ioport_write(void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
-static void mipsnet_save(QEMUFile *f, void *opaque)
-{
-    MIPSnetState *s = opaque;
-
-    qemu_put_be32s(f, &s->busy);
-    qemu_put_be32s(f, &s->rx_count);
-    qemu_put_be32s(f, &s->rx_read);
-    qemu_put_be32s(f, &s->tx_count);
-    qemu_put_be32s(f, &s->tx_written);
-    qemu_put_be32s(f, &s->intctl);
-    qemu_put_buffer(f, s->rx_buffer, MAX_ETH_FRAME_SIZE);
-    qemu_put_buffer(f, s->tx_buffer, MAX_ETH_FRAME_SIZE);
-}
-
-static int mipsnet_load(QEMUFile *f, void *opaque, int version_id)
-{
-    MIPSnetState *s = opaque;
-
-    if (version_id > 0)
-        return -EINVAL;
-
-    qemu_get_be32s(f, &s->busy);
-    qemu_get_be32s(f, &s->rx_count);
-    qemu_get_be32s(f, &s->rx_read);
-    qemu_get_be32s(f, &s->tx_count);
-    qemu_get_be32s(f, &s->tx_written);
-    qemu_get_be32s(f, &s->intctl);
-    qemu_get_buffer(f, s->rx_buffer, MAX_ETH_FRAME_SIZE);
-    qemu_get_buffer(f, s->tx_buffer, MAX_ETH_FRAME_SIZE);
-
-    return 0;
-}
+static const VMStateDescription vmstate_mipsnet = {
+    .name = "mipsnet",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(busy, MIPSnetState),
+        VMSTATE_UINT32(rx_count, MIPSnetState),
+        VMSTATE_UINT32(rx_read, MIPSnetState),
+        VMSTATE_UINT32(tx_count, MIPSnetState),
+        VMSTATE_UINT32(tx_written, MIPSnetState),
+        VMSTATE_UINT32(intctl, MIPSnetState),
+        VMSTATE_BUFFER(rx_buffer, MIPSnetState),
+        VMSTATE_BUFFER(tx_buffer, MIPSnetState),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static void mipsnet_cleanup(VLANClientState *nc)
 {
     MIPSnetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
 
-    unregister_savevm(NULL, "mipsnet", s);
+    vmstate_unregister(NULL, &vmstate_mipsnet, s);
 
     isa_unassign_ioport(s->io_base, 36);
 
@@ -284,5 +269,5 @@ void mipsnet_init (int base, qemu_irq irq, NICInfo *nd)
     }
 
     mipsnet_reset(s);
-    register_savevm(NULL, "mipsnet", 0, 0, mipsnet_save, mipsnet_load, s);
+    vmstate_register(NULL, 0, &vmstate_mipsnet, s);
 }

From 81986ac4b66af8005fbe79558c319ba6a38561c2 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Wed, 1 Dec 2010 23:12:32 +0100
Subject: [PATCH 247/386] vmstate: port arm sp804

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/arm_timer.c | 29 +++++++++++------------------
 1 file changed, 11 insertions(+), 18 deletions(-)

diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index 82f05dec84..cfd1ebe22f 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -235,24 +235,17 @@ static CPUWriteMemoryFunc * const sp804_writefn[] = {
    sp804_write
 };
 
-static void sp804_save(QEMUFile *f, void *opaque)
-{
-    sp804_state *s = (sp804_state *)opaque;
-    qemu_put_be32(f, s->level[0]);
-    qemu_put_be32(f, s->level[1]);
-}
 
-static int sp804_load(QEMUFile *f, void *opaque, int version_id)
-{
-    sp804_state *s = (sp804_state *)opaque;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    s->level[0] = qemu_get_be32(f);
-    s->level[1] = qemu_get_be32(f);
-    return 0;
-}
+static const VMStateDescription vmstate_sp804 = {
+    .name = "sp804",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_INT32_ARRAY(level, sp804_state, 2),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static int sp804_init(SysBusDevice *dev)
 {
@@ -271,7 +264,7 @@ static int sp804_init(SysBusDevice *dev)
     iomemtype = cpu_register_io_memory(sp804_readfn,
                                        sp804_writefn, s, DEVICE_NATIVE_ENDIAN);
     sysbus_init_mmio(dev, 0x1000, iomemtype);
-    register_savevm(&dev->qdev, "sp804", -1, 1, sp804_save, sp804_load, s);
+    vmstate_register(&dev->qdev, -1, &vmstate_sp804, s);
     return 0;
 }
 

From eecd33a57895a579bd4d2270b1bc758b608ae5a4 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Wed, 1 Dec 2010 23:15:41 +0100
Subject: [PATCH 248/386] vmstate: port arm_timer

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/arm_timer.c | 37 ++++++++++++++-----------------------
 1 file changed, 14 insertions(+), 23 deletions(-)

diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index cfd1ebe22f..dac9e70750 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -140,28 +140,19 @@ static void arm_timer_tick(void *opaque)
     arm_timer_update(s);
 }
 
-static void arm_timer_save(QEMUFile *f, void *opaque)
-{
-    arm_timer_state *s = (arm_timer_state *)opaque;
-    qemu_put_be32(f, s->control);
-    qemu_put_be32(f, s->limit);
-    qemu_put_be32(f, s->int_level);
-    qemu_put_ptimer(f, s->timer);
-}
-
-static int arm_timer_load(QEMUFile *f, void *opaque, int version_id)
-{
-    arm_timer_state *s = (arm_timer_state *)opaque;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    s->control = qemu_get_be32(f);
-    s->limit = qemu_get_be32(f);
-    s->int_level = qemu_get_be32(f);
-    qemu_get_ptimer(f, s->timer);
-    return 0;
-}
+static const VMStateDescription vmstate_arm_timer = {
+    .name = "arm_timer",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(control, arm_timer_state),
+        VMSTATE_UINT32(limit, arm_timer_state),
+        VMSTATE_INT32(int_level, arm_timer_state),
+        VMSTATE_PTIMER(timer, arm_timer_state),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static arm_timer_state *arm_timer_init(uint32_t freq)
 {
@@ -174,7 +165,7 @@ static arm_timer_state *arm_timer_init(uint32_t freq)
 
     bh = qemu_bh_new(arm_timer_tick, s);
     s->timer = ptimer_init(bh);
-    register_savevm(NULL, "arm_timer", -1, 1, arm_timer_save, arm_timer_load, s);
+    vmstate_register(NULL, -1, &vmstate_arm_timer, s);
     return s;
 }
 

From 22a3faf507a9de2fab8988daf39ff41d09419bec Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Wed, 1 Dec 2010 23:18:59 +0100
Subject: [PATCH 249/386] vmstate: port sysborg_timer

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/syborg_timer.c | 46 ++++++++++++++++------------------------------
 1 file changed, 16 insertions(+), 30 deletions(-)

diff --git a/hw/syborg_timer.c b/hw/syborg_timer.c
index cedcd8ed47..50c813e969 100644
--- a/hw/syborg_timer.c
+++ b/hw/syborg_timer.c
@@ -174,34 +174,21 @@ static CPUWriteMemoryFunc * const syborg_timer_writefn[] = {
     syborg_timer_write
 };
 
-static void syborg_timer_save(QEMUFile *f, void *opaque)
-{
-    SyborgTimerState *s = opaque;
-
-    qemu_put_be32(f, s->running);
-    qemu_put_be32(f, s->oneshot);
-    qemu_put_be32(f, s->limit);
-    qemu_put_be32(f, s->int_level);
-    qemu_put_be32(f, s->int_enabled);
-    qemu_put_ptimer(f, s->timer);
-}
-
-static int syborg_timer_load(QEMUFile *f, void *opaque, int version_id)
-{
-    SyborgTimerState *s = opaque;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    s->running = qemu_get_be32(f);
-    s->oneshot = qemu_get_be32(f);
-    s->limit = qemu_get_be32(f);
-    s->int_level = qemu_get_be32(f);
-    s->int_enabled = qemu_get_be32(f);
-    qemu_get_ptimer(f, s->timer);
-
-    return 0;
-}
+static const VMStateDescription vmstate_syborg_timer = {
+    .name = "syborg_timer",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_INT32(running, SyborgTimerState),
+        VMSTATE_INT32(oneshot, SyborgTimerState),
+        VMSTATE_UINT32(limit, SyborgTimerState),
+        VMSTATE_UINT32(int_level, SyborgTimerState),
+        VMSTATE_UINT32(int_enabled, SyborgTimerState),
+        VMSTATE_PTIMER(timer, SyborgTimerState),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static int syborg_timer_init(SysBusDevice *dev)
 {
@@ -222,8 +209,7 @@ static int syborg_timer_init(SysBusDevice *dev)
     bh = qemu_bh_new(syborg_timer_tick, s);
     s->timer = ptimer_init(bh);
     ptimer_set_freq(s->timer, s->freq);
-    register_savevm(&dev->qdev, "syborg_timer", -1, 1,
-                    syborg_timer_save, syborg_timer_load, s);
+    vmstate_register(&dev->qdev, -1, &vmstate_syborg_timer, s);
     return 0;
 }
 

From 852f771ec9e5cb5e57b4023209f37dd331d5dbdd Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Wed, 1 Dec 2010 23:51:14 +0100
Subject: [PATCH 250/386] vmstate: port pmtimer

It was a half conversion.  Finish it.
enabled can only get values of 0, 1 or 2, was declared as an int but
sent as an unint8_t, change its type.

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/hw.h      | 17 +++++++++------
 hw/ptimer.c  | 59 ++++++++++++++--------------------------------------
 qemu-timer.h |  2 --
 3 files changed, 27 insertions(+), 51 deletions(-)

diff --git a/hw/hw.h b/hw/hw.h
index 1b090395ab..56447a735d 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -689,6 +689,17 @@ extern const VMStateDescription vmstate_usb_device;
     .offset     = vmstate_offset_macaddr(_state, _field),            \
 }
 
+extern const VMStateDescription vmstate_ptimer;
+
+#define VMSTATE_PTIMER(_field, _state) {                             \
+    .name       = (stringify(_field)),                               \
+    .version_id = (1),                                               \
+    .vmsd       = &vmstate_ptimer,                                   \
+    .size       = sizeof(ptimer_state *),                            \
+    .flags      = VMS_STRUCT|VMS_POINTER,                            \
+    .offset     = vmstate_offset_pointer(_state, _field, ptimer_state), \
+}
+
 /* _f : field name
    _f_n : num of elements field_name
    _n : num of elements
@@ -784,12 +795,6 @@ extern const VMStateDescription vmstate_usb_device;
 #define VMSTATE_TIMER_ARRAY(_f, _s, _n)                              \
     VMSTATE_ARRAY_OF_POINTER(_f, _s, _n, 0, vmstate_info_timer, QEMUTimer *)
 
-#define VMSTATE_PTIMER_V(_f, _s, _v)                                  \
-    VMSTATE_POINTER(_f, _s, _v, vmstate_info_ptimer, ptimer_state *)
-
-#define VMSTATE_PTIMER(_f, _s)                                        \
-    VMSTATE_PTIMER_V(_f, _s, 0)
-
 #define VMSTATE_BOOL_ARRAY_V(_f, _s, _n, _v)                         \
     VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_bool, bool)
 
diff --git a/hw/ptimer.c b/hw/ptimer.c
index e68c1d1415..47964a67e1 100644
--- a/hw/ptimer.c
+++ b/hw/ptimer.c
@@ -11,7 +11,7 @@
 
 struct ptimer_state
 {
-    int enabled; /* 0 = disabled, 1 = periodic, 2 = oneshot.  */
+    uint8_t enabled; /* 0 = disabled, 1 = periodic, 2 = oneshot.  */
     uint64_t limit;
     uint64_t delta;
     uint32_t period_frac;
@@ -188,49 +188,22 @@ void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload)
     }
 }
 
-void qemu_put_ptimer(QEMUFile *f, ptimer_state *s)
-{
-    qemu_put_byte(f, s->enabled);
-    qemu_put_be64s(f, &s->limit);
-    qemu_put_be64s(f, &s->delta);
-    qemu_put_be32s(f, &s->period_frac);
-    qemu_put_sbe64s(f, &s->period);
-    qemu_put_sbe64s(f, &s->last_event);
-    qemu_put_sbe64s(f, &s->next_event);
-    qemu_put_timer(f, s->timer);
-}
-
-void qemu_get_ptimer(QEMUFile *f, ptimer_state *s)
-{
-    s->enabled = qemu_get_byte(f);
-    qemu_get_be64s(f, &s->limit);
-    qemu_get_be64s(f, &s->delta);
-    qemu_get_be32s(f, &s->period_frac);
-    qemu_get_sbe64s(f, &s->period);
-    qemu_get_sbe64s(f, &s->last_event);
-    qemu_get_sbe64s(f, &s->next_event);
-    qemu_get_timer(f, s->timer);
-}
-
-static int get_ptimer(QEMUFile *f, void *pv, size_t size)
-{
-    ptimer_state *v = pv;
-
-    qemu_get_ptimer(f, v);
-    return 0;
-}
-
-static void put_ptimer(QEMUFile *f, void *pv, size_t size)
-{
-    ptimer_state *v = pv;
-
-    qemu_put_ptimer(f, v);
-}
-
-const VMStateInfo vmstate_info_ptimer = {
+const VMStateDescription vmstate_ptimer = {
     .name = "ptimer",
-    .get  = get_ptimer,
-    .put  = put_ptimer,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT8(enabled, ptimer_state),
+        VMSTATE_UINT64(limit, ptimer_state),
+        VMSTATE_UINT64(delta, ptimer_state),
+        VMSTATE_UINT32(period_frac, ptimer_state),
+        VMSTATE_INT64(period, ptimer_state),
+        VMSTATE_INT64(last_event, ptimer_state),
+        VMSTATE_INT64(next_event, ptimer_state),
+        VMSTATE_TIMER(timer, ptimer_state),
+        VMSTATE_END_OF_LIST()
+    }
 };
 
 ptimer_state *ptimer_init(QEMUBH *bh)
diff --git a/qemu-timer.h b/qemu-timer.h
index bbc3452bc3..2cacf65535 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -144,8 +144,6 @@ uint64_t ptimer_get_count(ptimer_state *s);
 void ptimer_set_count(ptimer_state *s, uint64_t count);
 void ptimer_run(ptimer_state *s, int oneshot);
 void ptimer_stop(ptimer_state *s);
-void qemu_put_ptimer(QEMUFile *f, ptimer_state *s);
-void qemu_get_ptimer(QEMUFile *f, ptimer_state *s);
 
 /* icount */
 int64_t qemu_icount_round(int64_t count);

From 4ba673ce628ea554a0c095c432813debe6ec339a Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 00:44:28 +0100
Subject: [PATCH 251/386] vmstate: port syborg_rtc

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/syborg_rtc.c | 34 ++++++++++++----------------------
 1 file changed, 12 insertions(+), 22 deletions(-)

diff --git a/hw/syborg_rtc.c b/hw/syborg_rtc.c
index 16d8f9edb8..69f6ccf29c 100644
--- a/hw/syborg_rtc.c
+++ b/hw/syborg_rtc.c
@@ -102,26 +102,17 @@ static CPUWriteMemoryFunc * const syborg_rtc_writefn[] = {
     syborg_rtc_write
 };
 
-static void syborg_rtc_save(QEMUFile *f, void *opaque)
-{
-    SyborgRTCState *s = opaque;
-
-    qemu_put_be64(f, s->offset);
-    qemu_put_be64(f, s->data);
-}
-
-static int syborg_rtc_load(QEMUFile *f, void *opaque, int version_id)
-{
-    SyborgRTCState *s = opaque;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    s->offset = qemu_get_be64(f);
-    s->data = qemu_get_be64(f);
-
-    return 0;
-}
+static const VMStateDescription vmstate_syborg_rtc = {
+    .name = "syborg_keyboard",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_INT64(offset, SyborgRTCState),
+        VMSTATE_INT64(data, SyborgRTCState),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static int syborg_rtc_init(SysBusDevice *dev)
 {
@@ -137,8 +128,7 @@ static int syborg_rtc_init(SysBusDevice *dev)
     qemu_get_timedate(&tm, 0);
     s->offset = (uint64_t)mktime(&tm) * 1000000000;
 
-    register_savevm(&dev->qdev, "syborg_rtc", -1, 1,
-                    syborg_rtc_save, syborg_rtc_load, s);
+    vmstate_register(&dev->qdev, -1, &vmstate_syborg_rtc, s);
     return 0;
 }
 

From 25f5a1b7df5b55aa850326673e30560f294577c7 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 01:06:08 +0100
Subject: [PATCH 252/386] vmstate: port pxa2xx_keypad

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/pxa2xx_keypad.c | 53 +++++++++++++++-------------------------------
 1 file changed, 17 insertions(+), 36 deletions(-)

diff --git a/hw/pxa2xx_keypad.c b/hw/pxa2xx_keypad.c
index d77dbf1793..10ef154aa1 100644
--- a/hw/pxa2xx_keypad.c
+++ b/hw/pxa2xx_keypad.c
@@ -289,40 +289,22 @@ static CPUWriteMemoryFunc * const pxa2xx_keypad_writefn[] = {
     pxa2xx_keypad_write
 };
 
-static void pxa2xx_keypad_save(QEMUFile *f, void *opaque)
-{
-    PXA2xxKeyPadState *s = (PXA2xxKeyPadState *) opaque;
-
-    qemu_put_be32s(f, &s->kpc);
-    qemu_put_be32s(f, &s->kpdk);
-    qemu_put_be32s(f, &s->kprec);
-    qemu_put_be32s(f, &s->kpmk);
-    qemu_put_be32s(f, &s->kpas);
-    qemu_put_be32s(f, &s->kpasmkp[0]);
-    qemu_put_be32s(f, &s->kpasmkp[1]);
-    qemu_put_be32s(f, &s->kpasmkp[2]);
-    qemu_put_be32s(f, &s->kpasmkp[3]);
-    qemu_put_be32s(f, &s->kpkdi);
-
-}
-
-static int pxa2xx_keypad_load(QEMUFile *f, void *opaque, int version_id)
-{
-    PXA2xxKeyPadState *s = (PXA2xxKeyPadState *) opaque;
-
-    qemu_get_be32s(f, &s->kpc);
-    qemu_get_be32s(f, &s->kpdk);
-    qemu_get_be32s(f, &s->kprec);
-    qemu_get_be32s(f, &s->kpmk);
-    qemu_get_be32s(f, &s->kpas);
-    qemu_get_be32s(f, &s->kpasmkp[0]);
-    qemu_get_be32s(f, &s->kpasmkp[1]);
-    qemu_get_be32s(f, &s->kpasmkp[2]);
-    qemu_get_be32s(f, &s->kpasmkp[3]);
-    qemu_get_be32s(f, &s->kpkdi);
-
-    return 0;
-}
+static const VMStateDescription vmstate_pxa2xx_keypad = {
+    .name = "pxa2xx_keypad",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(kpc, PXA2xxKeyPadState),
+        VMSTATE_UINT32(kpdk, PXA2xxKeyPadState),
+        VMSTATE_UINT32(kprec, PXA2xxKeyPadState),
+        VMSTATE_UINT32(kpmk, PXA2xxKeyPadState),
+        VMSTATE_UINT32(kpas, PXA2xxKeyPadState),
+        VMSTATE_UINT32_ARRAY(kpasmkp, PXA2xxKeyPadState, 4),
+        VMSTATE_UINT32(kpkdi, PXA2xxKeyPadState),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 PXA2xxKeyPadState *pxa27x_keypad_init(target_phys_addr_t base,
         qemu_irq irq)
@@ -337,8 +319,7 @@ PXA2xxKeyPadState *pxa27x_keypad_init(target_phys_addr_t base,
                     pxa2xx_keypad_writefn, s, DEVICE_NATIVE_ENDIAN);
     cpu_register_physical_memory(base, 0x00100000, iomemtype);
 
-    register_savevm(NULL, "pxa2xx_keypad", 0, 0,
-                    pxa2xx_keypad_save, pxa2xx_keypad_load, s);
+    vmstate_register(NULL, 0, &vmstate_pxa2xx_keypad, s);
 
     return s;
 }

From 02b687579578a1df9f5733023544c21a8446d3a3 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 01:50:33 +0100
Subject: [PATCH 253/386] vmstate: port pl011

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/pl011.c | 76 ++++++++++++++++++------------------------------------
 1 file changed, 25 insertions(+), 51 deletions(-)

diff --git a/hw/pl011.c b/hw/pl011.c
index 77f0dbf137..3b94b14cb9 100644
--- a/hw/pl011.c
+++ b/hw/pl011.c
@@ -235,56 +235,30 @@ static CPUWriteMemoryFunc * const pl011_writefn[] = {
    pl011_write
 };
 
-static void pl011_save(QEMUFile *f, void *opaque)
-{
-    pl011_state *s = (pl011_state *)opaque;
-    int i;
-
-    qemu_put_be32(f, s->readbuff);
-    qemu_put_be32(f, s->flags);
-    qemu_put_be32(f, s->lcr);
-    qemu_put_be32(f, s->cr);
-    qemu_put_be32(f, s->dmacr);
-    qemu_put_be32(f, s->int_enabled);
-    qemu_put_be32(f, s->int_level);
-    for (i = 0; i < 16; i++)
-        qemu_put_be32(f, s->read_fifo[i]);
-    qemu_put_be32(f, s->ilpr);
-    qemu_put_be32(f, s->ibrd);
-    qemu_put_be32(f, s->fbrd);
-    qemu_put_be32(f, s->ifl);
-    qemu_put_be32(f, s->read_pos);
-    qemu_put_be32(f, s->read_count);
-    qemu_put_be32(f, s->read_trigger);
-}
-
-static int pl011_load(QEMUFile *f, void *opaque, int version_id)
-{
-    pl011_state *s = (pl011_state *)opaque;
-    int i;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    s->readbuff = qemu_get_be32(f);
-    s->flags = qemu_get_be32(f);
-    s->lcr = qemu_get_be32(f);
-    s->cr = qemu_get_be32(f);
-    s->dmacr = qemu_get_be32(f);
-    s->int_enabled = qemu_get_be32(f);
-    s->int_level = qemu_get_be32(f);
-    for (i = 0; i < 16; i++)
-        s->read_fifo[i] = qemu_get_be32(f);
-    s->ilpr = qemu_get_be32(f);
-    s->ibrd = qemu_get_be32(f);
-    s->fbrd = qemu_get_be32(f);
-    s->ifl = qemu_get_be32(f);
-    s->read_pos = qemu_get_be32(f);
-    s->read_count = qemu_get_be32(f);
-    s->read_trigger = qemu_get_be32(f);
-
-    return 0;
-}
+static const VMStateDescription vmstate_pl011 = {
+    .name = "pl011",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(readbuff, pl011_state),
+        VMSTATE_UINT32(flags, pl011_state),
+        VMSTATE_UINT32(lcr, pl011_state),
+        VMSTATE_UINT32(cr, pl011_state),
+        VMSTATE_UINT32(dmacr, pl011_state),
+        VMSTATE_UINT32(int_enabled, pl011_state),
+        VMSTATE_UINT32(int_level, pl011_state),
+        VMSTATE_UINT32_ARRAY(read_fifo, pl011_state, 16),
+        VMSTATE_UINT32(ilpr, pl011_state),
+        VMSTATE_UINT32(ibrd, pl011_state),
+        VMSTATE_UINT32(fbrd, pl011_state),
+        VMSTATE_UINT32(ifl, pl011_state),
+        VMSTATE_INT32(read_pos, pl011_state),
+        VMSTATE_INT32(read_count, pl011_state),
+        VMSTATE_INT32(read_trigger, pl011_state),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static int pl011_init(SysBusDevice *dev, const unsigned char *id)
 {
@@ -307,7 +281,7 @@ static int pl011_init(SysBusDevice *dev, const unsigned char *id)
         qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive,
                               pl011_event, s);
     }
-    register_savevm(&dev->qdev, "pl011_uart", -1, 1, pl011_save, pl011_load, s);
+    vmstate_register(&dev->qdev, -1, &vmstate_pl011, s);
     return 0;
 }
 

From 0797226c56ea51a72ebbf7dcecfd2c1e44147cf0 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 02:17:33 +0100
Subject: [PATCH 254/386] vmstate: port armv7m nvic

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/armv7m_nvic.c | 39 ++++++++++++++-------------------------
 1 file changed, 14 insertions(+), 25 deletions(-)

diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index ffe16b8a61..d06eec9b39 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -365,30 +365,19 @@ static void nvic_writel(void *opaque, uint32_t offset, uint32_t value)
     }
 }
 
-static void nvic_save(QEMUFile *f, void *opaque)
-{
-    nvic_state *s = (nvic_state *)opaque;
-
-    qemu_put_be32(f, s->systick.control);
-    qemu_put_be32(f, s->systick.reload);
-    qemu_put_be64(f, s->systick.tick);
-    qemu_put_timer(f, s->systick.timer);
-}
-
-static int nvic_load(QEMUFile *f, void *opaque, int version_id)
-{
-    nvic_state *s = (nvic_state *)opaque;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    s->systick.control = qemu_get_be32(f);
-    s->systick.reload = qemu_get_be32(f);
-    s->systick.tick = qemu_get_be64(f);
-    qemu_get_timer(f, s->systick.timer);
-
-    return 0;
-}
+static const VMStateDescription vmstate_nvic = {
+    .name = "armv7m_nvic",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(systick.control, nvic_state),
+        VMSTATE_UINT32(systick.reload, nvic_state),
+        VMSTATE_INT64(systick.tick, nvic_state),
+        VMSTATE_TIMER(systick.timer, nvic_state),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static int armv7m_nvic_init(SysBusDevice *dev)
 {
@@ -397,7 +386,7 @@ static int armv7m_nvic_init(SysBusDevice *dev)
     gic_init(&s->gic);
     cpu_register_physical_memory(0xe000e000, 0x1000, s->gic.iomemtype);
     s->systick.timer = qemu_new_timer_ns(vm_clock, systick_timer_tick, s);
-    register_savevm(&dev->qdev, "armv7m_nvic", -1, 1, nvic_save, nvic_load, s);
+    vmstate_register(&dev->qdev, -1, &vmstate_nvic, s);
     return 0;
 }
 

From ff269cd041d33cded58bc734f88456720dcc1864 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 02:48:43 +0100
Subject: [PATCH 255/386] vmstate: port stellaris i2c

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/stellaris.c | 49 +++++++++++++++++--------------------------------
 1 file changed, 17 insertions(+), 32 deletions(-)

diff --git a/hw/stellaris.c b/hw/stellaris.c
index 7932c24576..d0b1588393 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -843,36 +843,22 @@ static CPUWriteMemoryFunc * const stellaris_i2c_writefn[] = {
    stellaris_i2c_write
 };
 
-static void stellaris_i2c_save(QEMUFile *f, void *opaque)
-{
-    stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
-
-    qemu_put_be32(f, s->msa);
-    qemu_put_be32(f, s->mcs);
-    qemu_put_be32(f, s->mdr);
-    qemu_put_be32(f, s->mtpr);
-    qemu_put_be32(f, s->mimr);
-    qemu_put_be32(f, s->mris);
-    qemu_put_be32(f, s->mcr);
-}
-
-static int stellaris_i2c_load(QEMUFile *f, void *opaque, int version_id)
-{
-    stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    s->msa = qemu_get_be32(f);
-    s->mcs = qemu_get_be32(f);
-    s->mdr = qemu_get_be32(f);
-    s->mtpr = qemu_get_be32(f);
-    s->mimr = qemu_get_be32(f);
-    s->mris = qemu_get_be32(f);
-    s->mcr = qemu_get_be32(f);
-
-    return 0;
-}
+static const VMStateDescription vmstate_stellaris_i2c = {
+    .name = "stellaris_i2c",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(msa, stellaris_i2c_state),
+        VMSTATE_UINT32(mcs, stellaris_i2c_state),
+        VMSTATE_UINT32(mdr, stellaris_i2c_state),
+        VMSTATE_UINT32(mtpr, stellaris_i2c_state),
+        VMSTATE_UINT32(mimr, stellaris_i2c_state),
+        VMSTATE_UINT32(mris, stellaris_i2c_state),
+        VMSTATE_UINT32(mcr, stellaris_i2c_state),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static int stellaris_i2c_init(SysBusDevice * dev)
 {
@@ -890,8 +876,7 @@ static int stellaris_i2c_init(SysBusDevice * dev)
     sysbus_init_mmio(dev, 0x1000, iomemtype);
     /* ??? For now we only implement the master interface.  */
     stellaris_i2c_reset(s);
-    register_savevm(&dev->qdev, "stellaris_i2c", -1, 1,
-                    stellaris_i2c_save, stellaris_i2c_load, s);
+    vmstate_register(&dev->qdev, -1, &vmstate_stellaris_i2c, s);
     return 0;
 }
 

From a4dec1d0d423443d3e5a026a1776fb41b33c06eb Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 02:51:29 +0100
Subject: [PATCH 256/386] vmstate: port stellaris ssi bus

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/stellaris.c | 31 +++++++++++--------------------
 1 file changed, 11 insertions(+), 20 deletions(-)

diff --git a/hw/stellaris.c b/hw/stellaris.c
index d0b1588393..00efb36037 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -1218,24 +1218,16 @@ static uint32_t stellaris_ssi_bus_transfer(SSISlave *dev, uint32_t val)
     return ssi_transfer(s->bus[s->current_dev], val);
 }
 
-static void stellaris_ssi_bus_save(QEMUFile *f, void *opaque)
-{
-    stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
-
-    qemu_put_be32(f, s->current_dev);
-}
-
-static int stellaris_ssi_bus_load(QEMUFile *f, void *opaque, int version_id)
-{
-    stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    s->current_dev = qemu_get_be32(f);
-
-    return 0;
-}
+static const VMStateDescription vmstate_stellaris_ssi_bus = {
+    .name = "stellaris_ssi_bus",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_INT32(current_dev, stellaris_ssi_bus_state),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static int stellaris_ssi_bus_init(SSISlave *dev)
 {
@@ -1245,8 +1237,7 @@ static int stellaris_ssi_bus_init(SSISlave *dev)
     s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1");
     qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1);
 
-    register_savevm(&dev->qdev, "stellaris_ssi_bus", -1, 1,
-                    stellaris_ssi_bus_save, stellaris_ssi_bus_load, s);
+    vmstate_register(&dev->qdev, -1, &vmstate_stellaris_ssi_bus, s);
     return 0;
 }
 

From 293c16aa372fcdfed3be460cf657aced56327195 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 03:03:11 +0100
Subject: [PATCH 257/386] vmstate: port stellaris sys

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/stellaris.c | 71 ++++++++++++++++++--------------------------------
 1 file changed, 25 insertions(+), 46 deletions(-)

diff --git a/hw/stellaris.c b/hw/stellaris.c
index 00efb36037..11d618d87a 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -604,58 +604,37 @@ static void ssys_reset(void *opaque)
     s->dcgc[0] = 1;
 }
 
-static void ssys_save(QEMUFile *f, void *opaque)
+static int stellaris_sys_post_load(void *opaque, int version_id)
 {
-    ssys_state *s = (ssys_state *)opaque;
+    ssys_state *s = opaque;
 
-    qemu_put_be32(f, s->pborctl);
-    qemu_put_be32(f, s->ldopctl);
-    qemu_put_be32(f, s->int_mask);
-    qemu_put_be32(f, s->int_status);
-    qemu_put_be32(f, s->resc);
-    qemu_put_be32(f, s->rcc);
-    qemu_put_be32(f, s->rcgc[0]);
-    qemu_put_be32(f, s->rcgc[1]);
-    qemu_put_be32(f, s->rcgc[2]);
-    qemu_put_be32(f, s->scgc[0]);
-    qemu_put_be32(f, s->scgc[1]);
-    qemu_put_be32(f, s->scgc[2]);
-    qemu_put_be32(f, s->dcgc[0]);
-    qemu_put_be32(f, s->dcgc[1]);
-    qemu_put_be32(f, s->dcgc[2]);
-    qemu_put_be32(f, s->clkvclr);
-    qemu_put_be32(f, s->ldoarst);
-}
-
-static int ssys_load(QEMUFile *f, void *opaque, int version_id)
-{
-    ssys_state *s = (ssys_state *)opaque;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    s->pborctl = qemu_get_be32(f);
-    s->ldopctl = qemu_get_be32(f);
-    s->int_mask = qemu_get_be32(f);
-    s->int_status = qemu_get_be32(f);
-    s->resc = qemu_get_be32(f);
-    s->rcc = qemu_get_be32(f);
-    s->rcgc[0] = qemu_get_be32(f);
-    s->rcgc[1] = qemu_get_be32(f);
-    s->rcgc[2] = qemu_get_be32(f);
-    s->scgc[0] = qemu_get_be32(f);
-    s->scgc[1] = qemu_get_be32(f);
-    s->scgc[2] = qemu_get_be32(f);
-    s->dcgc[0] = qemu_get_be32(f);
-    s->dcgc[1] = qemu_get_be32(f);
-    s->dcgc[2] = qemu_get_be32(f);
-    s->clkvclr = qemu_get_be32(f);
-    s->ldoarst = qemu_get_be32(f);
     ssys_calculate_system_clock(s);
 
     return 0;
 }
 
+static const VMStateDescription vmstate_stellaris_sys = {
+    .name = "stellaris_sys",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .post_load = stellaris_sys_post_load,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(pborctl, ssys_state),
+        VMSTATE_UINT32(ldopctl, ssys_state),
+        VMSTATE_UINT32(int_mask, ssys_state),
+        VMSTATE_UINT32(int_status, ssys_state),
+        VMSTATE_UINT32(resc, ssys_state),
+        VMSTATE_UINT32(rcc, ssys_state),
+        VMSTATE_UINT32_ARRAY(rcgc, ssys_state, 3),
+        VMSTATE_UINT32_ARRAY(scgc, ssys_state, 3),
+        VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3),
+        VMSTATE_UINT32(clkvclr, ssys_state),
+        VMSTATE_UINT32(ldoarst, ssys_state),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static int stellaris_sys_init(uint32_t base, qemu_irq irq,
                               stellaris_board_info * board,
                               uint8_t *macaddr)
@@ -675,7 +654,7 @@ static int stellaris_sys_init(uint32_t base, qemu_irq irq,
                                        DEVICE_NATIVE_ENDIAN);
     cpu_register_physical_memory(base, 0x00001000, iomemtype);
     ssys_reset(s);
-    register_savevm(NULL, "stellaris_sys", -1, 1, ssys_save, ssys_load, s);
+    vmstate_register(NULL, -1, &vmstate_stellaris_sys, s);
     return 0;
 }
 

From 075790c2c24f0dee15c584ae5c49903a52343bd4 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 12:43:50 +0100
Subject: [PATCH 258/386] vmstate: port pl022 ssp

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/pl022.c | 84 +++++++++++++++++++++++-------------------------------
 1 file changed, 36 insertions(+), 48 deletions(-)

diff --git a/hw/pl022.c b/hw/pl022.c
index ffe05ab747..00e494a0de 100644
--- a/hw/pl022.c
+++ b/hw/pl022.c
@@ -239,54 +239,42 @@ static CPUWriteMemoryFunc * const pl022_writefn[] = {
    pl022_write
 };
 
-static void pl022_save(QEMUFile *f, void *opaque)
-{
-    pl022_state *s = (pl022_state *)opaque;
-    int i;
-
-    qemu_put_be32(f, s->cr0);
-    qemu_put_be32(f, s->cr1);
-    qemu_put_be32(f, s->bitmask);
-    qemu_put_be32(f, s->sr);
-    qemu_put_be32(f, s->cpsr);
-    qemu_put_be32(f, s->is);
-    qemu_put_be32(f, s->im);
-    qemu_put_be32(f, s->tx_fifo_head);
-    qemu_put_be32(f, s->rx_fifo_head);
-    qemu_put_be32(f, s->tx_fifo_len);
-    qemu_put_be32(f, s->rx_fifo_len);
-    for (i = 0; i < 8; i++) {
-        qemu_put_be16(f, s->tx_fifo[i]);
-        qemu_put_be16(f, s->rx_fifo[i]);
+static const VMStateDescription vmstate_pl022 = {
+    .name = "pl022_ssp",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(cr0, pl022_state),
+        VMSTATE_UINT32(cr1, pl022_state),
+        VMSTATE_UINT32(bitmask, pl022_state),
+        VMSTATE_UINT32(sr, pl022_state),
+        VMSTATE_UINT32(cpsr, pl022_state),
+        VMSTATE_UINT32(is, pl022_state),
+        VMSTATE_UINT32(im, pl022_state),
+        VMSTATE_INT32(tx_fifo_head, pl022_state),
+        VMSTATE_INT32(rx_fifo_head, pl022_state),
+        VMSTATE_INT32(tx_fifo_len, pl022_state),
+        VMSTATE_INT32(rx_fifo_len, pl022_state),
+        VMSTATE_UINT16(tx_fifo[0], pl022_state),
+        VMSTATE_UINT16(rx_fifo[0], pl022_state),
+        VMSTATE_UINT16(tx_fifo[1], pl022_state),
+        VMSTATE_UINT16(rx_fifo[1], pl022_state),
+        VMSTATE_UINT16(tx_fifo[2], pl022_state),
+        VMSTATE_UINT16(rx_fifo[2], pl022_state),
+        VMSTATE_UINT16(tx_fifo[3], pl022_state),
+        VMSTATE_UINT16(rx_fifo[3], pl022_state),
+        VMSTATE_UINT16(tx_fifo[4], pl022_state),
+        VMSTATE_UINT16(rx_fifo[4], pl022_state),
+        VMSTATE_UINT16(tx_fifo[5], pl022_state),
+        VMSTATE_UINT16(rx_fifo[5], pl022_state),
+        VMSTATE_UINT16(tx_fifo[6], pl022_state),
+        VMSTATE_UINT16(rx_fifo[6], pl022_state),
+        VMSTATE_UINT16(tx_fifo[7], pl022_state),
+        VMSTATE_UINT16(rx_fifo[7], pl022_state),
+        VMSTATE_END_OF_LIST()
     }
-}
-
-static int pl022_load(QEMUFile *f, void *opaque, int version_id)
-{
-    pl022_state *s = (pl022_state *)opaque;
-    int i;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    s->cr0 = qemu_get_be32(f);
-    s->cr1 = qemu_get_be32(f);
-    s->bitmask = qemu_get_be32(f);
-    s->sr = qemu_get_be32(f);
-    s->cpsr = qemu_get_be32(f);
-    s->is = qemu_get_be32(f);
-    s->im = qemu_get_be32(f);
-    s->tx_fifo_head = qemu_get_be32(f);
-    s->rx_fifo_head = qemu_get_be32(f);
-    s->tx_fifo_len = qemu_get_be32(f);
-    s->rx_fifo_len = qemu_get_be32(f);
-    for (i = 0; i < 8; i++) {
-        s->tx_fifo[i] = qemu_get_be16(f);
-        s->rx_fifo[i] = qemu_get_be16(f);
-    }
-
-    return 0;
-}
+};
 
 static int pl022_init(SysBusDevice *dev)
 {
@@ -300,7 +288,7 @@ static int pl022_init(SysBusDevice *dev)
     sysbus_init_irq(dev, &s->irq);
     s->ssi = ssi_create_bus(&dev->qdev, "ssi");
     pl022_reset(s);
-    register_savevm(&dev->qdev, "pl022_ssp", -1, 1, pl022_save, pl022_load, s);
+    vmstate_register(&dev->qdev, -1, &vmstate_pl022, s);
     return 0;
 }
 

From 4acd38cef07820238e9d76ae68f14689f9764ef0 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 13:17:23 +0100
Subject: [PATCH 259/386] vmstate: port heathrow_pic

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/heathrow_pic.c | 62 +++++++++++++++++++----------------------------
 1 file changed, 25 insertions(+), 37 deletions(-)

diff --git a/hw/heathrow_pic.c b/hw/heathrow_pic.c
index b19b754b31..5fd71a0f71 100644
--- a/hw/heathrow_pic.c
+++ b/hw/heathrow_pic.c
@@ -159,42 +159,31 @@ static void heathrow_pic_set_irq(void *opaque, int num, int level)
     heathrow_pic_update(s);
 }
 
-static void heathrow_pic_save_one(QEMUFile *f, HeathrowPIC *s)
-{
-    qemu_put_be32s(f, &s->events);
-    qemu_put_be32s(f, &s->mask);
-    qemu_put_be32s(f, &s->levels);
-    qemu_put_be32s(f, &s->level_triggered);
-}
+static const VMStateDescription vmstate_heathrow_pic_one = {
+    .name = "heathrow_pic_one",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(events, HeathrowPIC),
+        VMSTATE_UINT32(mask, HeathrowPIC),
+        VMSTATE_UINT32(levels, HeathrowPIC),
+        VMSTATE_UINT32(level_triggered, HeathrowPIC),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
-static void heathrow_pic_save(QEMUFile *f, void *opaque)
-{
-    HeathrowPICS *s = (HeathrowPICS *)opaque;
-
-    heathrow_pic_save_one(f, &s->pics[0]);
-    heathrow_pic_save_one(f, &s->pics[1]);
-}
-
-static void heathrow_pic_load_one(QEMUFile *f, HeathrowPIC *s)
-{
-    qemu_get_be32s(f, &s->events);
-    qemu_get_be32s(f, &s->mask);
-    qemu_get_be32s(f, &s->levels);
-    qemu_get_be32s(f, &s->level_triggered);
-}
-
-static int heathrow_pic_load(QEMUFile *f, void *opaque, int version_id)
-{
-    HeathrowPICS *s = (HeathrowPICS *)opaque;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    heathrow_pic_load_one(f, &s->pics[0]);
-    heathrow_pic_load_one(f, &s->pics[1]);
-
-    return 0;
-}
+static const VMStateDescription vmstate_heathrow_pic = {
+    .name = "heathrow_pic",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_STRUCT_ARRAY(pics, HeathrowPICS, 2, 1,
+                             vmstate_heathrow_pic_one, HeathrowPIC),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static void heathrow_pic_reset_one(HeathrowPIC *s)
 {
@@ -223,8 +212,7 @@ qemu_irq *heathrow_pic_init(int *pmem_index,
     *pmem_index = cpu_register_io_memory(pic_read, pic_write, s,
                                          DEVICE_LITTLE_ENDIAN);
 
-    register_savevm(NULL, "heathrow_pic", -1, 1, heathrow_pic_save,
-                    heathrow_pic_load, s);
+    vmstate_register(NULL, -1, &vmstate_heathrow_pic, s);
     qemu_register_reset(heathrow_pic_reset, s);
     return qemu_allocate_irqs(heathrow_pic_set_irq, s, 64);
 }

From c0a93a9efabae3c9a8500bf2f14ffb06e313dc73 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 13:53:24 +0100
Subject: [PATCH 260/386] vmstate: port cuda

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/cuda.c | 118 ++++++++++++++++++++++--------------------------------
 1 file changed, 47 insertions(+), 71 deletions(-)

diff --git a/hw/cuda.c b/hw/cuda.c
index 37aa3f47fc..065c362aef 100644
--- a/hw/cuda.c
+++ b/hw/cuda.c
@@ -644,80 +644,56 @@ static CPUReadMemoryFunc * const cuda_read[] = {
     &cuda_readl,
 };
 
-static void cuda_save_timer(QEMUFile *f, CUDATimer *s)
+static bool cuda_timer_exist(void *opaque, int version_id)
 {
-    qemu_put_be16s(f, &s->latch);
-    qemu_put_be16s(f, &s->counter_value);
-    qemu_put_sbe64s(f, &s->load_time);
-    qemu_put_sbe64s(f, &s->next_irq_time);
-    if (s->timer)
-        qemu_put_timer(f, s->timer);
+    CUDATimer *s = opaque;
+
+    return s->timer != NULL;
 }
 
-static void cuda_save(QEMUFile *f, void *opaque)
-{
-    CUDAState *s = (CUDAState *)opaque;
+static const VMStateDescription vmstate_cuda_timer = {
+    .name = "cuda_timer",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT16(latch, CUDATimer),
+        VMSTATE_UINT16(counter_value, CUDATimer),
+        VMSTATE_INT64(load_time, CUDATimer),
+        VMSTATE_INT64(next_irq_time, CUDATimer),
+        VMSTATE_TIMER_TEST(timer, CUDATimer, cuda_timer_exist),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
-    qemu_put_ubyte(f, s->b);
-    qemu_put_ubyte(f, s->a);
-    qemu_put_ubyte(f, s->dirb);
-    qemu_put_ubyte(f, s->dira);
-    qemu_put_ubyte(f, s->sr);
-    qemu_put_ubyte(f, s->acr);
-    qemu_put_ubyte(f, s->pcr);
-    qemu_put_ubyte(f, s->ifr);
-    qemu_put_ubyte(f, s->ier);
-    qemu_put_ubyte(f, s->anh);
-    qemu_put_sbe32s(f, &s->data_in_size);
-    qemu_put_sbe32s(f, &s->data_in_index);
-    qemu_put_sbe32s(f, &s->data_out_index);
-    qemu_put_ubyte(f, s->autopoll);
-    qemu_put_buffer(f, s->data_in, sizeof(s->data_in));
-    qemu_put_buffer(f, s->data_out, sizeof(s->data_out));
-    qemu_put_be32s(f, &s->tick_offset);
-    cuda_save_timer(f, &s->timers[0]);
-    cuda_save_timer(f, &s->timers[1]);
-}
-
-static void cuda_load_timer(QEMUFile *f, CUDATimer *s)
-{
-    qemu_get_be16s(f, &s->latch);
-    qemu_get_be16s(f, &s->counter_value);
-    qemu_get_sbe64s(f, &s->load_time);
-    qemu_get_sbe64s(f, &s->next_irq_time);
-    if (s->timer)
-        qemu_get_timer(f, s->timer);
-}
-
-static int cuda_load(QEMUFile *f, void *opaque, int version_id)
-{
-    CUDAState *s = (CUDAState *)opaque;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    s->b = qemu_get_ubyte(f);
-    s->a = qemu_get_ubyte(f);
-    s->dirb = qemu_get_ubyte(f);
-    s->dira = qemu_get_ubyte(f);
-    s->sr = qemu_get_ubyte(f);
-    s->acr = qemu_get_ubyte(f);
-    s->pcr = qemu_get_ubyte(f);
-    s->ifr = qemu_get_ubyte(f);
-    s->ier = qemu_get_ubyte(f);
-    s->anh = qemu_get_ubyte(f);
-    qemu_get_sbe32s(f, &s->data_in_size);
-    qemu_get_sbe32s(f, &s->data_in_index);
-    qemu_get_sbe32s(f, &s->data_out_index);
-    s->autopoll = qemu_get_ubyte(f);
-    qemu_get_buffer(f, s->data_in, sizeof(s->data_in));
-    qemu_get_buffer(f, s->data_out, sizeof(s->data_out));
-    qemu_get_be32s(f, &s->tick_offset);
-    cuda_load_timer(f, &s->timers[0]);
-    cuda_load_timer(f, &s->timers[1]);
-
-    return 0;
-}
+static const VMStateDescription vmstate_cuda = {
+    .name = "cuda",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT8(a, CUDAState),
+        VMSTATE_UINT8(b, CUDAState),
+        VMSTATE_UINT8(dira, CUDAState),
+        VMSTATE_UINT8(dirb, CUDAState),
+        VMSTATE_UINT8(sr, CUDAState),
+        VMSTATE_UINT8(acr, CUDAState),
+        VMSTATE_UINT8(pcr, CUDAState),
+        VMSTATE_UINT8(ifr, CUDAState),
+        VMSTATE_UINT8(ier, CUDAState),
+        VMSTATE_UINT8(anh, CUDAState),
+        VMSTATE_INT32(data_in_size, CUDAState),
+        VMSTATE_INT32(data_in_index, CUDAState),
+        VMSTATE_INT32(data_out_index, CUDAState),
+        VMSTATE_UINT8(autopoll, CUDAState),
+        VMSTATE_BUFFER(data_in, CUDAState),
+        VMSTATE_BUFFER(data_out, CUDAState),
+        VMSTATE_UINT32(tick_offset, CUDAState),
+        VMSTATE_STRUCT_ARRAY(timers, CUDAState, 2, 1,
+                             vmstate_cuda_timer, CUDATimer),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static void cuda_reset(void *opaque)
 {
@@ -764,6 +740,6 @@ void cuda_init (int *cuda_mem_index, qemu_irq irq)
     s->adb_poll_timer = qemu_new_timer_ns(vm_clock, cuda_adb_poll, s);
     *cuda_mem_index = cpu_register_io_memory(cuda_read, cuda_write, s,
                                              DEVICE_NATIVE_ENDIAN);
-    register_savevm(NULL, "cuda", -1, 1, cuda_save, cuda_load, s);
+    vmstate_register(NULL, -1, &vmstate_cuda, s);
     qemu_register_reset(cuda_reset, s);
 }

From 10f85a2934eb0b59470015b1243acc9369f71fd0 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 14:07:01 +0100
Subject: [PATCH 261/386] vmstate: port stellaris gptm

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/stellaris.c | 84 +++++++++++++++-----------------------------------
 1 file changed, 24 insertions(+), 60 deletions(-)

diff --git a/hw/stellaris.c b/hw/stellaris.c
index 11d618d87a..31aa102d14 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -279,64 +279,29 @@ static CPUWriteMemoryFunc * const gptm_writefn[] = {
    gptm_write
 };
 
-static void gptm_save(QEMUFile *f, void *opaque)
-{
-    gptm_state *s = (gptm_state *)opaque;
-
-    qemu_put_be32(f, s->config);
-    qemu_put_be32(f, s->mode[0]);
-    qemu_put_be32(f, s->mode[1]);
-    qemu_put_be32(f, s->control);
-    qemu_put_be32(f, s->state);
-    qemu_put_be32(f, s->mask);
-    qemu_put_be32(f, s->mode[0]);
-    qemu_put_be32(f, s->mode[0]);
-    qemu_put_be32(f, s->load[0]);
-    qemu_put_be32(f, s->load[1]);
-    qemu_put_be32(f, s->match[0]);
-    qemu_put_be32(f, s->match[1]);
-    qemu_put_be32(f, s->prescale[0]);
-    qemu_put_be32(f, s->prescale[1]);
-    qemu_put_be32(f, s->match_prescale[0]);
-    qemu_put_be32(f, s->match_prescale[1]);
-    qemu_put_be32(f, s->rtc);
-    qemu_put_be64(f, s->tick[0]);
-    qemu_put_be64(f, s->tick[1]);
-    qemu_put_timer(f, s->timer[0]);
-    qemu_put_timer(f, s->timer[1]);
-}
-
-static int gptm_load(QEMUFile *f, void *opaque, int version_id)
-{
-    gptm_state *s = (gptm_state *)opaque;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    s->config = qemu_get_be32(f);
-    s->mode[0] = qemu_get_be32(f);
-    s->mode[1] = qemu_get_be32(f);
-    s->control = qemu_get_be32(f);
-    s->state = qemu_get_be32(f);
-    s->mask = qemu_get_be32(f);
-    s->mode[0] = qemu_get_be32(f);
-    s->mode[0] = qemu_get_be32(f);
-    s->load[0] = qemu_get_be32(f);
-    s->load[1] = qemu_get_be32(f);
-    s->match[0] = qemu_get_be32(f);
-    s->match[1] = qemu_get_be32(f);
-    s->prescale[0] = qemu_get_be32(f);
-    s->prescale[1] = qemu_get_be32(f);
-    s->match_prescale[0] = qemu_get_be32(f);
-    s->match_prescale[1] = qemu_get_be32(f);
-    s->rtc = qemu_get_be32(f);
-    s->tick[0] = qemu_get_be64(f);
-    s->tick[1] = qemu_get_be64(f);
-    qemu_get_timer(f, s->timer[0]);
-    qemu_get_timer(f, s->timer[1]);
-
-    return 0;
-}
+static const VMStateDescription vmstate_stellaris_gptm = {
+    .name = "stellaris_gptm",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(config, gptm_state),
+        VMSTATE_UINT32_ARRAY(mode, gptm_state, 2),
+        VMSTATE_UINT32(control, gptm_state),
+        VMSTATE_UINT32(state, gptm_state),
+        VMSTATE_UINT32(mask, gptm_state),
+        VMSTATE_UINT32(mode[0], gptm_state),
+        VMSTATE_UINT32(mode[0], gptm_state),
+        VMSTATE_UINT32_ARRAY(load, gptm_state, 2),
+        VMSTATE_UINT32_ARRAY(match, gptm_state, 2),
+        VMSTATE_UINT32_ARRAY(prescale, gptm_state, 2),
+        VMSTATE_UINT32_ARRAY(match_prescale, gptm_state, 2),
+        VMSTATE_UINT32(rtc, gptm_state),
+        VMSTATE_INT64_ARRAY(tick, gptm_state, 2),
+        VMSTATE_TIMER_ARRAY(timer, gptm_state, 2),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static int stellaris_gptm_init(SysBusDevice *dev)
 {
@@ -354,8 +319,7 @@ static int stellaris_gptm_init(SysBusDevice *dev)
     s->opaque[0] = s->opaque[1] = s;
     s->timer[0] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[0]);
     s->timer[1] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[1]);
-    register_savevm(&dev->qdev, "stellaris_gptm", -1, 1,
-                    gptm_save, gptm_load, s);
+    vmstate_register(&dev->qdev, -1, &vmstate_stellaris_gptm, s);
     return 0;
 }
 

From 9f5dfe298bbbf539b7a4ee802f274adff52b8648 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 14:14:56 +0100
Subject: [PATCH 262/386] vmstate: port pxa2xx_i2s

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/pxa2xx.c | 53 ++++++++++++++++++-----------------------------------
 1 file changed, 18 insertions(+), 35 deletions(-)

diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index 9b95e2c8e2..96932ef829 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -1748,39 +1748,23 @@ static CPUWriteMemoryFunc * const pxa2xx_i2s_writefn[] = {
     pxa2xx_i2s_write,
 };
 
-static void pxa2xx_i2s_save(QEMUFile *f, void *opaque)
-{
-    PXA2xxI2SState *s = (PXA2xxI2SState *) opaque;
-
-    qemu_put_be32s(f, &s->control[0]);
-    qemu_put_be32s(f, &s->control[1]);
-    qemu_put_be32s(f, &s->status);
-    qemu_put_be32s(f, &s->mask);
-    qemu_put_be32s(f, &s->clk);
-
-    qemu_put_be32(f, s->enable);
-    qemu_put_be32(f, s->rx_len);
-    qemu_put_be32(f, s->tx_len);
-    qemu_put_be32(f, s->fifo_len);
-}
-
-static int pxa2xx_i2s_load(QEMUFile *f, void *opaque, int version_id)
-{
-    PXA2xxI2SState *s = (PXA2xxI2SState *) opaque;
-
-    qemu_get_be32s(f, &s->control[0]);
-    qemu_get_be32s(f, &s->control[1]);
-    qemu_get_be32s(f, &s->status);
-    qemu_get_be32s(f, &s->mask);
-    qemu_get_be32s(f, &s->clk);
-
-    s->enable = qemu_get_be32(f);
-    s->rx_len = qemu_get_be32(f);
-    s->tx_len = qemu_get_be32(f);
-    s->fifo_len = qemu_get_be32(f);
-
-    return 0;
-}
+static const VMStateDescription vmstate_pxa2xx_i2s = {
+    .name = "pxa2xx_i2s",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(control, PXA2xxI2SState, 2),
+        VMSTATE_UINT32(status, PXA2xxI2SState),
+        VMSTATE_UINT32(mask, PXA2xxI2SState),
+        VMSTATE_UINT32(clk, PXA2xxI2SState),
+        VMSTATE_INT32(enable, PXA2xxI2SState),
+        VMSTATE_INT32(rx_len, PXA2xxI2SState),
+        VMSTATE_INT32(tx_len, PXA2xxI2SState),
+        VMSTATE_INT32(fifo_len, PXA2xxI2SState),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static void pxa2xx_i2s_data_req(void *opaque, int tx, int rx)
 {
@@ -1822,8 +1806,7 @@ static PXA2xxI2SState *pxa2xx_i2s_init(target_phys_addr_t base,
                     pxa2xx_i2s_writefn, s, DEVICE_NATIVE_ENDIAN);
     cpu_register_physical_memory(base, 0x100000, iomemtype);
 
-    register_savevm(NULL, "pxa2xx_i2s", base, 0,
-                    pxa2xx_i2s_save, pxa2xx_i2s_load, s);
+    vmstate_register(NULL, base, &vmstate_pxa2xx_i2s, s);
 
     return s;
 }

From ae1f90de0664475cd1f12c5b229f0cb99bd8fcc3 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 14:31:14 +0100
Subject: [PATCH 263/386] vmstate: port pxa2xx_cm

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/pxa2xx.c | 39 ++++++++++++++-------------------------
 1 file changed, 14 insertions(+), 25 deletions(-)

diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index 96932ef829..a824c22e65 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -227,29 +227,18 @@ static CPUWriteMemoryFunc * const pxa2xx_cm_writefn[] = {
     pxa2xx_cm_write,
 };
 
-static void pxa2xx_cm_save(QEMUFile *f, void *opaque)
-{
-    PXA2xxState *s = (PXA2xxState *) opaque;
-    int i;
-
-    for (i = 0; i < 4; i ++)
-        qemu_put_be32s(f, &s->cm_regs[i]);
-    qemu_put_be32s(f, &s->clkcfg);
-    qemu_put_be32s(f, &s->pmnc);
-}
-
-static int pxa2xx_cm_load(QEMUFile *f, void *opaque, int version_id)
-{
-    PXA2xxState *s = (PXA2xxState *) opaque;
-    int i;
-
-    for (i = 0; i < 4; i ++)
-        qemu_get_be32s(f, &s->cm_regs[i]);
-    qemu_get_be32s(f, &s->clkcfg);
-    qemu_get_be32s(f, &s->pmnc);
-
-    return 0;
-}
+static const VMStateDescription vmstate_pxa2xx_cm = {
+    .name = "pxa2xx_cm",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(cm_regs, PXA2xxState, 4),
+        VMSTATE_UINT32(clkcfg, PXA2xxState),
+        VMSTATE_UINT32(pmnc, PXA2xxState),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static uint32_t pxa2xx_clkpwr_read(void *opaque, int op2, int reg, int crm)
 {
@@ -2171,7 +2160,7 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
     iomemtype = cpu_register_io_memory(pxa2xx_cm_readfn,
                     pxa2xx_cm_writefn, s, DEVICE_NATIVE_ENDIAN);
     cpu_register_physical_memory(s->cm_base, 0x1000, iomemtype);
-    register_savevm(NULL, "pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s);
+    vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s);
 
     cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s);
 
@@ -2307,7 +2296,7 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
     iomemtype = cpu_register_io_memory(pxa2xx_cm_readfn,
                     pxa2xx_cm_writefn, s, DEVICE_NATIVE_ENDIAN);
     cpu_register_physical_memory(s->cm_base, 0x1000, iomemtype);
-    register_savevm(NULL, "pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s);
+    vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s);
 
     cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s);
 

From d102d49545273661016f66646a9f56ee52b2aee5 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 14:36:57 +0100
Subject: [PATCH 264/386] vmstate: port pxa2xx_mm

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/pxa2xx.c | 33 ++++++++++++---------------------
 1 file changed, 12 insertions(+), 21 deletions(-)

diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index a824c22e65..e174c20d47 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -516,25 +516,16 @@ static CPUWriteMemoryFunc * const pxa2xx_mm_writefn[] = {
     pxa2xx_mm_write,
 };
 
-static void pxa2xx_mm_save(QEMUFile *f, void *opaque)
-{
-    PXA2xxState *s = (PXA2xxState *) opaque;
-    int i;
-
-    for (i = 0; i < 0x1a; i ++)
-        qemu_put_be32s(f, &s->mm_regs[i]);
-}
-
-static int pxa2xx_mm_load(QEMUFile *f, void *opaque, int version_id)
-{
-    PXA2xxState *s = (PXA2xxState *) opaque;
-    int i;
-
-    for (i = 0; i < 0x1a; i ++)
-        qemu_get_be32s(f, &s->mm_regs[i]);
-
-    return 0;
-}
+static const VMStateDescription vmstate_pxa2xx_mm = {
+    .name = "pxa2xx_mm",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(mm_regs, PXA2xxState, 0x1a),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 /* Synchronous Serial Ports */
 typedef struct {
@@ -2171,7 +2162,7 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
     iomemtype = cpu_register_io_memory(pxa2xx_mm_readfn,
                     pxa2xx_mm_writefn, s, DEVICE_NATIVE_ENDIAN);
     cpu_register_physical_memory(s->mm_base, 0x1000, iomemtype);
-    register_savevm(NULL, "pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s);
+    vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s);
 
     s->pm_base = 0x40f00000;
     iomemtype = cpu_register_io_memory(pxa2xx_pm_readfn,
@@ -2307,7 +2298,7 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
     iomemtype = cpu_register_io_memory(pxa2xx_mm_readfn,
                     pxa2xx_mm_writefn, s, DEVICE_NATIVE_ENDIAN);
     cpu_register_physical_memory(s->mm_base, 0x1000, iomemtype);
-    register_savevm(NULL, "pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s);
+    vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s);
 
     s->pm_base = 0x40f00000;
     iomemtype = cpu_register_io_memory(pxa2xx_pm_readfn,

From f0ab24ce69347f71a5952b105777bfe22665259a Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 14:54:38 +0100
Subject: [PATCH 265/386] vmstate: port pxa2xx_pm

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/pxa2xx.c | 33 ++++++++++++---------------------
 1 file changed, 12 insertions(+), 21 deletions(-)

diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index e174c20d47..ac5d95d718 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -146,25 +146,16 @@ static CPUWriteMemoryFunc * const pxa2xx_pm_writefn[] = {
     pxa2xx_pm_write,
 };
 
-static void pxa2xx_pm_save(QEMUFile *f, void *opaque)
-{
-    PXA2xxState *s = (PXA2xxState *) opaque;
-    int i;
-
-    for (i = 0; i < 0x40; i ++)
-        qemu_put_be32s(f, &s->pm_regs[i]);
-}
-
-static int pxa2xx_pm_load(QEMUFile *f, void *opaque, int version_id)
-{
-    PXA2xxState *s = (PXA2xxState *) opaque;
-    int i;
-
-    for (i = 0; i < 0x40; i ++)
-        qemu_get_be32s(f, &s->pm_regs[i]);
-
-    return 0;
-}
+static const VMStateDescription vmstate_pxa2xx_pm = {
+    .name = "pxa2xx_pm",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(pm_regs, PXA2xxState, 0x40),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 #define CCCR	0x00	/* Core Clock Configuration register */
 #define CKEN	0x04	/* Clock Enable register */
@@ -2168,7 +2159,7 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
     iomemtype = cpu_register_io_memory(pxa2xx_pm_readfn,
                     pxa2xx_pm_writefn, s, DEVICE_NATIVE_ENDIAN);
     cpu_register_physical_memory(s->pm_base, 0x100, iomemtype);
-    register_savevm(NULL, "pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s);
+    vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s);
 
     for (i = 0; pxa27x_ssp[i].io_base; i ++);
     s->ssp = (SSIBus **)qemu_mallocz(sizeof(SSIBus *) * i);
@@ -2304,7 +2295,7 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
     iomemtype = cpu_register_io_memory(pxa2xx_pm_readfn,
                     pxa2xx_pm_writefn, s, DEVICE_NATIVE_ENDIAN);
     cpu_register_physical_memory(s->pm_base, 0x100, iomemtype);
-    register_savevm(NULL, "pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s);
+    vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s);
 
     for (i = 0; pxa255_ssp[i].io_base; i ++);
     s->ssp = (SSIBus **)qemu_mallocz(sizeof(SSIBus *) * i);

From e0433ecc6ead41f1581113eb892f744235f12120 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 15:29:42 +0100
Subject: [PATCH 266/386] vmstate: port ppce500_pci

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/ppce500_pci.c | 87 ++++++++++++++++++++++--------------------------
 1 file changed, 40 insertions(+), 47 deletions(-)

diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 2fc879236a..83a20e4620 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -216,56 +216,49 @@ static void mpc85xx_pci_set_irq(void *opaque, int irq_num, int level)
     qemu_set_irq(pic[irq_num], level);
 }
 
-static void ppce500_pci_save(QEMUFile *f, void *opaque)
-{
-    PPCE500PCIState *controller = opaque;
-    int i;
-
-    pci_device_save(controller->pci_dev, f);
-
-    for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
-        qemu_put_be32s(f, &controller->pob[i].potar);
-        qemu_put_be32s(f, &controller->pob[i].potear);
-        qemu_put_be32s(f, &controller->pob[i].powbar);
-        qemu_put_be32s(f, &controller->pob[i].powar);
+static const VMStateDescription vmstate_pci_outbound = {
+    .name = "pci_outbound",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(potar, struct pci_outbound),
+        VMSTATE_UINT32(potear, struct pci_outbound),
+        VMSTATE_UINT32(powbar, struct pci_outbound),
+        VMSTATE_UINT32(powar, struct pci_outbound),
+        VMSTATE_END_OF_LIST()
     }
+};
 
-    for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
-        qemu_put_be32s(f, &controller->pib[i].pitar);
-        qemu_put_be32s(f, &controller->pib[i].piwbar);
-        qemu_put_be32s(f, &controller->pib[i].piwbear);
-        qemu_put_be32s(f, &controller->pib[i].piwar);
+static const VMStateDescription vmstate_pci_inbound = {
+    .name = "pci_inbound",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(pitar, struct pci_inbound),
+        VMSTATE_UINT32(piwbar, struct pci_inbound),
+        VMSTATE_UINT32(piwbear, struct pci_inbound),
+        VMSTATE_UINT32(piwar, struct pci_inbound),
+        VMSTATE_END_OF_LIST()
     }
-    qemu_put_be32s(f, &controller->gasket_time);
-}
+};
 
-static int ppce500_pci_load(QEMUFile *f, void *opaque, int version_id)
-{
-    PPCE500PCIState *controller = opaque;
-    int i;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    pci_device_load(controller->pci_dev, f);
-
-    for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
-        qemu_get_be32s(f, &controller->pob[i].potar);
-        qemu_get_be32s(f, &controller->pob[i].potear);
-        qemu_get_be32s(f, &controller->pob[i].powbar);
-        qemu_get_be32s(f, &controller->pob[i].powar);
+static const VMStateDescription vmstate_ppce500_pci = {
+    .name = "ppce500_pci",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_PCI_DEVICE_POINTER(pci_dev, PPCE500PCIState),
+        VMSTATE_STRUCT_ARRAY(pob, PPCE500PCIState, PPCE500_PCI_NR_POBS, 1,
+                             vmstate_pci_outbound, struct pci_outbound),
+        VMSTATE_STRUCT_ARRAY(pib, PPCE500PCIState, PPCE500_PCI_NR_PIBS, 1,
+                             vmstate_pci_outbound, struct pci_inbound),
+        VMSTATE_UINT32(gasket_time, PPCE500PCIState),
+        VMSTATE_END_OF_LIST()
     }
-
-    for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
-        qemu_get_be32s(f, &controller->pib[i].pitar);
-        qemu_get_be32s(f, &controller->pib[i].piwbar);
-        qemu_get_be32s(f, &controller->pib[i].piwbear);
-        qemu_get_be32s(f, &controller->pib[i].piwar);
-    }
-    qemu_get_be32s(f, &controller->gasket_time);
-
-    return 0;
-}
+};
 
 PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers)
 {
@@ -314,8 +307,8 @@ PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers)
                                    PCIE500_REG_SIZE, index);
 
     /* XXX load/save code not tested. */
-    register_savevm(&d->qdev, "ppce500_pci", ppce500_pci_id++,
-                    1, ppce500_pci_save, ppce500_pci_load, controller);
+    vmstate_register(&d->qdev, ppce500_pci_id++, &vmstate_ppce500_pci,
+                     controller);
 
     return controller->pci_state.bus;
 

From b605f22212875d95e9c5f82369d48fe5cd8d10e4 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 17:27:49 +0100
Subject: [PATCH 267/386] vmstate: port ppc4xx_pci

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/ppc4xx_pci.c | 80 ++++++++++++++++++++++++-------------------------
 1 file changed, 39 insertions(+), 41 deletions(-)

diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index f62f1f91d5..299473c4b5 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -285,50 +285,48 @@ static void ppc4xx_pci_set_irq(void *opaque, int irq_num, int level)
     qemu_set_irq(pci_irqs[irq_num], level);
 }
 
-static void ppc4xx_pci_save(QEMUFile *f, void *opaque)
-{
-    PPC4xxPCIState *controller = opaque;
-    int i;
-
-    pci_device_save(controller->pci_dev, f);
-
-    for (i = 0; i < PPC4xx_PCI_NR_PMMS; i++) {
-        qemu_put_be32s(f, &controller->pmm[i].la);
-        qemu_put_be32s(f, &controller->pmm[i].ma);
-        qemu_put_be32s(f, &controller->pmm[i].pcila);
-        qemu_put_be32s(f, &controller->pmm[i].pciha);
+static const VMStateDescription vmstate_pci_master_map = {
+    .name = "pci_master_map",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(la, struct PCIMasterMap),
+        VMSTATE_UINT32(ma, struct PCIMasterMap),
+        VMSTATE_UINT32(pcila, struct PCIMasterMap),
+        VMSTATE_UINT32(pciha, struct PCIMasterMap),
+        VMSTATE_END_OF_LIST()
     }
+};
 
-    for (i = 0; i < PPC4xx_PCI_NR_PTMS; i++) {
-        qemu_put_be32s(f, &controller->ptm[i].ms);
-        qemu_put_be32s(f, &controller->ptm[i].la);
+static const VMStateDescription vmstate_pci_target_map = {
+    .name = "pci_target_map",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(ms, struct PCITargetMap),
+        VMSTATE_UINT32(la, struct PCITargetMap),
+        VMSTATE_END_OF_LIST()
     }
-}
+};
 
-static int ppc4xx_pci_load(QEMUFile *f, void *opaque, int version_id)
-{
-    PPC4xxPCIState *controller = opaque;
-    int i;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    pci_device_load(controller->pci_dev, f);
-
-    for (i = 0; i < PPC4xx_PCI_NR_PMMS; i++) {
-        qemu_get_be32s(f, &controller->pmm[i].la);
-        qemu_get_be32s(f, &controller->pmm[i].ma);
-        qemu_get_be32s(f, &controller->pmm[i].pcila);
-        qemu_get_be32s(f, &controller->pmm[i].pciha);
+static const VMStateDescription vmstate_ppc4xx_pci = {
+    .name = "ppc4xx_pci",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_PCI_DEVICE_POINTER(pci_dev, PPC4xxPCIState),
+        VMSTATE_STRUCT_ARRAY(pmm, PPC4xxPCIState, PPC4xx_PCI_NR_PMMS, 1,
+                             vmstate_pci_master_map,
+                             struct PCIMasterMap),
+        VMSTATE_STRUCT_ARRAY(ptm, PPC4xxPCIState, PPC4xx_PCI_NR_PTMS, 1,
+                             vmstate_pci_target_map,
+                             struct PCITargetMap),
+        VMSTATE_END_OF_LIST()
     }
-
-    for (i = 0; i < PPC4xx_PCI_NR_PTMS; i++) {
-        qemu_get_be32s(f, &controller->ptm[i].ms);
-        qemu_get_be32s(f, &controller->ptm[i].la);
-    }
-
-    return 0;
-}
+};
 
 /* XXX Interrupt acknowledge cycles not supported. */
 PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
@@ -381,8 +379,8 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
     qemu_register_reset(ppc4xx_pci_reset, controller);
 
     /* XXX load/save code not tested. */
-    register_savevm(&controller->pci_dev->qdev, "ppc4xx_pci", ppc4xx_pci_id++,
-                    1, ppc4xx_pci_save, ppc4xx_pci_load, controller);
+    vmstate_register(&controller->pci_dev->qdev, ppc4xx_pci_id++,
+                     &vmstate_ppc4xx_pci, controller);
 
     return controller->pci_state.bus;
 

From 80a526802c39e95ea0e65b879c91f240185889f2 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Fri, 3 Dec 2010 00:37:35 +0100
Subject: [PATCH 268/386] vmstate: port syborg_pointer

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/syborg_pointer.c | 73 +++++++++++++++++----------------------------
 1 file changed, 28 insertions(+), 45 deletions(-)

diff --git a/hw/syborg_pointer.c b/hw/syborg_pointer.c
index a886888467..2f99707040 100644
--- a/hw/syborg_pointer.c
+++ b/hw/syborg_pointer.c
@@ -152,52 +152,36 @@ static void syborg_pointer_event(void *opaque, int dx, int dy, int dz,
     syborg_pointer_update(s);
 }
 
-static void syborg_pointer_save(QEMUFile *f, void *opaque)
-{
-    SyborgPointerState *s = (SyborgPointerState *)opaque;
-    int i;
-
-    qemu_put_be32(f, s->fifo_size);
-    qemu_put_be32(f, s->absolute);
-    qemu_put_be32(f, s->int_enabled);
-    qemu_put_be32(f, s->read_pos);
-    qemu_put_be32(f, s->read_count);
-    for (i = 0; i < s->fifo_size; i++) {
-        qemu_put_be32(f, s->event_fifo[i].x);
-        qemu_put_be32(f, s->event_fifo[i].y);
-        qemu_put_be32(f, s->event_fifo[i].z);
-        qemu_put_be32(f, s->event_fifo[i].pointer_buttons);
+static const VMStateDescription vmstate_event_data = {
+    .name = "dbma_channel",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_INT32(x, event_data),
+        VMSTATE_INT32(y, event_data),
+        VMSTATE_INT32(z, event_data),
+        VMSTATE_INT32(pointer_buttons, event_data),
+        VMSTATE_END_OF_LIST()
     }
-}
+};
 
-static int syborg_pointer_load(QEMUFile *f, void *opaque, int version_id)
-{
-    SyborgPointerState *s = (SyborgPointerState *)opaque;
-    uint32_t val;
-    int i;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    val = qemu_get_be32(f);
-    if (val != s->fifo_size)
-        return -EINVAL;
-
-    val = qemu_get_be32(f);
-    if (val != s->absolute)
-        return -EINVAL;
-
-    s->int_enabled = qemu_get_be32(f);
-    s->read_pos = qemu_get_be32(f);
-    s->read_count = qemu_get_be32(f);
-    for (i = 0; i < s->fifo_size; i++) {
-        s->event_fifo[i].x = qemu_get_be32(f);
-        s->event_fifo[i].y = qemu_get_be32(f);
-        s->event_fifo[i].z = qemu_get_be32(f);
-        s->event_fifo[i].pointer_buttons = qemu_get_be32(f);
+static const VMStateDescription vmstate_syborg_pointer = {
+    .name = "syborg_pointer",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_EQUAL(fifo_size, SyborgPointerState),
+        VMSTATE_UINT32_EQUAL(absolute, SyborgPointerState),
+        VMSTATE_INT32(int_enabled, SyborgPointerState),
+        VMSTATE_INT32(read_pos, SyborgPointerState),
+        VMSTATE_INT32(read_count, SyborgPointerState),
+        VMSTATE_STRUCT_VARRAY_UINT32(event_fifo, SyborgPointerState, fifo_size,
+                                     1, vmstate_event_data, event_data),
+        VMSTATE_END_OF_LIST()
     }
-    return 0;
-}
+};
 
 static int syborg_pointer_init(SysBusDevice *dev)
 {
@@ -219,8 +203,7 @@ static int syborg_pointer_init(SysBusDevice *dev)
     qemu_add_mouse_event_handler(syborg_pointer_event, s, s->absolute,
                                  "Syborg Pointer");
 
-    register_savevm(&dev->qdev, "syborg_pointer", -1, 1,
-                    syborg_pointer_save, syborg_pointer_load, s);
+    vmstate_register(&dev->qdev, -1, &vmstate_syborg_pointer, s);
     return 0;
 }
 

From cf1d31dc5cd3a98199af6169d80a1a6d191d8e55 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Fri, 3 Dec 2010 01:27:58 +0100
Subject: [PATCH 269/386] vmstate: port stellaris_adc

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/stellaris.c | 89 +++++++++++++++++++-------------------------------
 1 file changed, 34 insertions(+), 55 deletions(-)

diff --git a/hw/stellaris.c b/hw/stellaris.c
index 31aa102d14..58aec190ec 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -1057,60 +1057,40 @@ static CPUWriteMemoryFunc * const stellaris_adc_writefn[] = {
    stellaris_adc_write
 };
 
-static void stellaris_adc_save(QEMUFile *f, void *opaque)
-{
-    stellaris_adc_state *s = (stellaris_adc_state *)opaque;
-    int i;
-    int j;
-
-    qemu_put_be32(f, s->actss);
-    qemu_put_be32(f, s->ris);
-    qemu_put_be32(f, s->im);
-    qemu_put_be32(f, s->emux);
-    qemu_put_be32(f, s->ostat);
-    qemu_put_be32(f, s->ustat);
-    qemu_put_be32(f, s->sspri);
-    qemu_put_be32(f, s->sac);
-    for (i = 0; i < 4; i++) {
-        qemu_put_be32(f, s->fifo[i].state);
-        for (j = 0; j < 16; j++) {
-            qemu_put_be32(f, s->fifo[i].data[j]);
-        }
-        qemu_put_be32(f, s->ssmux[i]);
-        qemu_put_be32(f, s->ssctl[i]);
+static const VMStateDescription vmstate_stellaris_adc = {
+    .name = "stellaris_adc",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(actss, stellaris_adc_state),
+        VMSTATE_UINT32(ris, stellaris_adc_state),
+        VMSTATE_UINT32(im, stellaris_adc_state),
+        VMSTATE_UINT32(emux, stellaris_adc_state),
+        VMSTATE_UINT32(ostat, stellaris_adc_state),
+        VMSTATE_UINT32(ustat, stellaris_adc_state),
+        VMSTATE_UINT32(sspri, stellaris_adc_state),
+        VMSTATE_UINT32(sac, stellaris_adc_state),
+        VMSTATE_UINT32(fifo[0].state, stellaris_adc_state),
+        VMSTATE_UINT32_ARRAY(fifo[0].data, stellaris_adc_state, 16),
+        VMSTATE_UINT32(ssmux[0], stellaris_adc_state),
+        VMSTATE_UINT32(ssctl[0], stellaris_adc_state),
+        VMSTATE_UINT32(fifo[1].state, stellaris_adc_state),
+        VMSTATE_UINT32_ARRAY(fifo[1].data, stellaris_adc_state, 16),
+        VMSTATE_UINT32(ssmux[1], stellaris_adc_state),
+        VMSTATE_UINT32(ssctl[1], stellaris_adc_state),
+        VMSTATE_UINT32(fifo[2].state, stellaris_adc_state),
+        VMSTATE_UINT32_ARRAY(fifo[2].data, stellaris_adc_state, 16),
+        VMSTATE_UINT32(ssmux[2], stellaris_adc_state),
+        VMSTATE_UINT32(ssctl[2], stellaris_adc_state),
+        VMSTATE_UINT32(fifo[3].state, stellaris_adc_state),
+        VMSTATE_UINT32_ARRAY(fifo[3].data, stellaris_adc_state, 16),
+        VMSTATE_UINT32(ssmux[3], stellaris_adc_state),
+        VMSTATE_UINT32(ssctl[3], stellaris_adc_state),
+        VMSTATE_UINT32(noise, stellaris_adc_state),
+        VMSTATE_END_OF_LIST()
     }
-    qemu_put_be32(f, s->noise);
-}
-
-static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id)
-{
-    stellaris_adc_state *s = (stellaris_adc_state *)opaque;
-    int i;
-    int j;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    s->actss = qemu_get_be32(f);
-    s->ris = qemu_get_be32(f);
-    s->im = qemu_get_be32(f);
-    s->emux = qemu_get_be32(f);
-    s->ostat = qemu_get_be32(f);
-    s->ustat = qemu_get_be32(f);
-    s->sspri = qemu_get_be32(f);
-    s->sac = qemu_get_be32(f);
-    for (i = 0; i < 4; i++) {
-        s->fifo[i].state = qemu_get_be32(f);
-        for (j = 0; j < 16; j++) {
-            s->fifo[i].data[j] = qemu_get_be32(f);
-        }
-        s->ssmux[i] = qemu_get_be32(f);
-        s->ssctl[i] = qemu_get_be32(f);
-    }
-    s->noise = qemu_get_be32(f);
-
-    return 0;
-}
+};
 
 static int stellaris_adc_init(SysBusDevice *dev)
 {
@@ -1128,8 +1108,7 @@ static int stellaris_adc_init(SysBusDevice *dev)
     sysbus_init_mmio(dev, 0x1000, iomemtype);
     stellaris_adc_reset(s);
     qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1);
-    register_savevm(&dev->qdev, "stellaris_adc", -1, 1,
-                    stellaris_adc_save, stellaris_adc_load, s);
+    vmstate_register(&dev->qdev, -1, &vmstate_stellaris_adc, s);
     return 0;
 }
 

From 8dc5907090fd35fd80e643534ab02092b73ec9cd Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Fri, 3 Dec 2010 02:10:53 +0100
Subject: [PATCH 270/386] vmstate: port syborg_serial

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/syborg_serial.c | 60 ++++++++++++++--------------------------------
 1 file changed, 18 insertions(+), 42 deletions(-)

diff --git a/hw/syborg_serial.c b/hw/syborg_serial.c
index 34ce076d45..df2950fe88 100644
--- a/hw/syborg_serial.c
+++ b/hw/syborg_serial.c
@@ -273,47 +273,24 @@ static CPUWriteMemoryFunc * const syborg_serial_writefn[] = {
      syborg_serial_write
 };
 
-static void syborg_serial_save(QEMUFile *f, void *opaque)
-{
-    SyborgSerialState *s = opaque;
-    int i;
-
-    qemu_put_be32(f, s->fifo_size);
-    qemu_put_be32(f, s->int_enable);
-    qemu_put_be32(f, s->read_pos);
-    qemu_put_be32(f, s->read_count);
-    qemu_put_be32(f, s->dma_tx_ptr);
-    qemu_put_be32(f, s->dma_rx_ptr);
-    qemu_put_be32(f, s->dma_rx_size);
-    for (i = 0; i < s->fifo_size; i++) {
-        qemu_put_be32(f, s->read_fifo[i]);
+static const VMStateDescription vmstate_syborg_serial = {
+    .name = "syborg_serial",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_EQUAL(fifo_size, SyborgSerialState),
+        VMSTATE_UINT32(int_enable, SyborgSerialState),
+        VMSTATE_INT32(read_pos, SyborgSerialState),
+        VMSTATE_INT32(read_count, SyborgSerialState),
+        VMSTATE_UINT32(dma_tx_ptr, SyborgSerialState),
+        VMSTATE_UINT32(dma_rx_ptr, SyborgSerialState),
+        VMSTATE_UINT32(dma_rx_size, SyborgSerialState),
+        VMSTATE_VARRAY_UINT32(read_fifo, SyborgSerialState, fifo_size, 1,
+                              vmstate_info_uint32, uint32),
+        VMSTATE_END_OF_LIST()
     }
-}
-
-static int syborg_serial_load(QEMUFile *f, void *opaque, int version_id)
-{
-    SyborgSerialState *s = opaque;
-    int i;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    i = qemu_get_be32(f);
-    if (s->fifo_size != i)
-        return -EINVAL;
-
-    s->int_enable = qemu_get_be32(f);
-    s->read_pos = qemu_get_be32(f);
-    s->read_count = qemu_get_be32(f);
-    s->dma_tx_ptr = qemu_get_be32(f);
-    s->dma_rx_ptr = qemu_get_be32(f);
-    s->dma_rx_size = qemu_get_be32(f);
-    for (i = 0; i < s->fifo_size; i++) {
-        s->read_fifo[i] = qemu_get_be32(f);
-    }
-
-    return 0;
-}
+};
 
 static int syborg_serial_init(SysBusDevice *dev)
 {
@@ -336,8 +313,6 @@ static int syborg_serial_init(SysBusDevice *dev)
     }
     s->read_fifo = qemu_mallocz(s->fifo_size * sizeof(s->read_fifo[0]));
 
-    register_savevm(&dev->qdev, "syborg_serial", -1, 1,
-                    syborg_serial_save, syborg_serial_load, s);
     return 0;
 }
 
@@ -345,6 +320,7 @@ static SysBusDeviceInfo syborg_serial_info = {
     .init = syborg_serial_init,
     .qdev.name  = "syborg,serial",
     .qdev.size  = sizeof(SyborgSerialState),
+    .qdev.vmsd  = &vmstate_syborg_serial,
     .qdev.props = (Property[]) {
         DEFINE_PROP_UINT32("fifo-size", SyborgSerialState, fifo_size, 16),
         DEFINE_PROP_END_OF_LIST(),

From 0c067bbb26e3dae03807ba7eeb4bfd697f5f01c4 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Wed, 1 Dec 2010 22:51:07 +0100
Subject: [PATCH 271/386] vmstate: port syborg_keyboard

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/syborg_keyboard.c | 57 +++++++++++++-------------------------------
 1 file changed, 17 insertions(+), 40 deletions(-)

diff --git a/hw/syborg_keyboard.c b/hw/syborg_keyboard.c
index d295e99ebd..706a03966f 100644
--- a/hw/syborg_keyboard.c
+++ b/hw/syborg_keyboard.c
@@ -51,11 +51,11 @@ enum {
 
 typedef struct {
     SysBusDevice busdev;
-    int int_enabled;
+    uint32_t int_enabled;
     int extension_bit;
     uint32_t fifo_size;
     uint32_t *key_fifo;
-    int read_pos, read_count;
+    uint32_t read_pos, read_count;
     qemu_irq irq;
 } SyborgKeyboardState;
 
@@ -165,43 +165,21 @@ static void syborg_keyboard_event(void *opaque, int keycode)
     syborg_keyboard_update(s);
 }
 
-static void syborg_keyboard_save(QEMUFile *f, void *opaque)
-{
-    SyborgKeyboardState *s = (SyborgKeyboardState *)opaque;
-    int i;
-
-    qemu_put_be32(f, s->fifo_size);
-    qemu_put_be32(f, s->int_enabled);
-    qemu_put_be32(f, s->extension_bit);
-    qemu_put_be32(f, s->read_pos);
-    qemu_put_be32(f, s->read_count);
-    for (i = 0; i < s->fifo_size; i++) {
-        qemu_put_be32(f, s->key_fifo[i]);
+static const VMStateDescription vmstate_syborg_keyboard = {
+    .name = "syborg_keyboard",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_EQUAL(fifo_size, SyborgKeyboardState),
+        VMSTATE_UINT32(int_enabled, SyborgKeyboardState),
+        VMSTATE_UINT32(read_pos, SyborgKeyboardState),
+        VMSTATE_UINT32(read_count, SyborgKeyboardState),
+        VMSTATE_VARRAY_UINT32(key_fifo, SyborgKeyboardState, fifo_size, 1,
+                              vmstate_info_uint32, uint32),
+        VMSTATE_END_OF_LIST()
     }
-}
-
-static int syborg_keyboard_load(QEMUFile *f, void *opaque, int version_id)
-{
-    SyborgKeyboardState *s = (SyborgKeyboardState *)opaque;
-    uint32_t val;
-    int i;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    val = qemu_get_be32(f);
-    if (val != s->fifo_size)
-        return -EINVAL;
-
-    s->int_enabled = qemu_get_be32(f);
-    s->extension_bit = qemu_get_be32(f);
-    s->read_pos = qemu_get_be32(f);
-    s->read_count = qemu_get_be32(f);
-    for (i = 0; i < s->fifo_size; i++) {
-        s->key_fifo[i] = qemu_get_be32(f);
-    }
-    return 0;
-}
+};
 
 static int syborg_keyboard_init(SysBusDevice *dev)
 {
@@ -221,8 +199,7 @@ static int syborg_keyboard_init(SysBusDevice *dev)
 
     qemu_add_kbd_event_handler(syborg_keyboard_event, s);
 
-    register_savevm(&dev->qdev, "syborg_keyboard", -1, 1,
-                    syborg_keyboard_save, syborg_keyboard_load, s);
+    vmstate_register(&dev->qdev, -1, &vmstate_syborg_keyboard, s);
     return 0;
 }
 

From 4483c7ac31f76e91fe69bf7f2346e77a10ac427e Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 02:36:38 +0100
Subject: [PATCH 272/386] vmstate: port stellaris gamepad

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/stellaris_input.c | 50 +++++++++++++++++++++-----------------------
 1 file changed, 24 insertions(+), 26 deletions(-)

diff --git a/hw/stellaris_input.c b/hw/stellaris_input.c
index 16aae96f2f..06c5f9d955 100644
--- a/hw/stellaris_input.c
+++ b/hw/stellaris_input.c
@@ -13,7 +13,7 @@
 typedef struct {
     qemu_irq irq;
     int keycode;
-    int pressed;
+    uint8_t pressed;
 } gamepad_button;
 
 typedef struct {
@@ -47,30 +47,29 @@ static void stellaris_gamepad_put_key(void * opaque, int keycode)
     s->extension = 0;
 }
 
-static void stellaris_gamepad_save(QEMUFile *f, void *opaque)
-{
-    gamepad_state *s = (gamepad_state *)opaque;
-    int i;
+static const VMStateDescription vmstate_stellaris_button = {
+    .name = "stellaris_button",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT8(pressed, gamepad_button),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
-    qemu_put_be32(f, s->extension);
-    for (i = 0; i < s->num_buttons; i++)
-        qemu_put_byte(f, s->buttons[i].pressed);
-}
-
-static int stellaris_gamepad_load(QEMUFile *f, void *opaque, int version_id)
-{
-    gamepad_state *s = (gamepad_state *)opaque;
-    int i;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    s->extension = qemu_get_be32(f);
-    for (i = 0; i < s->num_buttons; i++)
-        s->buttons[i].pressed = qemu_get_byte(f);
-
-    return 0;
-}
+static const VMStateDescription vmstate_stellaris_gamepad = {
+    .name = "stellaris_gamepad",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_INT32(extension, gamepad_state),
+        VMSTATE_STRUCT_VARRAY_INT32(buttons, gamepad_state, num_buttons, 0,
+                              vmstate_stellaris_button, gamepad_button),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 /* Returns an array 5 ouput slots.  */
 void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
@@ -86,6 +85,5 @@ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
     }
     s->num_buttons = n;
     qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
-    register_savevm(NULL, "stellaris_gamepad", -1, 1,
-                    stellaris_gamepad_save, stellaris_gamepad_load, s);
+    vmstate_register(NULL, -1, &vmstate_stellaris_gamepad, s);
 }

From dd8a4dcda4c985cfa313cfe70ab0385c07341480 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 14:07:44 +0100
Subject: [PATCH 273/386] vmstate: stellaris use unused for placeholder entries

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/stellaris.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/stellaris.c b/hw/stellaris.c
index 58aec190ec..ac9fcc1f38 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -290,8 +290,7 @@ static const VMStateDescription vmstate_stellaris_gptm = {
         VMSTATE_UINT32(control, gptm_state),
         VMSTATE_UINT32(state, gptm_state),
         VMSTATE_UINT32(mask, gptm_state),
-        VMSTATE_UINT32(mode[0], gptm_state),
-        VMSTATE_UINT32(mode[0], gptm_state),
+        VMSTATE_UNUSED(8),
         VMSTATE_UINT32_ARRAY(load, gptm_state, 2),
         VMSTATE_UINT32_ARRAY(match, gptm_state, 2),
         VMSTATE_UINT32_ARRAY(prescale, gptm_state, 2),

From 2b7251e0f2e9414f2440e9b485e95f337b869d53 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 15:56:04 +0100
Subject: [PATCH 274/386] pxa2xx_lcd: name anonymous struct

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/pxa2xx_lcd.c | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index 5b2b07e02c..9a193474e0 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -15,6 +15,20 @@
 #include "sysemu.h"
 #include "framebuffer.h"
 
+struct DMAChannel {
+    target_phys_addr_t branch;
+    int up;
+    uint8_t palette[1024];
+    uint8_t pbuffer[1024];
+    void (*redraw)(PXA2xxLCDState *s, target_phys_addr_t addr,
+                   int *miny, int *maxy);
+
+    target_phys_addr_t descriptor;
+    target_phys_addr_t source;
+    uint32_t id;
+    uint32_t command;
+};
+
 struct PXA2xxLCDState {
     qemu_irq irq;
     int irqlevel;
@@ -50,19 +64,7 @@ struct PXA2xxLCDState {
     uint32_t liidr;
     uint8_t bscntr;
 
-    struct {
-        target_phys_addr_t branch;
-        int up;
-        uint8_t palette[1024];
-        uint8_t pbuffer[1024];
-        void (*redraw)(PXA2xxLCDState *s, target_phys_addr_t addr,
-                        int *miny, int *maxy);
-
-        target_phys_addr_t descriptor;
-        target_phys_addr_t source;
-        uint32_t id;
-        uint32_t command;
-    } dma_ch[7];
+    struct DMAChannel dma_ch[7];
 
     qemu_irq vsync_cb;
     int orientation;

From 469954090ff1a11285a29c4e03df09c128ebc5bc Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 16:01:57 +0100
Subject: [PATCH 275/386] pxa2xx_lcd: up field is used as a bool and migrated
 as an uint8_t

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/pxa2xx_lcd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index 9a193474e0..55e95be766 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -17,7 +17,7 @@
 
 struct DMAChannel {
     target_phys_addr_t branch;
-    int up;
+    uint8_t up;
     uint8_t palette[1024];
     uint8_t pbuffer[1024];
     void (*redraw)(PXA2xxLCDState *s, target_phys_addr_t addr,

From 99838363ba37553321bc6a0274b08c4af65541ea Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 16:11:24 +0100
Subject: [PATCH 276/386] vmstate: port pxa2xx_lcd

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/pxa2xx_lcd.c | 110 +++++++++++++++++++-----------------------------
 1 file changed, 43 insertions(+), 67 deletions(-)

diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index 55e95be766..e5248023f8 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -833,74 +833,26 @@ static void pxa2xx_lcdc_orientation(void *opaque, int angle)
     pxa2xx_lcdc_resize(s);
 }
 
-static void pxa2xx_lcdc_save(QEMUFile *f, void *opaque)
-{
-    PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
-    int i;
-
-    qemu_put_be32(f, s->irqlevel);
-    qemu_put_be32(f, s->transp);
-
-    for (i = 0; i < 6; i ++)
-        qemu_put_be32s(f, &s->control[i]);
-    for (i = 0; i < 2; i ++)
-        qemu_put_be32s(f, &s->status[i]);
-    for (i = 0; i < 2; i ++)
-        qemu_put_be32s(f, &s->ovl1c[i]);
-    for (i = 0; i < 2; i ++)
-        qemu_put_be32s(f, &s->ovl2c[i]);
-    qemu_put_be32s(f, &s->ccr);
-    qemu_put_be32s(f, &s->cmdcr);
-    qemu_put_be32s(f, &s->trgbr);
-    qemu_put_be32s(f, &s->tcr);
-    qemu_put_be32s(f, &s->liidr);
-    qemu_put_8s(f, &s->bscntr);
-
-    for (i = 0; i < 7; i ++) {
-        qemu_put_betl(f, s->dma_ch[i].branch);
-        qemu_put_byte(f, s->dma_ch[i].up);
-        qemu_put_buffer(f, s->dma_ch[i].pbuffer, sizeof(s->dma_ch[i].pbuffer));
-
-        qemu_put_betl(f, s->dma_ch[i].descriptor);
-        qemu_put_betl(f, s->dma_ch[i].source);
-        qemu_put_be32s(f, &s->dma_ch[i].id);
-        qemu_put_be32s(f, &s->dma_ch[i].command);
+static const VMStateDescription vmstate_dma_channel = {
+    .name = "dma_channel",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINTTL(branch, struct DMAChannel),
+        VMSTATE_UINT8(up, struct DMAChannel),
+        VMSTATE_BUFFER(pbuffer, struct DMAChannel),
+        VMSTATE_UINTTL(descriptor, struct DMAChannel),
+        VMSTATE_UINTTL(source, struct DMAChannel),
+        VMSTATE_UINT32(id, struct DMAChannel),
+        VMSTATE_UINT32(command, struct DMAChannel),
+        VMSTATE_END_OF_LIST()
     }
-}
+};
 
-static int pxa2xx_lcdc_load(QEMUFile *f, void *opaque, int version_id)
+static int pxa2xx_lcdc_post_load(void *opaque, int version_id)
 {
-    PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
-    int i;
-
-    s->irqlevel = qemu_get_be32(f);
-    s->transp = qemu_get_be32(f);
-
-    for (i = 0; i < 6; i ++)
-        qemu_get_be32s(f, &s->control[i]);
-    for (i = 0; i < 2; i ++)
-        qemu_get_be32s(f, &s->status[i]);
-    for (i = 0; i < 2; i ++)
-        qemu_get_be32s(f, &s->ovl1c[i]);
-    for (i = 0; i < 2; i ++)
-        qemu_get_be32s(f, &s->ovl2c[i]);
-    qemu_get_be32s(f, &s->ccr);
-    qemu_get_be32s(f, &s->cmdcr);
-    qemu_get_be32s(f, &s->trgbr);
-    qemu_get_be32s(f, &s->tcr);
-    qemu_get_be32s(f, &s->liidr);
-    qemu_get_8s(f, &s->bscntr);
-
-    for (i = 0; i < 7; i ++) {
-        s->dma_ch[i].branch = qemu_get_betl(f);
-        s->dma_ch[i].up = qemu_get_byte(f);
-        qemu_get_buffer(f, s->dma_ch[i].pbuffer, sizeof(s->dma_ch[i].pbuffer));
-
-        s->dma_ch[i].descriptor = qemu_get_betl(f);
-        s->dma_ch[i].source = qemu_get_betl(f);
-        qemu_get_be32s(f, &s->dma_ch[i].id);
-        qemu_get_be32s(f, &s->dma_ch[i].command);
-    }
+    PXA2xxLCDState *s = opaque;
 
     s->bpp = LCCR3_BPP(s->control[3]);
     s->xres = s->yres = s->pal_for = -1;
@@ -908,6 +860,31 @@ static int pxa2xx_lcdc_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
+static const VMStateDescription vmstate_pxa2xx_lcdc = {
+    .name = "pxa2xx_lcdc",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .post_load = pxa2xx_lcdc_post_load,
+    .fields      = (VMStateField[]) {
+        VMSTATE_INT32(irqlevel, PXA2xxLCDState),
+        VMSTATE_INT32(transp, PXA2xxLCDState),
+        VMSTATE_UINT32_ARRAY(control, PXA2xxLCDState, 6),
+        VMSTATE_UINT32_ARRAY(status, PXA2xxLCDState, 2),
+        VMSTATE_UINT32_ARRAY(ovl1c, PXA2xxLCDState, 2),
+        VMSTATE_UINT32_ARRAY(ovl2c, PXA2xxLCDState, 2),
+        VMSTATE_UINT32(ccr, PXA2xxLCDState),
+        VMSTATE_UINT32(cmdcr, PXA2xxLCDState),
+        VMSTATE_UINT32(trgbr, PXA2xxLCDState),
+        VMSTATE_UINT32(tcr, PXA2xxLCDState),
+        VMSTATE_UINT32(liidr, PXA2xxLCDState),
+        VMSTATE_UINT8(bscntr, PXA2xxLCDState),
+        VMSTATE_STRUCT_ARRAY(dma_ch, PXA2xxLCDState, 7, 0,
+                             vmstate_dma_channel, struct DMAChannel),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 #define BITS 8
 #include "pxa2xx_template.h"
 #define BITS 15
@@ -972,8 +949,7 @@ PXA2xxLCDState *pxa2xx_lcdc_init(target_phys_addr_t base, qemu_irq irq)
         exit(1);
     }
 
-    register_savevm(NULL, "pxa2xx_lcdc", 0, 0,
-                    pxa2xx_lcdc_save, pxa2xx_lcdc_load, s);
+    vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s);
 
     return s;
 }

From 54d970d134f3bf820f51266113f1b7489b794fe2 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Fri, 3 Dec 2010 01:03:10 +0100
Subject: [PATCH 277/386] max111x: input field is only used as uint8_t

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/max111x.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/max111x.c b/hw/max111x.c
index 2844665ba3..3adc3e4d2f 100644
--- a/hw/max111x.c
+++ b/hw/max111x.c
@@ -15,7 +15,7 @@ typedef struct {
     uint8_t tb1, rb2, rb3;
     int cycle;
 
-    int input[8];
+    uint8_t input[8];
     int inputs, com;
 } MAX111xState;
 

From 38cb3aa9b4d5b9085ff4635415b6d3c673e2dc7d Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Fri, 3 Dec 2010 01:03:59 +0100
Subject: [PATCH 278/386] vmstate: port max111x

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/max111x.c | 49 +++++++++++++++++--------------------------------
 1 file changed, 17 insertions(+), 32 deletions(-)

diff --git a/hw/max111x.c b/hw/max111x.c
index 3adc3e4d2f..70cd1af24f 100644
--- a/hw/max111x.c
+++ b/hw/max111x.c
@@ -94,36 +94,22 @@ static uint32_t max111x_transfer(SSISlave *dev, uint32_t value)
     return max111x_read(s);
 }
 
-static void max111x_save(QEMUFile *f, void *opaque)
-{
-    MAX111xState *s = (MAX111xState *) opaque;
-    int i;
-
-    qemu_put_8s(f, &s->tb1);
-    qemu_put_8s(f, &s->rb2);
-    qemu_put_8s(f, &s->rb3);
-    qemu_put_be32(f, s->inputs);
-    qemu_put_be32(f, s->com);
-    for (i = 0; i < s->inputs; i ++)
-        qemu_put_byte(f, s->input[i]);
-}
-
-static int max111x_load(QEMUFile *f, void *opaque, int version_id)
-{
-    MAX111xState *s = (MAX111xState *) opaque;
-    int i;
-
-    qemu_get_8s(f, &s->tb1);
-    qemu_get_8s(f, &s->rb2);
-    qemu_get_8s(f, &s->rb3);
-    if (s->inputs != qemu_get_be32(f))
-        return -EINVAL;
-    s->com = qemu_get_be32(f);
-    for (i = 0; i < s->inputs; i ++)
-        s->input[i] = qemu_get_byte(f);
-
-    return 0;
-}
+static const VMStateDescription vmstate_max111x = {
+    .name = "max111x",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT8(tb1, MAX111xState),
+        VMSTATE_UINT8(rb2, MAX111xState),
+        VMSTATE_UINT8(rb3, MAX111xState),
+        VMSTATE_INT32_EQUAL(inputs, MAX111xState),
+        VMSTATE_INT32(com, MAX111xState),
+        VMSTATE_ARRAY_INT32_UNSAFE(input, MAX111xState, inputs,
+                                   vmstate_info_uint8, uint8_t),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static int max111x_init(SSISlave *dev, int inputs)
 {
@@ -143,8 +129,7 @@ static int max111x_init(SSISlave *dev, int inputs)
     s->input[7] = 0x80;
     s->com = 0;
 
-    register_savevm(&dev->qdev, "max111x", -1, 0,
-                    max111x_save, max111x_load, s);
+    vmstate_register(&dev->qdev, -1, &vmstate_max111x, s);
     return 0;
 }
 

From 51db57f7e8ef46743cb3380bfd430d3ee1877866 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Fri, 3 Dec 2010 01:39:22 +0100
Subject: [PATCH 279/386] nand: pin values are uint8_t

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/flash.h | 4 ++--
 hw/nand.c  | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/flash.h b/hw/flash.h
index d7d103e66f..c22e1a922c 100644
--- a/hw/flash.h
+++ b/hw/flash.h
@@ -21,8 +21,8 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
 typedef struct NANDFlashState NANDFlashState;
 NANDFlashState *nand_init(int manf_id, int chip_id);
 void nand_done(NANDFlashState *s);
-void nand_setpins(NANDFlashState *s,
-                int cle, int ale, int ce, int wp, int gnd);
+void nand_setpins(NANDFlashState *s, uint8_t cle, uint8_t ale,
+                  uint8_t ce, uint8_t wp, uint8_t gnd);
 void nand_getpins(NANDFlashState *s, int *rb);
 void nand_setio(NANDFlashState *s, uint8_t value);
 uint8_t nand_getio(NANDFlashState *s);
diff --git a/hw/nand.c b/hw/nand.c
index f414aa139b..9f978d875a 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -52,7 +52,7 @@ struct NANDFlashState {
     BlockDriverState *bdrv;
     int mem_oob;
 
-    int cle, ale, ce, wp, gnd;
+    uint8_t cle, ale, ce, wp, gnd;
 
     uint8_t io[MAX_PAGE + MAX_OOB + 0x400];
     uint8_t *ioaddr;
@@ -329,8 +329,8 @@ static int nand_load(QEMUFile *f, void *opaque, int version_id)
  *
  * CE, WP and R/B are active low.
  */
-void nand_setpins(NANDFlashState *s,
-                int cle, int ale, int ce, int wp, int gnd)
+void nand_setpins(NANDFlashState *s, uint8_t cle, uint8_t ale,
+                  uint8_t ce, uint8_t wp, uint8_t gnd)
 {
     s->cle = cle;
     s->ale = ale;

From 7b9a3d86c1c5ed508ab07b536f44a308732b9069 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Fri, 3 Dec 2010 01:50:10 +0100
Subject: [PATCH 280/386] vmstate: port nand

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/nand.c | 73 +++++++++++++++++++++++++++++--------------------------
 1 file changed, 39 insertions(+), 34 deletions(-)

diff --git a/hw/nand.c b/hw/nand.c
index 9f978d875a..37e51d7140 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -66,6 +66,8 @@ struct NANDFlashState {
     void (*blk_write)(NANDFlashState *s);
     void (*blk_erase)(NANDFlashState *s);
     void (*blk_load)(NANDFlashState *s, uint32_t addr, int offset);
+
+    uint32_t ioaddr_vmstate;
 };
 
 # define NAND_NO_AUTOINCR	0x00000001
@@ -281,48 +283,51 @@ static void nand_command(NANDFlashState *s)
     }
 }
 
-static void nand_save(QEMUFile *f, void *opaque)
+static void nand_pre_save(void *opaque)
 {
-    NANDFlashState *s = (NANDFlashState *) opaque;
-    qemu_put_byte(f, s->cle);
-    qemu_put_byte(f, s->ale);
-    qemu_put_byte(f, s->ce);
-    qemu_put_byte(f, s->wp);
-    qemu_put_byte(f, s->gnd);
-    qemu_put_buffer(f, s->io, sizeof(s->io));
-    qemu_put_be32(f, s->ioaddr - s->io);
-    qemu_put_be32(f, s->iolen);
+    NANDFlashState *s = opaque;
 
-    qemu_put_be32s(f, &s->cmd);
-    qemu_put_be32s(f, &s->addr);
-    qemu_put_be32(f, s->addrlen);
-    qemu_put_be32(f, s->status);
-    qemu_put_be32(f, s->offset);
-    /* XXX: do we want to save s->storage too? */
+    s->ioaddr_vmstate = s->ioaddr - s->io;
 }
 
-static int nand_load(QEMUFile *f, void *opaque, int version_id)
+static int nand_post_load(void *opaque, int version_id)
 {
-    NANDFlashState *s = (NANDFlashState *) opaque;
-    s->cle = qemu_get_byte(f);
-    s->ale = qemu_get_byte(f);
-    s->ce = qemu_get_byte(f);
-    s->wp = qemu_get_byte(f);
-    s->gnd = qemu_get_byte(f);
-    qemu_get_buffer(f, s->io, sizeof(s->io));
-    s->ioaddr = s->io + qemu_get_be32(f);
-    s->iolen = qemu_get_be32(f);
-    if (s->ioaddr >= s->io + sizeof(s->io) || s->ioaddr < s->io)
-        return -EINVAL;
+    NANDFlashState *s = opaque;
+
+    if (s->ioaddr_vmstate > sizeof(s->io)) {
+        return -EINVAL;
+    }
+    s->ioaddr = s->io + s->ioaddr_vmstate;
 
-    qemu_get_be32s(f, &s->cmd);
-    qemu_get_be32s(f, &s->addr);
-    s->addrlen = qemu_get_be32(f);
-    s->status = qemu_get_be32(f);
-    s->offset = qemu_get_be32(f);
     return 0;
 }
 
+static const VMStateDescription vmstate_nand = {
+    .name = "nand",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .pre_save = nand_pre_save,
+    .post_load = nand_post_load,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT8(cle, NANDFlashState),
+        VMSTATE_UINT8(ale, NANDFlashState),
+        VMSTATE_UINT8(ce, NANDFlashState),
+        VMSTATE_UINT8(wp, NANDFlashState),
+        VMSTATE_UINT8(gnd, NANDFlashState),
+        VMSTATE_BUFFER(io, NANDFlashState),
+        VMSTATE_UINT32(ioaddr_vmstate, NANDFlashState),
+        VMSTATE_INT32(iolen, NANDFlashState),
+        VMSTATE_UINT32(cmd, NANDFlashState),
+        VMSTATE_UINT32(addr, NANDFlashState),
+        VMSTATE_INT32(addrlen, NANDFlashState),
+        VMSTATE_INT32(status, NANDFlashState),
+        VMSTATE_INT32(offset, NANDFlashState),
+        /* XXX: do we want to save s->storage too? */
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 /*
  * Chip inputs are CLE, ALE, CE, WP, GND and eight I/O pins.  Chip
  * outputs are R/B and eight I/O pins.
@@ -502,7 +507,7 @@ NANDFlashState *nand_init(int manf_id, int chip_id)
        is used.  */
     s->ioaddr = s->io;
 
-    register_savevm(NULL, "nand", -1, 0, nand_save, nand_load, s);
+    vmstate_register(NULL, -1, &vmstate_nand, s);
 
     return s;
 }

From 8a11f43bd5d42462c7d6a9321cefa59e78c69d51 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Fri, 3 Dec 2010 01:54:21 +0100
Subject: [PATCH 281/386] mac_nvram: size is a size, no need to be a target
 dependent type

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/mac_nvram.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/mac_nvram.c b/hw/mac_nvram.c
index c2a2fc21e4..64f0192b22 100644
--- a/hw/mac_nvram.c
+++ b/hw/mac_nvram.c
@@ -38,7 +38,7 @@
 #endif
 
 struct MacIONVRAMState {
-    target_phys_addr_t size;
+    uint32_t size;
     int mem_index;
     unsigned int it_shift;
     uint8_t *data;

From 8e470f8a77f6dfb0ca4bb087010b4bcd920a1d21 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Fri, 3 Dec 2010 01:59:09 +0100
Subject: [PATCH 282/386] vmstate: port mac_nvram

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/mac_nvram.c | 30 +++++++++++-------------------
 1 file changed, 11 insertions(+), 19 deletions(-)

diff --git a/hw/mac_nvram.c b/hw/mac_nvram.c
index 64f0192b22..61e53d28b4 100644
--- a/hw/mac_nvram.c
+++ b/hw/mac_nvram.c
@@ -105,24 +105,17 @@ static CPUReadMemoryFunc * const nvram_read[] = {
     &macio_nvram_readb,
 };
 
-static void macio_nvram_save(QEMUFile *f, void *opaque)
-{
-    MacIONVRAMState *s = (MacIONVRAMState *)opaque;
+static const VMStateDescription vmstate_macio_nvram = {
+    .name = "macio_nvram",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_VBUFFER_UINT32(data, MacIONVRAMState, 0, NULL, 0, size),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
-    qemu_put_buffer(f, s->data, s->size);
-}
-
-static int macio_nvram_load(QEMUFile *f, void *opaque, int version_id)
-{
-    MacIONVRAMState *s = (MacIONVRAMState *)opaque;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    qemu_get_buffer(f, s->data, s->size);
-
-    return 0;
-}
 
 static void macio_nvram_reset(void *opaque)
 {
@@ -141,8 +134,7 @@ MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size,
     s->mem_index = cpu_register_io_memory(nvram_read, nvram_write, s,
                                           DEVICE_NATIVE_ENDIAN);
     *mem_index = s->mem_index;
-    register_savevm(NULL, "macio_nvram", -1, 1, macio_nvram_save,
-                    macio_nvram_load, s);
+    vmstate_register(NULL, -1, &vmstate_macio_nvram, s);
     qemu_register_reset(macio_nvram_reset, s);
 
     return s;

From 1fc7cee0b40e23d3d8a7384df69c07e5dd5954ed Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 16:26:56 +0100
Subject: [PATCH 283/386] piix4: create PIIX4State

It only contains a PCIDevice by know, but it makes easy to use migration code

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/piix4.c | 29 +++++++++++++++++------------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/hw/piix4.c b/hw/piix4.c
index 72073cd0a0..40cd91a32f 100644
--- a/hw/piix4.c
+++ b/hw/piix4.c
@@ -30,10 +30,14 @@
 
 PCIDevice *piix4_dev;
 
+typedef struct PIIX4State {
+    PCIDevice dev;
+} PIIX4State;
+
 static void piix4_reset(void *opaque)
 {
-    PCIDevice *d = opaque;
-    uint8_t *pci_conf = d->config;
+    PIIX4State *d = opaque;
+    uint8_t *pci_conf = d->dev.config;
 
     pci_conf[0x04] = 0x07; // master, memory and I/O
     pci_conf[0x05] = 0x00;
@@ -70,31 +74,32 @@ static void piix4_reset(void *opaque)
 
 static void piix_save(QEMUFile* f, void *opaque)
 {
-    PCIDevice *d = opaque;
-    pci_device_save(d, f);
+    PIIX4State *d = opaque;
+    pci_device_save(&d->dev, f);
 }
 
 static int piix_load(QEMUFile* f, void *opaque, int version_id)
 {
-    PCIDevice *d = opaque;
+    PIIX4State *d = opaque;
     if (version_id != 2)
         return -EINVAL;
-    return pci_device_load(d, f);
+    return pci_device_load(&d->dev, f);
 }
 
-static int piix4_initfn(PCIDevice *d)
+static int piix4_initfn(PCIDevice *dev)
 {
+    PIIX4State *d = DO_UPCAST(PIIX4State, dev, dev);
     uint8_t *pci_conf;
 
-    isa_bus_new(&d->qdev);
-    register_savevm(&d->qdev, "PIIX4", 0, 2, piix_save, piix_load, d);
+    isa_bus_new(&d->dev.qdev);
+    register_savevm(&d->dev.qdev, "PIIX4", 0, 2, piix_save, piix_load, d);
 
-    pci_conf = d->config;
+    pci_conf = d->dev.config;
     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
     pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_0); // 82371AB/EB/MB PIIX4 PCI-to-ISA bridge
     pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA);
 
-    piix4_dev = d;
+    piix4_dev = &d->dev;
     qemu_register_reset(piix4_reset, d);
     return 0;
 }
@@ -111,7 +116,7 @@ static PCIDeviceInfo piix4_info[] = {
     {
         .qdev.name    = "PIIX4",
         .qdev.desc    = "ISA bridge",
-        .qdev.size    = sizeof(PCIDevice),
+        .qdev.size    = sizeof(PIIX4State),
         .qdev.no_user = 1,
         .no_hotplug   = 1,
         .init         = piix4_initfn,

From 9039d78e64648e6dca2aa7fe38c59ac2f5bac32b Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Thu, 2 Dec 2010 16:59:33 +0100
Subject: [PATCH 284/386] vmstate: port piix4

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/piix4.c | 25 +++++++++++--------------
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/hw/piix4.c b/hw/piix4.c
index 40cd91a32f..71f1f84dc0 100644
--- a/hw/piix4.c
+++ b/hw/piix4.c
@@ -72,19 +72,16 @@ static void piix4_reset(void *opaque)
     pci_conf[0xae] = 0x00;
 }
 
-static void piix_save(QEMUFile* f, void *opaque)
-{
-    PIIX4State *d = opaque;
-    pci_device_save(&d->dev, f);
-}
-
-static int piix_load(QEMUFile* f, void *opaque, int version_id)
-{
-    PIIX4State *d = opaque;
-    if (version_id != 2)
-        return -EINVAL;
-    return pci_device_load(&d->dev, f);
-}
+static const VMStateDescription vmstate_piix4 = {
+    .name = "PIIX4",
+    .version_id = 2,
+    .minimum_version_id = 2,
+    .minimum_version_id_old = 2,
+    .fields      = (VMStateField[]) {
+        VMSTATE_PCI_DEVICE(dev, PIIX4State),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static int piix4_initfn(PCIDevice *dev)
 {
@@ -92,7 +89,6 @@ static int piix4_initfn(PCIDevice *dev)
     uint8_t *pci_conf;
 
     isa_bus_new(&d->dev.qdev);
-    register_savevm(&d->dev.qdev, "PIIX4", 0, 2, piix_save, piix_load, d);
 
     pci_conf = d->dev.config;
     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
@@ -117,6 +113,7 @@ static PCIDeviceInfo piix4_info[] = {
         .qdev.name    = "PIIX4",
         .qdev.desc    = "ISA bridge",
         .qdev.size    = sizeof(PIIX4State),
+        .qdev.vmsd    = &vmstate_piix4,
         .qdev.no_user = 1,
         .no_hotplug   = 1,
         .init         = piix4_initfn,

From c20df14b1336b409c48fbbbfeb448f0043df75d5 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Fri, 3 Dec 2010 00:04:02 +0100
Subject: [PATCH 285/386] mac_dbdma: create DBDMAState instead of passing one
 array around

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/mac_dbdma.c | 45 +++++++++++++++++++++++++++------------------
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/hw/mac_dbdma.c b/hw/mac_dbdma.c
index 5680fa9c1c..c108aeee7d 100644
--- a/hw/mac_dbdma.c
+++ b/hw/mac_dbdma.c
@@ -165,6 +165,10 @@ typedef struct DBDMA_channel {
     int processing;
 } DBDMA_channel;
 
+typedef struct {
+    DBDMA_channel channels[DBDMA_CHANNELS];
+} DBDMAState;
+
 #ifdef DEBUG_DBDMA
 static void dump_dbdma_cmd(dbdma_cmd *cmd)
 {
@@ -617,31 +621,34 @@ static void channel_run(DBDMA_channel *ch)
     }
 }
 
-static void DBDMA_run (DBDMA_channel *ch)
+static void DBDMA_run(DBDMAState *s)
 {
     int channel;
 
-    for (channel = 0; channel < DBDMA_CHANNELS; channel++, ch++) {
-            uint32_t status = ch->regs[DBDMA_STATUS];
-            if (!ch->processing && (status & RUN) && (status & ACTIVE))
-                channel_run(ch);
+    for (channel = 0; channel < DBDMA_CHANNELS; channel++) {
+        DBDMA_channel *ch = &s->channels[channel];
+        uint32_t status = ch->regs[DBDMA_STATUS];
+        if (!ch->processing && (status & RUN) && (status & ACTIVE)) {
+            channel_run(ch);
+        }
     }
 }
 
 static void DBDMA_run_bh(void *opaque)
 {
-    DBDMA_channel *ch = opaque;
+    DBDMAState *s = opaque;
 
     DBDMA_DPRINTF("DBDMA_run_bh\n");
 
-    DBDMA_run(ch);
+    DBDMA_run(s);
 }
 
 void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
                             DBDMA_rw rw, DBDMA_flush flush,
                             void *opaque)
 {
-    DBDMA_channel *ch = ( DBDMA_channel *)dbdma + nchan;
+    DBDMAState *s = dbdma;
+    DBDMA_channel *ch = &s->channels[nchan];
 
     DBDMA_DPRINTF("DBDMA_register_channel 0x%x\n", nchan);
 
@@ -700,7 +707,8 @@ static void dbdma_writel (void *opaque,
                           target_phys_addr_t addr, uint32_t value)
 {
     int channel = addr >> DBDMA_CHANNEL_SHIFT;
-    DBDMA_channel *ch = (DBDMA_channel *)opaque + channel;
+    DBDMAState *s = opaque;
+    DBDMA_channel *ch = &s->channels[channel];
     int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2;
 
     DBDMA_DPRINTF("writel 0x" TARGET_FMT_plx " <= 0x%08x\n", addr, value);
@@ -749,7 +757,8 @@ static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr)
 {
     uint32_t value;
     int channel = addr >> DBDMA_CHANNEL_SHIFT;
-    DBDMA_channel *ch = (DBDMA_channel *)opaque + channel;
+    DBDMAState *s = opaque;
+    DBDMA_channel *ch = &s->channels[channel];
     int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2;
 
     value = ch->regs[reg];
@@ -803,17 +812,17 @@ static CPUReadMemoryFunc * const dbdma_read[] = {
 
 static void dbdma_save(QEMUFile *f, void *opaque)
 {
-    DBDMA_channel *s = opaque;
+    DBDMAState *s = opaque;
     unsigned int i, j;
 
     for (i = 0; i < DBDMA_CHANNELS; i++)
         for (j = 0; j < DBDMA_REGS; j++)
-            qemu_put_be32s(f, &s[i].regs[j]);
+            qemu_put_be32s(f, &s->channels[i].regs[j]);
 }
 
 static int dbdma_load(QEMUFile *f, void *opaque, int version_id)
 {
-    DBDMA_channel *s = opaque;
+    DBDMAState *s = opaque;
     unsigned int i, j;
 
     if (version_id != 2)
@@ -821,25 +830,25 @@ static int dbdma_load(QEMUFile *f, void *opaque, int version_id)
 
     for (i = 0; i < DBDMA_CHANNELS; i++)
         for (j = 0; j < DBDMA_REGS; j++)
-            qemu_get_be32s(f, &s[i].regs[j]);
+            qemu_get_be32s(f, &s->channels[i].regs[j]);
 
     return 0;
 }
 
 static void dbdma_reset(void *opaque)
 {
-    DBDMA_channel *s = opaque;
+    DBDMAState *s = opaque;
     int i;
 
     for (i = 0; i < DBDMA_CHANNELS; i++)
-        memset(s[i].regs, 0, DBDMA_SIZE);
+        memset(s->channels[i].regs, 0, DBDMA_SIZE);
 }
 
 void* DBDMA_init (int *dbdma_mem_index)
 {
-    DBDMA_channel *s;
+    DBDMAState *s;
 
-    s = qemu_mallocz(sizeof(DBDMA_channel) * DBDMA_CHANNELS);
+    s = qemu_mallocz(sizeof(DBDMAState));
 
     *dbdma_mem_index = cpu_register_io_memory(dbdma_read, dbdma_write, s,
                                               DEVICE_LITTLE_ENDIAN);

From da26fdc3145fc990762133beb8ad6bd67742a147 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Fri, 3 Dec 2010 00:07:26 +0100
Subject: [PATCH 286/386] vmstate: port mac_dbdma

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/mac_dbdma.c | 46 ++++++++++++++++++++++------------------------
 1 file changed, 22 insertions(+), 24 deletions(-)

diff --git a/hw/mac_dbdma.c b/hw/mac_dbdma.c
index c108aeee7d..ed4458e3bb 100644
--- a/hw/mac_dbdma.c
+++ b/hw/mac_dbdma.c
@@ -810,30 +810,28 @@ static CPUReadMemoryFunc * const dbdma_read[] = {
     dbdma_readl,
 };
 
-static void dbdma_save(QEMUFile *f, void *opaque)
-{
-    DBDMAState *s = opaque;
-    unsigned int i, j;
+static const VMStateDescription vmstate_dbdma_channel = {
+    .name = "dbdma_channel",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(regs, struct DBDMA_channel, DBDMA_REGS),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
-    for (i = 0; i < DBDMA_CHANNELS; i++)
-        for (j = 0; j < DBDMA_REGS; j++)
-            qemu_put_be32s(f, &s->channels[i].regs[j]);
-}
-
-static int dbdma_load(QEMUFile *f, void *opaque, int version_id)
-{
-    DBDMAState *s = opaque;
-    unsigned int i, j;
-
-    if (version_id != 2)
-        return -EINVAL;
-
-    for (i = 0; i < DBDMA_CHANNELS; i++)
-        for (j = 0; j < DBDMA_REGS; j++)
-            qemu_get_be32s(f, &s->channels[i].regs[j]);
-
-    return 0;
-}
+static const VMStateDescription vmstate_dbdma = {
+    .name = "dbdma",
+    .version_id = 2,
+    .minimum_version_id = 2,
+    .minimum_version_id_old = 2,
+    .fields      = (VMStateField[]) {
+        VMSTATE_STRUCT_ARRAY(channels, DBDMAState, DBDMA_CHANNELS, 1,
+                             vmstate_dbdma_channel, DBDMA_channel),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
 static void dbdma_reset(void *opaque)
 {
@@ -852,7 +850,7 @@ void* DBDMA_init (int *dbdma_mem_index)
 
     *dbdma_mem_index = cpu_register_io_memory(dbdma_read, dbdma_write, s,
                                               DEVICE_LITTLE_ENDIAN);
-    register_savevm(NULL, "dbdma", -1, 1, dbdma_save, dbdma_load, s);
+    vmstate_register(NULL, -1, &vmstate_dbdma, s);
     qemu_register_reset(dbdma_reset, s);
 
     dbdma_bh = qemu_bh_new(DBDMA_run_bh, s);

From e2f422047b6fd04c28630f80ab1161dbce07c6b7 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:22 +0200
Subject: [PATCH 287/386] softfloat: fix floatx80 handling of NaN

The floatx80 format uses an explicit bit that should be taken into account
when converting to and from commonNaN format.

When converting to commonNaN, the explicit bit should be removed if it is
a 1, and a default NaN should be used if it is 0.

When converting from commonNan, the explicit bit should be added.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat-specialize.h | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index b1101872af..9d68aae9d5 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -603,9 +603,15 @@ static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
     commonNaNT z;
 
     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
-    z.sign = a.high>>15;
-    z.low = 0;
-    z.high = a.low;
+    if ( a.low >> 63 ) {
+        z.sign = a.high >> 15;
+        z.low = 0;
+        z.high = a.low << 1;
+    } else {
+        z.sign = floatx80_default_nan_high >> 15;
+        z.low = 0;
+        z.high = floatx80_default_nan_low << 1;
+    }
     return z;
 }
 
@@ -624,11 +630,14 @@ static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
         return z;
     }
 
-    if (a.high)
-        z.low = a.high;
-    else
+    if (a.high >> 1) {
+        z.low = LIT64( 0x8000000000000000 ) | a.high >> 1;
+        z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
+    } else {
         z.low = floatx80_default_nan_low;
-    z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
+        z.high = floatx80_default_nan_high;
+    }
+
     return z;
 }
 

From b76235e400be0e4f2c87ac4b678384f43a932181 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:22 +0200
Subject: [PATCH 288/386] softfloat: fix floatx80_is_infinity()

With floatx80, the explicit bit is set for infinity.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 340f0a9f2e..336312839a 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -566,7 +566,7 @@ INLINE floatx80 floatx80_chs(floatx80 a)
 
 INLINE int floatx80_is_infinity(floatx80 a)
 {
-    return (a.high & 0x7fff) == 0x7fff && a.low == 0;
+    return (a.high & 0x7fff) == 0x7fff && a.low == 0x8000000000000000LL;
 }
 
 INLINE int floatx80_is_neg(floatx80 a)

From f3218a8df0365e515f2100c92016217826811200 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:22 +0200
Subject: [PATCH 289/386] softfloat: add floatx80 constants

Add floatx80 constants similarly to float32 or float64.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 336312839a..90e0c41210 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -154,6 +154,7 @@ typedef struct {
     uint64_t low;
     uint16_t high;
 } floatx80;
+#define make_floatx80(exp, mant) ((floatx80) { mant, exp })
 #endif
 #ifdef FLOAT128
 typedef struct {
@@ -584,6 +585,12 @@ INLINE int floatx80_is_any_nan(floatx80 a)
     return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
 }
 
+#define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL)
+#define floatx80_one make_floatx80(0x3fff, 0x8000000000000000LL)
+#define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL)
+#define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL)
+#define floatx80_infinity make_floatx80(0x7fff, 0x8000000000000000LL)
+
 /*----------------------------------------------------------------------------
 | The pattern for a default generated extended double-precision NaN.  The
 | `high' and `low' values hold the most- and least-significant bits,

From c4b4c77a80cec85206e502578887d8c82b70d6af Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:22 +0200
Subject: [PATCH 290/386] softfloat: add pi constants

Add a pi constant for float32, float64, floatx80. It will be used by
target-i386 and later by the trigonometric functions.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 90e0c41210..7b3b88f1b1 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -387,6 +387,7 @@ INLINE float32 float32_set_sign(float32 a, int sign)
 #define float32_zero make_float32(0)
 #define float32_one make_float32(0x3f800000)
 #define float32_ln2 make_float32(0x3f317218)
+#define float32_pi make_float32(0x40490fdb)
 #define float32_half make_float32(0x3f000000)
 #define float32_infinity make_float32(0x7f800000)
 
@@ -499,6 +500,7 @@ INLINE float64 float64_set_sign(float64 a, int sign)
 #define float64_zero make_float64(0)
 #define float64_one make_float64(0x3ff0000000000000LL)
 #define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
+#define float64_pi make_float64(0x400921fb54442d18LL)
 #define float64_half make_float64(0x3fe0000000000000LL)
 #define float64_infinity make_float64(0x7ff0000000000000LL)
 
@@ -588,6 +590,7 @@ INLINE int floatx80_is_any_nan(floatx80 a)
 #define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL)
 #define floatx80_one make_floatx80(0x3fff, 0x8000000000000000LL)
 #define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL)
+#define floatx80_pi make_floatx80(0x4000, 0xc90fdaa22168c235LL)
 #define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL)
 #define floatx80_infinity make_floatx80(0x7fff, 0x8000000000000000LL)
 

From d2b1027d5ffe7c6832bd50f167751171ed168ed0 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:22 +0200
Subject: [PATCH 291/386] softfloat-native: add a few constant values

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat-native.h | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
index ea7a15e1c4..97fb3c7a5c 100644
--- a/fpu/softfloat-native.h
+++ b/fpu/softfloat-native.h
@@ -171,6 +171,15 @@ floatx80 int64_to_floatx80( int64_t STATUS_PARAM);
 float128 int64_to_float128( int64_t STATUS_PARAM);
 #endif
 
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE single-precision conversion constants.
+*----------------------------------------------------------------------------*/
+#define float32_zero (0.0)
+#define float32_one (1.0)
+#define float32_ln2 (0.6931471)
+#define float32_pi (3.1415926)
+#define float32_half (0.5)
+
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE single-precision conversion routines.
 *----------------------------------------------------------------------------*/
@@ -279,6 +288,15 @@ INLINE float32 float32_scalbn(float32 a, int n)
     return scalbnf(a, n);
 }
 
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE double-precision conversion constants.
+*----------------------------------------------------------------------------*/
+#define float64_zero (0.0)
+#define float64_one (1.0)
+#define float64_ln2 (0.693147180559945)
+#define float64_pi (3.141592653589793)
+#define float64_half (0.5)
+
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE double-precision conversion routines.
 *----------------------------------------------------------------------------*/
@@ -393,6 +411,15 @@ INLINE float64 float64_scalbn(float64 a, int n)
 
 #ifdef FLOATX80
 
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE extended double-precision conversion constants.
+*----------------------------------------------------------------------------*/
+#define floatx80_zero (0.0L)
+#define floatx80_one (1.0L)
+#define floatx80_ln2 (0.69314718055994530943L)
+#define floatx80_pi (3.14159265358979323851L)
+#define floatx80_half (0.5L)
+
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE extended double-precision conversion routines.
 *----------------------------------------------------------------------------*/

From f6714d365da068481d83787b4044134ae2ec5dfd Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:22 +0200
Subject: [PATCH 292/386] softfloat: add floatx80_compare*() functions

Add floatx80_compare() and floatx80_compare_quiet() functions to match
the softfloat-native ones.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 fpu/softfloat.h |  2 ++
 2 files changed, 48 insertions(+)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 6ce0b61c19..4368069dd6 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6190,6 +6190,52 @@ int float ## s ## _compare_quiet( float ## s a, float ## s b STATUS_PARAM )  \
 COMPARE(32, 0xff)
 COMPARE(64, 0x7ff)
 
+INLINE int floatx80_compare_internal( floatx80 a, floatx80 b,
+                                      int is_quiet STATUS_PARAM )
+{
+    flag aSign, bSign;
+
+    if (( ( extractFloatx80Exp( a ) == 0x7fff ) &&
+          ( extractFloatx80Frac( a )<<1 ) ) ||
+        ( ( extractFloatx80Exp( b ) == 0x7fff ) &&
+          ( extractFloatx80Frac( b )<<1 ) )) {
+        if (!is_quiet ||
+            floatx80_is_signaling_nan( a ) ||
+            floatx80_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
+        return float_relation_unordered;
+    }
+    aSign = extractFloatx80Sign( a );
+    bSign = extractFloatx80Sign( b );
+    if ( aSign != bSign ) {
+
+        if ( ( ( (uint16_t) ( ( a.high | b.high ) << 1 ) ) == 0) &&
+             ( ( a.low | b.low ) == 0 ) ) {
+            /* zero case */
+            return float_relation_equal;
+        } else {
+            return 1 - (2 * aSign);
+        }
+    } else {
+        if (a.low == b.low && a.high == b.high) {
+            return float_relation_equal;
+        } else {
+            return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low ) ));
+        }
+    }
+}
+
+int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
+{
+    return floatx80_compare_internal(a, b, 0 STATUS_VAR);
+}
+
+int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
+{
+    return floatx80_compare_internal(a, b, 1 STATUS_VAR);
+}
+
 INLINE int float128_compare_internal( float128 a, float128 b,
                                       int is_quiet STATUS_PARAM )
 {
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 7b3b88f1b1..5eff0858f1 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -550,6 +550,8 @@ int floatx80_eq_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_unordered_quiet( floatx80, floatx80 STATUS_PARAM );
+int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
+int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_is_quiet_nan( floatx80 );
 int floatx80_is_signaling_nan( floatx80 );
 floatx80 floatx80_maybe_silence_nan( floatx80 );

From 326b9e98a391d542cc33c4c91782ff4ba51edfc5 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:22 +0200
Subject: [PATCH 293/386] softfloat: fix float*_scalnb() corner cases

float*_scalnb() were not taking into account all cases. This patch fixes
some corner cases:
- NaN values in input were not properly propagated and the invalid flag
  not correctly raised. Use propagateFloat*NaN() for that.
- NaN or infinite values in input of floatx80_scalnb() were not correctly
  detected due to a typo.
- The sum of exponent and n could overflow, leading to strange results.
  Additionally having int16 defined to int make that happening for a very
  small range of values. Fix that by saturating n to the maximum exponent
  range, and using an explicit wider type if needed.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat.c | 47 ++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 42 insertions(+), 5 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 4368069dd6..baba1dc44b 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6333,7 +6333,7 @@ MINMAX(64, 0x7ff)
 float32 float32_scalbn( float32 a, int n STATUS_PARAM )
 {
     flag aSign;
-    int16 aExp;
+    int16_t aExp;
     uint32_t aSig;
 
     a = float32_squash_input_denormal(a STATUS_VAR);
@@ -6342,6 +6342,9 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM )
     aSign = extractFloat32Sign( a );
 
     if ( aExp == 0xFF ) {
+        if ( aSig ) {
+            return propagateFloat32NaN( a, a STATUS_VAR );
+        }
         return a;
     }
     if ( aExp != 0 )
@@ -6349,6 +6352,12 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM )
     else if ( aSig == 0 )
         return a;
 
+    if (n > 0x200) {
+        n = 0x200;
+    } else if (n < -0x200) {
+        n = -0x200;
+    }
+
     aExp += n - 1;
     aSig <<= 7;
     return normalizeRoundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
@@ -6357,7 +6366,7 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM )
 float64 float64_scalbn( float64 a, int n STATUS_PARAM )
 {
     flag aSign;
-    int16 aExp;
+    int16_t aExp;
     uint64_t aSig;
 
     a = float64_squash_input_denormal(a STATUS_VAR);
@@ -6366,6 +6375,9 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM )
     aSign = extractFloat64Sign( a );
 
     if ( aExp == 0x7FF ) {
+        if ( aSig ) {
+            return propagateFloat64NaN( a, a STATUS_VAR );
+        }
         return a;
     }
     if ( aExp != 0 )
@@ -6373,6 +6385,12 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM )
     else if ( aSig == 0 )
         return a;
 
+    if (n > 0x1000) {
+        n = 0x1000;
+    } else if (n < -0x1000) {
+        n = -0x1000;
+    }
+
     aExp += n - 1;
     aSig <<= 10;
     return normalizeRoundAndPackFloat64( aSign, aExp, aSig STATUS_VAR );
@@ -6382,19 +6400,29 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM )
 floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
 {
     flag aSign;
-    int16 aExp;
+    int32_t aExp;
     uint64_t aSig;
 
     aSig = extractFloatx80Frac( a );
     aExp = extractFloatx80Exp( a );
     aSign = extractFloatx80Sign( a );
 
-    if ( aExp == 0x7FF ) {
+    if ( aExp == 0x7FFF ) {
+        if ( aSig<<1 ) {
+            return propagateFloatx80NaN( a, a STATUS_VAR );
+        }
         return a;
     }
+
     if (aExp == 0 && aSig == 0)
         return a;
 
+    if (n > 0x10000) {
+        n = 0x10000;
+    } else if (n < -0x10000) {
+        n = -0x10000;
+    }
+
     aExp += n;
     return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision),
                                           aSign, aExp, aSig, 0 STATUS_VAR );
@@ -6405,7 +6433,7 @@ floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
 float128 float128_scalbn( float128 a, int n STATUS_PARAM )
 {
     flag aSign;
-    int32 aExp;
+    int32_t aExp;
     uint64_t aSig0, aSig1;
 
     aSig1 = extractFloat128Frac1( a );
@@ -6413,6 +6441,9 @@ float128 float128_scalbn( float128 a, int n STATUS_PARAM )
     aExp = extractFloat128Exp( a );
     aSign = extractFloat128Sign( a );
     if ( aExp == 0x7FFF ) {
+        if ( aSig0 | aSig1 ) {
+            return propagateFloat128NaN( a, a STATUS_VAR );
+        }
         return a;
     }
     if ( aExp != 0 )
@@ -6420,6 +6451,12 @@ float128 float128_scalbn( float128 a, int n STATUS_PARAM )
     else if ( aSig0 == 0 && aSig1 == 0 )
         return a;
 
+    if (n > 0x10000) {
+        n = 0x10000;
+    } else if (n < -0x10000) {
+        n = -0x10000;
+    }
+
     aExp += n - 1;
     return normalizeRoundAndPackFloat128( aSign, aExp, aSig0, aSig1
                                           STATUS_VAR );

From d6882cf01fd9e3e1c9dee38ff7dae0d8d377c8f7 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:23 +0200
Subject: [PATCH 294/386] softfloat-native: fix float*_scalbn() functions

float*_scalbn() should be able to take a status parameter. Fix that.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat-native.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
index 97fb3c7a5c..f497e64239 100644
--- a/fpu/softfloat-native.h
+++ b/fpu/softfloat-native.h
@@ -283,7 +283,7 @@ INLINE float32 float32_is_zero(float32 a)
     return fpclassify(a) == FP_ZERO;
 }
 
-INLINE float32 float32_scalbn(float32 a, int n)
+INLINE float32 float32_scalbn(float32 a, int n STATUS_PARAM)
 {
     return scalbnf(a, n);
 }
@@ -404,7 +404,7 @@ INLINE float64 float64_is_zero(float64 a)
     return fpclassify(a) == FP_ZERO;
 }
 
-INLINE float64 float64_scalbn(float64 a, int n)
+INLINE float64 float64_scalbn(float64 a, int n STATUS_PARAM)
 {
     return scalbn(a, n);
 }
@@ -520,7 +520,7 @@ INLINE floatx80 floatx80_is_zero(floatx80 a)
     return fpclassify(a) == FP_ZERO;
 }
 
-INLINE floatx80 floatx80_scalbn(floatx80 a, int n)
+INLINE floatx80 floatx80_scalbn(floatx80 a, int n STATUS_PARAM)
 {
     return scalbnl(a, n);
 }

From 4cc5383f807a7d70942de51326a8dddad7331fa5 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:23 +0200
Subject: [PATCH 295/386] softfloat-native: add float*_is_any_nan() functions

Add float*_is_any_nan() functions to match the softfloat API.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat-native.c | 26 ++++++++++++++++++++++++++
 fpu/softfloat-native.h |  3 +++
 2 files changed, 29 insertions(+)

diff --git a/fpu/softfloat-native.c b/fpu/softfloat-native.c
index 50355a4c3f..88486511ee 100644
--- a/fpu/softfloat-native.c
+++ b/fpu/softfloat-native.c
@@ -263,6 +263,15 @@ int float32_is_quiet_nan( float32 a1 )
     return ( 0xFF800000 < ( a<<1 ) );
 }
 
+int float32_is_any_nan( float32 a1 )
+{
+    float32u u;
+    uint32_t a;
+    u.f = a1;
+    a = u.i;
+    return (a & ~(1 << 31)) > 0x7f800000U;
+}
+
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE double-precision conversion routines.
 *----------------------------------------------------------------------------*/
@@ -422,6 +431,16 @@ int float64_is_quiet_nan( float64 a1 )
 
 }
 
+int float64_is_any_nan( float64 a1 )
+{
+    float64u u;
+    uint64_t a;
+    u.f = a1;
+    a = u.i;
+
+    return (a & ~(1ULL << 63)) > LIT64 (0x7FF0000000000000 );
+}
+
 #ifdef FLOATX80
 
 /*----------------------------------------------------------------------------
@@ -511,4 +530,11 @@ int floatx80_is_quiet_nan( floatx80 a1 )
     return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (uint64_t) ( u.i.low<<1 );
 }
 
+int floatx80_is_any_nan( floatx80 a1 )
+{
+    floatx80u u;
+    u.f = a1;
+    return ((u.i.high & 0x7FFF) == 0x7FFF) && ( u.i.low<<1 );
+}
+
 #endif
diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
index f497e64239..6afb74a152 100644
--- a/fpu/softfloat-native.h
+++ b/fpu/softfloat-native.h
@@ -255,6 +255,7 @@ int float32_compare( float32, float32 STATUS_PARAM );
 int float32_compare_quiet( float32, float32 STATUS_PARAM );
 int float32_is_signaling_nan( float32 );
 int float32_is_quiet_nan( float32 );
+int float32_is_any_nan( float32 );
 
 INLINE float32 float32_abs(float32 a)
 {
@@ -375,6 +376,7 @@ INLINE int float64_unordered_quiet( float64 a, float64 b STATUS_PARAM)
 int float64_compare( float64, float64 STATUS_PARAM );
 int float64_compare_quiet( float64, float64 STATUS_PARAM );
 int float64_is_signaling_nan( float64 );
+int float64_is_any_nan( float64 );
 int float64_is_quiet_nan( float64 );
 
 INLINE float64 float64_abs(float64 a)
@@ -492,6 +494,7 @@ int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
 int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_is_signaling_nan( floatx80 );
 int floatx80_is_quiet_nan( floatx80 );
+int floatx80_is_any_nan( floatx80 );
 
 INLINE floatx80 floatx80_abs(floatx80 a)
 {

From be1c17c7fdc16d9cb88f4092f23a494b942b68d7 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:23 +0200
Subject: [PATCH 296/386] target-i386: fix helper_fscale() wrt softfloat

Use the scalbn softfloat function to implement helper_fscale(). This
fixes corner cases (e.g. NaN) and makes a few more GNU libc math tests
to pass.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/exec.h      | 4 ++++
 target-i386/op_helper.c | 7 ++++++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/target-i386/exec.h b/target-i386/exec.h
index ae6b94740f..211cc8c28e 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -115,9 +115,11 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_sub floatx80_sub
 #define floatx_abs floatx80_abs
 #define floatx_chs floatx80_chs
+#define floatx_scalbn floatx80_scalbn
 #define floatx_round_to_int floatx80_round_to_int
 #define floatx_compare floatx80_compare
 #define floatx_compare_quiet floatx80_compare_quiet
+#define floatx_is_any_nan floatx80_is_any_nan
 #else
 #define floatx_to_int32 float64_to_int32
 #define floatx_to_int64 float64_to_int64
@@ -134,9 +136,11 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_sub float64_sub
 #define floatx_abs float64_abs
 #define floatx_chs float64_chs
+#define floatx_scalbn float64_scalbn
 #define floatx_round_to_int float64_round_to_int
 #define floatx_compare float64_compare
 #define floatx_compare_quiet float64_compare_quiet
+#define floatx_is_any_nan float64_is_any_nan
 #endif
 
 #define RC_MASK         0xc00
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index fba536f0fb..dce28fa054 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4174,7 +4174,12 @@ void helper_frndint(void)
 
 void helper_fscale(void)
 {
-    ST0 = ldexp (ST0, (int)(ST1));
+    if (floatx_is_any_nan(ST1)) {
+        ST0 = ST1;
+    } else {
+        int n = floatx_to_int32_round_to_zero(ST1, &env->fp_status);
+        ST0 = floatx_scalbn(ST0, n, &env->fp_status);
+    }
 }
 
 void helper_fsin(void)

From 788e733664aab69e65bf5d5d228767cf4371f3ab Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:23 +0200
Subject: [PATCH 297/386] target-i386: fix helper_fbld_ST0() wrt softfloat

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/op_helper.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index dce28fa054..943d217e6e 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -3920,9 +3920,10 @@ void helper_fbld_ST0(target_ulong ptr)
         v = ldub(ptr + i);
         val = (val * 100) + ((v >> 4) * 10) + (v & 0xf);
     }
-    tmp = val;
-    if (ldub(ptr + 9) & 0x80)
-        tmp = -tmp;
+    tmp = int64_to_floatx(val, &env->fp_status);
+    if (ldub(ptr + 9) & 0x80) {
+        floatx_chs(tmp);
+    }
     fpush();
     ST0 = tmp;
 }

From c9ad19c57b4e35dda507ec636443069048a4ad72 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:23 +0200
Subject: [PATCH 298/386] target-i386: fix helper_fxtract() wrt softfloat

With softfloat it's not possible to play with the overflow of an
unsigned value to get the 0 case partially correct. Use a special case
for that. Using a division to generate an infinity is the easiest way
that works for both softfloat and softfloat-native.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/op_helper.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 943d217e6e..4850c63699 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4005,15 +4005,24 @@ void helper_fpatan(void)
 void helper_fxtract(void)
 {
     CPU86_LDoubleU temp;
-    unsigned int expdif;
 
     temp.d = ST0;
-    expdif = EXPD(temp) - EXPBIAS;
-    /*DP exponent bias*/
-    ST0 = expdif;
-    fpush();
-    BIASEXPONENT(temp);
-    ST0 = temp.d;
+
+    if (floatx_is_zero(ST0)) {
+        /* Easy way to generate -inf and raising division by 0 exception */
+        ST0 = floatx_div(floatx_chs(floatx_one), floatx_zero, &env->fp_status);
+        fpush();
+        ST0 = temp.d;
+    } else {
+        int expdif;
+
+        expdif = EXPD(temp) - EXPBIAS;
+        /*DP exponent bias*/
+        ST0 = int32_to_floatx(expdif, &env->fp_status);
+        fpush();
+        BIASEXPONENT(temp);
+        ST0 = temp.d;
+    }
 }
 
 void helper_fprem1(void)

From 13822781d4732f847555a2f60560c71c531c9f98 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:23 +0200
Subject: [PATCH 299/386] target-i386: fix helper_fdiv() wrt softfloat

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/exec.h      | 4 ++++
 target-i386/op_helper.c | 5 +++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/target-i386/exec.h b/target-i386/exec.h
index 211cc8c28e..b2af8945c5 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -111,6 +111,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_to_float32 floatx80_to_float32
 #define floatx_to_float64 floatx80_to_float64
 #define floatx_add floatx80_add
+#define floatx_div floatx80_div
 #define floatx_mul floatx80_mul
 #define floatx_sub floatx80_sub
 #define floatx_abs floatx80_abs
@@ -120,6 +121,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_compare floatx80_compare
 #define floatx_compare_quiet floatx80_compare_quiet
 #define floatx_is_any_nan floatx80_is_any_nan
+#define floatx_is_zero floatx80_is_zero
 #else
 #define floatx_to_int32 float64_to_int32
 #define floatx_to_int64 float64_to_int64
@@ -132,6 +134,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_to_float32 float64_to_float32
 #define floatx_to_float64(x, e) (x)
 #define floatx_add float64_add
+#define floatx_div float64_div
 #define floatx_mul float64_mul
 #define floatx_sub float64_sub
 #define floatx_abs float64_abs
@@ -141,6 +144,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_compare float64_compare
 #define floatx_compare_quiet float64_compare_quiet
 #define floatx_is_any_nan float64_is_any_nan
+#define floatx_is_zero float64_is_zero
 #endif
 
 #define RC_MASK         0xc00
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 4850c63699..bd24d8c442 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -3440,9 +3440,10 @@ static void fpu_set_exception(int mask)
 
 static inline CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b)
 {
-    if (b == 0.0)
+    if (floatx_is_zero(b)) {
         fpu_set_exception(FPUS_ZE);
-    return a / b;
+    }
+    return floatx_div(a, b, &env->fp_status);
 }
 
 static void fpu_raise_exception(void)

From fec05e429943a2486ebe4c65da7b46a90f2dcfb2 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:23 +0200
Subject: [PATCH 300/386] target-i386: fix helper_fsqrt() wrt softfloat

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/exec.h      | 4 ++++
 target-i386/op_helper.c | 7 ++-----
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/target-i386/exec.h b/target-i386/exec.h
index b2af8945c5..292e0de325 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -114,6 +114,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_div floatx80_div
 #define floatx_mul floatx80_mul
 #define floatx_sub floatx80_sub
+#define floatx_sqrt floatx80_sqrt
 #define floatx_abs floatx80_abs
 #define floatx_chs floatx80_chs
 #define floatx_scalbn floatx80_scalbn
@@ -121,6 +122,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_compare floatx80_compare
 #define floatx_compare_quiet floatx80_compare_quiet
 #define floatx_is_any_nan floatx80_is_any_nan
+#define floatx_is_neg floatx80_is_neg
 #define floatx_is_zero floatx80_is_zero
 #else
 #define floatx_to_int32 float64_to_int32
@@ -137,6 +139,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_div float64_div
 #define floatx_mul float64_mul
 #define floatx_sub float64_sub
+#define floatx_sqrt float64_sqrt
 #define floatx_abs float64_abs
 #define floatx_chs float64_chs
 #define floatx_scalbn float64_scalbn
@@ -144,6 +147,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_compare float64_compare
 #define floatx_compare_quiet float64_compare_quiet
 #define floatx_is_any_nan float64_is_any_nan
+#define floatx_is_neg float64_is_neg
 #define floatx_is_zero float64_is_zero
 #endif
 
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index bd24d8c442..589a68bc71 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4152,14 +4152,11 @@ void helper_fyl2xp1(void)
 
 void helper_fsqrt(void)
 {
-    CPU86_LDouble fptemp;
-
-    fptemp = ST0;
-    if (fptemp<0.0) {
+    if (floatx_is_neg(ST0)) {
         env->fpus &= (~0x4700);  /* (C3,C2,C1,C0) <-- 0000 */
         env->fpus |= 0x400;
     }
-    ST0 = sqrt(fptemp);
+    ST0 = floatx_sqrt(ST0, &env->fp_status);
 }
 
 void helper_fsincos(void)

From c2ef9a83be8a176802c33db7f826ff30a18b50f3 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:23 +0200
Subject: [PATCH 301/386] target-i386: replace approx_rsqrt and approx_rcp by
 softfloat ops

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/op_helper.c | 10 ----------
 target-i386/ops_sse.h   | 36 ++++++++++++++++++++++++------------
 2 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 589a68bc71..f7cdaaa222 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4794,16 +4794,6 @@ void helper_boundl(target_ulong a0, int v)
     }
 }
 
-static float approx_rsqrt(float a)
-{
-    return 1.0 / sqrt(a);
-}
-
-static float approx_rcp(float a)
-{
-    return 1.0 / a;
-}
-
 #if !defined(CONFIG_USER_ONLY)
 
 #define MMUSUFFIX _mmu
diff --git a/target-i386/ops_sse.h b/target-i386/ops_sse.h
index ac0f150070..703be99cd2 100644
--- a/target-i386/ops_sse.h
+++ b/target-i386/ops_sse.h
@@ -778,28 +778,38 @@ int64_t helper_cvttsd2sq(XMMReg *s)
 
 void helper_rsqrtps(XMMReg *d, XMMReg *s)
 {
-    d->XMM_S(0) = approx_rsqrt(s->XMM_S(0));
-    d->XMM_S(1) = approx_rsqrt(s->XMM_S(1));
-    d->XMM_S(2) = approx_rsqrt(s->XMM_S(2));
-    d->XMM_S(3) = approx_rsqrt(s->XMM_S(3));
+    d->XMM_S(0) = float32_div(float32_one,
+                              float32_sqrt(s->XMM_S(0), &env->sse_status),
+                              &env->sse_status);
+    d->XMM_S(1) = float32_div(float32_one,
+                              float32_sqrt(s->XMM_S(1), &env->sse_status),
+                              &env->sse_status);
+    d->XMM_S(2) = float32_div(float32_one,
+                              float32_sqrt(s->XMM_S(2), &env->sse_status),
+                              &env->sse_status);
+    d->XMM_S(3) = float32_div(float32_one,
+                              float32_sqrt(s->XMM_S(3), &env->sse_status),
+                              &env->sse_status);
 }
 
 void helper_rsqrtss(XMMReg *d, XMMReg *s)
 {
-    d->XMM_S(0) = approx_rsqrt(s->XMM_S(0));
+    d->XMM_S(0) = float32_div(float32_one,
+                              float32_sqrt(s->XMM_S(0), &env->sse_status),
+                              &env->sse_status);
 }
 
 void helper_rcpps(XMMReg *d, XMMReg *s)
 {
-    d->XMM_S(0) = approx_rcp(s->XMM_S(0));
-    d->XMM_S(1) = approx_rcp(s->XMM_S(1));
-    d->XMM_S(2) = approx_rcp(s->XMM_S(2));
-    d->XMM_S(3) = approx_rcp(s->XMM_S(3));
+    d->XMM_S(0) = float32_div(float32_one, s->XMM_S(0), &env->sse_status);
+    d->XMM_S(1) = float32_div(float32_one, s->XMM_S(1), &env->sse_status);
+    d->XMM_S(2) = float32_div(float32_one, s->XMM_S(2), &env->sse_status);
+    d->XMM_S(3) = float32_div(float32_one, s->XMM_S(3), &env->sse_status);
 }
 
 void helper_rcpss(XMMReg *d, XMMReg *s)
 {
-    d->XMM_S(0) = approx_rcp(s->XMM_S(0));
+    d->XMM_S(0) = float32_div(float32_one, s->XMM_S(0), &env->sse_status);
 }
 
 static inline uint64_t helper_extrq(uint64_t src, int shift, int len)
@@ -1272,14 +1282,16 @@ void helper_pfpnacc(MMXReg *d, MMXReg *s)
 
 void helper_pfrcp(MMXReg *d, MMXReg *s)
 {
-    d->MMX_S(0) = approx_rcp(s->MMX_S(0));
+    d->MMX_S(0) = float32_div(float32_one, s->MMX_S(0), &env->mmx_status);
     d->MMX_S(1) = d->MMX_S(0);
 }
 
 void helper_pfrsqrt(MMXReg *d, MMXReg *s)
 {
     d->MMX_L(1) = s->MMX_L(0) & 0x7fffffff;
-    d->MMX_S(1) = approx_rsqrt(d->MMX_S(1));
+    d->MMX_S(1) = float32_div(float32_one,
+                              float32_sqrt(d->MMX_S(1), &env->mmx_status),
+                              &env->mmx_status);
     d->MMX_L(1) |= s->MMX_L(0) & 0x80000000;
     d->MMX_L(0) = d->MMX_L(1);
 }

From 47c0143cdde080101e97a1b39f3ff13e33b5726c Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:23 +0200
Subject: [PATCH 302/386] target-i386: add CPU86_LDouble <-> double conversion
 functions

Add functions to convert CPU86_LDouble to double and vice versa. They
are going to be used to implement logarithmic and trigonometric function
until softfloat implement them.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/op_helper.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index f7cdaaa222..64c0bbf0ce 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -3431,6 +3431,28 @@ void helper_verw(target_ulong selector1)
 
 /* x87 FPU helpers */
 
+static inline double CPU86_LDouble_to_double(CPU86_LDouble a)
+{
+    union {
+        float64 f64;
+        double d;
+    } u;
+
+    u.f64 = floatx_to_float64(a, &env->fp_status);
+    return u.d;
+}
+
+static inline CPU86_LDouble double_to_CPU86_LDouble(double a)
+{
+    union {
+        float64 f64;
+        double d;
+    } u;
+
+    u.d = a;
+    return float64_to_floatx(u.f64, &env->fp_status);
+}
+
 static void fpu_set_exception(int mask)
 {
     env->fpus |= mask;

From a2c9ed3cbfde4ce521b6b9672afc4fd8cf67ab8e Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:23 +0200
Subject: [PATCH 303/386] target-i386: fix logarithmic and trigonometric
 helpers wrt softfloat

Use the new CPU86_LDouble <-> double conversion functions to make logarithmic
and trigonometric helpers working with softfloat.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/op_helper.c | 52 ++++++++++++++++++++---------------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 64c0bbf0ce..fd9d8d3117 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -17,6 +17,7 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <math.h>
 #include "exec.h"
 #include "exec-all.h"
 #include "host-utils.h"
@@ -3981,17 +3982,19 @@ void helper_fbst_ST0(target_ulong ptr)
 
 void helper_f2xm1(void)
 {
-    ST0 = pow(2.0,ST0) - 1.0;
+    double val = CPU86_LDouble_to_double(ST0);
+    val = pow(2.0, val) - 1.0;
+    ST0 = double_to_CPU86_LDouble(val);
 }
 
 void helper_fyl2x(void)
 {
-    CPU86_LDouble fptemp;
+    double fptemp = CPU86_LDouble_to_double(ST0);
 
-    fptemp = ST0;
     if (fptemp>0.0){
-        fptemp = log(fptemp)/log(2.0);	 /* log2(ST) */
-        ST1 *= fptemp;
+        fptemp = log(fptemp)/log(2.0);    /* log2(ST) */
+        fptemp *= CPU86_LDouble_to_double(ST1);
+        ST1 = double_to_CPU86_LDouble(fptemp);
         fpop();
     } else {
         env->fpus &= (~0x4700);
@@ -4001,15 +4004,15 @@ void helper_fyl2x(void)
 
 void helper_fptan(void)
 {
-    CPU86_LDouble fptemp;
+    double fptemp = CPU86_LDouble_to_double(ST0);
 
-    fptemp = ST0;
     if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
         env->fpus |= 0x400;
     } else {
-        ST0 = tan(fptemp);
+        fptemp = tan(fptemp);
+        ST0 = double_to_CPU86_LDouble(fptemp);
         fpush();
-        ST0 = 1.0;
+        ST0 = floatx_one;
         env->fpus &= (~0x400);  /* C2 <-- 0 */
         /* the above code is for  |arg| < 2**52 only */
     }
@@ -4017,11 +4020,11 @@ void helper_fptan(void)
 
 void helper_fpatan(void)
 {
-    CPU86_LDouble fptemp, fpsrcop;
+    double fptemp, fpsrcop;
 
-    fpsrcop = ST1;
-    fptemp = ST0;
-    ST1 = atan2(fpsrcop,fptemp);
+    fpsrcop = CPU86_LDouble_to_double(ST1);
+    fptemp = CPU86_LDouble_to_double(ST0);
+    ST1 = double_to_CPU86_LDouble(atan2(fpsrcop, fptemp));
     fpop();
 }
 
@@ -4159,12 +4162,12 @@ void helper_fprem(void)
 
 void helper_fyl2xp1(void)
 {
-    CPU86_LDouble fptemp;
+    double fptemp = CPU86_LDouble_to_double(ST0);
 
-    fptemp = ST0;
     if ((fptemp+1.0)>0.0) {
         fptemp = log(fptemp+1.0) / log(2.0); /* log2(ST+1.0) */
-        ST1 *= fptemp;
+        fptemp *= CPU86_LDouble_to_double(ST1);
+        ST1 = double_to_CPU86_LDouble(fptemp);
         fpop();
     } else {
         env->fpus &= (~0x4700);
@@ -4183,15 +4186,14 @@ void helper_fsqrt(void)
 
 void helper_fsincos(void)
 {
-    CPU86_LDouble fptemp;
+    double fptemp = CPU86_LDouble_to_double(ST0);
 
-    fptemp = ST0;
     if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
         env->fpus |= 0x400;
     } else {
-        ST0 = sin(fptemp);
+        ST0 = double_to_CPU86_LDouble(sin(fptemp));
         fpush();
-        ST0 = cos(fptemp);
+        ST0 = double_to_CPU86_LDouble(cos(fptemp));
         env->fpus &= (~0x400);  /* C2 <-- 0 */
         /* the above code is for  |arg| < 2**63 only */
     }
@@ -4214,13 +4216,12 @@ void helper_fscale(void)
 
 void helper_fsin(void)
 {
-    CPU86_LDouble fptemp;
+    double fptemp = CPU86_LDouble_to_double(ST0);
 
-    fptemp = ST0;
     if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
         env->fpus |= 0x400;
     } else {
-        ST0 = sin(fptemp);
+        ST0 = double_to_CPU86_LDouble(sin(fptemp));
         env->fpus &= (~0x400);  /* C2 <-- 0 */
         /* the above code is for  |arg| < 2**53 only */
     }
@@ -4228,13 +4229,12 @@ void helper_fsin(void)
 
 void helper_fcos(void)
 {
-    CPU86_LDouble fptemp;
+    double fptemp = CPU86_LDouble_to_double(ST0);
 
-    fptemp = ST0;
     if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
         env->fpus |= 0x400;
     } else {
-        ST0 = cos(fptemp);
+        ST0 = double_to_CPU86_LDouble(cos(fptemp));
         env->fpus &= (~0x400);  /* C2 <-- 0 */
         /* the above code is for  |arg5 < 2**63 only */
     }

From bcb5fec5af5d543f6ea0efa513c00503a2ada5b6 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:23 +0200
Subject: [PATCH 304/386] target-i386: fix helper_fprem() and helper_fprem1()
 wrt softfloat

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/op_helper.c | 48 ++++++++++++++++++++++++-----------------
 1 file changed, 28 insertions(+), 20 deletions(-)

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index fd9d8d3117..334f1301fd 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4053,21 +4053,24 @@ void helper_fxtract(void)
 
 void helper_fprem1(void)
 {
-    CPU86_LDouble dblq, fpsrcop, fptemp;
+    double st0, st1, dblq, fpsrcop, fptemp;
     CPU86_LDoubleU fpsrcop1, fptemp1;
     int expdif;
     signed long long int q;
 
-    if (isinf(ST0) || isnan(ST0) || isnan(ST1) || (ST1 == 0.0)) {
-        ST0 = 0.0 / 0.0; /* NaN */
+    st0 = CPU86_LDouble_to_double(ST0);
+    st1 = CPU86_LDouble_to_double(ST1);
+
+    if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) {
+        ST0 = double_to_CPU86_LDouble(0.0 / 0.0); /* NaN */
         env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
         return;
     }
 
-    fpsrcop = ST0;
-    fptemp = ST1;
-    fpsrcop1.d = fpsrcop;
-    fptemp1.d = fptemp;
+    fpsrcop = st0;
+    fptemp = st1;
+    fpsrcop1.d = ST0;
+    fptemp1.d = ST1;
     expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
 
     if (expdif < 0) {
@@ -4081,7 +4084,7 @@ void helper_fprem1(void)
         dblq = fpsrcop / fptemp;
         /* round dblq towards nearest integer */
         dblq = rint(dblq);
-        ST0 = fpsrcop - fptemp * dblq;
+        st0 = fpsrcop - fptemp * dblq;
 
         /* convert dblq to q by truncating towards zero */
         if (dblq < 0.0)
@@ -4097,31 +4100,35 @@ void helper_fprem1(void)
     } else {
         env->fpus |= 0x400;  /* C2 <-- 1 */
         fptemp = pow(2.0, expdif - 50);
-        fpsrcop = (ST0 / ST1) / fptemp;
+        fpsrcop = (st0 / st1) / fptemp;
         /* fpsrcop = integer obtained by chopping */
         fpsrcop = (fpsrcop < 0.0) ?
                   -(floor(fabs(fpsrcop))) : floor(fpsrcop);
-        ST0 -= (ST1 * fpsrcop * fptemp);
+        st0 -= (st1 * fpsrcop * fptemp);
     }
+    ST0 = double_to_CPU86_LDouble(st0);
 }
 
 void helper_fprem(void)
 {
-    CPU86_LDouble dblq, fpsrcop, fptemp;
+    double st0, st1, dblq, fpsrcop, fptemp;
     CPU86_LDoubleU fpsrcop1, fptemp1;
     int expdif;
     signed long long int q;
 
-    if (isinf(ST0) || isnan(ST0) || isnan(ST1) || (ST1 == 0.0)) {
-       ST0 = 0.0 / 0.0; /* NaN */
+    st0 = CPU86_LDouble_to_double(ST0);
+    st1 = CPU86_LDouble_to_double(ST1);
+
+    if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) {
+       ST0 = double_to_CPU86_LDouble(0.0 / 0.0); /* NaN */
        env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
        return;
     }
 
-    fpsrcop = (CPU86_LDouble)ST0;
-    fptemp = (CPU86_LDouble)ST1;
-    fpsrcop1.d = fpsrcop;
-    fptemp1.d = fptemp;
+    fpsrcop = st0;
+    fptemp = st1;
+    fpsrcop1.d = ST0;
+    fptemp1.d = ST1;
     expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
 
     if (expdif < 0) {
@@ -4135,7 +4142,7 @@ void helper_fprem(void)
         dblq = fpsrcop/*ST0*/ / fptemp/*ST1*/;
         /* round dblq towards zero */
         dblq = (dblq < 0.0) ? ceil(dblq) : floor(dblq);
-        ST0 = fpsrcop/*ST0*/ - fptemp * dblq;
+        st0 = fpsrcop/*ST0*/ - fptemp * dblq;
 
         /* convert dblq to q by truncating towards zero */
         if (dblq < 0.0)
@@ -4152,12 +4159,13 @@ void helper_fprem(void)
         int N = 32 + (expdif % 32); /* as per AMD docs */
         env->fpus |= 0x400;  /* C2 <-- 1 */
         fptemp = pow(2.0, (double)(expdif - N));
-        fpsrcop = (ST0 / ST1) / fptemp;
+        fpsrcop = (st0 / st1) / fptemp;
         /* fpsrcop = integer obtained by chopping */
         fpsrcop = (fpsrcop < 0.0) ?
                   -(floor(fabs(fpsrcop))) : floor(fpsrcop);
-        ST0 -= (ST1 * fpsrcop * fptemp);
+        st0 -= (st1 * fpsrcop * fptemp);
     }
+    ST0 = double_to_CPU86_LDouble(st0);
 }
 
 void helper_fyl2xp1(void)

From a1d8db07fb46e1da410ca7b4ce24a997707d4a53 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:23 +0200
Subject: [PATCH 305/386] target-i386: fix constants wrt softfloat

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/exec.h      |  8 ++++++++
 target-i386/op_helper.c | 24 +++++++++++++++++-------
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/target-i386/exec.h b/target-i386/exec.h
index 292e0de325..ee36a7181a 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -124,6 +124,10 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_is_any_nan floatx80_is_any_nan
 #define floatx_is_neg floatx80_is_neg
 #define floatx_is_zero floatx80_is_zero
+#define floatx_zero floatx80_zero
+#define floatx_one floatx80_one
+#define floatx_ln2 floatx80_ln2
+#define floatx_pi floatx80_pi
 #else
 #define floatx_to_int32 float64_to_int32
 #define floatx_to_int64 float64_to_int64
@@ -149,6 +153,10 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_is_any_nan float64_is_any_nan
 #define floatx_is_neg float64_is_neg
 #define floatx_is_zero float64_is_zero
+#define floatx_zero float64_zero
+#define floatx_one float64_one
+#define floatx_ln2 float64_ln2
+#define floatx_pi float64_pi
 #endif
 
 #define RC_MASK         0xc00
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 334f1301fd..3c539f37cf 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -95,15 +95,25 @@ static const uint8_t rclb_table[32] = {
     6, 7, 8, 0, 1, 2, 3, 4,
 };
 
+#if defined(CONFIG_SOFTFLOAT)
+# define floatx_lg2 make_floatx80( 0x3ffd, 0x9a209a84fbcff799LL )
+# define floatx_l2e make_floatx80( 0x3fff, 0xb8aa3b295c17f0bcLL )
+# define floatx_l2t make_floatx80( 0x4000, 0xd49a784bcd1b8afeLL )
+#else
+# define floatx_lg2 (0.30102999566398119523L)
+# define floatx_l2e (1.44269504088896340739L)
+# define floatx_l2t (3.32192809488736234781L)
+#endif
+
 static const CPU86_LDouble f15rk[7] =
 {
-    0.00000000000000000000L,
-    1.00000000000000000000L,
-    3.14159265358979323851L,  /*pi*/
-    0.30102999566398119523L,  /*lg2*/
-    0.69314718055994530943L,  /*ln2*/
-    1.44269504088896340739L,  /*l2e*/
-    3.32192809488736234781L,  /*l2t*/
+    floatx_zero,
+    floatx_one,
+    floatx_pi,
+    floatx_lg2,
+    floatx_ln2,
+    floatx_l2e,
+    floatx_l2t,
 };
 
 /* broken thread support */

From 347ac8e35661eff1c2b5ec74d11ee152f2a61856 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 20 Apr 2011 13:04:23 +0200
Subject: [PATCH 306/386] target-i386: switch to softfloat

This increase the correctness (precision, NaN values, corner cases) on
non-x86 machines, and add the possibility to handle the exception
correctly.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 configure | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/configure b/configure
index da2da04059..f2eab308b2 100755
--- a/configure
+++ b/configure
@@ -3275,14 +3275,7 @@ if test ! -z "$gdb_xml_files" ; then
   echo "TARGET_XML_FILES=$list" >> $config_target_mak
 fi
 
-case "$target_arch2" in
-  i386|x86_64)
-    echo "CONFIG_NOSOFTFLOAT=y" >> $config_target_mak
-    ;;
-  *)
-    echo "CONFIG_SOFTFLOAT=y" >> $config_target_mak
-    ;;
-esac
+echo "CONFIG_SOFTFLOAT=y" >> $config_target_mak
 
 if test "$target_user_only" = "yes" -a "$bflt" = "yes"; then
   echo "TARGET_HAS_BFLT=y" >> $config_target_mak

From 93262b1625ecb9c6ff22d5a51f38e312b5b7725a Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 18 Apr 2011 19:07:11 +0100
Subject: [PATCH 307/386] target-arm: Handle UNDEFs for Neon single element
 load/stores

Handle the UNDEF and UNPREDICTABLE cases for Neon "single element to
one lane" VLD and "single element from one lane" VST.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index e1bda57e81..80b25ac5c4 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3975,6 +3975,7 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
             stride = (1 << size) * nregs;
         } else {
             /* Single element.  */
+            int idx = (insn >> 4) & 0xf;
             pass = (insn >> 7) & 1;
             switch (size) {
             case 0:
@@ -3993,6 +3994,39 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
                 abort();
             }
             nregs = ((insn >> 8) & 3) + 1;
+            /* Catch the UNDEF cases. This is unavoidably a bit messy. */
+            switch (nregs) {
+            case 1:
+                if (((idx & (1 << size)) != 0) ||
+                    (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
+                    return 1;
+                }
+                break;
+            case 3:
+                if ((idx & 1) != 0) {
+                    return 1;
+                }
+                /* fall through */
+            case 2:
+                if (size == 2 && (idx & 2) != 0) {
+                    return 1;
+                }
+                break;
+            case 4:
+                if ((size == 2) && ((idx & 3) == 3)) {
+                    return 1;
+                }
+                break;
+            default:
+                abort();
+            }
+            if ((rd + stride * (nregs - 1)) > 31) {
+                /* Attempts to write off the end of the register file
+                 * are UNPREDICTABLE; we choose to UNDEF because otherwise
+                 * the neon_load_reg() would write off the end of the array.
+                 */
+                return 1;
+            }
             addr = tcg_temp_new_i32();
             load_reg_var(s, addr, rn);
             for (reg = 0; reg < nregs; reg++) {

From f2dd89d0c7e5d39237f43392ccaed79bda47a71e Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Mon, 18 Apr 2011 19:07:12 +0100
Subject: [PATCH 308/386] target-arm: Handle UNDEF cases for Neon VLD/VST
 multiple-structures

Correctly UNDEF for Neon VLD/VST "multiple structures" forms where the
align field is not valid.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 80b25ac5c4..8b309d48b8 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3830,6 +3830,21 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
         size = (insn >> 6) & 3;
         if (op > 10)
             return 1;
+        /* Catch UNDEF cases for bad values of align field */
+        switch (op & 0xc) {
+        case 4:
+            if (((insn >> 5) & 1) == 1) {
+                return 1;
+            }
+            break;
+        case 8:
+            if (((insn >> 4) & 3) == 3) {
+                return 1;
+            }
+            break;
+        default:
+            break;
+        }
         nregs = neon_ls_element_type[op].nregs;
         interleave = neon_ls_element_type[op].interleave;
         spacing = neon_ls_element_type[op].spacing;

From 7cb4db8f41d20d2c9d9c9a6830a362eebaeb42ed Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Wed, 20 Apr 2011 11:19:15 +0100
Subject: [PATCH 309/386] linux-user/arm/nwfpe: rename REG_PC to ARM_REG_PC

The REG_PC constant used in the ARM nwfpe code is fine in the kernel
but when used in qemu can clash with a definition in the host system
include files (in particular on Ubuntu Lucid SPARC, including signal.h
will define a REG_PC). Rename the constant to avoid this issue.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 linux-user/arm/nwfpe/fpa11.c      | 2 +-
 linux-user/arm/nwfpe/fpa11.h      | 2 +-
 linux-user/arm/nwfpe/fpa11_cpdt.c | 8 ++++----
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
index 0a87c43133..eebd93fc00 100644
--- a/linux-user/arm/nwfpe/fpa11.c
+++ b/linux-user/arm/nwfpe/fpa11.c
@@ -144,7 +144,7 @@ unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs)
 
 #if 0
   fprintf(stderr,"emulating FP insn 0x%08x, PC=0x%08x\n",
-          opcode, qregs[REG_PC]);
+          opcode, qregs[ARM_REG_PC]);
 #endif
   fpa11 = GET_FPA11();
 
diff --git a/linux-user/arm/nwfpe/fpa11.h b/linux-user/arm/nwfpe/fpa11.h
index f17647bdb9..002b3cbb82 100644
--- a/linux-user/arm/nwfpe/fpa11.h
+++ b/linux-user/arm/nwfpe/fpa11.h
@@ -111,7 +111,7 @@ static inline void writeConditionCodes(unsigned int x)
         cpsr_write(user_registers,x,CPSR_NZCV);
 }
 
-#define REG_PC 15
+#define ARM_REG_PC 15
 
 unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs);
 
diff --git a/linux-user/arm/nwfpe/fpa11_cpdt.c b/linux-user/arm/nwfpe/fpa11_cpdt.c
index b12e27dcb0..3e7a938253 100644
--- a/linux-user/arm/nwfpe/fpa11_cpdt.c
+++ b/linux-user/arm/nwfpe/fpa11_cpdt.c
@@ -220,7 +220,7 @@ static unsigned int PerformLDF(const unsigned int opcode)
    //printk("PerformLDF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
 
    pBase = readRegister(getRn(opcode));
-   if (REG_PC == getRn(opcode))
+   if (ARM_REG_PC == getRn(opcode))
    {
      pBase += 8;
      write_back = 0;
@@ -256,7 +256,7 @@ static unsigned int PerformSTF(const unsigned int opcode)
    SetRoundingMode(ROUND_TO_NEAREST);
 
    pBase = readRegister(getRn(opcode));
-   if (REG_PC == getRn(opcode))
+   if (ARM_REG_PC == getRn(opcode))
    {
      pBase += 8;
      write_back = 0;
@@ -289,7 +289,7 @@ static unsigned int PerformLFM(const unsigned int opcode)
    target_ulong pBase, pAddress, pFinal;
 
    pBase = readRegister(getRn(opcode));
-   if (REG_PC == getRn(opcode))
+   if (ARM_REG_PC == getRn(opcode))
    {
      pBase += 8;
      write_back = 0;
@@ -322,7 +322,7 @@ static unsigned int PerformSFM(const unsigned int opcode)
    target_ulong pBase, pAddress, pFinal;
 
    pBase = readRegister(getRn(opcode));
-   if (REG_PC == getRn(opcode))
+   if (ARM_REG_PC == getRn(opcode))
    {
      pBase += 8;
      write_back = 0;

From afcd9c0dcd1d6ab14a72db6abde76142c6a0ac12 Mon Sep 17 00:00:00 2001
From: Benjamin Poirier <benjamin.poirier@gmail.com>
Date: Wed, 20 Apr 2011 19:39:00 -0400
Subject: [PATCH 310/386] rtl8139: use TARGET_FMT_plx in debug messages
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Prevents a compilation failure when DEBUG_RTL8139 is defined:

CC    libhw32/rtl8139.o
cc1: warnings being treated as errors
hw/rtl8139.c: In function ‘rtl8139_cplus_transmit_one’:
hw/rtl8139.c:1960: error: format ‘%8lx’ expects type ‘long unsigned int’, but argument 5 has type ‘target_phys_addr_t’
make[1]: *** [rtl8139.o] Error 1

Signed-off-by: Benjamin Poirier <benjamin.poirier@gmail.com>
Cc: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/rtl8139.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 8790a00afb..a46416ef77 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -978,8 +978,9 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
         cplus_rx_ring_desc = rtl8139_addr64(s->RxRingAddrLO, s->RxRingAddrHI);
         cplus_rx_ring_desc += 16 * descriptor;
 
-        DEBUG_PRINT(("RTL8139: +++ C+ mode reading RX descriptor %d from host memory at %08x %08x = %016" PRIx64 "\n",
-               descriptor, s->RxRingAddrHI, s->RxRingAddrLO, (uint64_t)cplus_rx_ring_desc));
+        DEBUG_PRINT(("RTL8139: +++ C+ mode reading RX descriptor %d from "
+                "host memory at %08x %08x = " TARGET_FMT_plx "\n", descriptor,
+                s->RxRingAddrHI, s->RxRingAddrLO, cplus_rx_ring_desc));
 
         uint32_t val, rxdw0,rxdw1,rxbufLO,rxbufHI;
 
@@ -1957,8 +1958,9 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
     /* Normal priority ring */
     cplus_tx_ring_desc += 16 * descriptor;
 
-    DEBUG_PRINT(("RTL8139: +++ C+ mode reading TX descriptor %d from host memory at %08x0x%08x = 0x%8lx\n",
-           descriptor, s->TxAddr[1], s->TxAddr[0], cplus_tx_ring_desc));
+    DEBUG_PRINT(("RTL8139: +++ C+ mode reading TX descriptor %d from host "
+            "memory at %08x0x%08x = 0x" TARGET_FMT_plx "\n", descriptor,
+            s->TxAddr[1], s->TxAddr[0], cplus_tx_ring_desc));
 
     uint32_t val, txdw0,txdw1,txbufLO,txbufHI;
 
@@ -2069,8 +2071,9 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
 
     /* append more data to the packet */
 
-    DEBUG_PRINT(("RTL8139: +++ C+ mode transmit reading %d bytes from host memory at %016" PRIx64 " to offset %d\n",
-                 txsize, (uint64_t)tx_addr, s->cplus_txbuffer_offset));
+    DEBUG_PRINT(("RTL8139: +++ C+ mode transmit reading %d bytes from host "
+            "memory at " TARGET_FMT_plx " to offset %d\n", txsize, tx_addr,
+            s->cplus_txbuffer_offset));
 
     cpu_physical_memory_read(tx_addr, s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize);
     s->cplus_txbuffer_offset += txsize;

From 7cdeb319e46b8aeef866e17119093e1646e77b02 Mon Sep 17 00:00:00 2001
From: Benjamin Poirier <benjamin.poirier@gmail.com>
Date: Wed, 20 Apr 2011 19:39:01 -0400
Subject: [PATCH 311/386] rtl8139: use variadic macro for debug statements

Removes double (( )) to make DEBUG_PRINT compatible with real function calls.
Change the name to DPRINTF to be consistent with other DPRINTF macros
throughout qemu.
Include the "RTL8139: " prefix in the macro. This changes some debug output
slightly since the prefix wasn't present on all lines.

Part of the change was done using the "coccinelle" tool with the following
small semantic match:
    @@ expression E; @@

    - DEBUG_PRINT((E))
    + DPRINTF(E)

Signed-off-by: Benjamin Poirier <benjamin.poirier@gmail.com>
Cc: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/rtl8139.c | 435 +++++++++++++++++++++++++++------------------------
 1 file changed, 232 insertions(+), 203 deletions(-)

diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index a46416ef77..13b14e4e10 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -85,9 +85,10 @@
 #define VLAN_HLEN (ETHER_TYPE_LEN + VLAN_TCI_LEN)
 
 #if defined (DEBUG_RTL8139)
-#  define DEBUG_PRINT(x) do { printf x ; } while (0)
+#  define DPRINTF(fmt, ...) \
+    do { fprintf(stderr, "RTL8139: " fmt, ## __VA_ARGS__); } while (0)
 #else
-#  define DEBUG_PRINT(x)
+#  define DPRINTF(fmt, ...) do { } while (0)
 #endif
 
 /* Symbolic offsets to registers. */
@@ -510,7 +511,7 @@ static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time);
 
 static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command)
 {
-    DEBUG_PRINT(("RTL8139: eeprom command 0x%02x\n", command));
+    DPRINTF("eeprom command 0x%02x\n", command);
 
     switch (command & Chip9346_op_mask)
     {
@@ -521,8 +522,8 @@ static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command)
             eeprom->eedo = 0;
             eeprom->tick = 0;
             eeprom->mode = Chip9346_data_read;
-            DEBUG_PRINT(("RTL8139: eeprom read from address 0x%02x data=0x%04x\n",
-                   eeprom->address, eeprom->output));
+            DPRINTF("eeprom read from address 0x%02x data=0x%04x\n",
+                eeprom->address, eeprom->output);
         }
         break;
 
@@ -532,8 +533,8 @@ static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command)
             eeprom->input = 0;
             eeprom->tick = 0;
             eeprom->mode = Chip9346_none; /* Chip9346_data_write */
-            DEBUG_PRINT(("RTL8139: eeprom begin write to address 0x%02x\n",
-                   eeprom->address));
+            DPRINTF("eeprom begin write to address 0x%02x\n",
+                eeprom->address);
         }
         break;
         default:
@@ -541,13 +542,13 @@ static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command)
             switch (command & Chip9346_op_ext_mask)
             {
                 case Chip9346_op_write_enable:
-                    DEBUG_PRINT(("RTL8139: eeprom write enabled\n"));
+                    DPRINTF("eeprom write enabled\n");
                     break;
                 case Chip9346_op_write_all:
-                    DEBUG_PRINT(("RTL8139: eeprom begin write all\n"));
+                    DPRINTF("eeprom begin write all\n");
                     break;
                 case Chip9346_op_write_disable:
-                    DEBUG_PRINT(("RTL8139: eeprom write disabled\n"));
+                    DPRINTF("eeprom write disabled\n");
                     break;
             }
             break;
@@ -560,7 +561,8 @@ static void prom9346_shift_clock(EEprom9346 *eeprom)
 
     ++ eeprom->tick;
 
-    DEBUG_PRINT(("eeprom: tick %d eedi=%d eedo=%d\n", eeprom->tick, eeprom->eedi, eeprom->eedo));
+    DPRINTF("eeprom: tick %d eedi=%d eedo=%d\n", eeprom->tick, eeprom->eedi,
+        eeprom->eedo);
 
     switch (eeprom->mode)
     {
@@ -570,7 +572,7 @@ static void prom9346_shift_clock(EEprom9346 *eeprom)
                 eeprom->mode = Chip9346_read_command;
                 eeprom->tick = 0;
                 eeprom->input = 0;
-                DEBUG_PRINT(("eeprom: +++ synchronized, begin command read\n"));
+                DPRINTF("eeprom: +++ synchronized, begin command read\n");
             }
             break;
 
@@ -595,7 +597,7 @@ static void prom9346_shift_clock(EEprom9346 *eeprom)
                 eeprom->input = 0;
                 eeprom->tick = 0;
 
-                DEBUG_PRINT(("eeprom: +++ end of read, awaiting next command\n"));
+                DPRINTF("eeprom: +++ end of read, awaiting next command\n");
 #else
         // original behaviour
                 ++eeprom->address;
@@ -603,8 +605,8 @@ static void prom9346_shift_clock(EEprom9346 *eeprom)
                 eeprom->output = eeprom->contents[eeprom->address];
                 eeprom->tick = 0;
 
-                DEBUG_PRINT(("eeprom: +++ read next address 0x%02x data=0x%04x\n",
-                       eeprom->address, eeprom->output));
+                DPRINTF("eeprom: +++ read next address 0x%02x data=0x%04x\n",
+                    eeprom->address, eeprom->output);
 #endif
             }
             break;
@@ -613,8 +615,8 @@ static void prom9346_shift_clock(EEprom9346 *eeprom)
             eeprom->input = (eeprom->input << 1) | (bit & 1);
             if (eeprom->tick == 16)
             {
-                DEBUG_PRINT(("RTL8139: eeprom write to address 0x%02x data=0x%04x\n",
-                       eeprom->address, eeprom->input));
+                DPRINTF("eeprom write to address 0x%02x data=0x%04x\n",
+                    eeprom->address, eeprom->input);
 
                 eeprom->contents[eeprom->address] = eeprom->input;
                 eeprom->mode = Chip9346_none; /* waiting for next command after CS cycle */
@@ -632,8 +634,7 @@ static void prom9346_shift_clock(EEprom9346 *eeprom)
                 {
                     eeprom->contents[i] = eeprom->input;
                 }
-                DEBUG_PRINT(("RTL8139: eeprom filled with data=0x%04x\n",
-                       eeprom->input));
+                DPRINTF("eeprom filled with data=0x%04x\n", eeprom->input);
 
                 eeprom->mode = Chip9346_enter_command_mode;
                 eeprom->tick = 0;
@@ -666,8 +667,8 @@ static void prom9346_set_wire(RTL8139State *s, int eecs, int eesk, int eedi)
     eeprom->eesk = eesk;
     eeprom->eedi = eedi;
 
-    DEBUG_PRINT(("eeprom: +++ wires CS=%d SK=%d DI=%d DO=%d\n",
-                 eeprom->eecs, eeprom->eesk, eeprom->eedi, eeprom->eedo));
+    DPRINTF("eeprom: +++ wires CS=%d SK=%d DI=%d DO=%d\n", eeprom->eecs,
+        eeprom->eesk, eeprom->eedi, eeprom->eedo);
 
     if (!old_eecs && eecs)
     {
@@ -677,12 +678,12 @@ static void prom9346_set_wire(RTL8139State *s, int eecs, int eesk, int eedi)
         eeprom->output = 0;
         eeprom->mode = Chip9346_enter_command_mode;
 
-        DEBUG_PRINT(("=== eeprom: begin access, enter command mode\n"));
+        DPRINTF("=== eeprom: begin access, enter command mode\n");
     }
 
     if (!eecs)
     {
-        DEBUG_PRINT(("=== eeprom: end access\n"));
+        DPRINTF("=== eeprom: end access\n");
         return;
     }
 
@@ -698,8 +699,8 @@ static void rtl8139_update_irq(RTL8139State *s)
     int isr;
     isr = (s->IntrStatus & s->IntrMask) & 0xffff;
 
-    DEBUG_PRINT(("RTL8139: Set IRQ to %d (%04x %04x)\n",
-       isr ? 1 : 0, s->IntrStatus, s->IntrMask));
+    DPRINTF("Set IRQ to %d (%04x %04x)\n", isr ? 1 : 0, s->IntrStatus,
+        s->IntrMask);
 
     qemu_set_irq(s->dev.irq[0], (isr != 0));
 }
@@ -763,7 +764,7 @@ static void rtl8139_write_buffer(RTL8139State *s, const void *buf, int size)
         /* write packet data */
         if (wrapped && !(s->RxBufferSize < 65536 && rtl8139_RxWrap(s)))
         {
-            DEBUG_PRINT((">>> RTL8139: rx packet wrapped in buffer at %d\n", size-wrapped));
+            DPRINTF(">>> rx packet wrapped in buffer at %d\n", size - wrapped);
 
             if (size > wrapped)
             {
@@ -834,12 +835,12 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
     static const uint8_t broadcast_macaddr[6] =
         { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
-    DEBUG_PRINT((">>> RTL8139: received len=%d\n", size));
+    DPRINTF(">>> received len=%d\n", size);
 
     /* test if board clock is stopped */
     if (!s->clock_enabled)
     {
-        DEBUG_PRINT(("RTL8139: stopped ==========================\n"));
+        DPRINTF("stopped ==========================\n");
         return -1;
     }
 
@@ -847,21 +848,21 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
 
     if (!rtl8139_receiver_enabled(s))
     {
-        DEBUG_PRINT(("RTL8139: receiver disabled ================\n"));
+        DPRINTF("receiver disabled ================\n");
         return -1;
     }
 
     /* XXX: check this */
     if (s->RxConfig & AcceptAllPhys) {
         /* promiscuous: receive all */
-        DEBUG_PRINT((">>> RTL8139: packet received in promiscuous mode\n"));
+        DPRINTF(">>> packet received in promiscuous mode\n");
 
     } else {
         if (!memcmp(buf,  broadcast_macaddr, 6)) {
             /* broadcast address */
             if (!(s->RxConfig & AcceptBroadcast))
             {
-                DEBUG_PRINT((">>> RTL8139: broadcast packet rejected\n"));
+                DPRINTF(">>> broadcast packet rejected\n");
 
                 /* update tally counter */
                 ++s->tally_counters.RxERR;
@@ -871,7 +872,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
 
             packet_header |= RxBroadcast;
 
-            DEBUG_PRINT((">>> RTL8139: broadcast packet received\n"));
+            DPRINTF(">>> broadcast packet received\n");
 
             /* update tally counter */
             ++s->tally_counters.RxOkBrd;
@@ -880,7 +881,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
             /* multicast */
             if (!(s->RxConfig & AcceptMulticast))
             {
-                DEBUG_PRINT((">>> RTL8139: multicast packet rejected\n"));
+                DPRINTF(">>> multicast packet rejected\n");
 
                 /* update tally counter */
                 ++s->tally_counters.RxERR;
@@ -892,7 +893,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
 
             if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))
             {
-                DEBUG_PRINT((">>> RTL8139: multicast address mismatch\n"));
+                DPRINTF(">>> multicast address mismatch\n");
 
                 /* update tally counter */
                 ++s->tally_counters.RxERR;
@@ -902,7 +903,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
 
             packet_header |= RxMulticast;
 
-            DEBUG_PRINT((">>> RTL8139: multicast packet received\n"));
+            DPRINTF(">>> multicast packet received\n");
 
             /* update tally counter */
             ++s->tally_counters.RxOkMul;
@@ -916,7 +917,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
             /* match */
             if (!(s->RxConfig & AcceptMyPhys))
             {
-                DEBUG_PRINT((">>> RTL8139: rejecting physical address matching packet\n"));
+                DPRINTF(">>> rejecting physical address matching packet\n");
 
                 /* update tally counter */
                 ++s->tally_counters.RxERR;
@@ -926,14 +927,14 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
 
             packet_header |= RxPhysical;
 
-            DEBUG_PRINT((">>> RTL8139: physical address matching packet received\n"));
+            DPRINTF(">>> physical address matching packet received\n");
 
             /* update tally counter */
             ++s->tally_counters.RxOkPhy;
 
         } else {
 
-            DEBUG_PRINT((">>> RTL8139: unknown packet\n"));
+            DPRINTF(">>> unknown packet\n");
 
             /* update tally counter */
             ++s->tally_counters.RxERR;
@@ -955,7 +956,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
 
     if (rtl8139_cp_receiver_enabled(s))
     {
-        DEBUG_PRINT(("RTL8139: in C+ Rx mode ================\n"));
+        DPRINTF("in C+ Rx mode ================\n");
 
         /* begin C+ receiver mode */
 
@@ -978,9 +979,9 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
         cplus_rx_ring_desc = rtl8139_addr64(s->RxRingAddrLO, s->RxRingAddrHI);
         cplus_rx_ring_desc += 16 * descriptor;
 
-        DEBUG_PRINT(("RTL8139: +++ C+ mode reading RX descriptor %d from "
-                "host memory at %08x %08x = " TARGET_FMT_plx "\n", descriptor,
-                s->RxRingAddrHI, s->RxRingAddrLO, cplus_rx_ring_desc));
+        DPRINTF("+++ C+ mode reading RX descriptor %d from host memory at "
+            "%08x %08x = "TARGET_FMT_plx"\n", descriptor, s->RxRingAddrHI,
+            s->RxRingAddrLO, cplus_rx_ring_desc);
 
         uint32_t val, rxdw0,rxdw1,rxbufLO,rxbufHI;
 
@@ -993,13 +994,13 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
         cpu_physical_memory_read(cplus_rx_ring_desc+12, (uint8_t *)&val, 4);
         rxbufHI = le32_to_cpu(val);
 
-        DEBUG_PRINT(("RTL8139: +++ C+ mode RX descriptor %d %08x %08x %08x %08x\n",
-               descriptor,
-               rxdw0, rxdw1, rxbufLO, rxbufHI));
+        DPRINTF("+++ C+ mode RX descriptor %d %08x %08x %08x %08x\n",
+            descriptor, rxdw0, rxdw1, rxbufLO, rxbufHI);
 
         if (!(rxdw0 & CP_RX_OWN))
         {
-            DEBUG_PRINT(("RTL8139: C+ Rx mode : descriptor %d is owned by host\n", descriptor));
+            DPRINTF("C+ Rx mode : descriptor %d is owned by host\n",
+                descriptor);
 
             s->IntrStatus |= RxOverflow;
             ++s->RxMissed;
@@ -1029,9 +1030,8 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
             rxdw1 |= CP_RX_TAVA | le16_to_cpup((uint16_t *)
                 &dot1q_buf[ETHER_TYPE_LEN]);
 
-            DEBUG_PRINT(("RTL8139: C+ Rx mode : extracted vlan tag with tci: "
-                    "%u\n", be16_to_cpup((uint16_t *)
-                        &dot1q_buf[ETHER_TYPE_LEN])));
+            DPRINTF("C+ Rx mode : extracted vlan tag with tci: ""%u\n",
+                be16_to_cpup((uint16_t *)&dot1q_buf[ETHER_TYPE_LEN]));
         } else {
             /* reset VLAN tag flag */
             rxdw1 &= ~CP_RX_TAVA;
@@ -1041,8 +1041,8 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
 
         if (size+4 > rx_space)
         {
-            DEBUG_PRINT(("RTL8139: C+ Rx mode : descriptor %d size %d received %d + 4\n",
-                   descriptor, rx_space, size));
+            DPRINTF("C+ Rx mode : descriptor %d size %d received %d + 4\n",
+                descriptor, rx_space, size);
 
             s->IntrStatus |= RxOverflow;
             ++s->RxMissed;
@@ -1137,12 +1137,12 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
             ++s->currCPlusRxDesc;
         }
 
-        DEBUG_PRINT(("RTL8139: done C+ Rx mode ----------------\n"));
+        DPRINTF("done C+ Rx mode ----------------\n");
 
     }
     else
     {
-        DEBUG_PRINT(("RTL8139: in ring Rx mode ================\n"));
+        DPRINTF("in ring Rx mode ================\n");
 
         /* begin ring receiver mode */
         int avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr, s->RxBufferSize);
@@ -1151,8 +1151,9 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
 
         if (avail != 0 && size + 8 >= avail)
         {
-            DEBUG_PRINT(("rx overflow: rx buffer length %d head 0x%04x read 0x%04x === available 0x%04x need 0x%04x\n",
-                   s->RxBufferSize, s->RxBufAddr, s->RxBufPtr, avail, size + 8));
+            DPRINTF("rx overflow: rx buffer length %d head 0x%04x "
+                "read 0x%04x === available 0x%04x need 0x%04x\n",
+                s->RxBufferSize, s->RxBufAddr, s->RxBufPtr, avail, size + 8);
 
             s->IntrStatus |= RxOverflow;
             ++s->RxMissed;
@@ -1180,8 +1181,8 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
 
         /* now we can signal we have received something */
 
-        DEBUG_PRINT(("   received: rx buffer length %d head 0x%04x read 0x%04x\n",
-               s->RxBufferSize, s->RxBufAddr, s->RxBufPtr));
+        DPRINTF("received: rx buffer length %d head 0x%04x read 0x%04x\n",
+            s->RxBufferSize, s->RxBufAddr, s->RxBufPtr);
     }
 
     s->IntrStatus |= RxOK;
@@ -1375,22 +1376,22 @@ static void rtl8139_ChipCmd_write(RTL8139State *s, uint32_t val)
 {
     val &= 0xff;
 
-    DEBUG_PRINT(("RTL8139: ChipCmd write val=0x%08x\n", val));
+    DPRINTF("ChipCmd write val=0x%08x\n", val);
 
     if (val & CmdReset)
     {
-        DEBUG_PRINT(("RTL8139: ChipCmd reset\n"));
+        DPRINTF("ChipCmd reset\n");
         rtl8139_reset(&s->dev.qdev);
     }
     if (val & CmdRxEnb)
     {
-        DEBUG_PRINT(("RTL8139: ChipCmd enable receiver\n"));
+        DPRINTF("ChipCmd enable receiver\n");
 
         s->currCPlusRxDesc = 0;
     }
     if (val & CmdTxEnb)
     {
-        DEBUG_PRINT(("RTL8139: ChipCmd enable transmitter\n"));
+        DPRINTF("ChipCmd enable transmitter\n");
 
         s->currCPlusTxDesc = 0;
     }
@@ -1410,11 +1411,11 @@ static int rtl8139_RxBufferEmpty(RTL8139State *s)
 
     if (unread != 0)
     {
-        DEBUG_PRINT(("RTL8139: receiver buffer data available 0x%04x\n", unread));
+        DPRINTF("receiver buffer data available 0x%04x\n", unread);
         return 0;
     }
 
-    DEBUG_PRINT(("RTL8139: receiver buffer is empty\n"));
+    DPRINTF("receiver buffer is empty\n");
 
     return 1;
 }
@@ -1426,7 +1427,7 @@ static uint32_t rtl8139_ChipCmd_read(RTL8139State *s)
     if (rtl8139_RxBufferEmpty(s))
         ret |= RxBufEmpty;
 
-    DEBUG_PRINT(("RTL8139: ChipCmd read val=0x%04x\n", ret));
+    DPRINTF("ChipCmd read val=0x%04x\n", ret);
 
     return ret;
 }
@@ -1435,7 +1436,7 @@ static void rtl8139_CpCmd_write(RTL8139State *s, uint32_t val)
 {
     val &= 0xffff;
 
-    DEBUG_PRINT(("RTL8139C+ command register write(w) val=0x%04x\n", val));
+    DPRINTF("C+ command register write(w) val=0x%04x\n", val);
 
     s->cplus_enabled = 1;
 
@@ -1449,21 +1450,21 @@ static uint32_t rtl8139_CpCmd_read(RTL8139State *s)
 {
     uint32_t ret = s->CpCmd;
 
-    DEBUG_PRINT(("RTL8139C+ command register read(w) val=0x%04x\n", ret));
+    DPRINTF("C+ command register read(w) val=0x%04x\n", ret);
 
     return ret;
 }
 
 static void rtl8139_IntrMitigate_write(RTL8139State *s, uint32_t val)
 {
-    DEBUG_PRINT(("RTL8139C+ IntrMitigate register write(w) val=0x%04x\n", val));
+    DPRINTF("C+ IntrMitigate register write(w) val=0x%04x\n", val);
 }
 
 static uint32_t rtl8139_IntrMitigate_read(RTL8139State *s)
 {
     uint32_t ret = 0;
 
-    DEBUG_PRINT(("RTL8139C+ IntrMitigate register read(w) val=0x%04x\n", ret));
+    DPRINTF("C+ IntrMitigate register read(w) val=0x%04x\n", ret);
 
     return ret;
 }
@@ -1475,7 +1476,7 @@ static int rtl8139_config_writeable(RTL8139State *s)
         return 1;
     }
 
-    DEBUG_PRINT(("RTL8139: Configuration registers are write-protected\n"));
+    DPRINTF("Configuration registers are write-protected\n");
 
     return 0;
 }
@@ -1484,7 +1485,7 @@ static void rtl8139_BasicModeCtrl_write(RTL8139State *s, uint32_t val)
 {
     val &= 0xffff;
 
-    DEBUG_PRINT(("RTL8139: BasicModeCtrl register write(w) val=0x%04x\n", val));
+    DPRINTF("BasicModeCtrl register write(w) val=0x%04x\n", val);
 
     /* mask unwriteable bits */
     uint32_t mask = 0x4cff;
@@ -1506,7 +1507,7 @@ static uint32_t rtl8139_BasicModeCtrl_read(RTL8139State *s)
 {
     uint32_t ret = s->BasicModeCtrl;
 
-    DEBUG_PRINT(("RTL8139: BasicModeCtrl register read(w) val=0x%04x\n", ret));
+    DPRINTF("BasicModeCtrl register read(w) val=0x%04x\n", ret);
 
     return ret;
 }
@@ -1515,7 +1516,7 @@ static void rtl8139_BasicModeStatus_write(RTL8139State *s, uint32_t val)
 {
     val &= 0xffff;
 
-    DEBUG_PRINT(("RTL8139: BasicModeStatus register write(w) val=0x%04x\n", val));
+    DPRINTF("BasicModeStatus register write(w) val=0x%04x\n", val);
 
     /* mask unwriteable bits */
     val = SET_MASKED(val, 0xff3f, s->BasicModeStatus);
@@ -1527,7 +1528,7 @@ static uint32_t rtl8139_BasicModeStatus_read(RTL8139State *s)
 {
     uint32_t ret = s->BasicModeStatus;
 
-    DEBUG_PRINT(("RTL8139: BasicModeStatus register read(w) val=0x%04x\n", ret));
+    DPRINTF("BasicModeStatus register read(w) val=0x%04x\n", ret);
 
     return ret;
 }
@@ -1536,7 +1537,7 @@ static void rtl8139_Cfg9346_write(RTL8139State *s, uint32_t val)
 {
     val &= 0xff;
 
-    DEBUG_PRINT(("RTL8139: Cfg9346 write val=0x%02x\n", val));
+    DPRINTF("Cfg9346 write val=0x%02x\n", val);
 
     /* mask unwriteable bits */
     val = SET_MASKED(val, 0x31, s->Cfg9346);
@@ -1579,7 +1580,7 @@ static uint32_t rtl8139_Cfg9346_read(RTL8139State *s)
         }
     }
 
-    DEBUG_PRINT(("RTL8139: Cfg9346 read val=0x%02x\n", ret));
+    DPRINTF("Cfg9346 read val=0x%02x\n", ret);
 
     return ret;
 }
@@ -1588,7 +1589,7 @@ static void rtl8139_Config0_write(RTL8139State *s, uint32_t val)
 {
     val &= 0xff;
 
-    DEBUG_PRINT(("RTL8139: Config0 write val=0x%02x\n", val));
+    DPRINTF("Config0 write val=0x%02x\n", val);
 
     if (!rtl8139_config_writeable(s))
         return;
@@ -1603,7 +1604,7 @@ static uint32_t rtl8139_Config0_read(RTL8139State *s)
 {
     uint32_t ret = s->Config0;
 
-    DEBUG_PRINT(("RTL8139: Config0 read val=0x%02x\n", ret));
+    DPRINTF("Config0 read val=0x%02x\n", ret);
 
     return ret;
 }
@@ -1612,7 +1613,7 @@ static void rtl8139_Config1_write(RTL8139State *s, uint32_t val)
 {
     val &= 0xff;
 
-    DEBUG_PRINT(("RTL8139: Config1 write val=0x%02x\n", val));
+    DPRINTF("Config1 write val=0x%02x\n", val);
 
     if (!rtl8139_config_writeable(s))
         return;
@@ -1627,7 +1628,7 @@ static uint32_t rtl8139_Config1_read(RTL8139State *s)
 {
     uint32_t ret = s->Config1;
 
-    DEBUG_PRINT(("RTL8139: Config1 read val=0x%02x\n", ret));
+    DPRINTF("Config1 read val=0x%02x\n", ret);
 
     return ret;
 }
@@ -1636,7 +1637,7 @@ static void rtl8139_Config3_write(RTL8139State *s, uint32_t val)
 {
     val &= 0xff;
 
-    DEBUG_PRINT(("RTL8139: Config3 write val=0x%02x\n", val));
+    DPRINTF("Config3 write val=0x%02x\n", val);
 
     if (!rtl8139_config_writeable(s))
         return;
@@ -1651,7 +1652,7 @@ static uint32_t rtl8139_Config3_read(RTL8139State *s)
 {
     uint32_t ret = s->Config3;
 
-    DEBUG_PRINT(("RTL8139: Config3 read val=0x%02x\n", ret));
+    DPRINTF("Config3 read val=0x%02x\n", ret);
 
     return ret;
 }
@@ -1660,7 +1661,7 @@ static void rtl8139_Config4_write(RTL8139State *s, uint32_t val)
 {
     val &= 0xff;
 
-    DEBUG_PRINT(("RTL8139: Config4 write val=0x%02x\n", val));
+    DPRINTF("Config4 write val=0x%02x\n", val);
 
     if (!rtl8139_config_writeable(s))
         return;
@@ -1675,7 +1676,7 @@ static uint32_t rtl8139_Config4_read(RTL8139State *s)
 {
     uint32_t ret = s->Config4;
 
-    DEBUG_PRINT(("RTL8139: Config4 read val=0x%02x\n", ret));
+    DPRINTF("Config4 read val=0x%02x\n", ret);
 
     return ret;
 }
@@ -1684,7 +1685,7 @@ static void rtl8139_Config5_write(RTL8139State *s, uint32_t val)
 {
     val &= 0xff;
 
-    DEBUG_PRINT(("RTL8139: Config5 write val=0x%02x\n", val));
+    DPRINTF("Config5 write val=0x%02x\n", val);
 
     /* mask unwriteable bits */
     val = SET_MASKED(val, 0x80, s->Config5);
@@ -1696,7 +1697,7 @@ static uint32_t rtl8139_Config5_read(RTL8139State *s)
 {
     uint32_t ret = s->Config5;
 
-    DEBUG_PRINT(("RTL8139: Config5 read val=0x%02x\n", ret));
+    DPRINTF("Config5 read val=0x%02x\n", ret);
 
     return ret;
 }
@@ -1705,11 +1706,11 @@ static void rtl8139_TxConfig_write(RTL8139State *s, uint32_t val)
 {
     if (!rtl8139_transmitter_enabled(s))
     {
-        DEBUG_PRINT(("RTL8139: transmitter disabled; no TxConfig write val=0x%08x\n", val));
+        DPRINTF("transmitter disabled; no TxConfig write val=0x%08x\n", val);
         return;
     }
 
-    DEBUG_PRINT(("RTL8139: TxConfig write val=0x%08x\n", val));
+    DPRINTF("TxConfig write val=0x%08x\n", val);
 
     val = SET_MASKED(val, TxVersionMask | 0x8070f80f, s->TxConfig);
 
@@ -1718,7 +1719,7 @@ static void rtl8139_TxConfig_write(RTL8139State *s, uint32_t val)
 
 static void rtl8139_TxConfig_writeb(RTL8139State *s, uint32_t val)
 {
-    DEBUG_PRINT(("RTL8139C TxConfig via write(b) val=0x%02x\n", val));
+    DPRINTF("RTL8139C TxConfig via write(b) val=0x%02x\n", val);
 
     uint32_t tc = s->TxConfig;
     tc &= 0xFFFFFF00;
@@ -1730,14 +1731,14 @@ static uint32_t rtl8139_TxConfig_read(RTL8139State *s)
 {
     uint32_t ret = s->TxConfig;
 
-    DEBUG_PRINT(("RTL8139: TxConfig read val=0x%04x\n", ret));
+    DPRINTF("TxConfig read val=0x%04x\n", ret);
 
     return ret;
 }
 
 static void rtl8139_RxConfig_write(RTL8139State *s, uint32_t val)
 {
-    DEBUG_PRINT(("RTL8139: RxConfig write val=0x%08x\n", val));
+    DPRINTF("RxConfig write val=0x%08x\n", val);
 
     /* mask unwriteable bits */
     val = SET_MASKED(val, 0xf0fc0040, s->RxConfig);
@@ -1747,14 +1748,14 @@ static void rtl8139_RxConfig_write(RTL8139State *s, uint32_t val)
     /* reset buffer size and read/write pointers */
     rtl8139_reset_rxring(s, 8192 << ((s->RxConfig >> 11) & 0x3));
 
-    DEBUG_PRINT(("RTL8139: RxConfig write reset buffer size to %d\n", s->RxBufferSize));
+    DPRINTF("RxConfig write reset buffer size to %d\n", s->RxBufferSize);
 }
 
 static uint32_t rtl8139_RxConfig_read(RTL8139State *s)
 {
     uint32_t ret = s->RxConfig;
 
-    DEBUG_PRINT(("RTL8139: RxConfig read val=0x%08x\n", ret));
+    DPRINTF("RxConfig read val=0x%08x\n", ret);
 
     return ret;
 }
@@ -1766,7 +1767,7 @@ static void rtl8139_transfer_frame(RTL8139State *s, uint8_t *buf, int size,
 
     if (!size)
     {
-        DEBUG_PRINT(("RTL8139: +++ empty ethernet frame\n"));
+        DPRINTF("+++ empty ethernet frame\n");
         return;
     }
 
@@ -1791,7 +1792,7 @@ static void rtl8139_transfer_frame(RTL8139State *s, uint8_t *buf, int size,
             buf = buf2;
         }
 
-        DEBUG_PRINT(("RTL8139: +++ transmit loopback mode\n"));
+        DPRINTF("+++ transmit loopback mode\n");
         rtl8139_do_receive(&s->nic->nc, buf, size, do_interrupt);
 
         if (iov) {
@@ -1812,25 +1813,25 @@ static int rtl8139_transmit_one(RTL8139State *s, int descriptor)
 {
     if (!rtl8139_transmitter_enabled(s))
     {
-        DEBUG_PRINT(("RTL8139: +++ cannot transmit from descriptor %d: transmitter disabled\n",
-                     descriptor));
+        DPRINTF("+++ cannot transmit from descriptor %d: transmitter "
+            "disabled\n", descriptor);
         return 0;
     }
 
     if (s->TxStatus[descriptor] & TxHostOwns)
     {
-        DEBUG_PRINT(("RTL8139: +++ cannot transmit from descriptor %d: owned by host (%08x)\n",
-                     descriptor, s->TxStatus[descriptor]));
+        DPRINTF("+++ cannot transmit from descriptor %d: owned by host "
+            "(%08x)\n", descriptor, s->TxStatus[descriptor]);
         return 0;
     }
 
-    DEBUG_PRINT(("RTL8139: +++ transmitting from descriptor %d\n", descriptor));
+    DPRINTF("+++ transmitting from descriptor %d\n", descriptor);
 
     int txsize = s->TxStatus[descriptor] & 0x1fff;
     uint8_t txbuffer[0x2000];
 
-    DEBUG_PRINT(("RTL8139: +++ transmit reading %d bytes from host memory at 0x%08x\n",
-                 txsize, s->TxAddr[descriptor]));
+    DPRINTF("+++ transmit reading %d bytes from host memory at 0x%08x\n",
+        txsize, s->TxAddr[descriptor]);
 
     cpu_physical_memory_read(s->TxAddr[descriptor], txbuffer, txsize);
 
@@ -1840,7 +1841,8 @@ static int rtl8139_transmit_one(RTL8139State *s, int descriptor)
 
     rtl8139_transfer_frame(s, txbuffer, txsize, 0, NULL);
 
-    DEBUG_PRINT(("RTL8139: +++ transmitted %d bytes from descriptor %d\n", txsize, descriptor));
+    DPRINTF("+++ transmitted %d bytes from descriptor %d\n", txsize,
+        descriptor);
 
     /* update interrupt */
     s->IntrStatus |= TxOK;
@@ -1940,13 +1942,13 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
 {
     if (!rtl8139_transmitter_enabled(s))
     {
-        DEBUG_PRINT(("RTL8139: +++ C+ mode: transmitter disabled\n"));
+        DPRINTF("+++ C+ mode: transmitter disabled\n");
         return 0;
     }
 
     if (!rtl8139_cp_transmitter_enabled(s))
     {
-        DEBUG_PRINT(("RTL8139: +++ C+ mode: C+ transmitter disabled\n"));
+        DPRINTF("+++ C+ mode: C+ transmitter disabled\n");
         return 0 ;
     }
 
@@ -1958,9 +1960,9 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
     /* Normal priority ring */
     cplus_tx_ring_desc += 16 * descriptor;
 
-    DEBUG_PRINT(("RTL8139: +++ C+ mode reading TX descriptor %d from host "
-            "memory at %08x0x%08x = 0x" TARGET_FMT_plx "\n", descriptor,
-            s->TxAddr[1], s->TxAddr[0], cplus_tx_ring_desc));
+    DPRINTF("+++ C+ mode reading TX descriptor %d from host memory at "
+        "%08x0x%08x = 0x"TARGET_FMT_plx"\n", descriptor, s->TxAddr[1],
+        s->TxAddr[0], cplus_tx_ring_desc);
 
     uint32_t val, txdw0,txdw1,txbufLO,txbufHI;
 
@@ -1973,9 +1975,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
     cpu_physical_memory_read(cplus_tx_ring_desc+12, (uint8_t *)&val, 4);
     txbufHI = le32_to_cpu(val);
 
-    DEBUG_PRINT(("RTL8139: +++ C+ mode TX descriptor %d %08x %08x %08x %08x\n",
-           descriptor,
-           txdw0, txdw1, txbufLO, txbufHI));
+    DPRINTF("+++ C+ mode TX descriptor %d %08x %08x %08x %08x\n", descriptor,
+        txdw0, txdw1, txbufLO, txbufHI);
 
 /* w0 ownership flag */
 #define CP_TX_OWN (1<<31)
@@ -2021,15 +2022,16 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
 
     if (!(txdw0 & CP_TX_OWN))
     {
-        DEBUG_PRINT(("RTL8139: C+ Tx mode : descriptor %d is owned by host\n", descriptor));
+        DPRINTF("C+ Tx mode : descriptor %d is owned by host\n", descriptor);
         return 0 ;
     }
 
-    DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : transmitting from descriptor %d\n", descriptor));
+    DPRINTF("+++ C+ Tx mode : transmitting from descriptor %d\n", descriptor);
 
     if (txdw0 & CP_TX_FS)
     {
-        DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : descriptor %d is first segment descriptor\n", descriptor));
+        DPRINTF("+++ C+ Tx mode : descriptor %d is first segment "
+            "descriptor\n", descriptor);
 
         /* reset internal buffer offset */
         s->cplus_txbuffer_offset = 0;
@@ -2045,7 +2047,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
         s->cplus_txbuffer = qemu_malloc(s->cplus_txbuffer_len);
         s->cplus_txbuffer_offset = 0;
 
-        DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer allocated space %d\n", s->cplus_txbuffer_len));
+        DPRINTF("+++ C+ mode transmission buffer allocated space %d\n",
+            s->cplus_txbuffer_len);
     }
 
     while (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= s->cplus_txbuffer_len)
@@ -2053,14 +2056,16 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
         s->cplus_txbuffer_len += CP_TX_BUFFER_SIZE;
         s->cplus_txbuffer = qemu_realloc(s->cplus_txbuffer, s->cplus_txbuffer_len);
 
-        DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer space changed to %d\n", s->cplus_txbuffer_len));
+        DPRINTF("+++ C+ mode transmission buffer space changed to %d\n",
+            s->cplus_txbuffer_len);
     }
 
     if (!s->cplus_txbuffer)
     {
         /* out of memory */
 
-        DEBUG_PRINT(("RTL8139: +++ C+ mode transmiter failed to reallocate %d bytes\n", s->cplus_txbuffer_len));
+        DPRINTF("+++ C+ mode transmiter failed to reallocate %d bytes\n",
+            s->cplus_txbuffer_len);
 
         /* update tally counter */
         ++s->tally_counters.TxERR;
@@ -2071,9 +2076,9 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
 
     /* append more data to the packet */
 
-    DEBUG_PRINT(("RTL8139: +++ C+ mode transmit reading %d bytes from host "
-            "memory at " TARGET_FMT_plx " to offset %d\n", txsize, tx_addr,
-            s->cplus_txbuffer_offset));
+    DPRINTF("+++ C+ mode transmit reading %d bytes from host memory at "
+        TARGET_FMT_plx" to offset %d\n", txsize, tx_addr,
+        s->cplus_txbuffer_offset);
 
     cpu_physical_memory_read(tx_addr, s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize);
     s->cplus_txbuffer_offset += txsize;
@@ -2110,7 +2115,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
         uint8_t dot1q_buffer_space[VLAN_HLEN];
         uint16_t *dot1q_buffer;
 
-        DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : descriptor %d is last segment descriptor\n", descriptor));
+        DPRINTF("+++ C+ Tx mode : descriptor %d is last segment descriptor\n",
+            descriptor);
 
         /* can transfer fully assembled packet */
 
@@ -2122,8 +2128,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
         if (txdw1 & CP_TX_TAGC) {
             /* the vlan tag is in BE byte order in the descriptor
              * BE + le_to_cpu() + ~swap()~ = cpu */
-            DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : inserting vlan tag with "
-                    "tci: %u\n", bswap16(txdw1 & CP_TX_VLAN_TAG_MASK)));
+            DPRINTF("+++ C+ Tx mode : inserting vlan tag with ""tci: %u\n",
+                bswap16(txdw1 & CP_TX_VLAN_TAG_MASK));
 
             dot1q_buffer = (uint16_t *) dot1q_buffer_space;
             dot1q_buffer[0] = cpu_to_be16(ETH_P_8021Q);
@@ -2140,7 +2146,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
 
         if (txdw0 & (CP_TX_IPCS | CP_TX_UDPCS | CP_TX_TCPCS | CP_TX_LGSEN))
         {
-            DEBUG_PRINT(("RTL8139: +++ C+ mode offloaded task checksum\n"));
+            DPRINTF("+++ C+ mode offloaded task checksum\n");
 
             /* ip packet header */
             ip_header *ip = NULL;
@@ -2154,7 +2160,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
             int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12));
             if (proto == ETH_P_IP)
             {
-                DEBUG_PRINT(("RTL8139: +++ C+ mode has IP packet\n"));
+                DPRINTF("+++ C+ mode has IP packet\n");
 
                 /* not aligned */
                 eth_payload_data = saved_buffer + ETH_HLEN;
@@ -2163,7 +2169,9 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
                 ip = (ip_header*)eth_payload_data;
 
                 if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
-                    DEBUG_PRINT(("RTL8139: +++ C+ mode packet has bad IP version %d expected %d\n", IP_HEADER_VERSION(ip), IP_HEADER_VERSION_4));
+                    DPRINTF("+++ C+ mode packet has bad IP version %d "
+                        "expected %d\n", IP_HEADER_VERSION(ip),
+                        IP_HEADER_VERSION_4);
                     ip = NULL;
                 } else {
                     hlen = IP_HEADER_LENGTH(ip);
@@ -2176,7 +2184,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
             {
                 if (txdw0 & CP_TX_IPCS)
                 {
-                    DEBUG_PRINT(("RTL8139: +++ C+ mode need IP checksum\n"));
+                    DPRINTF("+++ C+ mode need IP checksum\n");
 
                     if (hlen<sizeof(ip_header) || hlen>eth_payload_len) {/* min header length */
                         /* bad packet header len */
@@ -2186,7 +2194,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
                     {
                         ip->ip_sum = 0;
                         ip->ip_sum = ip_checksum(ip, hlen);
-                        DEBUG_PRINT(("RTL8139: +++ C+ mode IP header len=%d checksum=%04x\n", hlen, ip->ip_sum));
+                        DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n",
+                            hlen, ip->ip_sum);
                     }
                 }
 
@@ -2195,8 +2204,9 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
 #if defined (DEBUG_RTL8139)
                     int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK;
 #endif
-                    DEBUG_PRINT(("RTL8139: +++ C+ mode offloaded task TSO MTU=%d IP data %d frame data %d specified MSS=%d\n",
-                                 ETH_MTU, ip_data_len, saved_size - ETH_HLEN, large_send_mss));
+                    DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d "
+                        "frame data %d specified MSS=%d\n", ETH_MTU,
+                        ip_data_len, saved_size - ETH_HLEN, large_send_mss);
 
                     int tcp_send_offset = 0;
                     int send_count = 0;
@@ -2220,8 +2230,9 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
                     int tcp_data_len = ip_data_len - tcp_hlen;
                     int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen;
 
-                    DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP data len %d TCP hlen %d TCP data len %d TCP chunk size %d\n",
-                                 ip_data_len, tcp_hlen, tcp_data_len, tcp_chunk_size));
+                    DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP "
+                        "data len %d TCP chunk size %d\n", ip_data_len,
+                        tcp_hlen, tcp_data_len, tcp_chunk_size);
 
                     /* note the cycle below overwrites IP header data,
                        but restores it from saved_ip_header before sending packet */
@@ -2239,13 +2250,16 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
                             chunk_size = tcp_data_len - tcp_send_offset;
                         }
 
-                        DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP seqno %08x\n", be32_to_cpu(p_tcp_hdr->th_seq)));
+                        DPRINTF("+++ C+ mode TSO TCP seqno %08x\n",
+                            be32_to_cpu(p_tcp_hdr->th_seq));
 
                         /* add 4 TCP pseudoheader fields */
                         /* copy IP source and destination fields */
                         memcpy(data_to_checksum, saved_ip_header + 12, 8);
 
-                        DEBUG_PRINT(("RTL8139: +++ C+ mode TSO calculating TCP checksum for packet with %d bytes data\n", tcp_hlen + chunk_size));
+                        DPRINTF("+++ C+ mode TSO calculating TCP checksum for "
+                            "packet with %d bytes data\n", tcp_hlen +
+                            chunk_size);
 
                         if (tcp_send_offset)
                         {
@@ -2267,7 +2281,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
                         p_tcp_hdr->th_sum = 0;
 
                         int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12);
-                        DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP checksum %04x\n", tcp_checksum));
+                        DPRINTF("+++ C+ mode TSO TCP checksum %04x\n",
+                            tcp_checksum);
 
                         p_tcp_hdr->th_sum = tcp_checksum;
 
@@ -2282,10 +2297,12 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
 
                         ip->ip_sum = 0;
                         ip->ip_sum = ip_checksum(eth_payload_data, hlen);
-                        DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP header len=%d checksum=%04x\n", hlen, ip->ip_sum));
+                        DPRINTF("+++ C+ mode TSO IP header len=%d "
+                            "checksum=%04x\n", hlen, ip->ip_sum);
 
                         int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size;
-                        DEBUG_PRINT(("RTL8139: +++ C+ mode TSO transferring packet size %d\n", tso_send_size));
+                        DPRINTF("+++ C+ mode TSO transferring packet size "
+                            "%d\n", tso_send_size);
                         rtl8139_transfer_frame(s, saved_buffer, tso_send_size,
                             0, (uint8_t *) dot1q_buffer);
 
@@ -2299,7 +2316,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
                 }
                 else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS))
                 {
-                    DEBUG_PRINT(("RTL8139: +++ C+ mode need TCP or UDP checksum\n"));
+                    DPRINTF("+++ C+ mode need TCP or UDP checksum\n");
 
                     /* maximum IP header length is 60 bytes */
                     uint8_t saved_ip_header[60];
@@ -2314,7 +2331,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
 
                     if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP)
                     {
-                        DEBUG_PRINT(("RTL8139: +++ C+ mode calculating TCP checksum for packet with %d bytes data\n", ip_data_len));
+                        DPRINTF("+++ C+ mode calculating TCP checksum for "
+                            "packet with %d bytes data\n", ip_data_len);
 
                         ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
                         p_tcpip_hdr->zeros      = 0;
@@ -2326,13 +2344,15 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
                         p_tcp_hdr->th_sum = 0;
 
                         int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
-                        DEBUG_PRINT(("RTL8139: +++ C+ mode TCP checksum %04x\n", tcp_checksum));
+                        DPRINTF("+++ C+ mode TCP checksum %04x\n",
+                            tcp_checksum);
 
                         p_tcp_hdr->th_sum = tcp_checksum;
                     }
                     else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP)
                     {
-                        DEBUG_PRINT(("RTL8139: +++ C+ mode calculating UDP checksum for packet with %d bytes data\n", ip_data_len));
+                        DPRINTF("+++ C+ mode calculating UDP checksum for "
+                            "packet with %d bytes data\n", ip_data_len);
 
                         ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum;
                         p_udpip_hdr->zeros      = 0;
@@ -2344,7 +2364,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
                         p_udp_hdr->uh_sum = 0;
 
                         int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
-                        DEBUG_PRINT(("RTL8139: +++ C+ mode UDP checksum %04x\n", udp_checksum));
+                        DPRINTF("+++ C+ mode UDP checksum %04x\n",
+                            udp_checksum);
 
                         p_udp_hdr->uh_sum = udp_checksum;
                     }
@@ -2358,7 +2379,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
         /* update tally counter */
         ++s->tally_counters.TxOk;
 
-        DEBUG_PRINT(("RTL8139: +++ C+ mode transmitting %d bytes packet\n", saved_size));
+        DPRINTF("+++ C+ mode transmitting %d bytes packet\n", saved_size);
 
         rtl8139_transfer_frame(s, saved_buffer, saved_size, 1,
             (uint8_t *) dot1q_buffer);
@@ -2377,7 +2398,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
     }
     else
     {
-        DEBUG_PRINT(("RTL8139: +++ C+ mode transmission continue to next descriptor\n"));
+        DPRINTF("+++ C+ mode transmission continue to next descriptor\n");
     }
 
     return 1;
@@ -2395,8 +2416,8 @@ static void rtl8139_cplus_transmit(RTL8139State *s)
     /* Mark transfer completed */
     if (!txcount)
     {
-        DEBUG_PRINT(("RTL8139: C+ mode : transmitter queue stalled, current TxDesc = %d\n",
-                     s->currCPlusTxDesc));
+        DPRINTF("C+ mode : transmitter queue stalled, current TxDesc = %d\n",
+            s->currCPlusTxDesc);
     }
     else
     {
@@ -2421,7 +2442,8 @@ static void rtl8139_transmit(RTL8139State *s)
     /* Mark transfer completed */
     if (!txcount)
     {
-        DEBUG_PRINT(("RTL8139: transmitter queue stalled, current TxDesc = %d\n", s->currTxDesc));
+        DPRINTF("transmitter queue stalled, current TxDesc = %d\n",
+            s->currTxDesc);
     }
 }
 
@@ -2434,7 +2456,8 @@ static void rtl8139_TxStatus_write(RTL8139State *s, uint32_t txRegOffset, uint32
 
     if (s->cplus_enabled)
     {
-        DEBUG_PRINT(("RTL8139C+ DTCCR write offset=0x%x val=0x%08x descriptor=%d\n", txRegOffset, val, descriptor));
+        DPRINTF("RTL8139C+ DTCCR write offset=0x%x val=0x%08x "
+            "descriptor=%d\n", txRegOffset, val, descriptor);
 
         /* handle Dump Tally Counters command */
         s->TxStatus[descriptor] = val;
@@ -2453,7 +2476,8 @@ static void rtl8139_TxStatus_write(RTL8139State *s, uint32_t txRegOffset, uint32
         return;
     }
 
-    DEBUG_PRINT(("RTL8139: TxStatus write offset=0x%x val=0x%08x descriptor=%d\n", txRegOffset, val, descriptor));
+    DPRINTF("TxStatus write offset=0x%x val=0x%08x descriptor=%d\n",
+        txRegOffset, val, descriptor);
 
     /* mask only reserved bits */
     val &= ~0xff00c000; /* these bits are reset on write */
@@ -2469,7 +2493,7 @@ static uint32_t rtl8139_TxStatus_read(RTL8139State *s, uint32_t txRegOffset)
 {
     uint32_t ret = s->TxStatus[txRegOffset/4];
 
-    DEBUG_PRINT(("RTL8139: TxStatus read offset=0x%x val=0x%08x\n", txRegOffset, ret));
+    DPRINTF("TxStatus read offset=0x%x val=0x%08x\n", txRegOffset, ret);
 
     return ret;
 }
@@ -2501,7 +2525,7 @@ static uint16_t rtl8139_TSAD_read(RTL8139State *s)
          |((s->TxStatus[0] & TxHostOwns )?TSAD_OWN0:0) ;
 
 
-    DEBUG_PRINT(("RTL8139: TSAD read val=0x%04x\n", ret));
+    DPRINTF("TSAD read val=0x%04x\n", ret);
 
     return ret;
 }
@@ -2510,14 +2534,14 @@ static uint16_t rtl8139_CSCR_read(RTL8139State *s)
 {
     uint16_t ret = s->CSCR;
 
-    DEBUG_PRINT(("RTL8139: CSCR read val=0x%04x\n", ret));
+    DPRINTF("CSCR read val=0x%04x\n", ret);
 
     return ret;
 }
 
 static void rtl8139_TxAddr_write(RTL8139State *s, uint32_t txAddrOffset, uint32_t val)
 {
-    DEBUG_PRINT(("RTL8139: TxAddr write offset=0x%x val=0x%08x\n", txAddrOffset, val));
+    DPRINTF("TxAddr write offset=0x%x val=0x%08x\n", txAddrOffset, val);
 
     s->TxAddr[txAddrOffset/4] = val;
 }
@@ -2526,20 +2550,20 @@ static uint32_t rtl8139_TxAddr_read(RTL8139State *s, uint32_t txAddrOffset)
 {
     uint32_t ret = s->TxAddr[txAddrOffset/4];
 
-    DEBUG_PRINT(("RTL8139: TxAddr read offset=0x%x val=0x%08x\n", txAddrOffset, ret));
+    DPRINTF("TxAddr read offset=0x%x val=0x%08x\n", txAddrOffset, ret);
 
     return ret;
 }
 
 static void rtl8139_RxBufPtr_write(RTL8139State *s, uint32_t val)
 {
-    DEBUG_PRINT(("RTL8139: RxBufPtr write val=0x%04x\n", val));
+    DPRINTF("RxBufPtr write val=0x%04x\n", val);
 
     /* this value is off by 16 */
     s->RxBufPtr = MOD2(val + 0x10, s->RxBufferSize);
 
-    DEBUG_PRINT((" CAPR write: rx buffer length %d head 0x%04x read 0x%04x\n",
-           s->RxBufferSize, s->RxBufAddr, s->RxBufPtr));
+    DPRINTF(" CAPR write: rx buffer length %d head 0x%04x read 0x%04x\n",
+        s->RxBufferSize, s->RxBufAddr, s->RxBufPtr);
 }
 
 static uint32_t rtl8139_RxBufPtr_read(RTL8139State *s)
@@ -2547,7 +2571,7 @@ static uint32_t rtl8139_RxBufPtr_read(RTL8139State *s)
     /* this value is off by 16 */
     uint32_t ret = s->RxBufPtr - 0x10;
 
-    DEBUG_PRINT(("RTL8139: RxBufPtr read val=0x%04x\n", ret));
+    DPRINTF("RxBufPtr read val=0x%04x\n", ret);
 
     return ret;
 }
@@ -2557,14 +2581,14 @@ static uint32_t rtl8139_RxBufAddr_read(RTL8139State *s)
     /* this value is NOT off by 16 */
     uint32_t ret = s->RxBufAddr;
 
-    DEBUG_PRINT(("RTL8139: RxBufAddr read val=0x%04x\n", ret));
+    DPRINTF("RxBufAddr read val=0x%04x\n", ret);
 
     return ret;
 }
 
 static void rtl8139_RxBuf_write(RTL8139State *s, uint32_t val)
 {
-    DEBUG_PRINT(("RTL8139: RxBuf write val=0x%08x\n", val));
+    DPRINTF("RxBuf write val=0x%08x\n", val);
 
     s->RxBuf = val;
 
@@ -2575,14 +2599,14 @@ static uint32_t rtl8139_RxBuf_read(RTL8139State *s)
 {
     uint32_t ret = s->RxBuf;
 
-    DEBUG_PRINT(("RTL8139: RxBuf read val=0x%08x\n", ret));
+    DPRINTF("RxBuf read val=0x%08x\n", ret);
 
     return ret;
 }
 
 static void rtl8139_IntrMask_write(RTL8139State *s, uint32_t val)
 {
-    DEBUG_PRINT(("RTL8139: IntrMask write(w) val=0x%04x\n", val));
+    DPRINTF("IntrMask write(w) val=0x%04x\n", val);
 
     /* mask unwriteable bits */
     val = SET_MASKED(val, 0x1e00, s->IntrMask);
@@ -2598,14 +2622,14 @@ static uint32_t rtl8139_IntrMask_read(RTL8139State *s)
 {
     uint32_t ret = s->IntrMask;
 
-    DEBUG_PRINT(("RTL8139: IntrMask read(w) val=0x%04x\n", ret));
+    DPRINTF("IntrMask read(w) val=0x%04x\n", ret);
 
     return ret;
 }
 
 static void rtl8139_IntrStatus_write(RTL8139State *s, uint32_t val)
 {
-    DEBUG_PRINT(("RTL8139: IntrStatus write(w) val=0x%04x\n", val));
+    DPRINTF("IntrStatus write(w) val=0x%04x\n", val);
 
 #if 0
 
@@ -2642,7 +2666,7 @@ static uint32_t rtl8139_IntrStatus_read(RTL8139State *s)
 
     uint32_t ret = s->IntrStatus;
 
-    DEBUG_PRINT(("RTL8139: IntrStatus read(w) val=0x%04x\n", ret));
+    DPRINTF("IntrStatus read(w) val=0x%04x\n", ret);
 
 #if 0
 
@@ -2658,7 +2682,7 @@ static uint32_t rtl8139_IntrStatus_read(RTL8139State *s)
 
 static void rtl8139_MultiIntr_write(RTL8139State *s, uint32_t val)
 {
-    DEBUG_PRINT(("RTL8139: MultiIntr write(w) val=0x%04x\n", val));
+    DPRINTF("MultiIntr write(w) val=0x%04x\n", val);
 
     /* mask unwriteable bits */
     val = SET_MASKED(val, 0xf000, s->MultiIntr);
@@ -2670,7 +2694,7 @@ static uint32_t rtl8139_MultiIntr_read(RTL8139State *s)
 {
     uint32_t ret = s->MultiIntr;
 
-    DEBUG_PRINT(("RTL8139: MultiIntr read(w) val=0x%04x\n", ret));
+    DPRINTF("MultiIntr read(w) val=0x%04x\n", ret);
 
     return ret;
 }
@@ -2718,11 +2742,12 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
             break;
         case MediaStatus:
             /* ignore */
-            DEBUG_PRINT(("RTL8139: not implemented write(b) to MediaStatus val=0x%02x\n", val));
+            DPRINTF("not implemented write(b) to MediaStatus val=0x%02x\n",
+                val);
             break;
 
         case HltClk:
-            DEBUG_PRINT(("RTL8139: HltClk write val=0x%08x\n", val));
+            DPRINTF("HltClk write val=0x%08x\n", val);
             if (val == 'R')
             {
                 s->clock_enabled = 1;
@@ -2734,27 +2759,29 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val)
             break;
 
         case TxThresh:
-            DEBUG_PRINT(("RTL8139C+ TxThresh write(b) val=0x%02x\n", val));
+            DPRINTF("C+ TxThresh write(b) val=0x%02x\n", val);
             s->TxThresh = val;
             break;
 
         case TxPoll:
-            DEBUG_PRINT(("RTL8139C+ TxPoll write(b) val=0x%02x\n", val));
+            DPRINTF("C+ TxPoll write(b) val=0x%02x\n", val);
             if (val & (1 << 7))
             {
-                DEBUG_PRINT(("RTL8139C+ TxPoll high priority transmission (not implemented)\n"));
+                DPRINTF("C+ TxPoll high priority transmission (not "
+                    "implemented)\n");
                 //rtl8139_cplus_transmit(s);
             }
             if (val & (1 << 6))
             {
-                DEBUG_PRINT(("RTL8139C+ TxPoll normal priority transmission\n"));
+                DPRINTF("C+ TxPoll normal priority transmission\n");
                 rtl8139_cplus_transmit(s);
             }
 
             break;
 
         default:
-            DEBUG_PRINT(("RTL8139: not implemented write(b) addr=0x%x val=0x%02x\n", addr, val));
+            DPRINTF("not implemented write(b) addr=0x%x val=0x%02x\n", addr,
+                val);
             break;
     }
 }
@@ -2790,14 +2817,14 @@ static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
             rtl8139_BasicModeStatus_write(s, val);
             break;
         case NWayAdvert:
-            DEBUG_PRINT(("RTL8139: NWayAdvert write(w) val=0x%04x\n", val));
+            DPRINTF("NWayAdvert write(w) val=0x%04x\n", val);
             s->NWayAdvert = val;
             break;
         case NWayLPAR:
-            DEBUG_PRINT(("RTL8139: forbidden NWayLPAR write(w) val=0x%04x\n", val));
+            DPRINTF("forbidden NWayLPAR write(w) val=0x%04x\n", val);
             break;
         case NWayExpansion:
-            DEBUG_PRINT(("RTL8139: NWayExpansion write(w) val=0x%04x\n", val));
+            DPRINTF("NWayExpansion write(w) val=0x%04x\n", val);
             s->NWayExpansion = val;
             break;
 
@@ -2810,7 +2837,8 @@ static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val)
             break;
 
         default:
-            DEBUG_PRINT(("RTL8139: ioport write(w) addr=0x%x val=0x%04x via write(b)\n", addr, val));
+            DPRINTF("ioport write(w) addr=0x%x val=0x%04x via write(b)\n",
+                addr, val);
 
             rtl8139_io_writeb(opaque, addr, val & 0xff);
             rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
@@ -2823,7 +2851,7 @@ static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time)
     int64_t pci_time, next_time;
     uint32_t low_pci;
 
-    DEBUG_PRINT(("RTL8139: entered rtl8139_set_next_tctr_time\n"));
+    DPRINTF("entered rtl8139_set_next_tctr_time\n");
 
     if (s->TimerExpire && current_time >= s->TimerExpire) {
         s->IntrStatus |= PCSTimeout;
@@ -2867,7 +2895,7 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
     switch (addr)
     {
         case RxMissed:
-            DEBUG_PRINT(("RTL8139: RxMissed clearing on write\n"));
+            DPRINTF("RxMissed clearing on write\n");
             s->RxMissed = 0;
             break;
 
@@ -2892,23 +2920,23 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
             break;
 
         case RxRingAddrLO:
-            DEBUG_PRINT(("RTL8139: C+ RxRing low bits write val=0x%08x\n", val));
+            DPRINTF("C+ RxRing low bits write val=0x%08x\n", val);
             s->RxRingAddrLO = val;
             break;
 
         case RxRingAddrHI:
-            DEBUG_PRINT(("RTL8139: C+ RxRing high bits write val=0x%08x\n", val));
+            DPRINTF("C+ RxRing high bits write val=0x%08x\n", val);
             s->RxRingAddrHI = val;
             break;
 
         case Timer:
-            DEBUG_PRINT(("RTL8139: TCTR Timer reset on write\n"));
+            DPRINTF("TCTR Timer reset on write\n");
             s->TCTR_base = qemu_get_clock_ns(vm_clock);
             rtl8139_set_next_tctr_time(s, s->TCTR_base);
             break;
 
         case FlashReg:
-            DEBUG_PRINT(("RTL8139: FlashReg TimerInt write val=0x%08x\n", val));
+            DPRINTF("FlashReg TimerInt write val=0x%08x\n", val);
             if (s->TimerInt != val) {
                 s->TimerInt = val;
                 rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
@@ -2916,7 +2944,8 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
             break;
 
         default:
-            DEBUG_PRINT(("RTL8139: ioport write(l) addr=0x%x val=0x%08x via write(b)\n", addr, val));
+            DPRINTF("ioport write(l) addr=0x%x val=0x%08x via write(b)\n",
+                addr, val);
             rtl8139_io_writeb(opaque, addr, val & 0xff);
             rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff);
             rtl8139_io_writeb(opaque, addr + 2, (val >> 16) & 0xff);
@@ -2967,31 +2996,31 @@ static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
 
         case MediaStatus:
             ret = 0xd0;
-            DEBUG_PRINT(("RTL8139: MediaStatus read 0x%x\n", ret));
+            DPRINTF("MediaStatus read 0x%x\n", ret);
             break;
 
         case HltClk:
             ret = s->clock_enabled;
-            DEBUG_PRINT(("RTL8139: HltClk read 0x%x\n", ret));
+            DPRINTF("HltClk read 0x%x\n", ret);
             break;
 
         case PCIRevisionID:
             ret = RTL8139_PCI_REVID;
-            DEBUG_PRINT(("RTL8139: PCI Revision ID read 0x%x\n", ret));
+            DPRINTF("PCI Revision ID read 0x%x\n", ret);
             break;
 
         case TxThresh:
             ret = s->TxThresh;
-            DEBUG_PRINT(("RTL8139C+ TxThresh read(b) val=0x%02x\n", ret));
+            DPRINTF("C+ TxThresh read(b) val=0x%02x\n", ret);
             break;
 
         case 0x43: /* Part of TxConfig register. Windows driver tries to read it */
             ret = s->TxConfig >> 24;
-            DEBUG_PRINT(("RTL8139C TxConfig at 0x43 read(b) val=0x%02x\n", ret));
+            DPRINTF("RTL8139C TxConfig at 0x43 read(b) val=0x%02x\n", ret);
             break;
 
         default:
-            DEBUG_PRINT(("RTL8139: not implemented read(b) addr=0x%x\n", addr));
+            DPRINTF("not implemented read(b) addr=0x%x\n", addr);
             ret = 0;
             break;
     }
@@ -3036,15 +3065,15 @@ static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
             break;
         case NWayAdvert:
             ret = s->NWayAdvert;
-            DEBUG_PRINT(("RTL8139: NWayAdvert read(w) val=0x%04x\n", ret));
+            DPRINTF("NWayAdvert read(w) val=0x%04x\n", ret);
             break;
         case NWayLPAR:
             ret = s->NWayLPAR;
-            DEBUG_PRINT(("RTL8139: NWayLPAR read(w) val=0x%04x\n", ret));
+            DPRINTF("NWayLPAR read(w) val=0x%04x\n", ret);
             break;
         case NWayExpansion:
             ret = s->NWayExpansion;
-            DEBUG_PRINT(("RTL8139: NWayExpansion read(w) val=0x%04x\n", ret));
+            DPRINTF("NWayExpansion read(w) val=0x%04x\n", ret);
             break;
 
         case CpCmd:
@@ -3064,12 +3093,12 @@ static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
             break;
 
         default:
-            DEBUG_PRINT(("RTL8139: ioport read(w) addr=0x%x via read(b)\n", addr));
+            DPRINTF("ioport read(w) addr=0x%x via read(b)\n", addr);
 
             ret  = rtl8139_io_readb(opaque, addr);
             ret |= rtl8139_io_readb(opaque, addr + 1) << 8;
 
-            DEBUG_PRINT(("RTL8139: ioport read(w) addr=0x%x val=0x%04x\n", addr, ret));
+            DPRINTF("ioport read(w) addr=0x%x val=0x%04x\n", addr, ret);
             break;
     }
 
@@ -3088,7 +3117,7 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr)
         case RxMissed:
             ret = s->RxMissed;
 
-            DEBUG_PRINT(("RTL8139: RxMissed read val=0x%08x\n", ret));
+            DPRINTF("RxMissed read val=0x%08x\n", ret);
             break;
 
         case TxConfig:
@@ -3113,34 +3142,34 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr)
 
         case RxRingAddrLO:
             ret = s->RxRingAddrLO;
-            DEBUG_PRINT(("RTL8139: C+ RxRing low bits read val=0x%08x\n", ret));
+            DPRINTF("C+ RxRing low bits read val=0x%08x\n", ret);
             break;
 
         case RxRingAddrHI:
             ret = s->RxRingAddrHI;
-            DEBUG_PRINT(("RTL8139: C+ RxRing high bits read val=0x%08x\n", ret));
+            DPRINTF("C+ RxRing high bits read val=0x%08x\n", ret);
             break;
 
         case Timer:
             ret = muldiv64(qemu_get_clock_ns(vm_clock) - s->TCTR_base,
                            PCI_FREQUENCY, get_ticks_per_sec());
-            DEBUG_PRINT(("RTL8139: TCTR Timer read val=0x%08x\n", ret));
+            DPRINTF("TCTR Timer read val=0x%08x\n", ret);
             break;
 
         case FlashReg:
             ret = s->TimerInt;
-            DEBUG_PRINT(("RTL8139: FlashReg TimerInt read val=0x%08x\n", ret));
+            DPRINTF("FlashReg TimerInt read val=0x%08x\n", ret);
             break;
 
         default:
-            DEBUG_PRINT(("RTL8139: ioport read(l) addr=0x%x via read(b)\n", addr));
+            DPRINTF("ioport read(l) addr=0x%x via read(b)\n", addr);
 
             ret  = rtl8139_io_readb(opaque, addr);
             ret |= rtl8139_io_readb(opaque, addr + 1) << 8;
             ret |= rtl8139_io_readb(opaque, addr + 2) << 16;
             ret |= rtl8139_io_readb(opaque, addr + 3) << 24;
 
-            DEBUG_PRINT(("RTL8139: read(l) addr=0x%x val=%08x\n", addr, ret));
+            DPRINTF("read(l) addr=0x%x val=%08x\n", addr, ret);
             break;
     }
 
@@ -3385,7 +3414,7 @@ static void rtl8139_timer(void *opaque)
 
     if (!s->clock_enabled)
     {
-        DEBUG_PRINT(("RTL8139: >>> timer: clock is not running\n"));
+        DPRINTF(">>> timer: clock is not running\n");
         return;
     }
 

From ec48c7747acd1be25ca70586bc4e6640765e40c8 Mon Sep 17 00:00:00 2001
From: Benjamin Poirier <benjamin.poirier@gmail.com>
Date: Wed, 20 Apr 2011 19:39:02 -0400
Subject: [PATCH 312/386] rtl8139: add format attribute to DPRINTF

gcc can check the format string for correctness even when debugging output is
not enabled.
Have to make sure arguments are always available. They are optimized out if
unneeded.

Signed-off-by: Benjamin Poirier <benjamin.poirier@gmail.com>
Cc: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/rtl8139.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 13b14e4e10..cbf667a301 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -88,7 +88,11 @@
 #  define DPRINTF(fmt, ...) \
     do { fprintf(stderr, "RTL8139: " fmt, ## __VA_ARGS__); } while (0)
 #else
-#  define DPRINTF(fmt, ...) do { } while (0)
+static inline __attribute__ ((format (printf, 1, 2)))
+    int DPRINTF(const char *fmt, ...)
+{
+    return 0;
+}
 #endif
 
 /* Symbolic offsets to registers. */
@@ -2201,9 +2205,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
 
                 if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP)
                 {
-#if defined (DEBUG_RTL8139)
                     int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK;
-#endif
+
                     DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d "
                         "frame data %d specified MSS=%d\n", ETH_MTU,
                         ip_data_len, saved_size - ETH_HLEN, large_send_mss);

From b0b36e5d2e4c8a96c2f6dbc0981a9fd0cde111d8 Mon Sep 17 00:00:00 2001
From: Brad Hards <bradh@frogmouth.net>
Date: Sun, 24 Apr 2011 17:19:56 +1000
Subject: [PATCH 313/386] doc: fix slirp description

net/slirp.c says:
    /* default settings according to historic slirp */
    struct in_addr net  = { .s_addr = htonl(0x0a000200) }; /* 10.0.2.0 */
    struct in_addr mask = { .s_addr = htonl(0xffffff00) }; /* 255.255.255.0 */
    struct in_addr host = { .s_addr = htonl(0x0a000202) }; /* 10.0.2.2 */
    struct in_addr dhcp = { .s_addr = htonl(0x0a00020f) }; /* 10.0.2.15 */
    struct in_addr dns  = { .s_addr = htonl(0x0a000203) }; /* 10.0.2.3 */

Which I think is not what the documentation says.

Signed-off-by: Brad Hards <bradh@frogmouth.net>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 qemu-options.hx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index 677c550103..489df10c46 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1152,7 +1152,7 @@ Assign symbolic name for use in monitor commands.
 @item net=@var{addr}[/@var{mask}]
 Set IP network address the guest will see. Optionally specify the netmask,
 either in the form a.b.c.d or as number of valid top-most bits. Default is
-10.0.2.0/8.
+10.0.2.0/24.
 
 @item host=@var{addr}
 Specify the guest-visible address of the host. Default is the 2nd IP in the
@@ -1168,7 +1168,7 @@ Specifies the client hostname reported by the builtin DHCP server.
 
 @item dhcpstart=@var{addr}
 Specify the first of the 16 IPs the built-in DHCP server can assign. Default
-is the 16th to 31st IP in the guest network, i.e. x.x.x.16 to x.x.x.31.
+is the 15th to 31st IP in the guest network, i.e. x.x.x.15 to x.x.x.31.
 
 @item dns=@var{addr}
 Specify the guest-visible address of the virtual nameserver. The address must

From 05098a9315819621405eb662baddeec624127d7a Mon Sep 17 00:00:00 2001
From: Riku Voipio <riku.voipio@nokia.com>
Date: Fri, 4 Mar 2011 15:27:29 +0200
Subject: [PATCH 314/386] [v2] linux-user: bigger default stack

PTHREAD_STACK_MIN (16KB) is somewhat inadequate for a new stack for new
QEMU threads. Set new limit to 256K which should be enough, yet doesn't
increase memory pressure significantly.

Signed-off-by: Riku Voipio <riku.voipio@nokia.com>
Reviewed-by: Nathan Froyd <froydnj@codesourcery.com>
---
 linux-user/syscall.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index bb0999d1ab..732f71a6a0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3690,9 +3690,9 @@ static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
 
 #endif /* defined(TARGET_I386) */
 
-#if defined(CONFIG_USE_NPTL)
+#define NEW_STACK_SIZE 0x40000
 
-#define NEW_STACK_SIZE PTHREAD_STACK_MIN
+#if defined(CONFIG_USE_NPTL)
 
 static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
 typedef struct {
@@ -3736,9 +3736,6 @@ static void *clone_func(void *arg)
     return NULL;
 }
 #else
-/* this stack is the equivalent of the kernel stack associated with a
-   thread/process */
-#define NEW_STACK_SIZE 8192
 
 static int clone_func(void *arg)
 {

From 608e55921770bbae1609135aa0c351238f57fc5f Mon Sep 17 00:00:00 2001
From: Laurent Vivier <laurent@vivier.eu>
Date: Thu, 7 Apr 2011 00:25:32 +0200
Subject: [PATCH 315/386] linux-user: improve traces

Add trace details for getpid(), kill(), _llseek(), rt_sigaction(),
rt_sigprocmask(), clone().

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/strace.c    | 161 +++++++++++++++++++++++++++++++++++++++++
 linux-user/strace.list |  12 +--
 2 files changed, 167 insertions(+), 6 deletions(-)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index 8dd398b9f2..5d9bb085c7 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -9,6 +9,7 @@
 #include <sys/mount.h>
 #include <sys/mman.h>
 #include <unistd.h>
+#include <sched.h>
 #include "qemu.h"
 
 int do_strace=0;
@@ -63,6 +64,7 @@ UNUSED static void print_string(abi_long, int);
 UNUSED static void print_raw_param(const char *, abi_long, int);
 UNUSED static void print_timeval(abi_ulong, int);
 UNUSED static void print_number(abi_long, int);
+UNUSED static void print_signal(abi_ulong, int);
 
 /*
  * Utility functions
@@ -117,6 +119,37 @@ if( cmd == val ) { \
     gemu_log("%d",cmd);
 }
 
+static void
+print_signal(abi_ulong arg, int last)
+{
+    const char *signal_name = NULL;
+    switch(arg) {
+    case TARGET_SIGHUP: signal_name = "SIGHUP"; break;
+    case TARGET_SIGINT: signal_name = "SIGINT"; break;
+    case TARGET_SIGQUIT: signal_name = "SIGQUIT"; break;
+    case TARGET_SIGILL: signal_name = "SIGILL"; break;
+    case TARGET_SIGABRT: signal_name = "SIGABRT"; break;
+    case TARGET_SIGFPE: signal_name = "SIGFPE"; break;
+    case TARGET_SIGKILL: signal_name = "SIGKILL"; break;
+    case TARGET_SIGSEGV: signal_name = "SIGSEGV"; break;
+    case TARGET_SIGPIPE: signal_name = "SIGPIPE"; break;
+    case TARGET_SIGALRM: signal_name = "SIGALRM"; break;
+    case TARGET_SIGTERM: signal_name = "SIGTERM"; break;
+    case TARGET_SIGUSR1: signal_name = "SIGUSR1"; break;
+    case TARGET_SIGUSR2: signal_name = "SIGUSR2"; break;
+    case TARGET_SIGCHLD: signal_name = "SIGCHLD"; break;
+    case TARGET_SIGCONT: signal_name = "SIGCONT"; break;
+    case TARGET_SIGSTOP: signal_name = "SIGSTOP"; break;
+    case TARGET_SIGTTIN: signal_name = "SIGTTIN"; break;
+    case TARGET_SIGTTOU: signal_name = "SIGTTOU"; break;
+    }
+    if (signal_name == NULL) {
+        print_raw_param("%ld", arg, 1);
+        return;
+    }
+    gemu_log("%s%s", signal_name, get_comma(last));
+}
+
 #ifdef TARGET_NR__newselect
 static void
 print_fdset(int n, abi_ulong target_fds_addr)
@@ -427,6 +460,32 @@ UNUSED static struct flags fcntl_flags[] = {
     FLAG_END,
 };
 
+UNUSED static struct flags clone_flags[] = {
+    FLAG_GENERIC(CLONE_VM),
+    FLAG_GENERIC(CLONE_FS),
+    FLAG_GENERIC(CLONE_FILES),
+    FLAG_GENERIC(CLONE_SIGHAND),
+    FLAG_GENERIC(CLONE_PTRACE),
+    FLAG_GENERIC(CLONE_VFORK),
+    FLAG_GENERIC(CLONE_PARENT),
+    FLAG_GENERIC(CLONE_THREAD),
+    FLAG_GENERIC(CLONE_NEWNS),
+    FLAG_GENERIC(CLONE_SYSVSEM),
+    FLAG_GENERIC(CLONE_SETTLS),
+    FLAG_GENERIC(CLONE_PARENT_SETTID),
+    FLAG_GENERIC(CLONE_CHILD_CLEARTID),
+    FLAG_GENERIC(CLONE_DETACHED),
+    FLAG_GENERIC(CLONE_UNTRACED),
+    FLAG_GENERIC(CLONE_CHILD_SETTID),
+    FLAG_GENERIC(CLONE_NEWUTS),
+    FLAG_GENERIC(CLONE_NEWIPC),
+    FLAG_GENERIC(CLONE_NEWUSER),
+    FLAG_GENERIC(CLONE_NEWPID),
+    FLAG_GENERIC(CLONE_NEWNET),
+    FLAG_GENERIC(CLONE_IO),
+    FLAG_END,
+};
+
 /*
  * print_xxx utility functions.  These are used to print syscall
  * parameters in certain format.  All of these have parameter
@@ -669,6 +728,39 @@ print_chmod(const struct syscallname *name,
 }
 #endif
 
+#ifdef TARGET_NR_clone
+static void
+print_clone(const struct syscallname *name,
+    abi_long arg0, abi_long arg1, abi_long arg2,
+    abi_long arg3, abi_long arg4, abi_long arg5)
+{
+    print_syscall_prologue(name);
+#if defined(TARGET_M68K)
+    print_flags(clone_flags, arg0, 0);
+    print_raw_param("newsp=0x" TARGET_ABI_FMT_lx, arg1, 1);
+#elif defined(TARGET_SH4) || defined(TARGET_ALPHA)
+    print_flags(clone_flags, arg0, 0);
+    print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg1, 0);
+    print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
+    print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg3, 0);
+    print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg4, 1);
+#elif defined(TARGET_CRIS)
+    print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg0, 0);
+    print_flags(clone_flags, arg1, 0);
+    print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
+    print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg3, 0);
+    print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg4, 1);
+#else
+    print_flags(clone_flags, arg0, 0);
+    print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg1, 0);
+    print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
+    print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg3, 0);
+    print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg4, 1);
+#endif
+    print_syscall_epilogue(name);
+}
+#endif
+
 #ifdef TARGET_NR_creat
 static void
 print_creat(const struct syscallname *name,
@@ -805,6 +897,28 @@ print_linkat(const struct syscallname *name,
 }
 #endif
 
+#ifdef TARGET_NR__llseek
+static void
+print__llseek(const struct syscallname *name,
+    abi_long arg0, abi_long arg1, abi_long arg2,
+    abi_long arg3, abi_long arg4, abi_long arg5)
+{
+    const char *whence = "UNKNOWN";
+    print_syscall_prologue(name);
+    print_raw_param("%d", arg0, 0);
+    print_raw_param("%ld", arg1, 0);
+    print_raw_param("%ld", arg2, 0);
+    print_pointer(arg3, 0);
+    switch(arg4) {
+    case SEEK_SET: whence = "SEEK_SET"; break;
+    case SEEK_CUR: whence = "SEEK_CUR"; break;
+    case SEEK_END: whence = "SEEK_END"; break;
+    }
+    gemu_log("%s",whence);
+    print_syscall_epilogue(name);
+}
+#endif
+
 #if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) || \
     defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64)
 static void
@@ -875,6 +989,40 @@ print_rmdir(const struct syscallname *name,
 }
 #endif
 
+#ifdef TARGET_NR_rt_sigaction
+static void
+print_rt_sigaction(const struct syscallname *name,
+    abi_long arg0, abi_long arg1, abi_long arg2,
+    abi_long arg3, abi_long arg4, abi_long arg5)
+{
+    print_syscall_prologue(name);
+    print_signal(arg0, 0);
+    print_pointer(arg1, 0);
+    print_pointer(arg2, 1);
+    print_syscall_epilogue(name);
+}
+#endif
+
+#ifdef TARGET_NR_rt_sigprocmask
+static void
+print_rt_sigprocmask(const struct syscallname *name,
+    abi_long arg0, abi_long arg1, abi_long arg2,
+    abi_long arg3, abi_long arg4, abi_long arg5)
+{
+    const char *how = "UNKNOWN";
+    print_syscall_prologue(name);
+    switch(arg0) {
+    case TARGET_SIG_BLOCK: how = "SIG_BLOCK"; break;
+    case TARGET_SIG_UNBLOCK: how = "SIG_UNBLOCK"; break;
+    case TARGET_SIG_SETMASK: how = "SIG_SETMASK"; break;
+    }
+    gemu_log("%s,",how);
+    print_pointer(arg1, 0);
+    print_pointer(arg2, 1);
+    print_syscall_epilogue(name);
+}
+#endif
+
 #ifdef TARGET_NR_mknod
 static void
 print_mknod(const struct syscallname *name,
@@ -1298,6 +1446,19 @@ print_futex(const struct syscallname *name,
 }
 #endif
 
+#ifdef TARGET_NR_kill
+static void
+print_kill(const struct syscallname *name,
+    abi_long arg0, abi_long arg1, abi_long arg2,
+    abi_long arg3, abi_long arg4, abi_long arg5)
+{
+    print_syscall_prologue(name);
+    print_raw_param("%d", arg0, 0);
+    print_signal(arg1, 1);
+    print_syscall_epilogue(name);
+}
+#endif
+
 /*
  * An array of all of the syscalls we know about
  */
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 563a67f0a2..a7eeaef99f 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -85,7 +85,7 @@
 { TARGET_NR_clock_settime, "clock_settime" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_clone
-{ TARGET_NR_clone, "clone" , NULL, NULL, NULL },
+{ TARGET_NR_clone, "clone" , NULL, print_clone, NULL },
 #endif
 #ifdef TARGET_NR_close
 { TARGET_NR_close, "close" , "%s(%d)", NULL, NULL },
@@ -292,7 +292,7 @@
 { TARGET_NR_getpgrp, "getpgrp" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_getpid
-{ TARGET_NR_getpid, "getpid" , NULL, NULL, NULL },
+{ TARGET_NR_getpid, "getpid" , "%s()", NULL, NULL },
 #endif
 #ifdef TARGET_NR_getpmsg
 { TARGET_NR_getpmsg, "getpmsg" , NULL, NULL, NULL },
@@ -418,7 +418,7 @@
 { TARGET_NR_keyctl, "keyctl" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_kill
-{ TARGET_NR_kill, "kill" , NULL, NULL, NULL },
+{ TARGET_NR_kill, "kill", NULL, print_kill, NULL },
 #endif
 #ifdef TARGET_NR_lchown
 { TARGET_NR_lchown, "lchown" , NULL, NULL, NULL },
@@ -448,7 +448,7 @@
 { TARGET_NR_llistxattr, "llistxattr" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR__llseek
-{ TARGET_NR__llseek, "_llseek" , NULL, NULL, NULL },
+{ TARGET_NR__llseek, "_llseek" , NULL, print__llseek, NULL },
 #endif
 #ifdef TARGET_NR_lock
 { TARGET_NR_lock, "lock" , NULL, NULL, NULL },
@@ -1063,13 +1063,13 @@
 { TARGET_NR_rmdir, "rmdir" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_rt_sigaction
-{ TARGET_NR_rt_sigaction, "rt_sigaction" , NULL, NULL, NULL },
+{ TARGET_NR_rt_sigaction, "rt_sigaction" , NULL, print_rt_sigaction, NULL },
 #endif
 #ifdef TARGET_NR_rt_sigpending
 { TARGET_NR_rt_sigpending, "rt_sigpending" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_rt_sigprocmask
-{ TARGET_NR_rt_sigprocmask, "rt_sigprocmask" , NULL, NULL, NULL },
+{ TARGET_NR_rt_sigprocmask, "rt_sigprocmask" , NULL, print_rt_sigprocmask, NULL },
 #endif
 #ifdef TARGET_NR_rt_sigqueueinfo
 { TARGET_NR_rt_sigqueueinfo, "rt_sigqueueinfo" , NULL, NULL, NULL },

From 059c2f2cd773e0f3d7284a6eab662fd26f9cbad2 Mon Sep 17 00:00:00 2001
From: Laurent Vivier <laurent@vivier.eu>
Date: Wed, 30 Mar 2011 00:12:12 +0200
Subject: [PATCH 316/386] linux-user: convert ioctl(SIOCGIFCONF, ...) result.

The result needs to be converted as it is stored in an array of struct
ifreq and sizeof(struct ifreq) differs according to target and host
alignment rules.

This patch allows to execute correctly the following program on arm
and m68k:

 #include <stdio.h>
 #include <sys/ioctl.h>
 #include <net/if.h>
 #include <alloca.h>
 #include <string.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>

int main(void)
{
    int s, ret;
    struct ifconf ifc;
    int i;

    memset( &ifc, 0, sizeof( struct ifconf ) );
    ifc.ifc_len = 8 * sizeof(struct ifreq);
    ifc.ifc_buf = alloca(ifc.ifc_len);

    s = socket( AF_INET, SOCK_DGRAM, 0 );
    if (s < 0) {
        perror("Cannot open socket");
        return 1;
    }
    ret = ioctl( s, SIOCGIFCONF, &ifc );
    if (s < 0) {
        perror("ioctl() failed");
        return 1;
    }

    for (i = 0; i < ifc.ifc_len / sizeof(struct ifreq) ; i ++) {
        struct sockaddr_in *s;
        s = (struct sockaddr_in*)&ifc.ifc_req[i].ifr_addr;
        printf("%s\n", ifc.ifc_req[i].ifr_name);
        printf("%s\n", inet_ntoa(s->sin_addr));
    }
}

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/ioctls.h  |  3 +-
 linux-user/syscall.c | 96 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 526aaa2a76..ab15b867ec 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -112,7 +112,8 @@
   IOCTL(SIOCADDMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
   IOCTL(SIOCDELMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
   IOCTL(SIOCSIFLINK, 0, TYPE_NULL)
-  IOCTL(SIOCGIFCONF, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_ifconf)))
+  IOCTL_SPECIAL(SIOCGIFCONF, IOC_W | IOC_R, do_ioctl_ifconf,
+                MK_PTR(MK_STRUCT(STRUCT_ifconf)))
   IOCTL(SIOCGIFENCAP, IOC_RW, MK_PTR(TYPE_INT))
   IOCTL(SIOCSIFENCAP, IOC_W, MK_PTR(TYPE_INT))
   IOCTL(SIOCDARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 732f71a6a0..123909f190 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -59,6 +59,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 //#include <sys/user.h>
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
+#include <net/if.h>
 #include <qemu-common.h>
 #ifdef TARGET_GPROF
 #include <sys/gmon.h>
@@ -2970,7 +2971,6 @@ static abi_long do_ipc(unsigned int call, int first,
 #endif
 
 /* kernel structure types definitions */
-#define IFNAMSIZ        16
 
 #define STRUCT(name, ...) STRUCT_ ## name,
 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
@@ -3095,6 +3095,100 @@ static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
 }
 #endif
 
+static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
+                                int fd, abi_long cmd, abi_long arg)
+{
+    const argtype *arg_type = ie->arg_type;
+    int target_size;
+    void *argptr;
+    int ret;
+    struct ifconf *host_ifconf;
+    uint32_t outbufsz;
+    const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
+    int target_ifreq_size;
+    int nb_ifreq;
+    int free_buf = 0;
+    int i;
+    int target_ifc_len;
+    abi_long target_ifc_buf;
+    int host_ifc_len;
+    char *host_ifc_buf;
+
+    assert(arg_type[0] == TYPE_PTR);
+    assert(ie->access == IOC_RW);
+
+    arg_type++;
+    target_size = thunk_type_size(arg_type, 0);
+
+    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
+    if (!argptr)
+        return -TARGET_EFAULT;
+    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
+    unlock_user(argptr, arg, 0);
+
+    host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
+    target_ifc_len = host_ifconf->ifc_len;
+    target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
+
+    target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
+    nb_ifreq = target_ifc_len / target_ifreq_size;
+    host_ifc_len = nb_ifreq * sizeof(struct ifreq);
+
+    outbufsz = sizeof(*host_ifconf) + host_ifc_len;
+    if (outbufsz > MAX_STRUCT_SIZE) {
+        /* We can't fit all the extents into the fixed size buffer.
+         * Allocate one that is large enough and use it instead.
+         */
+        host_ifconf = malloc(outbufsz);
+        if (!host_ifconf) {
+            return -TARGET_ENOMEM;
+        }
+        memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
+        free_buf = 1;
+    }
+    host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
+
+    host_ifconf->ifc_len = host_ifc_len;
+    host_ifconf->ifc_buf = host_ifc_buf;
+
+    ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
+    if (!is_error(ret)) {
+	/* convert host ifc_len to target ifc_len */
+
+        nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
+        target_ifc_len = nb_ifreq * target_ifreq_size;
+        host_ifconf->ifc_len = target_ifc_len;
+
+	/* restore target ifc_buf */
+
+        host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
+
+	/* copy struct ifconf to target user */
+
+        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
+        if (!argptr)
+            return -TARGET_EFAULT;
+        thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
+        unlock_user(argptr, arg, target_size);
+
+	/* copy ifreq[] to target user */
+
+        argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
+        for (i = 0; i < nb_ifreq ; i++) {
+            thunk_convert(argptr + i * target_ifreq_size,
+                          host_ifc_buf + i * sizeof(struct ifreq),
+                          ifreq_arg_type, THUNK_TARGET);
+        }
+        unlock_user(argptr, target_ifc_buf, target_ifc_len);
+    }
+
+    if (free_buf) {
+        free(host_ifconf);
+    }
+
+    return ret;
+}
+
 static IOCTLEntry ioctl_entries[] = {
 #define IOCTL(cmd, access, ...) \
     { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },

From 86fcd9463240c256f00963440fbd084196eeb964 Mon Sep 17 00:00:00 2001
From: Laurent Vivier <laurent@vivier.eu>
Date: Wed, 30 Mar 2011 01:35:23 +0200
Subject: [PATCH 317/386] linux-user: add ioctl(SIOCGIWNAME, ...) support.

Allow to run properly following program from linux-user:

/* cc -o wifi wifi.c */

 #include <stdio.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <linux/wireless.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <string.h>

int main(int argc, char **argv)
{
    int ret;
    struct ifreq req;
    struct sockaddr_in *addr;
    int s;

    if (argc != 2) {
        fprintf(stderr, "Need an interface name (like wlan0)\n");
	return 1;
    }

    s = socket( AF_INET, SOCK_DGRAM, 0 );
    if (s < 0) {
        perror("Cannot open socket");
        return 1;
    }
    strncpy(req.ifr_name, argv[1], sizeof(req.ifr_name));
    ret = ioctl( s, SIOCGIWNAME, &req );
    if (ret < 0) {
	fprintf(stderr, "No wireless extension\n");
        return 1;
    }

    printf("%s\n", req.ifr_name);
    printf("%s\n", req.ifr_newname);
    return 0;
}

$ ./wifi eth0
No wireless extension

$ ./wifi wlan0
wlan0
IEEE 802.11bg

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/ioctls.h       | 1 +
 linux-user/syscall.c      | 2 +-
 linux-user/syscall_defs.h | 3 +++
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index ab15b867ec..42b3ae3725 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -122,6 +122,7 @@
   IOCTL(SIOCDRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
   IOCTL(SIOCSRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
   IOCTL(SIOCGRARP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
+  IOCTL(SIOCGIWNAME, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_char_ifreq)))
 
   IOCTL(CDROMPAUSE, 0, TYPE_NULL)
   IOCTL(CDROMSTART, 0, TYPE_NULL)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 123909f190..5f9061d498 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -59,7 +59,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 //#include <sys/user.h>
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
-#include <net/if.h>
+#include <linux/wireless.h>
 #include <qemu-common.h>
 #ifdef TARGET_GPROF
 #include <sys/gmon.h>
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index bde89213de..527f31d0c3 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -765,6 +765,9 @@ struct target_pollfd {
 #define TARGET_SIOCADDDLCI     0x8980          /* Create new DLCI device       */
 #define TARGET_SIOCDELDLCI     0x8981          /* Delete DLCI device           */
 
+/* From <linux/wireless.h> */
+
+#define TARGET_SIOCGIWNAME     0x8B01          /* get name == wireless protocol */
 
 /* From <linux/fs.h> */
 

From 42a39fbe0cb6549e9cedfe63e706fdf951126626 Mon Sep 17 00:00:00 2001
From: Alexander Graf <agraf@suse.de>
Date: Fri, 15 Apr 2011 17:32:45 +0200
Subject: [PATCH 318/386] linux-user: add s390x to llseek list

We keep a list of host architectures that do llseek with the same
syscall as lseek. S390x is one of them, so let's add it to the list.

Original-patch-by: Ulrich Hecht <uli@suse.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/syscall.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5f9061d498..e7af2ea1c0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -197,7 +197,8 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,	\
 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
 
-#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
+#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
+    defined(__s390x__)
 #define __NR__llseek __NR_lseek
 #endif
 

From 0c866a7ed47bc8a2df320e59bc669e4784d8ad2f Mon Sep 17 00:00:00 2001
From: Riku Voipio <riku.voipio@iki.fi>
Date: Mon, 18 Apr 2011 15:23:06 +0300
Subject: [PATCH 319/386] linux-user: untie syscalls from UID16

Quite a number of uid/gid related syscalls are only defined on systems
with USE_UID16 defined. This is apperently based on the idea that these
system calls would never be called on non-UID16 systems. Make these
syscalls available for all architectures that define them.

drop alpha hack to support selected UID16 syscalls. MIPS and PowerPC
were also defined as UID16, to get uid/gid syscalls available, drop
this error as well.

Change QEMU to reflect this.

Cc: Ulrich Hecht <uli@suse.de>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Alexander Graf <agraf@suse.de>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/alpha/syscall_nr.h |  7 -----
 linux-user/syscall.c          | 48 ++++++++++++++++++++++++++++-------
 linux-user/syscall_defs.h     |  5 +++-
 3 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/linux-user/alpha/syscall_nr.h b/linux-user/alpha/syscall_nr.h
index 7182223381..e3127df4ac 100644
--- a/linux-user/alpha/syscall_nr.h
+++ b/linux-user/alpha/syscall_nr.h
@@ -412,10 +412,3 @@
 #define TARGET_NR_timerfd			477
 #define TARGET_NR_eventfd			478
 
-/* The following aliases are defined in order to match up with the
-   standard i386 syscalls implemented in syscalls.c.  */
-#define TARGET_NR_chown32	TARGET_NR_chown
-#define TARGET_NR_setuid32	TARGET_NR_setuid
-#define TARGET_NR_setgid32	TARGET_NR_setgid
-#define TARGET_NR_setfsuid32	TARGET_NR_setfsuid
-#define TARGET_NR_setfsgid32	TARGET_NR_setfsgid
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e7af2ea1c0..e969d1b61d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -328,7 +328,7 @@ static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
   return (fchmodat(dirfd, pathname, mode, 0));
 }
 #endif
-#if defined(TARGET_NR_fchownat) && defined(USE_UID16)
+#if defined(TARGET_NR_fchownat)
 static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
     gid_t group, int flags)
 {
@@ -437,7 +437,7 @@ _syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode)
 #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
 _syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
 #endif
-#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
+#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
           uid_t,owner,gid_t,group,int,flags)
 #endif
@@ -4164,7 +4164,31 @@ static inline int low2highgid(int gid)
     else
         return gid;
 }
-
+static inline int tswapid(int id)
+{
+    return tswap16(id);
+}
+#else /* !USE_UID16 */
+static inline int high2lowuid(int uid)
+{
+    return uid;
+}
+static inline int high2lowgid(int gid)
+{
+    return gid;
+}
+static inline int low2highuid(int uid)
+{
+    return uid;
+}
+static inline int low2highgid(int gid)
+{
+    return gid;
+}
+static inline int tswapid(int id)
+{
+    return tswap32(id);
+}
 #endif /* USE_UID16 */
 
 void syscall_init(void)
@@ -6765,25 +6789,32 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             ret = host_to_target_stat64(cpu_env, arg3, &st);
         break;
 #endif
-#ifdef USE_UID16
     case TARGET_NR_lchown:
         if (!(p = lock_user_string(arg1)))
             goto efault;
         ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
         unlock_user(p, arg1, 0);
         break;
+#ifdef TARGET_NR_getuid
     case TARGET_NR_getuid:
         ret = get_errno(high2lowuid(getuid()));
         break;
+#endif
+#ifdef TARGET_NR_getgid
     case TARGET_NR_getgid:
         ret = get_errno(high2lowgid(getgid()));
         break;
+#endif
+#ifdef TARGET_NR_geteuid
     case TARGET_NR_geteuid:
         ret = get_errno(high2lowuid(geteuid()));
         break;
+#endif
+#ifdef TARGET_NR_getegid
     case TARGET_NR_getegid:
         ret = get_errno(high2lowgid(getegid()));
         break;
+#endif
     case TARGET_NR_setreuid:
         ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
         break;
@@ -6793,7 +6824,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_getgroups:
         {
             int gidsetsize = arg1;
-            uint16_t *target_grouplist;
+            target_id *target_grouplist;
             gid_t *grouplist;
             int i;
 
@@ -6806,7 +6837,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 if (!target_grouplist)
                     goto efault;
                 for(i = 0;i < ret; i++)
-                    target_grouplist[i] = tswap16(grouplist[i]);
+                    target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
                 unlock_user(target_grouplist, arg2, gidsetsize * 2);
             }
         }
@@ -6814,7 +6845,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_setgroups:
         {
             int gidsetsize = arg1;
-            uint16_t *target_grouplist;
+            target_id *target_grouplist;
             gid_t *grouplist;
             int i;
 
@@ -6825,7 +6856,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 goto fail;
             }
             for(i = 0;i < gidsetsize; i++)
-                grouplist[i] = tswap16(target_grouplist[i]);
+                grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
             unlock_user(target_grouplist, arg2, 0);
             ret = get_errno(setgroups(gidsetsize, grouplist));
         }
@@ -6901,7 +6932,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_setfsgid:
         ret = get_errno(setfsgid(arg1));
         break;
-#endif /* USE_UID16 */
 
 #ifdef TARGET_NR_lchown32
     case TARGET_NR_lchown32:
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 527f31d0c3..e05ddf9120 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -49,9 +49,12 @@
 #define TARGET_IOC_TYPEBITS	8
 
 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
-    || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS) || defined(TARGET_PPC) || defined(TARGET_MIPS)
+    || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
     /* 16 bit uid wrappers emulation */
 #define USE_UID16
+#define target_id uint16_t
+#else
+#define target_id uint32_t
 #endif
 
 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \

From 1a96dd472c37ceeefc0d488cb7722c6714d2f0b7 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 15 Apr 2011 15:23:59 +0200
Subject: [PATCH 320/386] tracetool: allow ) in trace output string

Be greedy in matching the trailing "\)*" pattern.  Otherwise, all the
text in the trace string up to the last closed parenthesis is taken as
part of the prototype.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 scripts/tracetool | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/tracetool b/scripts/tracetool
index 412f695863..9912f368d2 100755
--- a/scripts/tracetool
+++ b/scripts/tracetool
@@ -51,7 +51,7 @@ get_args()
 {
     local args
     args=${1#*\(}
-    args=${args%\)*}
+    args=${args%%\)*}
     echo "$args"
 }
 

From b4548fcc0314f5e118ed45b5774e9cd99f9a97d3 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Date: Thu, 14 Apr 2011 18:11:00 +0100
Subject: [PATCH 321/386] trace: Remove %s in grlib trace events

Trace events cannot use %s in their format strings because trace
backends vary in how they can deference pointers (if at all).  Recording
const char * values is not meaningful if their contents are not recorded
too.

Change grlib trace events that rely on strings so that they communicate
similar information without using strings.

A follow-up patch explains this limitation and updates docs/tracing.txt.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 hw/grlib_apbuart.c |  2 +-
 hw/grlib_gptimer.c | 29 ++++++++++++++---------------
 hw/grlib_irqmp.c   |  4 ++--
 trace-events       | 10 +++++-----
 4 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c
index 101b150aa5..169a56eb1b 100644
--- a/hw/grlib_apbuart.c
+++ b/hw/grlib_apbuart.c
@@ -133,7 +133,7 @@ grlib_apbuart_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
         break;
     }
 
-    trace_grlib_apbuart_unknown_register("write", addr);
+    trace_grlib_apbuart_writel_unknown(addr, value);
 }
 
 static CPUReadMemoryFunc * const grlib_apbuart_read[] = {
diff --git a/hw/grlib_gptimer.c b/hw/grlib_gptimer.c
index 596a9000a1..99e90336b6 100644
--- a/hw/grlib_gptimer.c
+++ b/hw/grlib_gptimer.c
@@ -165,15 +165,15 @@ static uint32_t grlib_gptimer_readl(void *opaque, target_phys_addr_t addr)
     /* Unit registers */
     switch (addr) {
     case SCALER_OFFSET:
-        trace_grlib_gptimer_readl(-1, "scaler:", unit->scaler);
+        trace_grlib_gptimer_readl(-1, addr, unit->scaler);
         return unit->scaler;
 
     case SCALER_RELOAD_OFFSET:
-        trace_grlib_gptimer_readl(-1, "reload:", unit->reload);
+        trace_grlib_gptimer_readl(-1, addr, unit->reload);
         return unit->reload;
 
     case CONFIG_OFFSET:
-        trace_grlib_gptimer_readl(-1, "config:", unit->config);
+        trace_grlib_gptimer_readl(-1, addr, unit->config);
         return unit->config;
 
     default:
@@ -189,17 +189,16 @@ static uint32_t grlib_gptimer_readl(void *opaque, target_phys_addr_t addr)
         switch (timer_addr) {
         case COUNTER_OFFSET:
             value = ptimer_get_count(unit->timers[id].ptimer);
-            trace_grlib_gptimer_readl(id, "counter value:", value);
+            trace_grlib_gptimer_readl(id, addr, value);
             return value;
 
         case COUNTER_RELOAD_OFFSET:
             value = unit->timers[id].reload;
-            trace_grlib_gptimer_readl(id, "reload value:", value);
+            trace_grlib_gptimer_readl(id, addr, value);
             return value;
 
         case CONFIG_OFFSET:
-            trace_grlib_gptimer_readl(id, "scaler value:",
-                                      unit->timers[id].config);
+            trace_grlib_gptimer_readl(id, addr, unit->timers[id].config);
             return unit->timers[id].config;
 
         default:
@@ -208,7 +207,7 @@ static uint32_t grlib_gptimer_readl(void *opaque, target_phys_addr_t addr)
 
     }
 
-    trace_grlib_gptimer_unknown_register("read", addr);
+    trace_grlib_gptimer_readl(-1, addr, 0);
     return 0;
 }
 
@@ -226,19 +225,19 @@ grlib_gptimer_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
     case SCALER_OFFSET:
         value &= 0xFFFF; /* clean up the value */
         unit->scaler = value;
-        trace_grlib_gptimer_writel(-1, "scaler:", unit->scaler);
+        trace_grlib_gptimer_writel(-1, addr, unit->scaler);
         return;
 
     case SCALER_RELOAD_OFFSET:
         value &= 0xFFFF; /* clean up the value */
         unit->reload = value;
-        trace_grlib_gptimer_writel(-1, "reload:", unit->reload);
+        trace_grlib_gptimer_writel(-1, addr, unit->reload);
         grlib_gptimer_set_scaler(unit, value);
         return;
 
     case CONFIG_OFFSET:
         /* Read Only (disable timer freeze not supported) */
-        trace_grlib_gptimer_writel(-1, "config (Read Only):", 0);
+        trace_grlib_gptimer_writel(-1, addr, 0);
         return;
 
     default:
@@ -253,18 +252,18 @@ grlib_gptimer_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
         /* GPTimer registers */
         switch (timer_addr) {
         case COUNTER_OFFSET:
-            trace_grlib_gptimer_writel(id, "counter:", value);
+            trace_grlib_gptimer_writel(id, addr, value);
             unit->timers[id].counter = value;
             grlib_gptimer_enable(&unit->timers[id]);
             return;
 
         case COUNTER_RELOAD_OFFSET:
-            trace_grlib_gptimer_writel(id, "reload:", value);
+            trace_grlib_gptimer_writel(id, addr, value);
             unit->timers[id].reload = value;
             return;
 
         case CONFIG_OFFSET:
-            trace_grlib_gptimer_writel(id, "config:", value);
+            trace_grlib_gptimer_writel(id, addr, value);
 
             if (value & GPTIMER_INT_PENDING) {
                 /* clear pending bit */
@@ -297,7 +296,7 @@ grlib_gptimer_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
 
     }
 
-    trace_grlib_gptimer_unknown_register("write", addr);
+    trace_grlib_gptimer_writel(-1, addr, value);
 }
 
 static CPUReadMemoryFunc * const grlib_gptimer_read[] = {
diff --git a/hw/grlib_irqmp.c b/hw/grlib_irqmp.c
index f47c491a48..b8738fc04d 100644
--- a/hw/grlib_irqmp.c
+++ b/hw/grlib_irqmp.c
@@ -220,7 +220,7 @@ static uint32_t grlib_irqmp_readl(void *opaque, target_phys_addr_t addr)
         return state->extended[cpu];
     }
 
-    trace_grlib_irqmp_unknown_register("read", addr);
+    trace_grlib_irqmp_readl_unknown(addr);
     return 0;
 }
 
@@ -308,7 +308,7 @@ grlib_irqmp_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
         return;
     }
 
-    trace_grlib_irqmp_unknown_register("write", addr);
+    trace_grlib_irqmp_writel_unknown(addr, value);
 }
 
 static CPUReadMemoryFunc * const grlib_irqmp_read[] = {
diff --git a/trace-events b/trace-events
index 703b745bc4..8272c86c6a 100644
--- a/trace-events
+++ b/trace-events
@@ -235,19 +235,19 @@ disable grlib_gptimer_disabled(int id, uint32_t config) "timer:%d Timer disable
 disable grlib_gptimer_restart(int id, uint32_t reload) "timer:%d reload val: 0x%x"
 disable grlib_gptimer_set_scaler(uint32_t scaler, uint32_t freq) "scaler:0x%x freq: 0x%x"
 disable grlib_gptimer_hit(int id) "timer:%d HIT"
-disable grlib_gptimer_readl(int id, const char *s, uint32_t val) "timer:%d %s 0x%x"
-disable grlib_gptimer_writel(int id, const char *s, uint32_t val) "timer:%d %s 0x%x"
-disable grlib_gptimer_unknown_register(const char *op, uint64_t val) "%s unknown register 0x%"PRIx64""
+disable grlib_gptimer_readl(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
+disable grlib_gptimer_writel(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
 
 # hw/grlib_irqmp.c
 disable grlib_irqmp_check_irqs(uint32_t pend, uint32_t force, uint32_t mask, uint32_t lvl1, uint32_t lvl2) "pend:0x%04x force:0x%04x mask:0x%04x lvl1:0x%04x lvl0:0x%04x\n"
 disable grlib_irqmp_ack(int intno) "interrupt:%d"
 disable grlib_irqmp_set_irq(int irq) "Raise CPU IRQ %d"
-disable grlib_irqmp_unknown_register(const char *op, uint64_t val) "%s unknown register 0x%"PRIx64""
+disable grlib_irqmp_readl_unknown(uint64_t addr) "addr 0x%"PRIx64""
+disable grlib_irqmp_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
 
 # hw/grlib_apbuart.c
 disable grlib_apbuart_event(int event) "event:%d"
-disable grlib_apbuart_unknown_register(const char *op, uint64_t val) "%s unknown register 0x%"PRIx64""
+disable grlib_apbuart_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
 
 # hw/leon3.c
 disable leon3_set_irq(int intno) "Set CPU IRQ %d"

From e6a750aab57e4dccefd6291dba4fee6b9b3bf9ee Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Date: Thu, 14 Apr 2011 18:24:50 +0100
Subject: [PATCH 322/386] docs: Trace events must not expect pointer
 dereferencing

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 docs/tracing.txt | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/docs/tracing.txt b/docs/tracing.txt
index f15069c96b..905a0837db 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -69,6 +69,11 @@ Trace events should use types as follows:
    cannot include all user-defined struct declarations and it is therefore
    necessary to use void * for pointers to structs.
 
+   Pointers (including char *) cannot be dereferenced easily (or at all) in
+   some trace backends.  If pointers are used, ensure they are meaningful by
+   themselves and do not assume the data they point to will be traced.  Do
+   not pass in string arguments.
+
  * For everything else, use primitive scalar types (char, int, long) with the
    appropriate signedness.
 

From 7b92e5bc6d7a61e9e7669b679a87480a6d1ad1a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Llu=C3=ADs?= <xscript@gmx.net>
Date: Wed, 6 Apr 2011 20:33:56 +0200
Subject: [PATCH 323/386] docs/tracing.txt: minor documentation fixes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 docs/tracing.txt | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/docs/tracing.txt b/docs/tracing.txt
index 905a0837db..c99a0f27cf 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -26,14 +26,14 @@ for debugging, profiling, and observing execution.
 
 == Trace events ==
 
-There is a set of static trace events declared in the trace-events source
+There is a set of static trace events declared in the "trace-events" source
 file.  Each trace event declaration names the event, its arguments, and the
 format string which can be used for pretty-printing:
 
     qemu_malloc(size_t size, void *ptr) "size %zu ptr %p"
     qemu_free(void *ptr) "ptr %p"
 
-The trace-events file is processed by the tracetool script during build to
+The "trace-events" file is processed by the "tracetool" script during build to
 generate code for the trace events.  Trace events are invoked directly from
 source code like this:
 
@@ -52,10 +52,10 @@ source code like this:
 
 === Declaring trace events ===
 
-The tracetool script produces the trace.h header file which is included by
+The "tracetool" script produces the trace.h header file which is included by
 every source file that uses trace events.  Since many source files include
-trace.h, it uses a minimum of types and other header files included to keep
-the namespace clean and compile times and dependencies down.
+trace.h, it uses a minimum of types and other header files included to keep the
+namespace clean and compile times and dependencies down.
 
 Trace events should use types as follows:
 
@@ -110,10 +110,10 @@ portability macros, ensure they are preceded and followed by double quotes:
 
 == Trace backends ==
 
-The tracetool script automates tedious trace event code generation and also
+The "tracetool" script automates tedious trace event code generation and also
 keeps the trace event declarations independent of the trace backend.  The trace
 events are not tightly coupled to a specific trace backend, such as LTTng or
-SystemTap.  Support for trace backends can be added by extending the tracetool
+SystemTap.  Support for trace backends can be added by extending the "tracetool"
 script.
 
 The trace backend is chosen at configure time and only one trace backend can
@@ -181,12 +181,12 @@ events at runtime inside QEMU:
 ==== Analyzing trace files ====
 
 The "simple" backend produces binary trace files that can be formatted with the
-simpletrace.py script.  The script takes the trace-events file and the binary
+simpletrace.py script.  The script takes the "trace-events" file and the binary
 trace:
 
     ./simpletrace.py trace-events trace-12345
 
-You must ensure that the same trace-events file was used to build QEMU,
+You must ensure that the same "trace-events" file was used to build QEMU,
 otherwise trace event declarations may have changed and output will not be
 consistent.
 

From fa2d480a20345b8f10881712dbcf3f5f48b5905b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Llu=C3=ADs?= <xscript@gmx.net>
Date: Wed, 6 Apr 2011 20:34:03 +0200
Subject: [PATCH 324/386] trace: [ust] fix generation of 'trace.c' on events
 without args
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 scripts/tracetool | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/scripts/tracetool b/scripts/tracetool
index 9912f368d2..2155a57df2 100755
--- a/scripts/tracetool
+++ b/scripts/tracetool
@@ -338,6 +338,7 @@ linetoc_ust()
     name=$(get_name "$1")
     args=$(get_args "$1")
     argnames=$(get_argnames "$1", ",")
+    [ -z "$argnames" ] || argnames=", $argnames"
     fmt=$(get_fmt "$1")
 
     cat <<EOF
@@ -345,7 +346,7 @@ DEFINE_TRACE(ust_$name);
 
 static void ust_${name}_probe($args)
 {
-    trace_mark(ust, $name, "$fmt", $argnames);
+    trace_mark(ust, $name, "$fmt"$argnames);
 }
 EOF
 
@@ -488,7 +489,7 @@ EOF
         cat <<EOF
   $arg = \$arg$i;
 EOF
-	i="$((i+1))"
+        i="$((i+1))"
     done
 
     cat <<EOF
@@ -585,7 +586,7 @@ tracetostap()
        exit 1
     fi
     if [ -z "$probeprefix" ]; then
-	probeprefix="qemu.$targettype.$targetarch";
+        probeprefix="qemu.$targettype.$targetarch";
     fi
     echo "/* This file is autogenerated by tracetool, do not edit. */"
     convert stap

From 2b287af620ac634a156a1c4dd68e937aacbcb144 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Llu=C3=ADs?= <xscript@gmx.net>
Date: Wed, 6 Apr 2011 20:34:11 +0200
Subject: [PATCH 325/386] trace: [trace-events] fix print formats in some
 events
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 trace-events | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/trace-events b/trace-events
index 8272c86c6a..77c96a5978 100644
--- a/trace-events
+++ b/trace-events
@@ -254,8 +254,8 @@ disable leon3_set_irq(int intno) "Set CPU IRQ %d"
 disable leon3_reset_irq(int intno) "Reset CPU IRQ %d"
 
 # spice-qemu-char.c
-disable spice_vmc_write(ssize_t out, int len) "spice wrottn %lu of requested %zd"
-disable spice_vmc_read(int bytes, int len) "spice read %lu of requested %zd"
+disable spice_vmc_write(ssize_t out, int len) "spice wrottn %zd of requested %d"
+disable spice_vmc_read(int bytes, int len) "spice read %d of requested %d"
 disable spice_vmc_register_interface(void *scd) "spice vmc registered interface %p"
 disable spice_vmc_unregister_interface(void *scd) "spice vmc unregistered interface %p"
 

From 71785abaea26e185f7dc19ab376c0ed51d469d90 Mon Sep 17 00:00:00 2001
From: Brad Hards <bradh@frogmouth.net>
Date: Sat, 23 Apr 2011 21:50:06 +1000
Subject: [PATCH 326/386] vl: trivial spelling fix

Signed-off-by: Brad Hards <bradh@frogmouth.net>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 vl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/vl.c b/vl.c
index 68c3b532bc..b46ee663bf 100644
--- a/vl.c
+++ b/vl.c
@@ -756,7 +756,7 @@ void add_boot_device_path(int32_t bootindex, DeviceState *dev,
 
 /*
  * This function returns null terminated string that consist of new line
- * separated device pathes.
+ * separated device paths.
  *
  * memory pointed by "size" is assigned total length of the array in bytes
  *

From 19e83f6bdf86f92ee90db77d606affe5b08f8b40 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Tue, 26 Apr 2011 16:56:40 +0100
Subject: [PATCH 327/386] configure: Make epoll_create1 test work around SPARC
 glibc bug

Work around a SPARC glibc bug which caused the epoll_create1 configure
test to wrongly claim that the function was present. Some versions of
SPARC glibc provided the function in the library but didn't declare
it in the include file; the result is that gcc warns about an implicit
declaration but a link succeeds. So we reference the function as a
value rather than a function call to induce a compile time error
if the declaration was not present.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 configure | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index de44bac1d6..2bbbbf5daa 100755
--- a/configure
+++ b/configure
@@ -2225,7 +2225,15 @@ cat > $TMPC << EOF
 
 int main(void)
 {
-    epoll_create1(0);
+    /* Note that we use epoll_create1 as a value, not as
+     * a function being called. This is necessary so that on
+     * old SPARC glibc versions where the function was present in
+     * the library but not declared in the header file we will
+     * fail the configure check. (Otherwise we will get a compiler
+     * warning but not an error, and will proceed to fail the
+     * qemu compile where we compile with -Werror.)
+     */
+    epoll_create1;
     return 0;
 }
 EOF

From de3a354a8323296f200a76c0de5984c4d14c0a9e Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Tue, 26 Apr 2011 00:24:07 +0200
Subject: [PATCH 328/386] configure: support target dependent linking

This patch is the first attempt to make configure more intelligent with
regard to how it links to libraries. It divides the softmmu libraries into
two lists, a general one and a list which depends on the target
architecture.

Signed-off-by: Michael Walle <michael@walle.cc>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Acked-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 configure | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index 2bbbbf5daa..2c957963e4 100755
--- a/configure
+++ b/configure
@@ -1946,11 +1946,11 @@ int main(void) { return 0; }
 EOF
   if compile_prog "" "$fdt_libs" ; then
     fdt=yes
-    libs_softmmu="$fdt_libs $libs_softmmu"
   else
     if test "$fdt" = "yes" ; then
       feature_not_found "fdt"
     fi
+    fdt_libs=
     fdt=no
   fi
 fi
@@ -1967,11 +1967,11 @@ int main(void) { GL_VERSION; return 0; }
 EOF
   if compile_prog "" "-lGL" ; then
     opengl=yes
-       libs_softmmu="$opengl_libs $libs_softmmu"
   else
     if test "$opengl" = "yes" ; then
       feature_not_found "opengl"
     fi
+    opengl_libs=
     opengl=no
   fi
 fi
@@ -3079,6 +3079,7 @@ target_short_alignment=2
 target_int_alignment=4
 target_long_alignment=4
 target_llong_alignment=8
+target_libs_softmmu=
 
 TARGET_ARCH="$target_arch2"
 TARGET_BASE_ARCH=""
@@ -3112,6 +3113,7 @@ case "$target_arch2" in
   ;;
   lm32)
     target_phys_bits=32
+    target_libs_softmmu="$opengl_libs"
   ;;
   m68k)
     bflt="yes"
@@ -3126,6 +3128,7 @@ case "$target_arch2" in
     bflt="yes"
     target_nptl="yes"
     target_phys_bits=32
+    target_libs_softmmu="$fdt_libs"
   ;;
   mips|mipsel)
     TARGET_ARCH=mips
@@ -3150,6 +3153,7 @@ case "$target_arch2" in
     gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
     target_phys_bits=32
     target_nptl="yes"
+    target_libs_softmmu="$fdt_libs"
   ;;
   ppcemb)
     TARGET_BASE_ARCH=ppc
@@ -3157,6 +3161,7 @@ case "$target_arch2" in
     gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
     target_phys_bits=64
     target_nptl="yes"
+    target_libs_softmmu="$fdt_libs"
   ;;
   ppc64)
     TARGET_BASE_ARCH=ppc
@@ -3164,6 +3169,7 @@ case "$target_arch2" in
     gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
     target_phys_bits=64
     target_long_alignment=8
+    target_libs_softmmu="$fdt_libs"
   ;;
   ppc64abi32)
     TARGET_ARCH=ppc64
@@ -3172,6 +3178,7 @@ case "$target_arch2" in
     echo "TARGET_ABI32=y" >> $config_target_mak
     gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
     target_phys_bits=64
+    target_libs_softmmu="$fdt_libs"
   ;;
   sh4|sh4eb)
     TARGET_ARCH=sh4
@@ -3257,7 +3264,7 @@ fi
 if test "$target_softmmu" = "yes" ; then
   echo "TARGET_PHYS_ADDR_BITS=$target_phys_bits" >> $config_target_mak
   echo "CONFIG_SOFTMMU=y" >> $config_target_mak
-  echo "LIBS+=$libs_softmmu" >> $config_target_mak
+  echo "LIBS+=$libs_softmmu $target_libs_softmmu" >> $config_target_mak
   echo "HWDIR=../libhw$target_phys_bits" >> $config_target_mak
   echo "subdir-$target: subdir-libhw$target_phys_bits" >> $config_host_mak
 fi

From 430a3c18064fd3c007048d757e8bd0fff45fcc99 Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Tue, 26 Apr 2011 00:09:01 +0200
Subject: [PATCH 329/386] configure: reenable opengl by default

Because the opengl library is only linked to for the lm32 target, we can
now safely enable opengl by default again.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 configure | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure b/configure
index 2c957963e4..35f7e8b7b2 100755
--- a/configure
+++ b/configure
@@ -177,7 +177,7 @@ spice=""
 rbd=""
 smartcard=""
 smartcard_nss=""
-opengl="no"
+opengl=""
 
 # parse CC options first
 for opt do

From 9a9d9dba3ea45b2bd1539db021ff7c2d7bfc2a98 Mon Sep 17 00:00:00 2001
From: Anthony Liguori <aliguori@us.ibm.com>
Date: Wed, 13 Apr 2011 15:51:47 +0100
Subject: [PATCH 330/386] qemu-img: allow rebase to a NULL backing file when
 unsafe

QEMU can drop a backing file so that an image file no longer depends on
the backing file, but this feature has not been exposed in qemu-img.
This is useful in an image streaming usecase or when an image file has
been fully allocated and no reads can hit the backing file anymore.

Since the dropping the backing file can make the image unusable, only
allow this when the unsafe flag has been set.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qemu-img.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qemu-img.c b/qemu-img.c
index d9c2c12fa0..ed5ba91117 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1240,7 +1240,7 @@ static int img_rebase(int argc, char **argv)
         }
     }
 
-    if ((optind >= argc) || !out_baseimg) {
+    if ((optind >= argc) || (!unsafe && !out_baseimg)) {
         help();
     }
     filename = argv[optind++];

From 45c7b37fb9c452bcc6fce0ac429ea1d1aa1f9e51 Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Thu, 24 Mar 2011 21:31:24 +0100
Subject: [PATCH 331/386] qemu-timer: Add and use new function
 qemu_timer_expired_ns

This simply moves code which is used three times
into a new function thus improving readability.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 qemu-timer.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/qemu-timer.c b/qemu-timer.c
index b8c0c8870d..f771697574 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -183,6 +183,11 @@ struct qemu_alarm_timer {
 
 static struct qemu_alarm_timer *alarm_timer;
 
+static bool qemu_timer_expired_ns(QEMUTimer *timer_head, int64_t current_time)
+{
+    return timer_head && (timer_head->expire_time <= current_time);
+}
+
 int qemu_alarm_pending(void)
 {
     return alarm_timer->pending;
@@ -528,10 +533,9 @@ static void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
     pt = &active_timers[ts->clock->type];
     for(;;) {
         t = *pt;
-        if (!t)
-            break;
-        if (t->expire_time > expire_time)
+        if (!qemu_timer_expired_ns(t, expire_time)) {
             break;
+        }
         pt = &t->next;
     }
     ts->expire_time = expire_time;
@@ -570,9 +574,7 @@ int qemu_timer_pending(QEMUTimer *ts)
 
 int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
 {
-    if (!timer_head)
-        return 0;
-    return (timer_head->expire_time <= current_time * timer_head->scale);
+    return qemu_timer_expired_ns(timer_head, current_time * timer_head->scale);
 }
 
 static void qemu_run_timers(QEMUClock *clock)
@@ -587,8 +589,9 @@ static void qemu_run_timers(QEMUClock *clock)
     ptimer_head = &active_timers[clock->type];
     for(;;) {
         ts = *ptimer_head;
-        if (!ts || ts->expire_time > current_time)
+        if (!qemu_timer_expired_ns(ts, current_time)) {
             break;
+        }
         /* remove timer from the list before calling the callback */
         *ptimer_head = ts->next;
         ts->next = NULL;

From 2821d0f3abe408ea656898828efb8573ac60f4f4 Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Wed, 6 Apr 2011 22:22:48 +0200
Subject: [PATCH 332/386] qemu-timer: Remove unneeded include statement (w32)

mmsystem.h is not needed in qemu-timer.h, so remove it.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 qemu-timer.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/qemu-timer.h b/qemu-timer.h
index 2cacf65535..06cbe20914 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -7,7 +7,6 @@
 
 #ifdef _WIN32
 #include <windows.h>
-#include <mmsystem.h>
 #endif
 
 /* timers */

From cd0544ee550cb125d752f765e9d9e7c3fdf464b2 Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Sun, 10 Apr 2011 20:15:09 +0200
Subject: [PATCH 333/386] qemu-timer: Avoid type casts

The type casts are no longer needed after some small changes
in struct qemu_alarm_timer. This also improves readability
of the code.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 qemu-timer.c | 42 ++++++++++++++++++++++--------------------
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/qemu-timer.c b/qemu-timer.c
index f771697574..e8e5e15c8e 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -175,8 +175,12 @@ struct qemu_alarm_timer {
     int (*start)(struct qemu_alarm_timer *t);
     void (*stop)(struct qemu_alarm_timer *t);
     void (*rearm)(struct qemu_alarm_timer *t);
-    void *priv;
-
+#if defined(__linux__)
+    int fd;
+    timer_t timer;
+#elif defined(_WIN32)
+    HANDLE timer;
+#endif
     char expired;
     char pending;
 };
@@ -295,18 +299,16 @@ static struct qemu_alarm_timer alarm_timers[] = {
 #ifndef _WIN32
 #ifdef __linux__
     {"dynticks", dynticks_start_timer,
-     dynticks_stop_timer, dynticks_rearm_timer, NULL},
+     dynticks_stop_timer, dynticks_rearm_timer},
     /* HPET - if available - is preferred */
-    {"hpet", hpet_start_timer, hpet_stop_timer, NULL, NULL},
+    {"hpet", hpet_start_timer, hpet_stop_timer, NULL},
     /* ...otherwise try RTC */
-    {"rtc", rtc_start_timer, rtc_stop_timer, NULL, NULL},
+    {"rtc", rtc_start_timer, rtc_stop_timer, NULL},
 #endif
-    {"unix", unix_start_timer, unix_stop_timer, NULL, NULL},
+    {"unix", unix_start_timer, unix_stop_timer, NULL},
 #else
-    {"dynticks", win32_start_timer,
-     win32_stop_timer, win32_rearm_timer, NULL},
-    {"win32", win32_start_timer,
-     win32_stop_timer, NULL, NULL},
+    {"dynticks", win32_start_timer, win32_stop_timer, win32_rearm_timer},
+    {"win32", win32_start_timer, win32_stop_timer, NULL},
 #endif
     {NULL, }
 };
@@ -864,7 +866,7 @@ static int hpet_start_timer(struct qemu_alarm_timer *t)
         goto fail;
 
     enable_sigio_timer(fd);
-    t->priv = (void *)(long)fd;
+    t->fd = fd;
 
     return 0;
 fail:
@@ -874,7 +876,7 @@ fail:
 
 static void hpet_stop_timer(struct qemu_alarm_timer *t)
 {
-    int fd = (long)t->priv;
+    int fd = t->fd;
 
     close(fd);
 }
@@ -903,14 +905,14 @@ static int rtc_start_timer(struct qemu_alarm_timer *t)
 
     enable_sigio_timer(rtc_fd);
 
-    t->priv = (void *)(long)rtc_fd;
+    t->fd = rtc_fd;
 
     return 0;
 }
 
 static void rtc_stop_timer(struct qemu_alarm_timer *t)
 {
-    int rtc_fd = (long)t->priv;
+    int rtc_fd = t->fd;
 
     close(rtc_fd);
 }
@@ -945,21 +947,21 @@ static int dynticks_start_timer(struct qemu_alarm_timer *t)
         return -1;
     }
 
-    t->priv = (void *)(long)host_timer;
+    t->timer = host_timer;
 
     return 0;
 }
 
 static void dynticks_stop_timer(struct qemu_alarm_timer *t)
 {
-    timer_t host_timer = (timer_t)(long)t->priv;
+    timer_t host_timer = t->timer;
 
     timer_delete(host_timer);
 }
 
 static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
 {
-    timer_t host_timer = (timer_t)(long)t->priv;
+    timer_t host_timer = t->timer;
     struct itimerspec timeout;
     int64_t nearest_delta_ns = INT64_MAX;
     int64_t current_ns;
@@ -1061,13 +1063,13 @@ static int win32_start_timer(struct qemu_alarm_timer *t)
         return -1;
     }
 
-    t->priv = (PVOID) hTimer;
+    t->timer = hTimer;
     return 0;
 }
 
 static void win32_stop_timer(struct qemu_alarm_timer *t)
 {
-    HANDLE hTimer = t->priv;
+    HANDLE hTimer = t->timer;
 
     if (hTimer) {
         DeleteTimerQueueTimer(NULL, hTimer, NULL);
@@ -1076,7 +1078,7 @@ static void win32_stop_timer(struct qemu_alarm_timer *t)
 
 static void win32_rearm_timer(struct qemu_alarm_timer *t)
 {
-    HANDLE hTimer = t->priv;
+    HANDLE hTimer = t->timer;
     int nearest_delta_ms;
     BOOLEAN success;
 

From 2f9cba0c148af32fad6813480f5c92efe17c2d49 Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Tue, 5 Apr 2011 18:34:21 +0200
Subject: [PATCH 334/386] qemu-timer: Fix timers for w32

Commit 68c23e5520e8286d79d96ab47c0ea722ceb75041 removed the
multimedia timer, but this timer is needed for certain
Linux kernels. Otherwise Linux boot stops with this error:

    MP-BIOS bug: 8254 timer not connected to IO-APIC

So the multimedia timer is added again here.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 qemu-timer.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 96 insertions(+)

diff --git a/qemu-timer.c b/qemu-timer.c
index e8e5e15c8e..4141b6edbe 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -215,6 +215,10 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
 
 #ifdef _WIN32
 
+static int mm_start_timer(struct qemu_alarm_timer *t);
+static void mm_stop_timer(struct qemu_alarm_timer *t);
+static void mm_rearm_timer(struct qemu_alarm_timer *t);
+
 static int win32_start_timer(struct qemu_alarm_timer *t);
 static void win32_stop_timer(struct qemu_alarm_timer *t);
 static void win32_rearm_timer(struct qemu_alarm_timer *t);
@@ -307,6 +311,8 @@ static struct qemu_alarm_timer alarm_timers[] = {
 #endif
     {"unix", unix_start_timer, unix_stop_timer, NULL},
 #else
+    {"mmtimer", mm_start_timer, mm_stop_timer, NULL},
+    {"mmtimer2", mm_start_timer, mm_stop_timer, mm_rearm_timer},
     {"dynticks", win32_start_timer, win32_stop_timer, win32_rearm_timer},
     {"win32", win32_start_timer, win32_stop_timer, NULL},
 #endif
@@ -1040,6 +1046,96 @@ static void unix_stop_timer(struct qemu_alarm_timer *t)
 
 #ifdef _WIN32
 
+static MMRESULT mm_timer;
+static unsigned mm_period;
+
+static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg,
+                                      DWORD_PTR dwUser, DWORD_PTR dw1,
+                                      DWORD_PTR dw2)
+{
+    struct qemu_alarm_timer *t = alarm_timer;
+    if (!t) {
+        return;
+    }
+    if (alarm_has_dynticks(t) || qemu_next_alarm_deadline() <= 0) {
+        t->expired = alarm_has_dynticks(t);
+        t->pending = 1;
+        qemu_notify_event();
+    }
+}
+
+static int mm_start_timer(struct qemu_alarm_timer *t)
+{
+    TIMECAPS tc;
+    UINT flags;
+
+    memset(&tc, 0, sizeof(tc));
+    timeGetDevCaps(&tc, sizeof(tc));
+
+    mm_period = tc.wPeriodMin;
+    timeBeginPeriod(mm_period);
+
+    flags = TIME_CALLBACK_FUNCTION;
+    if (alarm_has_dynticks(t)) {
+        flags |= TIME_ONESHOT;
+    } else {
+        flags |= TIME_PERIODIC;
+    }
+
+    mm_timer = timeSetEvent(1,                  /* interval (ms) */
+                            mm_period,          /* resolution */
+                            mm_alarm_handler,   /* function */
+                            (DWORD_PTR)t,       /* parameter */
+                            flags);
+
+    if (!mm_timer) {
+        fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
+                GetLastError());
+        timeEndPeriod(mm_period);
+        return -1;
+    }
+
+    return 0;
+}
+
+static void mm_stop_timer(struct qemu_alarm_timer *t)
+{
+    timeKillEvent(mm_timer);
+    timeEndPeriod(mm_period);
+}
+
+static void mm_rearm_timer(struct qemu_alarm_timer *t)
+{
+    int nearest_delta_ms;
+
+    assert(alarm_has_dynticks(t));
+    if (!active_timers[QEMU_CLOCK_REALTIME] &&
+        !active_timers[QEMU_CLOCK_VIRTUAL] &&
+        !active_timers[QEMU_CLOCK_HOST]) {
+        return;
+    }
+
+    timeKillEvent(mm_timer);
+
+    nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000;
+    if (nearest_delta_ms < 1) {
+        nearest_delta_ms = 1;
+    }
+    mm_timer = timeSetEvent(nearest_delta_ms,
+                            mm_period,
+                            mm_alarm_handler,
+                            (DWORD_PTR)t,
+                            TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
+
+    if (!mm_timer) {
+        fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n",
+                GetLastError());
+
+        timeEndPeriod(mm_period);
+        exit(1);
+    }
+}
+
 static int win32_start_timer(struct qemu_alarm_timer *t)
 {
     HANDLE hTimer;

From 4b9b7092b4cbef084138a446b8247ba89fd474f4 Mon Sep 17 00:00:00 2001
From: Amit Shah <amit.shah@redhat.com>
Date: Mon, 18 Apr 2011 17:15:46 +0530
Subject: [PATCH 335/386] atapi: Add 'medium ready' to 'medium not ready'
 transition on cd change

MMC-5 Table F.1 lists errors that can be thrown for the TEST_UNIT_READY
command.  Going from medium not ready to medium ready states is
communicated by throwing an error.

This adds the missing 'tray opened' event that we fail to report to
guests.  After doing this, older Linux guests properly revalidate a disc
on the change command.  HSM violation errors, which caused Linux guests
to do a soft-reset of the link, also go away:

ata2.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6
sr 1:0:0:0: CDB: Test Unit Ready: 00 00 00 00 00 00
ata2.00: cmd a0/00:00:00:00:00/00:00:00:00:00/a0 tag 0
         res 01/60:00:00:00:00/00:00:00:00:00/a0 Emask 0x3 (HSM violation)
ata2.00: status: { ERR }
ata2: soft resetting link
ata2.00: configured for MWDMA2
ata2: EH complete

Signed-off-by: Amit Shah <amit.shah@redhat.com>
Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Tested-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/core.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index f028ddb495..d8c613ae0d 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1248,12 +1248,19 @@ static void ide_atapi_cmd(IDEState *s)
         ide_atapi_cmd_check_status(s);
         return;
     }
+    if (bdrv_is_inserted(s->bs) && s->cdrom_changed) {
+        ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+
+        s->cdrom_changed = 0;
+        s->sense_key = SENSE_UNIT_ATTENTION;
+        s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED;
+        return;
+    }
     switch(s->io_buffer[0]) {
     case GPCMD_TEST_UNIT_READY:
-        if (bdrv_is_inserted(s->bs) && !s->cdrom_changed) {
+        if (bdrv_is_inserted(s->bs)) {
             ide_atapi_cmd_ok(s);
         } else {
-            s->cdrom_changed = 0;
             ide_atapi_cmd_error(s, SENSE_NOT_READY,
                                 ASC_MEDIUM_NOT_PRESENT);
         }
@@ -1734,8 +1741,13 @@ static void cdrom_change_cb(void *opaque, int reason)
     bdrv_get_geometry(s->bs, &nb_sectors);
     s->nb_sectors = nb_sectors;
 
-    s->sense_key = SENSE_UNIT_ATTENTION;
-    s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED;
+    /*
+     * First indicate to the guest that a CD has been removed.  That's
+     * done on the next command the guest sends us.
+     *
+     * Then we set SENSE_UNIT_ATTENTION, by which the guest will
+     * detect a new CD in the drive.  See ide_atapi_cmd() for details.
+     */
     s->cdrom_changed = 1;
     s->events.new_media = true;
     ide_set_irq(s->bus);

From ff5c52a379b9fddaf512907e9ffdc275a722e65a Mon Sep 17 00:00:00 2001
From: Avishay Traeger <AVISHAY@il.ibm.com>
Date: Sun, 3 Apr 2011 11:31:45 +0300
Subject: [PATCH 336/386] Improve accuracy of block migration bandwidth
 calculation

block_mig_state.total_time is currently the sum of the read request
latencies.  This is not very accurate because block migration uses aio and
so several requests can be submitted at once.  Bandwidth should be computed
with wall-clock time, not by adding the latencies.  In this case,
"total_time" has a higher value than it should, and so the computed
bandwidth is lower than it is in reality.  This means that migration can
take longer than it needs to.
However, we don't want to use pure wall-clock time here.  We are computing
bandwidth in the asynchronous phase, where the migration repeatedly wakes
up and sends some aio requests.  The computed bandwidth will be used for
synchronous transfer.

Signed-off-by: Avishay Traeger <avishay@il.ibm.com>
Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block-migration.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/block-migration.c b/block-migration.c
index 576e55a6a3..8d06a23649 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -62,7 +62,6 @@ typedef struct BlkMigBlock {
     QEMUIOVector qiov;
     BlockDriverAIOCB *aiocb;
     int ret;
-    int64_t time;
     QSIMPLEQ_ENTRY(BlkMigBlock) entry;
 } BlkMigBlock;
 
@@ -78,6 +77,7 @@ typedef struct BlkMigState {
     int prev_progress;
     int bulk_completed;
     long double total_time;
+    long double prev_time_offset;
     int reads;
 } BlkMigState;
 
@@ -131,12 +131,6 @@ uint64_t blk_mig_bytes_total(void)
     return sum << BDRV_SECTOR_BITS;
 }
 
-static inline void add_avg_read_time(int64_t time)
-{
-    block_mig_state.reads++;
-    block_mig_state.total_time += time;
-}
-
 static inline long double compute_read_bwidth(void)
 {
     assert(block_mig_state.total_time != 0);
@@ -191,13 +185,14 @@ static void alloc_aio_bitmap(BlkMigDevState *bmds)
 
 static void blk_mig_read_cb(void *opaque, int ret)
 {
+    long double curr_time = qemu_get_clock_ns(rt_clock);
     BlkMigBlock *blk = opaque;
 
     blk->ret = ret;
 
-    blk->time = qemu_get_clock_ns(rt_clock) - blk->time;
-
-    add_avg_read_time(blk->time);
+    block_mig_state.reads++;
+    block_mig_state.total_time += (curr_time - block_mig_state.prev_time_offset);
+    block_mig_state.prev_time_offset = curr_time;
 
     QSIMPLEQ_INSERT_TAIL(&block_mig_state.blk_list, blk, entry);
     bmds_set_aio_inflight(blk->bmds, blk->sector, blk->nr_sectors, 0);
@@ -250,7 +245,9 @@ static int mig_save_device_bulk(Monitor *mon, QEMUFile *f,
     blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE;
     qemu_iovec_init_external(&blk->qiov, &blk->iov, 1);
 
-    blk->time = qemu_get_clock_ns(rt_clock);
+    if (block_mig_state.submitted == 0) {
+        block_mig_state.prev_time_offset = qemu_get_clock_ns(rt_clock);
+    }
 
     blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov,
                                 nr_sectors, blk_mig_read_cb, blk);
@@ -409,7 +406,9 @@ static int mig_save_device_dirty(Monitor *mon, QEMUFile *f,
                 blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE;
                 qemu_iovec_init_external(&blk->qiov, &blk->iov, 1);
 
-                blk->time = qemu_get_clock_ns(rt_clock);
+                if (block_mig_state.submitted == 0) {
+                    block_mig_state.prev_time_offset = qemu_get_clock_ns(rt_clock);
+                }
 
                 blk->aiocb = bdrv_aio_readv(bmds->bs, sector, &blk->qiov,
                                             nr_sectors, blk_mig_read_cb, blk);

From 33231e0e221543759b11a4a79b54b9a88d4b455e Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Mon, 18 Apr 2011 16:45:49 +0200
Subject: [PATCH 337/386] ide: Split atapi.c out

Besides moving code, this patch only fixes some whitespace issues in the moved
code and makes all functions in atapi.c static which can be static.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 Makefile.objs     |    2 +-
 hw/ide/atapi.c    | 1083 +++++++++++++++++++++++++++++++++++++++++++++
 hw/ide/core.c     | 1065 +-------------------------------------------
 hw/ide/internal.h |   10 +
 4 files changed, 1098 insertions(+), 1062 deletions(-)
 create mode 100644 hw/ide/atapi.c

diff --git a/Makefile.objs b/Makefile.objs
index 44ce368d05..1b446958c5 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -242,7 +242,7 @@ hw-obj-$(CONFIG_LAN9118) += lan9118.o
 hw-obj-$(CONFIG_NE2000_ISA) += ne2000-isa.o
 
 # IDE
-hw-obj-$(CONFIG_IDE_CORE) += ide/core.o
+hw-obj-$(CONFIG_IDE_CORE) += ide/core.o ide/atapi.o
 hw-obj-$(CONFIG_IDE_QDEV) += ide/qdev.o
 hw-obj-$(CONFIG_IDE_PCI) += ide/pci.o
 hw-obj-$(CONFIG_IDE_ISA) += ide/isa.o
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
new file mode 100644
index 0000000000..0edfd580f2
--- /dev/null
+++ b/hw/ide/atapi.c
@@ -0,0 +1,1083 @@
+/*
+ * QEMU ATAPI Emulation
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2006 Openedhand Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw/ide/internal.h"
+#include "hw/scsi.h"
+
+static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
+
+static void padstr8(uint8_t *buf, int buf_size, const char *src)
+{
+    int i;
+    for(i = 0; i < buf_size; i++) {
+        if (*src)
+            buf[i] = *src++;
+        else
+            buf[i] = ' ';
+    }
+}
+
+static inline void cpu_to_ube16(uint8_t *buf, int val)
+{
+    buf[0] = val >> 8;
+    buf[1] = val & 0xff;
+}
+
+static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
+{
+    buf[0] = val >> 24;
+    buf[1] = val >> 16;
+    buf[2] = val >> 8;
+    buf[3] = val & 0xff;
+}
+
+static inline int ube16_to_cpu(const uint8_t *buf)
+{
+    return (buf[0] << 8) | buf[1];
+}
+
+static inline int ube32_to_cpu(const uint8_t *buf)
+{
+    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+}
+
+static void lba_to_msf(uint8_t *buf, int lba)
+{
+    lba += 150;
+    buf[0] = (lba / 75) / 60;
+    buf[1] = (lba / 75) % 60;
+    buf[2] = lba % 75;
+}
+
+/* XXX: DVDs that could fit on a CD will be reported as a CD */
+static inline int media_present(IDEState *s)
+{
+    return (s->nb_sectors > 0);
+}
+
+static inline int media_is_dvd(IDEState *s)
+{
+    return (media_present(s) && s->nb_sectors > CD_MAX_SECTORS);
+}
+
+static inline int media_is_cd(IDEState *s)
+{
+    return (media_present(s) && s->nb_sectors <= CD_MAX_SECTORS);
+}
+
+static void cd_data_to_raw(uint8_t *buf, int lba)
+{
+    /* sync bytes */
+    buf[0] = 0x00;
+    memset(buf + 1, 0xff, 10);
+    buf[11] = 0x00;
+    buf += 12;
+    /* MSF */
+    lba_to_msf(buf, lba);
+    buf[3] = 0x01; /* mode 1 data */
+    buf += 4;
+    /* data */
+    buf += 2048;
+    /* XXX: ECC not computed */
+    memset(buf, 0, 288);
+}
+
+static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
+                           int sector_size)
+{
+    int ret;
+
+    switch(sector_size) {
+    case 2048:
+        ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4);
+        break;
+    case 2352:
+        ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
+        if (ret < 0)
+            return ret;
+        cd_data_to_raw(buf, lba);
+        break;
+    default:
+        ret = -EIO;
+        break;
+    }
+    return ret;
+}
+
+void ide_atapi_cmd_ok(IDEState *s)
+{
+    s->error = 0;
+    s->status = READY_STAT | SEEK_STAT;
+    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
+    ide_set_irq(s->bus);
+}
+
+void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
+{
+#ifdef DEBUG_IDE_ATAPI
+    printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc);
+#endif
+    s->error = sense_key << 4;
+    s->status = READY_STAT | ERR_STAT;
+    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
+    s->sense_key = sense_key;
+    s->asc = asc;
+    ide_set_irq(s->bus);
+}
+
+void ide_atapi_io_error(IDEState *s, int ret)
+{
+    /* XXX: handle more errors */
+    if (ret == -ENOMEDIUM) {
+        ide_atapi_cmd_error(s, SENSE_NOT_READY,
+                            ASC_MEDIUM_NOT_PRESENT);
+    } else {
+        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                            ASC_LOGICAL_BLOCK_OOR);
+    }
+}
+
+/* The whole ATAPI transfer logic is handled in this function */
+void ide_atapi_cmd_reply_end(IDEState *s)
+{
+    int byte_count_limit, size, ret;
+#ifdef DEBUG_IDE_ATAPI
+    printf("reply: tx_size=%d elem_tx_size=%d index=%d\n",
+           s->packet_transfer_size,
+           s->elementary_transfer_size,
+           s->io_buffer_index);
+#endif
+    if (s->packet_transfer_size <= 0) {
+        /* end of transfer */
+        ide_transfer_stop(s);
+        s->status = READY_STAT | SEEK_STAT;
+        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
+        ide_set_irq(s->bus);
+#ifdef DEBUG_IDE_ATAPI
+        printf("status=0x%x\n", s->status);
+#endif
+    } else {
+        /* see if a new sector must be read */
+        if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
+            ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
+            if (ret < 0) {
+                ide_transfer_stop(s);
+                ide_atapi_io_error(s, ret);
+                return;
+            }
+            s->lba++;
+            s->io_buffer_index = 0;
+        }
+        if (s->elementary_transfer_size > 0) {
+            /* there are some data left to transmit in this elementary
+               transfer */
+            size = s->cd_sector_size - s->io_buffer_index;
+            if (size > s->elementary_transfer_size)
+                size = s->elementary_transfer_size;
+            s->packet_transfer_size -= size;
+            s->elementary_transfer_size -= size;
+            s->io_buffer_index += size;
+            ide_transfer_start(s, s->io_buffer + s->io_buffer_index - size,
+                               size, ide_atapi_cmd_reply_end);
+        } else {
+            /* a new transfer is needed */
+            s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
+            byte_count_limit = s->lcyl | (s->hcyl << 8);
+#ifdef DEBUG_IDE_ATAPI
+            printf("byte_count_limit=%d\n", byte_count_limit);
+#endif
+            if (byte_count_limit == 0xffff)
+                byte_count_limit--;
+            size = s->packet_transfer_size;
+            if (size > byte_count_limit) {
+                /* byte count limit must be even if this case */
+                if (byte_count_limit & 1)
+                    byte_count_limit--;
+                size = byte_count_limit;
+            }
+            s->lcyl = size;
+            s->hcyl = size >> 8;
+            s->elementary_transfer_size = size;
+            /* we cannot transmit more than one sector at a time */
+            if (s->lba != -1) {
+                if (size > (s->cd_sector_size - s->io_buffer_index))
+                    size = (s->cd_sector_size - s->io_buffer_index);
+            }
+            s->packet_transfer_size -= size;
+            s->elementary_transfer_size -= size;
+            s->io_buffer_index += size;
+            ide_transfer_start(s, s->io_buffer + s->io_buffer_index - size,
+                               size, ide_atapi_cmd_reply_end);
+            ide_set_irq(s->bus);
+#ifdef DEBUG_IDE_ATAPI
+            printf("status=0x%x\n", s->status);
+#endif
+        }
+    }
+}
+
+/* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
+static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
+{
+    if (size > max_size)
+        size = max_size;
+    s->lba = -1; /* no sector read */
+    s->packet_transfer_size = size;
+    s->io_buffer_size = size;    /* dma: send the reply data as one chunk */
+    s->elementary_transfer_size = 0;
+    s->io_buffer_index = 0;
+
+    if (s->atapi_dma) {
+        s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
+        s->bus->dma->ops->start_dma(s->bus->dma, s,
+                                   ide_atapi_cmd_read_dma_cb);
+    } else {
+        s->status = READY_STAT | SEEK_STAT;
+        ide_atapi_cmd_reply_end(s);
+    }
+}
+
+/* start a CD-CDROM read command */
+static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
+                                   int sector_size)
+{
+    s->lba = lba;
+    s->packet_transfer_size = nb_sectors * sector_size;
+    s->elementary_transfer_size = 0;
+    s->io_buffer_index = sector_size;
+    s->cd_sector_size = sector_size;
+
+    s->status = READY_STAT | SEEK_STAT;
+    ide_atapi_cmd_reply_end(s);
+}
+
+static void ide_atapi_cmd_check_status(IDEState *s)
+{
+#ifdef DEBUG_IDE_ATAPI
+    printf("atapi_cmd_check_status\n");
+#endif
+    s->error = MC_ERR | (SENSE_UNIT_ATTENTION << 4);
+    s->status = ERR_STAT;
+    s->nsector = 0;
+    ide_set_irq(s->bus);
+}
+/* ATAPI DMA support */
+
+/* XXX: handle read errors */
+static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
+{
+    IDEState *s = opaque;
+    int data_offset, n;
+
+    if (ret < 0) {
+        ide_atapi_io_error(s, ret);
+        goto eot;
+    }
+
+    if (s->io_buffer_size > 0) {
+        /*
+         * For a cdrom read sector command (s->lba != -1),
+         * adjust the lba for the next s->io_buffer_size chunk
+         * and dma the current chunk.
+         * For a command != read (s->lba == -1), just transfer
+         * the reply data.
+         */
+        if (s->lba != -1) {
+            if (s->cd_sector_size == 2352) {
+                n = 1;
+                cd_data_to_raw(s->io_buffer, s->lba);
+            } else {
+                n = s->io_buffer_size >> 11;
+            }
+            s->lba += n;
+        }
+        s->packet_transfer_size -= s->io_buffer_size;
+        if (s->bus->dma->ops->rw_buf(s->bus->dma, 1) == 0)
+            goto eot;
+    }
+
+    if (s->packet_transfer_size <= 0) {
+        s->status = READY_STAT | SEEK_STAT;
+        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
+        ide_set_irq(s->bus);
+    eot:
+        s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
+        ide_set_inactive(s);
+        return;
+    }
+
+    s->io_buffer_index = 0;
+    if (s->cd_sector_size == 2352) {
+        n = 1;
+        s->io_buffer_size = s->cd_sector_size;
+        data_offset = 16;
+    } else {
+        n = s->packet_transfer_size >> 11;
+        if (n > (IDE_DMA_BUF_SECTORS / 4))
+            n = (IDE_DMA_BUF_SECTORS / 4);
+        s->io_buffer_size = n * 2048;
+        data_offset = 0;
+    }
+#ifdef DEBUG_AIO
+    printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
+#endif
+    s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset);
+    s->bus->dma->iov.iov_len = n * 4 * 512;
+    qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1);
+    s->bus->dma->aiocb = bdrv_aio_readv(s->bs, (int64_t)s->lba << 2,
+                                       &s->bus->dma->qiov, n * 4,
+                                       ide_atapi_cmd_read_dma_cb, s);
+    if (!s->bus->dma->aiocb) {
+        /* Note: media not present is the most likely case */
+        ide_atapi_cmd_error(s, SENSE_NOT_READY,
+                            ASC_MEDIUM_NOT_PRESENT);
+        goto eot;
+    }
+}
+
+/* start a CD-CDROM read command with DMA */
+/* XXX: test if DMA is available */
+static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
+                                   int sector_size)
+{
+    s->lba = lba;
+    s->packet_transfer_size = nb_sectors * sector_size;
+    s->io_buffer_index = 0;
+    s->io_buffer_size = 0;
+    s->cd_sector_size = sector_size;
+
+    /* XXX: check if BUSY_STAT should be set */
+    s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
+    s->bus->dma->ops->start_dma(s->bus->dma, s,
+                               ide_atapi_cmd_read_dma_cb);
+}
+
+static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
+                               int sector_size)
+{
+#ifdef DEBUG_IDE_ATAPI
+    printf("read %s: LBA=%d nb_sectors=%d\n", s->atapi_dma ? "dma" : "pio",
+        lba, nb_sectors);
+#endif
+    if (s->atapi_dma) {
+        ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
+    } else {
+        ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);
+    }
+}
+
+static inline uint8_t ide_atapi_set_profile(uint8_t *buf, uint8_t *index,
+                                            uint16_t profile)
+{
+    uint8_t *buf_profile = buf + 12; /* start of profiles */
+
+    buf_profile += ((*index) * 4); /* start of indexed profile */
+    cpu_to_ube16 (buf_profile, profile);
+    buf_profile[2] = ((buf_profile[0] == buf[6]) && (buf_profile[1] == buf[7]));
+
+    /* each profile adds 4 bytes to the response */
+    (*index)++;
+    buf[11] += 4; /* Additional Length */
+
+    return 4;
+}
+
+static int ide_dvd_read_structure(IDEState *s, int format,
+                                  const uint8_t *packet, uint8_t *buf)
+{
+    switch (format) {
+        case 0x0: /* Physical format information */
+            {
+                int layer = packet[6];
+                uint64_t total_sectors;
+
+                if (layer != 0)
+                    return -ASC_INV_FIELD_IN_CMD_PACKET;
+
+                bdrv_get_geometry(s->bs, &total_sectors);
+                total_sectors >>= 2;
+                if (total_sectors == 0)
+                    return -ASC_MEDIUM_NOT_PRESENT;
+
+                buf[4] = 1;   /* DVD-ROM, part version 1 */
+                buf[5] = 0xf; /* 120mm disc, minimum rate unspecified */
+                buf[6] = 1;   /* one layer, read-only (per MMC-2 spec) */
+                buf[7] = 0;   /* default densities */
+
+                /* FIXME: 0x30000 per spec? */
+                cpu_to_ube32(buf + 8, 0); /* start sector */
+                cpu_to_ube32(buf + 12, total_sectors - 1); /* end sector */
+                cpu_to_ube32(buf + 16, total_sectors - 1); /* l0 end sector */
+
+                /* Size of buffer, not including 2 byte size field */
+                cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
+
+                /* 2k data + 4 byte header */
+                return (2048 + 4);
+            }
+
+        case 0x01: /* DVD copyright information */
+            buf[4] = 0; /* no copyright data */
+            buf[5] = 0; /* no region restrictions */
+
+            /* Size of buffer, not including 2 byte size field */
+            cpu_to_be16wu((uint16_t *)buf, 4 + 2);
+
+            /* 4 byte header + 4 byte data */
+            return (4 + 4);
+
+        case 0x03: /* BCA information - invalid field for no BCA info */
+            return -ASC_INV_FIELD_IN_CMD_PACKET;
+
+        case 0x04: /* DVD disc manufacturing information */
+            /* Size of buffer, not including 2 byte size field */
+            cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
+
+            /* 2k data + 4 byte header */
+            return (2048 + 4);
+
+        case 0xff:
+            /*
+             * This lists all the command capabilities above.  Add new ones
+             * in order and update the length and buffer return values.
+             */
+
+            buf[4] = 0x00; /* Physical format */
+            buf[5] = 0x40; /* Not writable, is readable */
+            cpu_to_be16wu((uint16_t *)(buf + 6), 2048 + 4);
+
+            buf[8] = 0x01; /* Copyright info */
+            buf[9] = 0x40; /* Not writable, is readable */
+            cpu_to_be16wu((uint16_t *)(buf + 10), 4 + 4);
+
+            buf[12] = 0x03; /* BCA info */
+            buf[13] = 0x40; /* Not writable, is readable */
+            cpu_to_be16wu((uint16_t *)(buf + 14), 188 + 4);
+
+            buf[16] = 0x04; /* Manufacturing info */
+            buf[17] = 0x40; /* Not writable, is readable */
+            cpu_to_be16wu((uint16_t *)(buf + 18), 2048 + 4);
+
+            /* Size of buffer, not including 2 byte size field */
+            cpu_to_be16wu((uint16_t *)buf, 16 + 2);
+
+            /* data written + 4 byte header */
+            return (16 + 4);
+
+        default: /* TODO: formats beyond DVD-ROM requires */
+            return -ASC_INV_FIELD_IN_CMD_PACKET;
+    }
+}
+
+static unsigned int event_status_media(IDEState *s,
+                                       uint8_t *buf)
+{
+    enum media_event_code {
+        MEC_NO_CHANGE = 0,       /* Status unchanged */
+        MEC_EJECT_REQUESTED,     /* received a request from user to eject */
+        MEC_NEW_MEDIA,           /* new media inserted and ready for access */
+        MEC_MEDIA_REMOVAL,       /* only for media changers */
+        MEC_MEDIA_CHANGED,       /* only for media changers */
+        MEC_BG_FORMAT_COMPLETED, /* MRW or DVD+RW b/g format completed */
+        MEC_BG_FORMAT_RESTARTED, /* MRW or DVD+RW b/g format restarted */
+    };
+    enum media_status {
+        MS_TRAY_OPEN = 1,
+        MS_MEDIA_PRESENT = 2,
+    };
+    uint8_t event_code, media_status;
+
+    media_status = 0;
+    if (s->bs->tray_open) {
+        media_status = MS_TRAY_OPEN;
+    } else if (bdrv_is_inserted(s->bs)) {
+        media_status = MS_MEDIA_PRESENT;
+    }
+
+    /* Event notification descriptor */
+    event_code = MEC_NO_CHANGE;
+    if (media_status != MS_TRAY_OPEN && s->events.new_media) {
+        event_code = MEC_NEW_MEDIA;
+        s->events.new_media = false;
+    }
+
+    buf[4] = event_code;
+    buf[5] = media_status;
+
+    /* These fields are reserved, just clear them. */
+    buf[6] = 0;
+    buf[7] = 0;
+
+    return 8; /* We wrote to 4 extra bytes from the header */
+}
+
+static void handle_get_event_status_notification(IDEState *s,
+                                                 uint8_t *buf,
+                                                 const uint8_t *packet)
+{
+    struct {
+        uint8_t opcode;
+        uint8_t polled;        /* lsb bit is polled; others are reserved */
+        uint8_t reserved2[2];
+        uint8_t class;
+        uint8_t reserved3[2];
+        uint16_t len;
+        uint8_t control;
+    } __attribute__((packed)) *gesn_cdb;
+
+    struct {
+        uint16_t len;
+        uint8_t notification_class;
+        uint8_t supported_events;
+    } __attribute((packed)) *gesn_event_header;
+
+    enum notification_class_request_type {
+        NCR_RESERVED1 = 1 << 0,
+        NCR_OPERATIONAL_CHANGE = 1 << 1,
+        NCR_POWER_MANAGEMENT = 1 << 2,
+        NCR_EXTERNAL_REQUEST = 1 << 3,
+        NCR_MEDIA = 1 << 4,
+        NCR_MULTI_HOST = 1 << 5,
+        NCR_DEVICE_BUSY = 1 << 6,
+        NCR_RESERVED2 = 1 << 7,
+    };
+    enum event_notification_class_field {
+        ENC_NO_EVENTS = 0,
+        ENC_OPERATIONAL_CHANGE,
+        ENC_POWER_MANAGEMENT,
+        ENC_EXTERNAL_REQUEST,
+        ENC_MEDIA,
+        ENC_MULTIPLE_HOSTS,
+        ENC_DEVICE_BUSY,
+        ENC_RESERVED,
+    };
+    unsigned int max_len, used_len;
+
+    gesn_cdb = (void *)packet;
+    gesn_event_header = (void *)buf;
+
+    max_len = be16_to_cpu(gesn_cdb->len);
+
+    /* It is fine by the MMC spec to not support async mode operations */
+    if (!(gesn_cdb->polled & 0x01)) { /* asynchronous mode */
+        /* Only polling is supported, asynchronous mode is not. */
+        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                            ASC_INV_FIELD_IN_CMD_PACKET);
+        return;
+    }
+
+    /* polling mode operation */
+
+    /*
+     * These are the supported events.
+     *
+     * We currently only support requests of the 'media' type.
+     */
+    gesn_event_header->supported_events = NCR_MEDIA;
+
+    /*
+     * We use |= below to set the class field; other bits in this byte
+     * are reserved now but this is useful to do if we have to use the
+     * reserved fields later.
+     */
+    gesn_event_header->notification_class = 0;
+
+    /*
+     * Responses to requests are to be based on request priority.  The
+     * notification_class_request_type enum above specifies the
+     * priority: upper elements are higher prio than lower ones.
+     */
+    if (gesn_cdb->class & NCR_MEDIA) {
+        gesn_event_header->notification_class |= ENC_MEDIA;
+        used_len = event_status_media(s, buf);
+    } else {
+        gesn_event_header->notification_class = 0x80; /* No event available */
+        used_len = sizeof(*gesn_event_header);
+    }
+    gesn_event_header->len = cpu_to_be16(used_len
+                                         - sizeof(*gesn_event_header));
+    ide_atapi_cmd_reply(s, used_len, max_len);
+}
+
+void ide_atapi_cmd(IDEState *s)
+{
+    const uint8_t *packet;
+    uint8_t *buf;
+    int max_len;
+
+    packet = s->io_buffer;
+    buf = s->io_buffer;
+#ifdef DEBUG_IDE_ATAPI
+    {
+        int i;
+        printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
+        for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
+            printf(" %02x", packet[i]);
+        }
+        printf("\n");
+    }
+#endif
+    /*
+     * If there's a UNIT_ATTENTION condition pending, only
+     * REQUEST_SENSE, INQUIRY, GET_CONFIGURATION and
+     * GET_EVENT_STATUS_NOTIFICATION commands are allowed to complete.
+     * MMC-5, section 4.1.6.1 lists only these commands being allowed
+     * to complete, with other commands getting a CHECK condition
+     * response unless a higher priority status, defined by the drive
+     * here, is pending.
+     */
+    if (s->sense_key == SENSE_UNIT_ATTENTION &&
+        s->io_buffer[0] != GPCMD_REQUEST_SENSE &&
+        s->io_buffer[0] != GPCMD_INQUIRY &&
+        s->io_buffer[0] != GPCMD_GET_EVENT_STATUS_NOTIFICATION) {
+        ide_atapi_cmd_check_status(s);
+        return;
+    }
+    if (bdrv_is_inserted(s->bs) && s->cdrom_changed) {
+        ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+
+        s->cdrom_changed = 0;
+        s->sense_key = SENSE_UNIT_ATTENTION;
+        s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED;
+        return;
+    }
+    switch(s->io_buffer[0]) {
+    case GPCMD_TEST_UNIT_READY:
+        if (bdrv_is_inserted(s->bs)) {
+            ide_atapi_cmd_ok(s);
+        } else {
+            ide_atapi_cmd_error(s, SENSE_NOT_READY,
+                                ASC_MEDIUM_NOT_PRESENT);
+        }
+        break;
+    case GPCMD_MODE_SENSE_6:
+    case GPCMD_MODE_SENSE_10:
+        {
+            int action, code;
+            if (packet[0] == GPCMD_MODE_SENSE_10)
+                max_len = ube16_to_cpu(packet + 7);
+            else
+                max_len = packet[4];
+            action = packet[2] >> 6;
+            code = packet[2] & 0x3f;
+            switch(action) {
+            case 0: /* current values */
+                switch(code) {
+                case GPMODE_R_W_ERROR_PAGE: /* error recovery */
+                    cpu_to_ube16(&buf[0], 16 + 6);
+                    buf[2] = 0x70;
+                    buf[3] = 0;
+                    buf[4] = 0;
+                    buf[5] = 0;
+                    buf[6] = 0;
+                    buf[7] = 0;
+
+                    buf[8] = 0x01;
+                    buf[9] = 0x06;
+                    buf[10] = 0x00;
+                    buf[11] = 0x05;
+                    buf[12] = 0x00;
+                    buf[13] = 0x00;
+                    buf[14] = 0x00;
+                    buf[15] = 0x00;
+                    ide_atapi_cmd_reply(s, 16, max_len);
+                    break;
+                case GPMODE_AUDIO_CTL_PAGE:
+                    cpu_to_ube16(&buf[0], 24 + 6);
+                    buf[2] = 0x70;
+                    buf[3] = 0;
+                    buf[4] = 0;
+                    buf[5] = 0;
+                    buf[6] = 0;
+                    buf[7] = 0;
+
+                    /* Fill with CDROM audio volume */
+                    buf[17] = 0;
+                    buf[19] = 0;
+                    buf[21] = 0;
+                    buf[23] = 0;
+
+                    ide_atapi_cmd_reply(s, 24, max_len);
+                    break;
+                case GPMODE_CAPABILITIES_PAGE:
+                    cpu_to_ube16(&buf[0], 28 + 6);
+                    buf[2] = 0x70;
+                    buf[3] = 0;
+                    buf[4] = 0;
+                    buf[5] = 0;
+                    buf[6] = 0;
+                    buf[7] = 0;
+
+                    buf[8] = 0x2a;
+                    buf[9] = 0x12;
+                    buf[10] = 0x00;
+                    buf[11] = 0x00;
+
+                    /* Claim PLAY_AUDIO capability (0x01) since some Linux
+                       code checks for this to automount media. */
+                    buf[12] = 0x71;
+                    buf[13] = 3 << 5;
+                    buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
+                    if (bdrv_is_locked(s->bs))
+                        buf[6] |= 1 << 1;
+                    buf[15] = 0x00;
+                    cpu_to_ube16(&buf[16], 706);
+                    buf[18] = 0;
+                    buf[19] = 2;
+                    cpu_to_ube16(&buf[20], 512);
+                    cpu_to_ube16(&buf[22], 706);
+                    buf[24] = 0;
+                    buf[25] = 0;
+                    buf[26] = 0;
+                    buf[27] = 0;
+                    ide_atapi_cmd_reply(s, 28, max_len);
+                    break;
+                default:
+                    goto error_cmd;
+                }
+                break;
+            case 1: /* changeable values */
+                goto error_cmd;
+            case 2: /* default values */
+                goto error_cmd;
+            default:
+            case 3: /* saved values */
+                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                                    ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
+                break;
+            }
+        }
+        break;
+    case GPCMD_REQUEST_SENSE:
+        max_len = packet[4];
+        memset(buf, 0, 18);
+        buf[0] = 0x70 | (1 << 7);
+        buf[2] = s->sense_key;
+        buf[7] = 10;
+        buf[12] = s->asc;
+        if (s->sense_key == SENSE_UNIT_ATTENTION)
+            s->sense_key = SENSE_NONE;
+        ide_atapi_cmd_reply(s, 18, max_len);
+        break;
+    case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
+        bdrv_set_locked(s->bs, packet[4] & 1);
+        ide_atapi_cmd_ok(s);
+        break;
+    case GPCMD_READ_10:
+    case GPCMD_READ_12:
+        {
+            int nb_sectors, lba;
+
+            if (packet[0] == GPCMD_READ_10)
+                nb_sectors = ube16_to_cpu(packet + 7);
+            else
+                nb_sectors = ube32_to_cpu(packet + 6);
+            lba = ube32_to_cpu(packet + 2);
+            if (nb_sectors == 0) {
+                ide_atapi_cmd_ok(s);
+                break;
+            }
+            ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
+        }
+        break;
+    case GPCMD_READ_CD:
+        {
+            int nb_sectors, lba, transfer_request;
+
+            nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
+            lba = ube32_to_cpu(packet + 2);
+            if (nb_sectors == 0) {
+                ide_atapi_cmd_ok(s);
+                break;
+            }
+            transfer_request = packet[9];
+            switch(transfer_request & 0xf8) {
+            case 0x00:
+                /* nothing */
+                ide_atapi_cmd_ok(s);
+                break;
+            case 0x10:
+                /* normal read */
+                ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
+                break;
+            case 0xf8:
+                /* read all data */
+                ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
+                break;
+            default:
+                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                                    ASC_INV_FIELD_IN_CMD_PACKET);
+                break;
+            }
+        }
+        break;
+    case GPCMD_SEEK:
+        {
+            unsigned int lba;
+            uint64_t total_sectors;
+
+            bdrv_get_geometry(s->bs, &total_sectors);
+            total_sectors >>= 2;
+            if (total_sectors == 0) {
+                ide_atapi_cmd_error(s, SENSE_NOT_READY,
+                                    ASC_MEDIUM_NOT_PRESENT);
+                break;
+            }
+            lba = ube32_to_cpu(packet + 2);
+            if (lba >= total_sectors) {
+                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                                    ASC_LOGICAL_BLOCK_OOR);
+                break;
+            }
+            ide_atapi_cmd_ok(s);
+        }
+        break;
+    case GPCMD_START_STOP_UNIT:
+        {
+            int start, eject, sense, err = 0;
+            start = packet[4] & 1;
+            eject = (packet[4] >> 1) & 1;
+
+            if (eject) {
+                err = bdrv_eject(s->bs, !start);
+            }
+
+            switch (err) {
+            case 0:
+                ide_atapi_cmd_ok(s);
+                break;
+            case -EBUSY:
+                sense = SENSE_NOT_READY;
+                if (bdrv_is_inserted(s->bs)) {
+                    sense = SENSE_ILLEGAL_REQUEST;
+                }
+                ide_atapi_cmd_error(s, sense,
+                                    ASC_MEDIA_REMOVAL_PREVENTED);
+                break;
+            default:
+                ide_atapi_cmd_error(s, SENSE_NOT_READY,
+                                    ASC_MEDIUM_NOT_PRESENT);
+                break;
+            }
+        }
+        break;
+    case GPCMD_MECHANISM_STATUS:
+        {
+            max_len = ube16_to_cpu(packet + 8);
+            cpu_to_ube16(buf, 0);
+            /* no current LBA */
+            buf[2] = 0;
+            buf[3] = 0;
+            buf[4] = 0;
+            buf[5] = 1;
+            cpu_to_ube16(buf + 6, 0);
+            ide_atapi_cmd_reply(s, 8, max_len);
+        }
+        break;
+    case GPCMD_READ_TOC_PMA_ATIP:
+        {
+            int format, msf, start_track, len;
+            uint64_t total_sectors;
+
+            bdrv_get_geometry(s->bs, &total_sectors);
+            total_sectors >>= 2;
+            if (total_sectors == 0) {
+                ide_atapi_cmd_error(s, SENSE_NOT_READY,
+                                    ASC_MEDIUM_NOT_PRESENT);
+                break;
+            }
+            max_len = ube16_to_cpu(packet + 7);
+            format = packet[9] >> 6;
+            msf = (packet[1] >> 1) & 1;
+            start_track = packet[6];
+            switch(format) {
+            case 0:
+                len = cdrom_read_toc(total_sectors, buf, msf, start_track);
+                if (len < 0)
+                    goto error_cmd;
+                ide_atapi_cmd_reply(s, len, max_len);
+                break;
+            case 1:
+                /* multi session : only a single session defined */
+                memset(buf, 0, 12);
+                buf[1] = 0x0a;
+                buf[2] = 0x01;
+                buf[3] = 0x01;
+                ide_atapi_cmd_reply(s, 12, max_len);
+                break;
+            case 2:
+                len = cdrom_read_toc_raw(total_sectors, buf, msf, start_track);
+                if (len < 0)
+                    goto error_cmd;
+                ide_atapi_cmd_reply(s, len, max_len);
+                break;
+            default:
+            error_cmd:
+                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                                    ASC_INV_FIELD_IN_CMD_PACKET);
+                break;
+            }
+        }
+        break;
+    case GPCMD_READ_CDVD_CAPACITY:
+        {
+            uint64_t total_sectors;
+
+            bdrv_get_geometry(s->bs, &total_sectors);
+            total_sectors >>= 2;
+            if (total_sectors == 0) {
+                ide_atapi_cmd_error(s, SENSE_NOT_READY,
+                                    ASC_MEDIUM_NOT_PRESENT);
+                break;
+            }
+            /* NOTE: it is really the number of sectors minus 1 */
+            cpu_to_ube32(buf, total_sectors - 1);
+            cpu_to_ube32(buf + 4, 2048);
+            ide_atapi_cmd_reply(s, 8, 8);
+        }
+        break;
+    case GPCMD_READ_DVD_STRUCTURE:
+        {
+            int media = packet[1];
+            int format = packet[7];
+            int ret;
+
+            max_len = ube16_to_cpu(packet + 8);
+
+            if (format < 0xff) {
+                if (media_is_cd(s)) {
+                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                                        ASC_INCOMPATIBLE_FORMAT);
+                    break;
+                } else if (!media_present(s)) {
+                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                                        ASC_INV_FIELD_IN_CMD_PACKET);
+                    break;
+                }
+            }
+
+            memset(buf, 0, max_len > IDE_DMA_BUF_SECTORS * 512 + 4 ?
+                   IDE_DMA_BUF_SECTORS * 512 + 4 : max_len);
+
+            switch (format) {
+                case 0x00 ... 0x7f:
+                case 0xff:
+                    if (media == 0) {
+                        ret = ide_dvd_read_structure(s, format, packet, buf);
+
+                        if (ret < 0)
+                            ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, -ret);
+                        else
+                            ide_atapi_cmd_reply(s, ret, max_len);
+
+                        break;
+                    }
+                    /* TODO: BD support, fall through for now */
+
+                /* Generic disk structures */
+                case 0x80: /* TODO: AACS volume identifier */
+                case 0x81: /* TODO: AACS media serial number */
+                case 0x82: /* TODO: AACS media identifier */
+                case 0x83: /* TODO: AACS media key block */
+                case 0x90: /* TODO: List of recognized format layers */
+                case 0xc0: /* TODO: Write protection status */
+                default:
+                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                                        ASC_INV_FIELD_IN_CMD_PACKET);
+                    break;
+            }
+        }
+        break;
+    case GPCMD_SET_SPEED:
+        ide_atapi_cmd_ok(s);
+        break;
+    case GPCMD_INQUIRY:
+        max_len = packet[4];
+        buf[0] = 0x05; /* CD-ROM */
+        buf[1] = 0x80; /* removable */
+        buf[2] = 0x00; /* ISO */
+        buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
+        buf[4] = 31; /* additional length */
+        buf[5] = 0; /* reserved */
+        buf[6] = 0; /* reserved */
+        buf[7] = 0; /* reserved */
+        padstr8(buf + 8, 8, "QEMU");
+        padstr8(buf + 16, 16, "QEMU DVD-ROM");
+        padstr8(buf + 32, 4, s->version);
+        ide_atapi_cmd_reply(s, 36, max_len);
+        break;
+    case GPCMD_GET_CONFIGURATION:
+        {
+            uint32_t len;
+            uint8_t index = 0;
+
+            /* only feature 0 is supported */
+            if (packet[2] != 0 || packet[3] != 0) {
+                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                                    ASC_INV_FIELD_IN_CMD_PACKET);
+                break;
+            }
+
+            /* XXX: could result in alignment problems in some architectures */
+            max_len = ube16_to_cpu(packet + 7);
+
+            /*
+             * XXX: avoid overflow for io_buffer if max_len is bigger than
+             *      the size of that buffer (dimensioned to max number of
+             *      sectors to transfer at once)
+             *
+             *      Only a problem if the feature/profiles grow.
+             */
+            if (max_len > 512) /* XXX: assume 1 sector */
+                max_len = 512;
+
+            memset(buf, 0, max_len);
+            /*
+             * the number of sectors from the media tells us which profile
+             * to use as current.  0 means there is no media
+             */
+            if (media_is_dvd(s))
+                cpu_to_ube16(buf + 6, MMC_PROFILE_DVD_ROM);
+            else if (media_is_cd(s))
+                cpu_to_ube16(buf + 6, MMC_PROFILE_CD_ROM);
+
+            buf[10] = 0x02 | 0x01; /* persistent and current */
+            len = 12; /* headers: 8 + 4 */
+            len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_DVD_ROM);
+            len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_CD_ROM);
+            cpu_to_ube32(buf, len - 4); /* data length */
+
+            ide_atapi_cmd_reply(s, len, max_len);
+            break;
+        }
+    case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
+        handle_get_event_status_notification(s, buf, packet);
+        break;
+    default:
+        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                            ASC_ILLEGAL_OPCODE);
+        break;
+    }
+}
diff --git a/hw/ide/core.c b/hw/ide/core.c
index d8c613ae0d..90f553b69b 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -25,7 +25,6 @@
 #include <hw/hw.h>
 #include <hw/pc.h>
 #include <hw/pci.h>
-#include <hw/scsi.h>
 #include "qemu-error.h"
 #include "qemu-timer.h"
 #include "sysemu.h"
@@ -56,23 +55,6 @@ static const int smart_attributes[][12] = {
     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 };
 
-/* XXX: DVDs that could fit on a CD will be reported as a CD */
-static inline int media_present(IDEState *s)
-{
-    return (s->nb_sectors > 0);
-}
-
-static inline int media_is_dvd(IDEState *s)
-{
-    return (media_present(s) && s->nb_sectors > CD_MAX_SECTORS);
-}
-
-static inline int media_is_cd(IDEState *s)
-{
-    return (media_present(s) && s->nb_sectors <= CD_MAX_SECTORS);
-}
-
-static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
 static int ide_handle_rw_error(IDEState *s, int error, int op);
 
 static void padstr(char *str, const char *src, int len)
@@ -87,17 +69,6 @@ static void padstr(char *str, const char *src, int len)
     }
 }
 
-static void padstr8(uint8_t *buf, int buf_size, const char *src)
-{
-    int i;
-    for(i = 0; i < buf_size; i++) {
-        if (*src)
-            buf[i] = *src++;
-        else
-            buf[i] = ' ';
-    }
-}
-
 static void put_le16(uint16_t *p, unsigned int v)
 {
     *p = cpu_to_le16(v);
@@ -335,8 +306,8 @@ static inline void ide_abort_command(IDEState *s)
 }
 
 /* prepare data transfer and tell what to do after */
-static void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
-                               EndTransferFunc *end_transfer_func)
+void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
+                        EndTransferFunc *end_transfer_func)
 {
     s->end_transfer_func = end_transfer_func;
     s->data_ptr = buf;
@@ -347,7 +318,7 @@ static void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
     s->bus->dma->ops->start_transfer(s->bus->dma);
 }
 
-static void ide_transfer_stop(IDEState *s)
+void ide_transfer_stop(IDEState *s)
 {
     s->end_transfer_func = ide_transfer_stop;
     s->data_ptr = s->io_buffer;
@@ -447,7 +418,7 @@ static void dma_buf_commit(IDEState *s, int is_write)
     qemu_sglist_destroy(&s->sg);
 }
 
-static void ide_set_inactive(IDEState *s)
+void ide_set_inactive(IDEState *s)
 {
     s->bus->dma->aiocb = NULL;
     s->bus->dma->ops->set_inactive(s->bus->dma);
@@ -617,38 +588,6 @@ void ide_sector_write(IDEState *s)
     }
 }
 
-void ide_atapi_cmd_ok(IDEState *s)
-{
-    s->error = 0;
-    s->status = READY_STAT | SEEK_STAT;
-    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
-    ide_set_irq(s->bus);
-}
-
-void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
-{
-#ifdef DEBUG_IDE_ATAPI
-    printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc);
-#endif
-    s->error = sense_key << 4;
-    s->status = READY_STAT | ERR_STAT;
-    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
-    s->sense_key = sense_key;
-    s->asc = asc;
-    ide_set_irq(s->bus);
-}
-
-static void ide_atapi_cmd_check_status(IDEState *s)
-{
-#ifdef DEBUG_IDE_ATAPI
-    printf("atapi_cmd_check_status\n");
-#endif
-    s->error = MC_ERR | (SENSE_UNIT_ATTENTION << 4);
-    s->status = ERR_STAT;
-    s->nsector = 0;
-    ide_set_irq(s->bus);
-}
-
 static void ide_flush_cb(void *opaque, int ret)
 {
     IDEState *s = opaque;
@@ -679,1002 +618,6 @@ void ide_flush_cache(IDEState *s)
     }
 }
 
-static inline void cpu_to_ube16(uint8_t *buf, int val)
-{
-    buf[0] = val >> 8;
-    buf[1] = val & 0xff;
-}
-
-static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
-{
-    buf[0] = val >> 24;
-    buf[1] = val >> 16;
-    buf[2] = val >> 8;
-    buf[3] = val & 0xff;
-}
-
-static inline int ube16_to_cpu(const uint8_t *buf)
-{
-    return (buf[0] << 8) | buf[1];
-}
-
-static inline int ube32_to_cpu(const uint8_t *buf)
-{
-    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
-}
-
-static void lba_to_msf(uint8_t *buf, int lba)
-{
-    lba += 150;
-    buf[0] = (lba / 75) / 60;
-    buf[1] = (lba / 75) % 60;
-    buf[2] = lba % 75;
-}
-
-static void cd_data_to_raw(uint8_t *buf, int lba)
-{
-    /* sync bytes */
-    buf[0] = 0x00;
-    memset(buf + 1, 0xff, 10);
-    buf[11] = 0x00;
-    buf += 12;
-    /* MSF */
-    lba_to_msf(buf, lba);
-    buf[3] = 0x01; /* mode 1 data */
-    buf += 4;
-    /* data */
-    buf += 2048;
-    /* XXX: ECC not computed */
-    memset(buf, 0, 288);
-}
-
-static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
-                           int sector_size)
-{
-    int ret;
-
-    switch(sector_size) {
-    case 2048:
-        ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4);
-        break;
-    case 2352:
-        ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
-        if (ret < 0)
-            return ret;
-        cd_data_to_raw(buf, lba);
-        break;
-    default:
-        ret = -EIO;
-        break;
-    }
-    return ret;
-}
-
-void ide_atapi_io_error(IDEState *s, int ret)
-{
-    /* XXX: handle more errors */
-    if (ret == -ENOMEDIUM) {
-        ide_atapi_cmd_error(s, SENSE_NOT_READY,
-                            ASC_MEDIUM_NOT_PRESENT);
-    } else {
-        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                            ASC_LOGICAL_BLOCK_OOR);
-    }
-}
-
-/* The whole ATAPI transfer logic is handled in this function */
-static void ide_atapi_cmd_reply_end(IDEState *s)
-{
-    int byte_count_limit, size, ret;
-#ifdef DEBUG_IDE_ATAPI
-    printf("reply: tx_size=%d elem_tx_size=%d index=%d\n",
-           s->packet_transfer_size,
-           s->elementary_transfer_size,
-           s->io_buffer_index);
-#endif
-    if (s->packet_transfer_size <= 0) {
-        /* end of transfer */
-        ide_transfer_stop(s);
-        s->status = READY_STAT | SEEK_STAT;
-        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
-        ide_set_irq(s->bus);
-#ifdef DEBUG_IDE_ATAPI
-        printf("status=0x%x\n", s->status);
-#endif
-    } else {
-        /* see if a new sector must be read */
-        if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
-            ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
-            if (ret < 0) {
-                ide_transfer_stop(s);
-                ide_atapi_io_error(s, ret);
-                return;
-            }
-            s->lba++;
-            s->io_buffer_index = 0;
-        }
-        if (s->elementary_transfer_size > 0) {
-            /* there are some data left to transmit in this elementary
-               transfer */
-            size = s->cd_sector_size - s->io_buffer_index;
-            if (size > s->elementary_transfer_size)
-                size = s->elementary_transfer_size;
-            s->packet_transfer_size -= size;
-            s->elementary_transfer_size -= size;
-            s->io_buffer_index += size;
-            ide_transfer_start(s, s->io_buffer + s->io_buffer_index - size,
-                               size, ide_atapi_cmd_reply_end);
-        } else {
-            /* a new transfer is needed */
-            s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
-            byte_count_limit = s->lcyl | (s->hcyl << 8);
-#ifdef DEBUG_IDE_ATAPI
-            printf("byte_count_limit=%d\n", byte_count_limit);
-#endif
-            if (byte_count_limit == 0xffff)
-                byte_count_limit--;
-            size = s->packet_transfer_size;
-            if (size > byte_count_limit) {
-                /* byte count limit must be even if this case */
-                if (byte_count_limit & 1)
-                    byte_count_limit--;
-                size = byte_count_limit;
-            }
-            s->lcyl = size;
-            s->hcyl = size >> 8;
-            s->elementary_transfer_size = size;
-            /* we cannot transmit more than one sector at a time */
-            if (s->lba != -1) {
-                if (size > (s->cd_sector_size - s->io_buffer_index))
-                    size = (s->cd_sector_size - s->io_buffer_index);
-            }
-            s->packet_transfer_size -= size;
-            s->elementary_transfer_size -= size;
-            s->io_buffer_index += size;
-            ide_transfer_start(s, s->io_buffer + s->io_buffer_index - size,
-                               size, ide_atapi_cmd_reply_end);
-            ide_set_irq(s->bus);
-#ifdef DEBUG_IDE_ATAPI
-            printf("status=0x%x\n", s->status);
-#endif
-        }
-    }
-}
-
-/* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
-static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
-{
-    if (size > max_size)
-        size = max_size;
-    s->lba = -1; /* no sector read */
-    s->packet_transfer_size = size;
-    s->io_buffer_size = size;    /* dma: send the reply data as one chunk */
-    s->elementary_transfer_size = 0;
-    s->io_buffer_index = 0;
-
-    if (s->atapi_dma) {
-    	s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
-        s->bus->dma->ops->start_dma(s->bus->dma, s,
-                                   ide_atapi_cmd_read_dma_cb);
-    } else {
-    	s->status = READY_STAT | SEEK_STAT;
-    	ide_atapi_cmd_reply_end(s);
-    }
-}
-
-/* start a CD-CDROM read command */
-static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
-                                   int sector_size)
-{
-    s->lba = lba;
-    s->packet_transfer_size = nb_sectors * sector_size;
-    s->elementary_transfer_size = 0;
-    s->io_buffer_index = sector_size;
-    s->cd_sector_size = sector_size;
-
-    s->status = READY_STAT | SEEK_STAT;
-    ide_atapi_cmd_reply_end(s);
-}
-
-/* ATAPI DMA support */
-
-/* XXX: handle read errors */
-static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
-{
-    IDEState *s = opaque;
-    int data_offset, n;
-
-    if (ret < 0) {
-        ide_atapi_io_error(s, ret);
-        goto eot;
-    }
-
-    if (s->io_buffer_size > 0) {
-	/*
-	 * For a cdrom read sector command (s->lba != -1),
-	 * adjust the lba for the next s->io_buffer_size chunk
-	 * and dma the current chunk.
-	 * For a command != read (s->lba == -1), just transfer
-	 * the reply data.
-	 */
-	if (s->lba != -1) {
-	    if (s->cd_sector_size == 2352) {
-		n = 1;
-		cd_data_to_raw(s->io_buffer, s->lba);
-	    } else {
-		n = s->io_buffer_size >> 11;
-	    }
-	    s->lba += n;
-	}
-        s->packet_transfer_size -= s->io_buffer_size;
-        if (s->bus->dma->ops->rw_buf(s->bus->dma, 1) == 0)
-            goto eot;
-    }
-
-    if (s->packet_transfer_size <= 0) {
-        s->status = READY_STAT | SEEK_STAT;
-        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
-        ide_set_irq(s->bus);
-    eot:
-        s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
-        ide_set_inactive(s);
-        return;
-    }
-
-    s->io_buffer_index = 0;
-    if (s->cd_sector_size == 2352) {
-        n = 1;
-        s->io_buffer_size = s->cd_sector_size;
-        data_offset = 16;
-    } else {
-        n = s->packet_transfer_size >> 11;
-        if (n > (IDE_DMA_BUF_SECTORS / 4))
-            n = (IDE_DMA_BUF_SECTORS / 4);
-        s->io_buffer_size = n * 2048;
-        data_offset = 0;
-    }
-#ifdef DEBUG_AIO
-    printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
-#endif
-    s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset);
-    s->bus->dma->iov.iov_len = n * 4 * 512;
-    qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1);
-    s->bus->dma->aiocb = bdrv_aio_readv(s->bs, (int64_t)s->lba << 2,
-                                       &s->bus->dma->qiov, n * 4,
-                                       ide_atapi_cmd_read_dma_cb, s);
-    if (!s->bus->dma->aiocb) {
-        /* Note: media not present is the most likely case */
-        ide_atapi_cmd_error(s, SENSE_NOT_READY,
-                            ASC_MEDIUM_NOT_PRESENT);
-        goto eot;
-    }
-}
-
-/* start a CD-CDROM read command with DMA */
-/* XXX: test if DMA is available */
-static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
-                                   int sector_size)
-{
-    s->lba = lba;
-    s->packet_transfer_size = nb_sectors * sector_size;
-    s->io_buffer_index = 0;
-    s->io_buffer_size = 0;
-    s->cd_sector_size = sector_size;
-
-    /* XXX: check if BUSY_STAT should be set */
-    s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
-    s->bus->dma->ops->start_dma(s->bus->dma, s,
-                               ide_atapi_cmd_read_dma_cb);
-}
-
-static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
-                               int sector_size)
-{
-#ifdef DEBUG_IDE_ATAPI
-    printf("read %s: LBA=%d nb_sectors=%d\n", s->atapi_dma ? "dma" : "pio",
-	lba, nb_sectors);
-#endif
-    if (s->atapi_dma) {
-        ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
-    } else {
-        ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);
-    }
-}
-
-static inline uint8_t ide_atapi_set_profile(uint8_t *buf, uint8_t *index,
-                                            uint16_t profile)
-{
-    uint8_t *buf_profile = buf + 12; /* start of profiles */
-
-    buf_profile += ((*index) * 4); /* start of indexed profile */
-    cpu_to_ube16 (buf_profile, profile);
-    buf_profile[2] = ((buf_profile[0] == buf[6]) && (buf_profile[1] == buf[7]));
-
-    /* each profile adds 4 bytes to the response */
-    (*index)++;
-    buf[11] += 4; /* Additional Length */
-
-    return 4;
-}
-
-static int ide_dvd_read_structure(IDEState *s, int format,
-                                  const uint8_t *packet, uint8_t *buf)
-{
-    switch (format) {
-        case 0x0: /* Physical format information */
-            {
-                int layer = packet[6];
-                uint64_t total_sectors;
-
-                if (layer != 0)
-                    return -ASC_INV_FIELD_IN_CMD_PACKET;
-
-                bdrv_get_geometry(s->bs, &total_sectors);
-                total_sectors >>= 2;
-                if (total_sectors == 0)
-                    return -ASC_MEDIUM_NOT_PRESENT;
-
-                buf[4] = 1;   /* DVD-ROM, part version 1 */
-                buf[5] = 0xf; /* 120mm disc, minimum rate unspecified */
-                buf[6] = 1;   /* one layer, read-only (per MMC-2 spec) */
-                buf[7] = 0;   /* default densities */
-
-                /* FIXME: 0x30000 per spec? */
-                cpu_to_ube32(buf + 8, 0); /* start sector */
-                cpu_to_ube32(buf + 12, total_sectors - 1); /* end sector */
-                cpu_to_ube32(buf + 16, total_sectors - 1); /* l0 end sector */
-
-                /* Size of buffer, not including 2 byte size field */
-                cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
-
-                /* 2k data + 4 byte header */
-                return (2048 + 4);
-            }
-
-        case 0x01: /* DVD copyright information */
-            buf[4] = 0; /* no copyright data */
-            buf[5] = 0; /* no region restrictions */
-
-            /* Size of buffer, not including 2 byte size field */
-            cpu_to_be16wu((uint16_t *)buf, 4 + 2);
-
-            /* 4 byte header + 4 byte data */
-            return (4 + 4);
-
-        case 0x03: /* BCA information - invalid field for no BCA info */
-            return -ASC_INV_FIELD_IN_CMD_PACKET;
-
-        case 0x04: /* DVD disc manufacturing information */
-            /* Size of buffer, not including 2 byte size field */
-            cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
-
-            /* 2k data + 4 byte header */
-            return (2048 + 4);
-
-        case 0xff:
-            /*
-             * This lists all the command capabilities above.  Add new ones
-             * in order and update the length and buffer return values.
-             */
-
-            buf[4] = 0x00; /* Physical format */
-            buf[5] = 0x40; /* Not writable, is readable */
-            cpu_to_be16wu((uint16_t *)(buf + 6), 2048 + 4);
-
-            buf[8] = 0x01; /* Copyright info */
-            buf[9] = 0x40; /* Not writable, is readable */
-            cpu_to_be16wu((uint16_t *)(buf + 10), 4 + 4);
-
-            buf[12] = 0x03; /* BCA info */
-            buf[13] = 0x40; /* Not writable, is readable */
-            cpu_to_be16wu((uint16_t *)(buf + 14), 188 + 4);
-
-            buf[16] = 0x04; /* Manufacturing info */
-            buf[17] = 0x40; /* Not writable, is readable */
-            cpu_to_be16wu((uint16_t *)(buf + 18), 2048 + 4);
-
-            /* Size of buffer, not including 2 byte size field */
-            cpu_to_be16wu((uint16_t *)buf, 16 + 2);
-
-            /* data written + 4 byte header */
-            return (16 + 4);
-
-        default: /* TODO: formats beyond DVD-ROM requires */
-            return -ASC_INV_FIELD_IN_CMD_PACKET;
-    }
-}
-
-static unsigned int event_status_media(IDEState *s,
-                                       uint8_t *buf)
-{
-    enum media_event_code {
-        MEC_NO_CHANGE = 0,       /* Status unchanged */
-        MEC_EJECT_REQUESTED,     /* received a request from user to eject */
-        MEC_NEW_MEDIA,           /* new media inserted and ready for access */
-        MEC_MEDIA_REMOVAL,       /* only for media changers */
-        MEC_MEDIA_CHANGED,       /* only for media changers */
-        MEC_BG_FORMAT_COMPLETED, /* MRW or DVD+RW b/g format completed */
-        MEC_BG_FORMAT_RESTARTED, /* MRW or DVD+RW b/g format restarted */
-    };
-    enum media_status {
-        MS_TRAY_OPEN = 1,
-        MS_MEDIA_PRESENT = 2,
-    };
-    uint8_t event_code, media_status;
-
-    media_status = 0;
-    if (s->bs->tray_open) {
-        media_status = MS_TRAY_OPEN;
-    } else if (bdrv_is_inserted(s->bs)) {
-        media_status = MS_MEDIA_PRESENT;
-    }
-
-    /* Event notification descriptor */
-    event_code = MEC_NO_CHANGE;
-    if (media_status != MS_TRAY_OPEN && s->events.new_media) {
-        event_code = MEC_NEW_MEDIA;
-        s->events.new_media = false;
-    }
-
-    buf[4] = event_code;
-    buf[5] = media_status;
-
-    /* These fields are reserved, just clear them. */
-    buf[6] = 0;
-    buf[7] = 0;
-
-    return 8; /* We wrote to 4 extra bytes from the header */
-}
-
-static void handle_get_event_status_notification(IDEState *s,
-                                                 uint8_t *buf,
-                                                 const uint8_t *packet)
-{
-    struct {
-        uint8_t opcode;
-        uint8_t polled;        /* lsb bit is polled; others are reserved */
-        uint8_t reserved2[2];
-        uint8_t class;
-        uint8_t reserved3[2];
-        uint16_t len;
-        uint8_t control;
-    } __attribute__((packed)) *gesn_cdb;
-
-    struct {
-        uint16_t len;
-        uint8_t notification_class;
-        uint8_t supported_events;
-    } __attribute((packed)) *gesn_event_header;
-
-    enum notification_class_request_type {
-        NCR_RESERVED1 = 1 << 0,
-        NCR_OPERATIONAL_CHANGE = 1 << 1,
-        NCR_POWER_MANAGEMENT = 1 << 2,
-        NCR_EXTERNAL_REQUEST = 1 << 3,
-        NCR_MEDIA = 1 << 4,
-        NCR_MULTI_HOST = 1 << 5,
-        NCR_DEVICE_BUSY = 1 << 6,
-        NCR_RESERVED2 = 1 << 7,
-    };
-    enum event_notification_class_field {
-        ENC_NO_EVENTS = 0,
-        ENC_OPERATIONAL_CHANGE,
-        ENC_POWER_MANAGEMENT,
-        ENC_EXTERNAL_REQUEST,
-        ENC_MEDIA,
-        ENC_MULTIPLE_HOSTS,
-        ENC_DEVICE_BUSY,
-        ENC_RESERVED,
-    };
-    unsigned int max_len, used_len;
-
-    gesn_cdb = (void *)packet;
-    gesn_event_header = (void *)buf;
-
-    max_len = be16_to_cpu(gesn_cdb->len);
-
-    /* It is fine by the MMC spec to not support async mode operations */
-    if (!(gesn_cdb->polled & 0x01)) { /* asynchronous mode */
-        /* Only polling is supported, asynchronous mode is not. */
-        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                            ASC_INV_FIELD_IN_CMD_PACKET);
-        return;
-    }
-
-    /* polling mode operation */
-
-    /*
-     * These are the supported events.
-     *
-     * We currently only support requests of the 'media' type.
-     */
-    gesn_event_header->supported_events = NCR_MEDIA;
-
-    /*
-     * We use |= below to set the class field; other bits in this byte
-     * are reserved now but this is useful to do if we have to use the
-     * reserved fields later.
-     */
-    gesn_event_header->notification_class = 0;
-
-    /*
-     * Responses to requests are to be based on request priority.  The
-     * notification_class_request_type enum above specifies the
-     * priority: upper elements are higher prio than lower ones.
-     */
-    if (gesn_cdb->class & NCR_MEDIA) {
-        gesn_event_header->notification_class |= ENC_MEDIA;
-        used_len = event_status_media(s, buf);
-    } else {
-        gesn_event_header->notification_class = 0x80; /* No event available */
-        used_len = sizeof(*gesn_event_header);
-    }
-    gesn_event_header->len = cpu_to_be16(used_len
-                                         - sizeof(*gesn_event_header));
-    ide_atapi_cmd_reply(s, used_len, max_len);
-}
-
-static void ide_atapi_cmd(IDEState *s)
-{
-    const uint8_t *packet;
-    uint8_t *buf;
-    int max_len;
-
-    packet = s->io_buffer;
-    buf = s->io_buffer;
-#ifdef DEBUG_IDE_ATAPI
-    {
-        int i;
-        printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
-        for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
-            printf(" %02x", packet[i]);
-        }
-        printf("\n");
-    }
-#endif
-    /*
-     * If there's a UNIT_ATTENTION condition pending, only
-     * REQUEST_SENSE, INQUIRY, GET_CONFIGURATION and
-     * GET_EVENT_STATUS_NOTIFICATION commands are allowed to complete.
-     * MMC-5, section 4.1.6.1 lists only these commands being allowed
-     * to complete, with other commands getting a CHECK condition
-     * response unless a higher priority status, defined by the drive
-     * here, is pending.
-     */
-    if (s->sense_key == SENSE_UNIT_ATTENTION &&
-        s->io_buffer[0] != GPCMD_REQUEST_SENSE &&
-        s->io_buffer[0] != GPCMD_INQUIRY &&
-        s->io_buffer[0] != GPCMD_GET_EVENT_STATUS_NOTIFICATION) {
-        ide_atapi_cmd_check_status(s);
-        return;
-    }
-    if (bdrv_is_inserted(s->bs) && s->cdrom_changed) {
-        ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
-
-        s->cdrom_changed = 0;
-        s->sense_key = SENSE_UNIT_ATTENTION;
-        s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED;
-        return;
-    }
-    switch(s->io_buffer[0]) {
-    case GPCMD_TEST_UNIT_READY:
-        if (bdrv_is_inserted(s->bs)) {
-            ide_atapi_cmd_ok(s);
-        } else {
-            ide_atapi_cmd_error(s, SENSE_NOT_READY,
-                                ASC_MEDIUM_NOT_PRESENT);
-        }
-        break;
-    case GPCMD_MODE_SENSE_6:
-    case GPCMD_MODE_SENSE_10:
-        {
-            int action, code;
-            if (packet[0] == GPCMD_MODE_SENSE_10)
-                max_len = ube16_to_cpu(packet + 7);
-            else
-                max_len = packet[4];
-            action = packet[2] >> 6;
-            code = packet[2] & 0x3f;
-            switch(action) {
-            case 0: /* current values */
-                switch(code) {
-                case GPMODE_R_W_ERROR_PAGE: /* error recovery */
-                    cpu_to_ube16(&buf[0], 16 + 6);
-                    buf[2] = 0x70;
-                    buf[3] = 0;
-                    buf[4] = 0;
-                    buf[5] = 0;
-                    buf[6] = 0;
-                    buf[7] = 0;
-
-                    buf[8] = 0x01;
-                    buf[9] = 0x06;
-                    buf[10] = 0x00;
-                    buf[11] = 0x05;
-                    buf[12] = 0x00;
-                    buf[13] = 0x00;
-                    buf[14] = 0x00;
-                    buf[15] = 0x00;
-                    ide_atapi_cmd_reply(s, 16, max_len);
-                    break;
-                case GPMODE_AUDIO_CTL_PAGE:
-                    cpu_to_ube16(&buf[0], 24 + 6);
-                    buf[2] = 0x70;
-                    buf[3] = 0;
-                    buf[4] = 0;
-                    buf[5] = 0;
-                    buf[6] = 0;
-                    buf[7] = 0;
-
-                    /* Fill with CDROM audio volume */
-                    buf[17] = 0;
-                    buf[19] = 0;
-                    buf[21] = 0;
-                    buf[23] = 0;
-
-                    ide_atapi_cmd_reply(s, 24, max_len);
-                    break;
-                case GPMODE_CAPABILITIES_PAGE:
-                    cpu_to_ube16(&buf[0], 28 + 6);
-                    buf[2] = 0x70;
-                    buf[3] = 0;
-                    buf[4] = 0;
-                    buf[5] = 0;
-                    buf[6] = 0;
-                    buf[7] = 0;
-
-                    buf[8] = 0x2a;
-                    buf[9] = 0x12;
-                    buf[10] = 0x00;
-                    buf[11] = 0x00;
-
-                    /* Claim PLAY_AUDIO capability (0x01) since some Linux
-                       code checks for this to automount media. */
-                    buf[12] = 0x71;
-                    buf[13] = 3 << 5;
-                    buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
-                    if (bdrv_is_locked(s->bs))
-                        buf[6] |= 1 << 1;
-                    buf[15] = 0x00;
-                    cpu_to_ube16(&buf[16], 706);
-                    buf[18] = 0;
-                    buf[19] = 2;
-                    cpu_to_ube16(&buf[20], 512);
-                    cpu_to_ube16(&buf[22], 706);
-                    buf[24] = 0;
-                    buf[25] = 0;
-                    buf[26] = 0;
-                    buf[27] = 0;
-                    ide_atapi_cmd_reply(s, 28, max_len);
-                    break;
-                default:
-                    goto error_cmd;
-                }
-                break;
-            case 1: /* changeable values */
-                goto error_cmd;
-            case 2: /* default values */
-                goto error_cmd;
-            default:
-            case 3: /* saved values */
-                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                                    ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
-                break;
-            }
-        }
-        break;
-    case GPCMD_REQUEST_SENSE:
-        max_len = packet[4];
-        memset(buf, 0, 18);
-        buf[0] = 0x70 | (1 << 7);
-        buf[2] = s->sense_key;
-        buf[7] = 10;
-        buf[12] = s->asc;
-        if (s->sense_key == SENSE_UNIT_ATTENTION)
-            s->sense_key = SENSE_NONE;
-        ide_atapi_cmd_reply(s, 18, max_len);
-        break;
-    case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
-        bdrv_set_locked(s->bs, packet[4] & 1);
-        ide_atapi_cmd_ok(s);
-        break;
-    case GPCMD_READ_10:
-    case GPCMD_READ_12:
-        {
-            int nb_sectors, lba;
-
-            if (packet[0] == GPCMD_READ_10)
-                nb_sectors = ube16_to_cpu(packet + 7);
-            else
-                nb_sectors = ube32_to_cpu(packet + 6);
-            lba = ube32_to_cpu(packet + 2);
-            if (nb_sectors == 0) {
-                ide_atapi_cmd_ok(s);
-                break;
-            }
-            ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
-        }
-        break;
-    case GPCMD_READ_CD:
-        {
-            int nb_sectors, lba, transfer_request;
-
-            nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
-            lba = ube32_to_cpu(packet + 2);
-            if (nb_sectors == 0) {
-                ide_atapi_cmd_ok(s);
-                break;
-            }
-            transfer_request = packet[9];
-            switch(transfer_request & 0xf8) {
-            case 0x00:
-                /* nothing */
-                ide_atapi_cmd_ok(s);
-                break;
-            case 0x10:
-                /* normal read */
-                ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
-                break;
-            case 0xf8:
-                /* read all data */
-                ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
-                break;
-            default:
-                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                                    ASC_INV_FIELD_IN_CMD_PACKET);
-                break;
-            }
-        }
-        break;
-    case GPCMD_SEEK:
-        {
-            unsigned int lba;
-            uint64_t total_sectors;
-
-            bdrv_get_geometry(s->bs, &total_sectors);
-            total_sectors >>= 2;
-            if (total_sectors == 0) {
-                ide_atapi_cmd_error(s, SENSE_NOT_READY,
-                                    ASC_MEDIUM_NOT_PRESENT);
-                break;
-            }
-            lba = ube32_to_cpu(packet + 2);
-            if (lba >= total_sectors) {
-                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                                    ASC_LOGICAL_BLOCK_OOR);
-                break;
-            }
-            ide_atapi_cmd_ok(s);
-        }
-        break;
-    case GPCMD_START_STOP_UNIT:
-        {
-            int start, eject, sense, err = 0;
-            start = packet[4] & 1;
-            eject = (packet[4] >> 1) & 1;
-
-            if (eject) {
-                err = bdrv_eject(s->bs, !start);
-            }
-
-            switch (err) {
-            case 0:
-                ide_atapi_cmd_ok(s);
-                break;
-            case -EBUSY:
-                sense = SENSE_NOT_READY;
-                if (bdrv_is_inserted(s->bs)) {
-                    sense = SENSE_ILLEGAL_REQUEST;
-                }
-                ide_atapi_cmd_error(s, sense,
-                                    ASC_MEDIA_REMOVAL_PREVENTED);
-                break;
-            default:
-                ide_atapi_cmd_error(s, SENSE_NOT_READY,
-                                    ASC_MEDIUM_NOT_PRESENT);
-                break;
-            }
-        }
-        break;
-    case GPCMD_MECHANISM_STATUS:
-        {
-            max_len = ube16_to_cpu(packet + 8);
-            cpu_to_ube16(buf, 0);
-            /* no current LBA */
-            buf[2] = 0;
-            buf[3] = 0;
-            buf[4] = 0;
-            buf[5] = 1;
-            cpu_to_ube16(buf + 6, 0);
-            ide_atapi_cmd_reply(s, 8, max_len);
-        }
-        break;
-    case GPCMD_READ_TOC_PMA_ATIP:
-        {
-            int format, msf, start_track, len;
-            uint64_t total_sectors;
-
-            bdrv_get_geometry(s->bs, &total_sectors);
-            total_sectors >>= 2;
-            if (total_sectors == 0) {
-                ide_atapi_cmd_error(s, SENSE_NOT_READY,
-                                    ASC_MEDIUM_NOT_PRESENT);
-                break;
-            }
-            max_len = ube16_to_cpu(packet + 7);
-            format = packet[9] >> 6;
-            msf = (packet[1] >> 1) & 1;
-            start_track = packet[6];
-            switch(format) {
-            case 0:
-                len = cdrom_read_toc(total_sectors, buf, msf, start_track);
-                if (len < 0)
-                    goto error_cmd;
-                ide_atapi_cmd_reply(s, len, max_len);
-                break;
-            case 1:
-                /* multi session : only a single session defined */
-                memset(buf, 0, 12);
-                buf[1] = 0x0a;
-                buf[2] = 0x01;
-                buf[3] = 0x01;
-                ide_atapi_cmd_reply(s, 12, max_len);
-                break;
-            case 2:
-                len = cdrom_read_toc_raw(total_sectors, buf, msf, start_track);
-                if (len < 0)
-                    goto error_cmd;
-                ide_atapi_cmd_reply(s, len, max_len);
-                break;
-            default:
-            error_cmd:
-                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                                    ASC_INV_FIELD_IN_CMD_PACKET);
-                break;
-            }
-        }
-        break;
-    case GPCMD_READ_CDVD_CAPACITY:
-        {
-            uint64_t total_sectors;
-
-            bdrv_get_geometry(s->bs, &total_sectors);
-            total_sectors >>= 2;
-            if (total_sectors == 0) {
-                ide_atapi_cmd_error(s, SENSE_NOT_READY,
-                                    ASC_MEDIUM_NOT_PRESENT);
-                break;
-            }
-            /* NOTE: it is really the number of sectors minus 1 */
-            cpu_to_ube32(buf, total_sectors - 1);
-            cpu_to_ube32(buf + 4, 2048);
-            ide_atapi_cmd_reply(s, 8, 8);
-        }
-        break;
-    case GPCMD_READ_DVD_STRUCTURE:
-        {
-            int media = packet[1];
-            int format = packet[7];
-            int ret;
-
-            max_len = ube16_to_cpu(packet + 8);
-
-            if (format < 0xff) {
-                if (media_is_cd(s)) {
-                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                                        ASC_INCOMPATIBLE_FORMAT);
-                    break;
-                } else if (!media_present(s)) {
-                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                                        ASC_INV_FIELD_IN_CMD_PACKET);
-                    break;
-                }
-            }
-
-            memset(buf, 0, max_len > IDE_DMA_BUF_SECTORS * 512 + 4 ?
-                   IDE_DMA_BUF_SECTORS * 512 + 4 : max_len);
-
-            switch (format) {
-                case 0x00 ... 0x7f:
-                case 0xff:
-                    if (media == 0) {
-                        ret = ide_dvd_read_structure(s, format, packet, buf);
-
-                        if (ret < 0)
-                            ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, -ret);
-                        else
-                            ide_atapi_cmd_reply(s, ret, max_len);
-
-                        break;
-                    }
-                    /* TODO: BD support, fall through for now */
-
-                /* Generic disk structures */
-                case 0x80: /* TODO: AACS volume identifier */
-                case 0x81: /* TODO: AACS media serial number */
-                case 0x82: /* TODO: AACS media identifier */
-                case 0x83: /* TODO: AACS media key block */
-                case 0x90: /* TODO: List of recognized format layers */
-                case 0xc0: /* TODO: Write protection status */
-                default:
-                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                                        ASC_INV_FIELD_IN_CMD_PACKET);
-                    break;
-            }
-        }
-        break;
-    case GPCMD_SET_SPEED:
-        ide_atapi_cmd_ok(s);
-        break;
-    case GPCMD_INQUIRY:
-        max_len = packet[4];
-        buf[0] = 0x05; /* CD-ROM */
-        buf[1] = 0x80; /* removable */
-        buf[2] = 0x00; /* ISO */
-        buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
-        buf[4] = 31; /* additional length */
-        buf[5] = 0; /* reserved */
-        buf[6] = 0; /* reserved */
-        buf[7] = 0; /* reserved */
-        padstr8(buf + 8, 8, "QEMU");
-        padstr8(buf + 16, 16, "QEMU DVD-ROM");
-        padstr8(buf + 32, 4, s->version);
-        ide_atapi_cmd_reply(s, 36, max_len);
-        break;
-    case GPCMD_GET_CONFIGURATION:
-        {
-            uint32_t len;
-            uint8_t index = 0;
-
-            /* only feature 0 is supported */
-            if (packet[2] != 0 || packet[3] != 0) {
-                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                                    ASC_INV_FIELD_IN_CMD_PACKET);
-                break;
-            }
-
-            /* XXX: could result in alignment problems in some architectures */
-            max_len = ube16_to_cpu(packet + 7);
-
-            /*
-             * XXX: avoid overflow for io_buffer if max_len is bigger than
-             *      the size of that buffer (dimensioned to max number of
-             *      sectors to transfer at once)
-             *
-             *      Only a problem if the feature/profiles grow.
-             */
-            if (max_len > 512) /* XXX: assume 1 sector */
-                max_len = 512;
-
-            memset(buf, 0, max_len);
-            /* 
-             * the number of sectors from the media tells us which profile
-             * to use as current.  0 means there is no media
-             */
-            if (media_is_dvd(s))
-                cpu_to_ube16(buf + 6, MMC_PROFILE_DVD_ROM);
-            else if (media_is_cd(s))
-                cpu_to_ube16(buf + 6, MMC_PROFILE_CD_ROM);
-
-            buf[10] = 0x02 | 0x01; /* persistent and current */
-            len = 12; /* headers: 8 + 4 */
-            len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_DVD_ROM);
-            len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_CD_ROM);
-            cpu_to_ube32(buf, len - 4); /* data length */
-
-            ide_atapi_cmd_reply(s, len, max_len);
-            break;
-        }
-    case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
-        handle_get_event_status_notification(s, buf, packet);
-        break;
-    default:
-        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                            ASC_ILLEGAL_OPCODE);
-        break;
-    }
-}
-
 static void ide_cfata_metadata_inquiry(IDEState *s)
 {
     uint16_t *p;
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index ba7e9a8ee2..aa198b6b12 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -9,6 +9,7 @@
 #include <hw/ide.h>
 #include "block_int.h"
 #include "iorange.h"
+#include "dma.h"
 
 /* debug IDE devices */
 //#define DEBUG_IDE
@@ -570,6 +571,15 @@ void ide_sector_write(IDEState *s);
 void ide_sector_read(IDEState *s);
 void ide_flush_cache(IDEState *s);
 
+void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
+                        EndTransferFunc *end_transfer_func);
+void ide_transfer_stop(IDEState *s);
+void ide_set_inactive(IDEState *s);
+
+/* hw/ide/atapi.c */
+void ide_atapi_cmd(IDEState *s);
+void ide_atapi_cmd_reply_end(IDEState *s);
+
 /* hw/ide/qdev.c */
 void ide_bus_new(IDEBus *idebus, DeviceState *dev, int bus_id);
 IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);

From a60cf7e7eba06bed118ae1b161f7e481ab72693c Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Mon, 18 Apr 2011 17:55:08 +0200
Subject: [PATCH 338/386] ide/atapi: Factor commands out

In preparation for a table of function pointers, factor each command out from
ide_atapi_cmd() into its own function.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/atapi.c | 837 +++++++++++++++++++++++++++----------------------
 1 file changed, 459 insertions(+), 378 deletions(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 0edfd580f2..25b796e7e5 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -621,11 +621,453 @@ static void handle_get_event_status_notification(IDEState *s,
     ide_atapi_cmd_reply(s, used_len, max_len);
 }
 
+static void cmd_request_sense(IDEState *s, uint8_t *buf)
+{
+    int max_len = buf[4];
+
+    memset(buf, 0, 18);
+    buf[0] = 0x70 | (1 << 7);
+    buf[2] = s->sense_key;
+    buf[7] = 10;
+    buf[12] = s->asc;
+
+    if (s->sense_key == SENSE_UNIT_ATTENTION) {
+        s->sense_key = SENSE_NONE;
+    }
+
+    ide_atapi_cmd_reply(s, 18, max_len);
+}
+
+static void cmd_inquiry(IDEState *s, uint8_t *buf)
+{
+    int max_len = buf[4];
+
+    buf[0] = 0x05; /* CD-ROM */
+    buf[1] = 0x80; /* removable */
+    buf[2] = 0x00; /* ISO */
+    buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
+    buf[4] = 31; /* additional length */
+    buf[5] = 0; /* reserved */
+    buf[6] = 0; /* reserved */
+    buf[7] = 0; /* reserved */
+    padstr8(buf + 8, 8, "QEMU");
+    padstr8(buf + 16, 16, "QEMU DVD-ROM");
+    padstr8(buf + 32, 4, s->version);
+    ide_atapi_cmd_reply(s, 36, max_len);
+}
+
+static void cmd_get_configuration(IDEState *s, uint8_t *buf)
+{
+    uint32_t len;
+    uint8_t index = 0;
+    int max_len;
+
+    /* only feature 0 is supported */
+    if (buf[2] != 0 || buf[3] != 0) {
+        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                            ASC_INV_FIELD_IN_CMD_PACKET);
+        return;
+    }
+
+    /* XXX: could result in alignment problems in some architectures */
+    max_len = ube16_to_cpu(buf + 7);
+
+    /*
+     * XXX: avoid overflow for io_buffer if max_len is bigger than
+     *      the size of that buffer (dimensioned to max number of
+     *      sectors to transfer at once)
+     *
+     *      Only a problem if the feature/profiles grow.
+     */
+    if (max_len > 512) {
+        /* XXX: assume 1 sector */
+        max_len = 512;
+    }
+
+    memset(buf, 0, max_len);
+    /*
+     * the number of sectors from the media tells us which profile
+     * to use as current.  0 means there is no media
+     */
+    if (media_is_dvd(s)) {
+        cpu_to_ube16(buf + 6, MMC_PROFILE_DVD_ROM);
+    } else if (media_is_cd(s)) {
+        cpu_to_ube16(buf + 6, MMC_PROFILE_CD_ROM);
+    }
+
+    buf[10] = 0x02 | 0x01; /* persistent and current */
+    len = 12; /* headers: 8 + 4 */
+    len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_DVD_ROM);
+    len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_CD_ROM);
+    cpu_to_ube32(buf, len - 4); /* data length */
+
+    ide_atapi_cmd_reply(s, len, max_len);
+}
+
+static void cmd_mode_sense(IDEState *s, uint8_t *buf)
+{
+    int action, code;
+    int max_len;
+
+    if (buf[0] == GPCMD_MODE_SENSE_10) {
+        max_len = ube16_to_cpu(buf + 7);
+    } else {
+        max_len = buf[4];
+    }
+
+    action = buf[2] >> 6;
+    code = buf[2] & 0x3f;
+
+    switch(action) {
+    case 0: /* current values */
+        switch(code) {
+        case GPMODE_R_W_ERROR_PAGE: /* error recovery */
+            cpu_to_ube16(&buf[0], 16 + 6);
+            buf[2] = 0x70;
+            buf[3] = 0;
+            buf[4] = 0;
+            buf[5] = 0;
+            buf[6] = 0;
+            buf[7] = 0;
+
+            buf[8] = 0x01;
+            buf[9] = 0x06;
+            buf[10] = 0x00;
+            buf[11] = 0x05;
+            buf[12] = 0x00;
+            buf[13] = 0x00;
+            buf[14] = 0x00;
+            buf[15] = 0x00;
+            ide_atapi_cmd_reply(s, 16, max_len);
+            break;
+        case GPMODE_AUDIO_CTL_PAGE:
+            cpu_to_ube16(&buf[0], 24 + 6);
+            buf[2] = 0x70;
+            buf[3] = 0;
+            buf[4] = 0;
+            buf[5] = 0;
+            buf[6] = 0;
+            buf[7] = 0;
+
+            /* Fill with CDROM audio volume */
+            buf[17] = 0;
+            buf[19] = 0;
+            buf[21] = 0;
+            buf[23] = 0;
+
+            ide_atapi_cmd_reply(s, 24, max_len);
+            break;
+        case GPMODE_CAPABILITIES_PAGE:
+            cpu_to_ube16(&buf[0], 28 + 6);
+            buf[2] = 0x70;
+            buf[3] = 0;
+            buf[4] = 0;
+            buf[5] = 0;
+            buf[6] = 0;
+            buf[7] = 0;
+
+            buf[8] = 0x2a;
+            buf[9] = 0x12;
+            buf[10] = 0x00;
+            buf[11] = 0x00;
+
+            /* Claim PLAY_AUDIO capability (0x01) since some Linux
+               code checks for this to automount media. */
+            buf[12] = 0x71;
+            buf[13] = 3 << 5;
+            buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
+            if (bdrv_is_locked(s->bs))
+                buf[6] |= 1 << 1;
+            buf[15] = 0x00;
+            cpu_to_ube16(&buf[16], 706);
+            buf[18] = 0;
+            buf[19] = 2;
+            cpu_to_ube16(&buf[20], 512);
+            cpu_to_ube16(&buf[22], 706);
+            buf[24] = 0;
+            buf[25] = 0;
+            buf[26] = 0;
+            buf[27] = 0;
+            ide_atapi_cmd_reply(s, 28, max_len);
+            break;
+        default:
+            goto error_cmd;
+        }
+        break;
+    case 1: /* changeable values */
+        goto error_cmd;
+    case 2: /* default values */
+        goto error_cmd;
+    default:
+    case 3: /* saved values */
+        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                            ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
+        break;
+    }
+    return;
+
+error_cmd:
+    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
+}
+
+static void cmd_test_unit_ready(IDEState *s, uint8_t *buf)
+{
+    if (bdrv_is_inserted(s->bs)) {
+        ide_atapi_cmd_ok(s);
+    } else {
+        ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+    }
+}
+
+static void cmd_prevent_allow_medium_removal(IDEState *s, uint8_t* buf)
+{
+    bdrv_set_locked(s->bs, buf[4] & 1);
+    ide_atapi_cmd_ok(s);
+}
+
+static void cmd_read(IDEState *s, uint8_t* buf)
+{
+    int nb_sectors, lba;
+
+    if (buf[0] == GPCMD_READ_10) {
+        nb_sectors = ube16_to_cpu(buf + 7);
+    } else {
+        nb_sectors = ube32_to_cpu(buf + 6);
+    }
+
+    lba = ube32_to_cpu(buf + 2);
+    if (nb_sectors == 0) {
+        ide_atapi_cmd_ok(s);
+        return;
+    }
+
+    ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
+}
+
+static void cmd_read_cd(IDEState *s, uint8_t* buf)
+{
+    int nb_sectors, lba, transfer_request;
+
+    nb_sectors = (buf[6] << 16) | (buf[7] << 8) | buf[8];
+    lba = ube32_to_cpu(buf + 2);
+
+    if (nb_sectors == 0) {
+        ide_atapi_cmd_ok(s);
+        return;
+    }
+
+    transfer_request = buf[9];
+    switch(transfer_request & 0xf8) {
+    case 0x00:
+        /* nothing */
+        ide_atapi_cmd_ok(s);
+        break;
+    case 0x10:
+        /* normal read */
+        ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
+        break;
+    case 0xf8:
+        /* read all data */
+        ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
+        break;
+    default:
+        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                            ASC_INV_FIELD_IN_CMD_PACKET);
+        break;
+    }
+}
+
+static void cmd_seek(IDEState *s, uint8_t* buf)
+{
+    unsigned int lba;
+    uint64_t total_sectors;
+
+    bdrv_get_geometry(s->bs, &total_sectors);
+
+    total_sectors >>= 2;
+    if (total_sectors == 0) {
+        ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+        return;
+    }
+
+    lba = ube32_to_cpu(buf + 2);
+    if (lba >= total_sectors) {
+        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
+        return;
+    }
+
+    ide_atapi_cmd_ok(s);
+}
+
+static void cmd_start_stop_unit(IDEState *s, uint8_t* buf)
+{
+    int start, eject, sense, err = 0;
+    start = buf[4] & 1;
+    eject = (buf[4] >> 1) & 1;
+
+    if (eject) {
+        err = bdrv_eject(s->bs, !start);
+    }
+
+    switch (err) {
+    case 0:
+        ide_atapi_cmd_ok(s);
+        break;
+    case -EBUSY:
+        sense = SENSE_NOT_READY;
+        if (bdrv_is_inserted(s->bs)) {
+            sense = SENSE_ILLEGAL_REQUEST;
+        }
+        ide_atapi_cmd_error(s, sense, ASC_MEDIA_REMOVAL_PREVENTED);
+        break;
+    default:
+        ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+        break;
+    }
+}
+
+static void cmd_mechanism_status(IDEState *s, uint8_t* buf)
+{
+    int max_len = ube16_to_cpu(buf + 8);
+
+    cpu_to_ube16(buf, 0);
+    /* no current LBA */
+    buf[2] = 0;
+    buf[3] = 0;
+    buf[4] = 0;
+    buf[5] = 1;
+    cpu_to_ube16(buf + 6, 0);
+    ide_atapi_cmd_reply(s, 8, max_len);
+}
+
+static void cmd_read_toc_pma_atip(IDEState *s, uint8_t* buf)
+{
+    int format, msf, start_track, len;
+    uint64_t total_sectors;
+    int max_len;
+
+    bdrv_get_geometry(s->bs, &total_sectors);
+
+    total_sectors >>= 2;
+    if (total_sectors == 0) {
+        ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+        return;
+    }
+
+    max_len = ube16_to_cpu(buf + 7);
+    format = buf[9] >> 6;
+    msf = (buf[1] >> 1) & 1;
+    start_track = buf[6];
+
+    switch(format) {
+    case 0:
+        len = cdrom_read_toc(total_sectors, buf, msf, start_track);
+        if (len < 0)
+            goto error_cmd;
+        ide_atapi_cmd_reply(s, len, max_len);
+        break;
+    case 1:
+        /* multi session : only a single session defined */
+        memset(buf, 0, 12);
+        buf[1] = 0x0a;
+        buf[2] = 0x01;
+        buf[3] = 0x01;
+        ide_atapi_cmd_reply(s, 12, max_len);
+        break;
+    case 2:
+        len = cdrom_read_toc_raw(total_sectors, buf, msf, start_track);
+        if (len < 0)
+            goto error_cmd;
+        ide_atapi_cmd_reply(s, len, max_len);
+        break;
+    default:
+    error_cmd:
+        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                            ASC_INV_FIELD_IN_CMD_PACKET);
+    }
+}
+
+static void cmd_read_cdvd_capacity(IDEState *s, uint8_t* buf)
+{
+    uint64_t total_sectors;
+
+    bdrv_get_geometry(s->bs, &total_sectors);
+
+    total_sectors >>= 2;
+    if (total_sectors == 0) {
+        ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+        return;
+    }
+
+    /* NOTE: it is really the number of sectors minus 1 */
+    cpu_to_ube32(buf, total_sectors - 1);
+    cpu_to_ube32(buf + 4, 2048);
+    ide_atapi_cmd_reply(s, 8, 8);
+}
+
+static void cmd_read_dvd_structure(IDEState *s, uint8_t* buf)
+{
+    int max_len;
+    int media = buf[1];
+    int format = buf[7];
+    int ret;
+
+    max_len = ube16_to_cpu(buf + 8);
+
+    if (format < 0xff) {
+        if (media_is_cd(s)) {
+            ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                                ASC_INCOMPATIBLE_FORMAT);
+            return;
+        } else if (!media_present(s)) {
+            ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                                ASC_INV_FIELD_IN_CMD_PACKET);
+            return;
+        }
+    }
+
+    memset(buf, 0, max_len > IDE_DMA_BUF_SECTORS * 512 + 4 ?
+           IDE_DMA_BUF_SECTORS * 512 + 4 : max_len);
+
+    switch (format) {
+        case 0x00 ... 0x7f:
+        case 0xff:
+            if (media == 0) {
+                ret = ide_dvd_read_structure(s, format, buf, buf);
+
+                if (ret < 0) {
+                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, -ret);
+                } else {
+                    ide_atapi_cmd_reply(s, ret, max_len);
+                }
+
+                break;
+            }
+            /* TODO: BD support, fall through for now */
+
+        /* Generic disk structures */
+        case 0x80: /* TODO: AACS volume identifier */
+        case 0x81: /* TODO: AACS media serial number */
+        case 0x82: /* TODO: AACS media identifier */
+        case 0x83: /* TODO: AACS media key block */
+        case 0x90: /* TODO: List of recognized format layers */
+        case 0xc0: /* TODO: Write protection status */
+        default:
+            ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+                                ASC_INV_FIELD_IN_CMD_PACKET);
+            break;
+    }
+}
+
+static void cmd_set_speed(IDEState *s, uint8_t* buf)
+{
+    ide_atapi_cmd_ok(s);
+}
+
 void ide_atapi_cmd(IDEState *s)
 {
     const uint8_t *packet;
     uint8_t *buf;
-    int max_len;
 
     packet = s->io_buffer;
     buf = s->io_buffer;
@@ -665,413 +1107,52 @@ void ide_atapi_cmd(IDEState *s)
     }
     switch(s->io_buffer[0]) {
     case GPCMD_TEST_UNIT_READY:
-        if (bdrv_is_inserted(s->bs)) {
-            ide_atapi_cmd_ok(s);
-        } else {
-            ide_atapi_cmd_error(s, SENSE_NOT_READY,
-                                ASC_MEDIUM_NOT_PRESENT);
-        }
+        cmd_test_unit_ready(s, buf);
         break;
     case GPCMD_MODE_SENSE_6:
     case GPCMD_MODE_SENSE_10:
-        {
-            int action, code;
-            if (packet[0] == GPCMD_MODE_SENSE_10)
-                max_len = ube16_to_cpu(packet + 7);
-            else
-                max_len = packet[4];
-            action = packet[2] >> 6;
-            code = packet[2] & 0x3f;
-            switch(action) {
-            case 0: /* current values */
-                switch(code) {
-                case GPMODE_R_W_ERROR_PAGE: /* error recovery */
-                    cpu_to_ube16(&buf[0], 16 + 6);
-                    buf[2] = 0x70;
-                    buf[3] = 0;
-                    buf[4] = 0;
-                    buf[5] = 0;
-                    buf[6] = 0;
-                    buf[7] = 0;
-
-                    buf[8] = 0x01;
-                    buf[9] = 0x06;
-                    buf[10] = 0x00;
-                    buf[11] = 0x05;
-                    buf[12] = 0x00;
-                    buf[13] = 0x00;
-                    buf[14] = 0x00;
-                    buf[15] = 0x00;
-                    ide_atapi_cmd_reply(s, 16, max_len);
-                    break;
-                case GPMODE_AUDIO_CTL_PAGE:
-                    cpu_to_ube16(&buf[0], 24 + 6);
-                    buf[2] = 0x70;
-                    buf[3] = 0;
-                    buf[4] = 0;
-                    buf[5] = 0;
-                    buf[6] = 0;
-                    buf[7] = 0;
-
-                    /* Fill with CDROM audio volume */
-                    buf[17] = 0;
-                    buf[19] = 0;
-                    buf[21] = 0;
-                    buf[23] = 0;
-
-                    ide_atapi_cmd_reply(s, 24, max_len);
-                    break;
-                case GPMODE_CAPABILITIES_PAGE:
-                    cpu_to_ube16(&buf[0], 28 + 6);
-                    buf[2] = 0x70;
-                    buf[3] = 0;
-                    buf[4] = 0;
-                    buf[5] = 0;
-                    buf[6] = 0;
-                    buf[7] = 0;
-
-                    buf[8] = 0x2a;
-                    buf[9] = 0x12;
-                    buf[10] = 0x00;
-                    buf[11] = 0x00;
-
-                    /* Claim PLAY_AUDIO capability (0x01) since some Linux
-                       code checks for this to automount media. */
-                    buf[12] = 0x71;
-                    buf[13] = 3 << 5;
-                    buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
-                    if (bdrv_is_locked(s->bs))
-                        buf[6] |= 1 << 1;
-                    buf[15] = 0x00;
-                    cpu_to_ube16(&buf[16], 706);
-                    buf[18] = 0;
-                    buf[19] = 2;
-                    cpu_to_ube16(&buf[20], 512);
-                    cpu_to_ube16(&buf[22], 706);
-                    buf[24] = 0;
-                    buf[25] = 0;
-                    buf[26] = 0;
-                    buf[27] = 0;
-                    ide_atapi_cmd_reply(s, 28, max_len);
-                    break;
-                default:
-                    goto error_cmd;
-                }
-                break;
-            case 1: /* changeable values */
-                goto error_cmd;
-            case 2: /* default values */
-                goto error_cmd;
-            default:
-            case 3: /* saved values */
-                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                                    ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
-                break;
-            }
-        }
+        cmd_mode_sense(s, buf);
         break;
     case GPCMD_REQUEST_SENSE:
-        max_len = packet[4];
-        memset(buf, 0, 18);
-        buf[0] = 0x70 | (1 << 7);
-        buf[2] = s->sense_key;
-        buf[7] = 10;
-        buf[12] = s->asc;
-        if (s->sense_key == SENSE_UNIT_ATTENTION)
-            s->sense_key = SENSE_NONE;
-        ide_atapi_cmd_reply(s, 18, max_len);
+        cmd_request_sense(s, buf);
         break;
     case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
-        bdrv_set_locked(s->bs, packet[4] & 1);
-        ide_atapi_cmd_ok(s);
+        cmd_prevent_allow_medium_removal(s, buf);
         break;
     case GPCMD_READ_10:
     case GPCMD_READ_12:
-        {
-            int nb_sectors, lba;
-
-            if (packet[0] == GPCMD_READ_10)
-                nb_sectors = ube16_to_cpu(packet + 7);
-            else
-                nb_sectors = ube32_to_cpu(packet + 6);
-            lba = ube32_to_cpu(packet + 2);
-            if (nb_sectors == 0) {
-                ide_atapi_cmd_ok(s);
-                break;
-            }
-            ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
-        }
+        cmd_read(s, buf);
         break;
     case GPCMD_READ_CD:
-        {
-            int nb_sectors, lba, transfer_request;
-
-            nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
-            lba = ube32_to_cpu(packet + 2);
-            if (nb_sectors == 0) {
-                ide_atapi_cmd_ok(s);
-                break;
-            }
-            transfer_request = packet[9];
-            switch(transfer_request & 0xf8) {
-            case 0x00:
-                /* nothing */
-                ide_atapi_cmd_ok(s);
-                break;
-            case 0x10:
-                /* normal read */
-                ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
-                break;
-            case 0xf8:
-                /* read all data */
-                ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
-                break;
-            default:
-                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                                    ASC_INV_FIELD_IN_CMD_PACKET);
-                break;
-            }
-        }
+        cmd_read_cd(s, buf);
         break;
     case GPCMD_SEEK:
-        {
-            unsigned int lba;
-            uint64_t total_sectors;
-
-            bdrv_get_geometry(s->bs, &total_sectors);
-            total_sectors >>= 2;
-            if (total_sectors == 0) {
-                ide_atapi_cmd_error(s, SENSE_NOT_READY,
-                                    ASC_MEDIUM_NOT_PRESENT);
-                break;
-            }
-            lba = ube32_to_cpu(packet + 2);
-            if (lba >= total_sectors) {
-                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                                    ASC_LOGICAL_BLOCK_OOR);
-                break;
-            }
-            ide_atapi_cmd_ok(s);
-        }
+        cmd_seek(s, buf);
         break;
     case GPCMD_START_STOP_UNIT:
-        {
-            int start, eject, sense, err = 0;
-            start = packet[4] & 1;
-            eject = (packet[4] >> 1) & 1;
-
-            if (eject) {
-                err = bdrv_eject(s->bs, !start);
-            }
-
-            switch (err) {
-            case 0:
-                ide_atapi_cmd_ok(s);
-                break;
-            case -EBUSY:
-                sense = SENSE_NOT_READY;
-                if (bdrv_is_inserted(s->bs)) {
-                    sense = SENSE_ILLEGAL_REQUEST;
-                }
-                ide_atapi_cmd_error(s, sense,
-                                    ASC_MEDIA_REMOVAL_PREVENTED);
-                break;
-            default:
-                ide_atapi_cmd_error(s, SENSE_NOT_READY,
-                                    ASC_MEDIUM_NOT_PRESENT);
-                break;
-            }
-        }
+        cmd_start_stop_unit(s, buf);
         break;
     case GPCMD_MECHANISM_STATUS:
-        {
-            max_len = ube16_to_cpu(packet + 8);
-            cpu_to_ube16(buf, 0);
-            /* no current LBA */
-            buf[2] = 0;
-            buf[3] = 0;
-            buf[4] = 0;
-            buf[5] = 1;
-            cpu_to_ube16(buf + 6, 0);
-            ide_atapi_cmd_reply(s, 8, max_len);
-        }
+        cmd_mechanism_status(s, buf);
         break;
     case GPCMD_READ_TOC_PMA_ATIP:
-        {
-            int format, msf, start_track, len;
-            uint64_t total_sectors;
-
-            bdrv_get_geometry(s->bs, &total_sectors);
-            total_sectors >>= 2;
-            if (total_sectors == 0) {
-                ide_atapi_cmd_error(s, SENSE_NOT_READY,
-                                    ASC_MEDIUM_NOT_PRESENT);
-                break;
-            }
-            max_len = ube16_to_cpu(packet + 7);
-            format = packet[9] >> 6;
-            msf = (packet[1] >> 1) & 1;
-            start_track = packet[6];
-            switch(format) {
-            case 0:
-                len = cdrom_read_toc(total_sectors, buf, msf, start_track);
-                if (len < 0)
-                    goto error_cmd;
-                ide_atapi_cmd_reply(s, len, max_len);
-                break;
-            case 1:
-                /* multi session : only a single session defined */
-                memset(buf, 0, 12);
-                buf[1] = 0x0a;
-                buf[2] = 0x01;
-                buf[3] = 0x01;
-                ide_atapi_cmd_reply(s, 12, max_len);
-                break;
-            case 2:
-                len = cdrom_read_toc_raw(total_sectors, buf, msf, start_track);
-                if (len < 0)
-                    goto error_cmd;
-                ide_atapi_cmd_reply(s, len, max_len);
-                break;
-            default:
-            error_cmd:
-                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                                    ASC_INV_FIELD_IN_CMD_PACKET);
-                break;
-            }
-        }
+        cmd_read_toc_pma_atip(s, buf);
         break;
     case GPCMD_READ_CDVD_CAPACITY:
-        {
-            uint64_t total_sectors;
-
-            bdrv_get_geometry(s->bs, &total_sectors);
-            total_sectors >>= 2;
-            if (total_sectors == 0) {
-                ide_atapi_cmd_error(s, SENSE_NOT_READY,
-                                    ASC_MEDIUM_NOT_PRESENT);
-                break;
-            }
-            /* NOTE: it is really the number of sectors minus 1 */
-            cpu_to_ube32(buf, total_sectors - 1);
-            cpu_to_ube32(buf + 4, 2048);
-            ide_atapi_cmd_reply(s, 8, 8);
-        }
+        cmd_read_cdvd_capacity(s, buf);
         break;
     case GPCMD_READ_DVD_STRUCTURE:
-        {
-            int media = packet[1];
-            int format = packet[7];
-            int ret;
-
-            max_len = ube16_to_cpu(packet + 8);
-
-            if (format < 0xff) {
-                if (media_is_cd(s)) {
-                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                                        ASC_INCOMPATIBLE_FORMAT);
-                    break;
-                } else if (!media_present(s)) {
-                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                                        ASC_INV_FIELD_IN_CMD_PACKET);
-                    break;
-                }
-            }
-
-            memset(buf, 0, max_len > IDE_DMA_BUF_SECTORS * 512 + 4 ?
-                   IDE_DMA_BUF_SECTORS * 512 + 4 : max_len);
-
-            switch (format) {
-                case 0x00 ... 0x7f:
-                case 0xff:
-                    if (media == 0) {
-                        ret = ide_dvd_read_structure(s, format, packet, buf);
-
-                        if (ret < 0)
-                            ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, -ret);
-                        else
-                            ide_atapi_cmd_reply(s, ret, max_len);
-
-                        break;
-                    }
-                    /* TODO: BD support, fall through for now */
-
-                /* Generic disk structures */
-                case 0x80: /* TODO: AACS volume identifier */
-                case 0x81: /* TODO: AACS media serial number */
-                case 0x82: /* TODO: AACS media identifier */
-                case 0x83: /* TODO: AACS media key block */
-                case 0x90: /* TODO: List of recognized format layers */
-                case 0xc0: /* TODO: Write protection status */
-                default:
-                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                                        ASC_INV_FIELD_IN_CMD_PACKET);
-                    break;
-            }
-        }
+        cmd_read_dvd_structure(s, buf);
         break;
     case GPCMD_SET_SPEED:
-        ide_atapi_cmd_ok(s);
+        cmd_set_speed(s, buf);
         break;
     case GPCMD_INQUIRY:
-        max_len = packet[4];
-        buf[0] = 0x05; /* CD-ROM */
-        buf[1] = 0x80; /* removable */
-        buf[2] = 0x00; /* ISO */
-        buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
-        buf[4] = 31; /* additional length */
-        buf[5] = 0; /* reserved */
-        buf[6] = 0; /* reserved */
-        buf[7] = 0; /* reserved */
-        padstr8(buf + 8, 8, "QEMU");
-        padstr8(buf + 16, 16, "QEMU DVD-ROM");
-        padstr8(buf + 32, 4, s->version);
-        ide_atapi_cmd_reply(s, 36, max_len);
+        cmd_inquiry(s, buf);
         break;
     case GPCMD_GET_CONFIGURATION:
-        {
-            uint32_t len;
-            uint8_t index = 0;
-
-            /* only feature 0 is supported */
-            if (packet[2] != 0 || packet[3] != 0) {
-                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                                    ASC_INV_FIELD_IN_CMD_PACKET);
-                break;
-            }
-
-            /* XXX: could result in alignment problems in some architectures */
-            max_len = ube16_to_cpu(packet + 7);
-
-            /*
-             * XXX: avoid overflow for io_buffer if max_len is bigger than
-             *      the size of that buffer (dimensioned to max number of
-             *      sectors to transfer at once)
-             *
-             *      Only a problem if the feature/profiles grow.
-             */
-            if (max_len > 512) /* XXX: assume 1 sector */
-                max_len = 512;
-
-            memset(buf, 0, max_len);
-            /*
-             * the number of sectors from the media tells us which profile
-             * to use as current.  0 means there is no media
-             */
-            if (media_is_dvd(s))
-                cpu_to_ube16(buf + 6, MMC_PROFILE_DVD_ROM);
-            else if (media_is_cd(s))
-                cpu_to_ube16(buf + 6, MMC_PROFILE_CD_ROM);
-
-            buf[10] = 0x02 | 0x01; /* persistent and current */
-            len = 12; /* headers: 8 + 4 */
-            len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_DVD_ROM);
-            len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_CD_ROM);
-            cpu_to_ube32(buf, len - 4); /* data length */
-
-            ide_atapi_cmd_reply(s, len, max_len);
-            break;
-        }
+        cmd_get_configuration(s, buf);
+        break;
     case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
         handle_get_event_status_notification(s, buf, packet);
         break;

From e1a064f982802ebb4a865482b7c0fe5e68d047f9 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Mon, 18 Apr 2011 17:55:08 +0200
Subject: [PATCH 339/386] ide/atapi: Use table instead of switch for commands

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/atapi.c | 115 +++++++++++++++++++++----------------------------
 1 file changed, 48 insertions(+), 67 deletions(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 25b796e7e5..277404b615 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -533,10 +533,11 @@ static unsigned int event_status_media(IDEState *s,
     return 8; /* We wrote to 4 extra bytes from the header */
 }
 
-static void handle_get_event_status_notification(IDEState *s,
-                                                 uint8_t *buf,
-                                                 const uint8_t *packet)
+static void cmd_get_event_status_notification(IDEState *s,
+                                              uint8_t *buf)
 {
+    const uint8_t *packet = buf;
+
     struct {
         uint8_t opcode;
         uint8_t polled;        /* lsb bit is polled; others are reserved */
@@ -1064,6 +1065,38 @@ static void cmd_set_speed(IDEState *s, uint8_t* buf)
     ide_atapi_cmd_ok(s);
 }
 
+enum {
+    /*
+     * Only commands flagged as ALLOW_UA are allowed to run under a
+     * unit attention condition. (See MMC-5, section 4.1.6.1)
+     */
+    ALLOW_UA = 0x01,
+};
+
+static const struct {
+    void (*handler)(IDEState *s, uint8_t *buf);
+    int flags;
+} atapi_cmd_table[0x100] = {
+    [ 0x00 ] = { cmd_test_unit_ready,               0 },
+    [ 0x03 ] = { cmd_request_sense,                 ALLOW_UA },
+    [ 0x12 ] = { cmd_inquiry,                       ALLOW_UA },
+    [ 0x1a ] = { cmd_mode_sense, /* (6) */          0 },
+    [ 0x1b ] = { cmd_start_stop_unit,               0 },
+    [ 0x1e ] = { cmd_prevent_allow_medium_removal,  0 },
+    [ 0x25 ] = { cmd_read_cdvd_capacity,            0 },
+    [ 0x28 ] = { cmd_read, /* (10) */               0 },
+    [ 0x2b ] = { cmd_seek,                          0 },
+    [ 0x43 ] = { cmd_read_toc_pma_atip,             0 },
+    [ 0x46 ] = { cmd_get_configuration,             ALLOW_UA },
+    [ 0x4a ] = { cmd_get_event_status_notification, ALLOW_UA },
+    [ 0x5a ] = { cmd_mode_sense, /* (10) */         0 },
+    [ 0xa8 ] = { cmd_read, /* (12) */               0 },
+    [ 0xad ] = { cmd_read_dvd_structure,            0 },
+    [ 0xbb ] = { cmd_set_speed,                     0 },
+    [ 0xbd ] = { cmd_mechanism_status,              0 },
+    [ 0xbe ] = { cmd_read_cd,                       0 },
+};
+
 void ide_atapi_cmd(IDEState *s)
 {
     const uint8_t *packet;
@@ -1082,21 +1115,17 @@ void ide_atapi_cmd(IDEState *s)
     }
 #endif
     /*
-     * If there's a UNIT_ATTENTION condition pending, only
-     * REQUEST_SENSE, INQUIRY, GET_CONFIGURATION and
-     * GET_EVENT_STATUS_NOTIFICATION commands are allowed to complete.
-     * MMC-5, section 4.1.6.1 lists only these commands being allowed
-     * to complete, with other commands getting a CHECK condition
-     * response unless a higher priority status, defined by the drive
+     * If there's a UNIT_ATTENTION condition pending, only command flagged with
+     * ALLOW_UA are allowed to complete. with other commands getting a CHECK
+     * condition response unless a higher priority status, defined by the drive
      * here, is pending.
      */
     if (s->sense_key == SENSE_UNIT_ATTENTION &&
-        s->io_buffer[0] != GPCMD_REQUEST_SENSE &&
-        s->io_buffer[0] != GPCMD_INQUIRY &&
-        s->io_buffer[0] != GPCMD_GET_EVENT_STATUS_NOTIFICATION) {
+        !(atapi_cmd_table[s->io_buffer[0]].flags & ALLOW_UA)) {
         ide_atapi_cmd_check_status(s);
         return;
     }
+
     if (bdrv_is_inserted(s->bs) && s->cdrom_changed) {
         ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
 
@@ -1105,60 +1134,12 @@ void ide_atapi_cmd(IDEState *s)
         s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED;
         return;
     }
-    switch(s->io_buffer[0]) {
-    case GPCMD_TEST_UNIT_READY:
-        cmd_test_unit_ready(s, buf);
-        break;
-    case GPCMD_MODE_SENSE_6:
-    case GPCMD_MODE_SENSE_10:
-        cmd_mode_sense(s, buf);
-        break;
-    case GPCMD_REQUEST_SENSE:
-        cmd_request_sense(s, buf);
-        break;
-    case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
-        cmd_prevent_allow_medium_removal(s, buf);
-        break;
-    case GPCMD_READ_10:
-    case GPCMD_READ_12:
-        cmd_read(s, buf);
-        break;
-    case GPCMD_READ_CD:
-        cmd_read_cd(s, buf);
-        break;
-    case GPCMD_SEEK:
-        cmd_seek(s, buf);
-        break;
-    case GPCMD_START_STOP_UNIT:
-        cmd_start_stop_unit(s, buf);
-        break;
-    case GPCMD_MECHANISM_STATUS:
-        cmd_mechanism_status(s, buf);
-        break;
-    case GPCMD_READ_TOC_PMA_ATIP:
-        cmd_read_toc_pma_atip(s, buf);
-        break;
-    case GPCMD_READ_CDVD_CAPACITY:
-        cmd_read_cdvd_capacity(s, buf);
-        break;
-    case GPCMD_READ_DVD_STRUCTURE:
-        cmd_read_dvd_structure(s, buf);
-        break;
-    case GPCMD_SET_SPEED:
-        cmd_set_speed(s, buf);
-        break;
-    case GPCMD_INQUIRY:
-        cmd_inquiry(s, buf);
-        break;
-    case GPCMD_GET_CONFIGURATION:
-        cmd_get_configuration(s, buf);
-        break;
-    case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
-        handle_get_event_status_notification(s, buf, packet);
-        break;
-    default:
-        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
-                            ASC_ILLEGAL_OPCODE);
-        break;
+
+    /* Execute the command */
+    if (atapi_cmd_table[s->io_buffer[0]].handler) {
+        atapi_cmd_table[s->io_buffer[0]].handler(s, buf);
+        return;
     }
+
+    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE);
 }

From e119bcaceb8dc17fe4874d6b0d2b62752639e488 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 19 Apr 2011 13:13:44 +0200
Subject: [PATCH 340/386] ide/atapi: Replace bdrv_get_geometry calls by
 s->nb_sectors

The disk size can only change when the medium is changed, and the change
callback takes care of updating s->nb_sectors in this case.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/atapi.c | 21 ++++++---------------
 1 file changed, 6 insertions(+), 15 deletions(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 277404b615..0452337175 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -416,10 +416,10 @@ static int ide_dvd_read_structure(IDEState *s, int format,
                 if (layer != 0)
                     return -ASC_INV_FIELD_IN_CMD_PACKET;
 
-                bdrv_get_geometry(s->bs, &total_sectors);
-                total_sectors >>= 2;
-                if (total_sectors == 0)
+                total_sectors = s->nb_sectors >> 2;
+                if (total_sectors == 0) {
                     return -ASC_MEDIUM_NOT_PRESENT;
+                }
 
                 buf[4] = 1;   /* DVD-ROM, part version 1 */
                 buf[5] = 0xf; /* 120mm disc, minimum rate unspecified */
@@ -881,11 +881,8 @@ static void cmd_read_cd(IDEState *s, uint8_t* buf)
 static void cmd_seek(IDEState *s, uint8_t* buf)
 {
     unsigned int lba;
-    uint64_t total_sectors;
+    uint64_t total_sectors = s->nb_sectors >> 2;
 
-    bdrv_get_geometry(s->bs, &total_sectors);
-
-    total_sectors >>= 2;
     if (total_sectors == 0) {
         ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
         return;
@@ -944,12 +941,9 @@ static void cmd_mechanism_status(IDEState *s, uint8_t* buf)
 static void cmd_read_toc_pma_atip(IDEState *s, uint8_t* buf)
 {
     int format, msf, start_track, len;
-    uint64_t total_sectors;
+    uint64_t total_sectors = s->nb_sectors >> 2;
     int max_len;
 
-    bdrv_get_geometry(s->bs, &total_sectors);
-
-    total_sectors >>= 2;
     if (total_sectors == 0) {
         ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
         return;
@@ -990,11 +984,8 @@ static void cmd_read_toc_pma_atip(IDEState *s, uint8_t* buf)
 
 static void cmd_read_cdvd_capacity(IDEState *s, uint8_t* buf)
 {
-    uint64_t total_sectors;
+    uint64_t total_sectors = s->nb_sectors >> 2;
 
-    bdrv_get_geometry(s->bs, &total_sectors);
-
-    total_sectors >>= 2;
     if (total_sectors == 0) {
         ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
         return;

From 7a2c4b82340d621bff462672b29c88d2020d68c1 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 19 Apr 2011 13:15:52 +0200
Subject: [PATCH 341/386] ide/atapi: Introduce CHECK_READY flag for commands

Some commands are supposed to report a Not Ready Condition (i.e. they require
a medium to be present in order to execute successfully). Instead of
duplicating the check in each command implementation, let's add a flag and
check it before calling the command.

This patch only converts existing checks, it does not introduce new checks for
any of the other commands that can/should report a Not Ready Condition.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/atapi.c | 48 +++++++++++++++++++++++-------------------------
 1 file changed, 23 insertions(+), 25 deletions(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 0452337175..690a0abdda 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -813,11 +813,9 @@ error_cmd:
 
 static void cmd_test_unit_ready(IDEState *s, uint8_t *buf)
 {
-    if (bdrv_is_inserted(s->bs)) {
-        ide_atapi_cmd_ok(s);
-    } else {
-        ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
-    }
+    /* Not Ready Conditions are already handled in ide_atapi_cmd(), so if we
+     * come here, we know that it's ready. */
+    ide_atapi_cmd_ok(s);
 }
 
 static void cmd_prevent_allow_medium_removal(IDEState *s, uint8_t* buf)
@@ -883,11 +881,6 @@ static void cmd_seek(IDEState *s, uint8_t* buf)
     unsigned int lba;
     uint64_t total_sectors = s->nb_sectors >> 2;
 
-    if (total_sectors == 0) {
-        ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
-        return;
-    }
-
     lba = ube32_to_cpu(buf + 2);
     if (lba >= total_sectors) {
         ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
@@ -941,13 +934,8 @@ static void cmd_mechanism_status(IDEState *s, uint8_t* buf)
 static void cmd_read_toc_pma_atip(IDEState *s, uint8_t* buf)
 {
     int format, msf, start_track, len;
-    uint64_t total_sectors = s->nb_sectors >> 2;
     int max_len;
-
-    if (total_sectors == 0) {
-        ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
-        return;
-    }
+    uint64_t total_sectors = s->nb_sectors >> 2;
 
     max_len = ube16_to_cpu(buf + 7);
     format = buf[9] >> 6;
@@ -986,11 +974,6 @@ static void cmd_read_cdvd_capacity(IDEState *s, uint8_t* buf)
 {
     uint64_t total_sectors = s->nb_sectors >> 2;
 
-    if (total_sectors == 0) {
-        ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
-        return;
-    }
-
     /* NOTE: it is really the number of sectors minus 1 */
     cpu_to_ube32(buf, total_sectors - 1);
     cpu_to_ube32(buf + 4, 2048);
@@ -1062,22 +1045,29 @@ enum {
      * unit attention condition. (See MMC-5, section 4.1.6.1)
      */
     ALLOW_UA = 0x01,
+
+    /*
+     * Commands flagged with CHECK_READY can only execute if a medium is present.
+     * Otherwise they report the Not Ready Condition. (See MMC-5, section
+     * 4.1.8)
+     */
+    CHECK_READY = 0x02,
 };
 
 static const struct {
     void (*handler)(IDEState *s, uint8_t *buf);
     int flags;
 } atapi_cmd_table[0x100] = {
-    [ 0x00 ] = { cmd_test_unit_ready,               0 },
+    [ 0x00 ] = { cmd_test_unit_ready,               CHECK_READY },
     [ 0x03 ] = { cmd_request_sense,                 ALLOW_UA },
     [ 0x12 ] = { cmd_inquiry,                       ALLOW_UA },
     [ 0x1a ] = { cmd_mode_sense, /* (6) */          0 },
     [ 0x1b ] = { cmd_start_stop_unit,               0 },
     [ 0x1e ] = { cmd_prevent_allow_medium_removal,  0 },
-    [ 0x25 ] = { cmd_read_cdvd_capacity,            0 },
+    [ 0x25 ] = { cmd_read_cdvd_capacity,            CHECK_READY },
     [ 0x28 ] = { cmd_read, /* (10) */               0 },
-    [ 0x2b ] = { cmd_seek,                          0 },
-    [ 0x43 ] = { cmd_read_toc_pma_atip,             0 },
+    [ 0x2b ] = { cmd_seek,                          CHECK_READY },
+    [ 0x43 ] = { cmd_read_toc_pma_atip,             CHECK_READY },
     [ 0x46 ] = { cmd_get_configuration,             ALLOW_UA },
     [ 0x4a ] = { cmd_get_event_status_notification, ALLOW_UA },
     [ 0x5a ] = { cmd_mode_sense, /* (10) */         0 },
@@ -1126,6 +1116,14 @@ void ide_atapi_cmd(IDEState *s)
         return;
     }
 
+    /* Report a Not Ready condition if appropriate for the command */
+    if ((atapi_cmd_table[s->io_buffer[0]].flags & CHECK_READY) &&
+        (!media_present(s) || !bdrv_is_inserted(s->bs)))
+    {
+        ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+        return;
+    }
+
     /* Execute the command */
     if (atapi_cmd_table[s->io_buffer[0]].handler) {
         atapi_cmd_table[s->io_buffer[0]].handler(s, buf);

From 19dfc44a94f759848a0f7de7378b2f8b9af6b5d0 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Date: Sun, 24 Apr 2011 18:38:58 +0100
Subject: [PATCH 342/386] qed: Fix consistency check on 32-bit hosts

The qed_bytes_to_clusters() function is normally used with size_t
lengths.  Consistency check used it with file size length and therefore
failed on 32-bit hosts when the image file is 4 GB or more.

Make qed_bytes_to_clusters() explicitly 64-bit and update consistency
check to keep 64-bit cluster counts.

Reported-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/qed-check.c | 4 ++--
 block/qed.h       | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/block/qed-check.c b/block/qed-check.c
index ea4ebc8e20..22cd07fa1f 100644
--- a/block/qed-check.c
+++ b/block/qed-check.c
@@ -18,7 +18,7 @@ typedef struct {
     BdrvCheckResult *result;
     bool fix;                           /* whether to fix invalid offsets */
 
-    size_t nclusters;
+    uint64_t nclusters;
     uint32_t *used_clusters;            /* referenced cluster bitmap */
 
     QEDRequest request;
@@ -177,7 +177,7 @@ static int qed_check_l1_table(QEDCheck *check, QEDTable *table)
 static void qed_check_for_leaks(QEDCheck *check)
 {
     BDRVQEDState *s = check->s;
-    size_t i;
+    uint64_t i;
 
     for (i = s->header.header_size; i < check->nclusters; i++) {
         if (!qed_test_bit(check->used_clusters, i)) {
diff --git a/block/qed.h b/block/qed.h
index 3e1ab84781..1d1421fee1 100644
--- a/block/qed.h
+++ b/block/qed.h
@@ -252,7 +252,7 @@ static inline uint64_t qed_offset_into_cluster(BDRVQEDState *s, uint64_t offset)
     return offset & (s->header.cluster_size - 1);
 }
 
-static inline unsigned int qed_bytes_to_clusters(BDRVQEDState *s, size_t bytes)
+static inline uint64_t qed_bytes_to_clusters(BDRVQEDState *s, uint64_t bytes)
 {
     return qed_start_of_cluster(s, bytes + (s->header.cluster_size - 1)) /
            (s->header.cluster_size - 1);

From a55c73ba3fb3f5700788933c519c193c5e85c878 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@redhat.com>
Date: Wed, 27 Apr 2011 14:31:50 +0200
Subject: [PATCH 343/386] Add dd-style SIGUSR1 progress reporting

This introduces support for dd-style progress reporting on POSIX
systems, if the user hasn't specified -p to report progress. If sent a
SIGUSR1, qemu-img will report current progress for commands that
support progress reporting.

Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qemu-progress.c | 53 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 48 insertions(+), 5 deletions(-)

diff --git a/qemu-progress.c b/qemu-progress.c
index 656e065b1d..b4b751c9ec 100644
--- a/qemu-progress.c
+++ b/qemu-progress.c
@@ -26,12 +26,15 @@
 #include "osdep.h"
 #include "sysemu.h"
 #include <stdio.h>
+#include <signal.h>
 
 struct progress_state {
     int enabled;
     float current;
     float last_print;
     float min_skip;
+    void (*print)(void);
+    void (*end)(void);
 };
 
 static struct progress_state state;
@@ -51,20 +54,60 @@ static void progress_simple_print(void)
 
 static void progress_simple_end(void)
 {
-    if (state.enabled) {
-        printf("\n");
-    }
+    printf("\n");
+}
+
+static void progress_simple_init(void)
+{
+    state.print = progress_simple_print;
+    state.end = progress_simple_end;
+}
+
+#ifdef CONFIG_POSIX
+static void sigusr_print(int signal)
+{
+    printf("    (%3.2f/100%%)\n", state.current);
+}
+#endif
+
+static void progress_dummy_print(void)
+{
+}
+
+static void progress_dummy_end(void)
+{
+}
+
+static void progress_dummy_init(void)
+{
+#ifdef CONFIG_POSIX
+    struct sigaction action;
+
+    memset(&action, 0, sizeof(action));
+    sigfillset(&action.sa_mask);
+    action.sa_handler = sigusr_print;
+    action.sa_flags = 0;
+    sigaction(SIGUSR1, &action, NULL);
+#endif
+
+    state.print = progress_dummy_print;
+    state.end = progress_dummy_end;
 }
 
 void qemu_progress_init(int enabled, float min_skip)
 {
     state.enabled = enabled;
     state.min_skip = min_skip;
+    if (enabled) {
+        progress_simple_init();
+    } else {
+        progress_dummy_init();
+    }
 }
 
 void qemu_progress_end(void)
 {
-    progress_simple_end();
+    state.end();
 }
 
 void qemu_progress_print(float percent, int max)
@@ -84,6 +127,6 @@ void qemu_progress_print(float percent, int max)
     if (current > (state.last_print + state.min_skip) ||
         (current == 100) || (current == 0)) {
         state.last_print = state.current;
-        progress_simple_print();
+        state.print();
     }
 }

From df6e008a8814af9db872f1319b58784d87987c93 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@redhat.com>
Date: Wed, 27 Apr 2011 14:31:51 +0200
Subject: [PATCH 344/386] Remove obsolete 'enabled' variable from progress
 state

Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qemu-progress.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/qemu-progress.c b/qemu-progress.c
index b4b751c9ec..e1feb89614 100644
--- a/qemu-progress.c
+++ b/qemu-progress.c
@@ -29,7 +29,6 @@
 #include <signal.h>
 
 struct progress_state {
-    int enabled;
     float current;
     float last_print;
     float min_skip;
@@ -46,10 +45,8 @@ static struct progress_state state;
  */
 static void progress_simple_print(void)
 {
-    if (state.enabled) {
-        printf("    (%3.2f/100%%)\r", state.current);
-        fflush(stdout);
-    }
+    printf("    (%3.2f/100%%)\r", state.current);
+    fflush(stdout);
 }
 
 static void progress_simple_end(void)
@@ -96,7 +93,6 @@ static void progress_dummy_init(void)
 
 void qemu_progress_init(int enabled, float min_skip)
 {
-    state.enabled = enabled;
     state.min_skip = min_skip;
     if (enabled) {
         progress_simple_init();

From c6a0487b1fc29bc6047da0e484f79d4d627f9018 Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Tue, 26 Apr 2011 10:17:48 +0200
Subject: [PATCH 345/386] rtl8139: Fix compilation for w32/w64

Compilation for Windows needs a different declaration for the
printf format attribute, so use the macro which was defined for
this purpose.

Cc: Benjamin Poirier <benjamin.poirier@gmail.com>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/rtl8139.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index cbf667a301..515652f270 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -88,8 +88,7 @@
 #  define DPRINTF(fmt, ...) \
     do { fprintf(stderr, "RTL8139: " fmt, ## __VA_ARGS__); } while (0)
 #else
-static inline __attribute__ ((format (printf, 1, 2)))
-    int DPRINTF(const char *fmt, ...)
+static inline GCC_FMT_ATTR(1, 2) int DPRINTF(const char *fmt, ...)
 {
     return 0;
 }

From 70afb8ff90e9d922ed729e6dbabaff6d67c461aa Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Sun, 3 Apr 2011 18:22:45 +0200
Subject: [PATCH 346/386] darwin-user: Remove unneeded null pointer check

cppcheck reports this error:

commpage.c:223: error: Possible null pointer dereference:
value - otherwise it is redundant to check if value is null at line 214

The null pointer check in line 214 is indeed not needed.
If value were null, the code would crash in line 223.
See do_compare_and_swap64 were for a reference.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 darwin-user/commpage.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/darwin-user/commpage.c b/darwin-user/commpage.c
index f6aa71e058..cc29bddd95 100644
--- a/darwin-user/commpage.c
+++ b/darwin-user/commpage.c
@@ -211,7 +211,7 @@ void do_compare_and_swap32(void *cpu_env, int num)
     uint32_t *value = (uint32_t*)((CPUX86State*)cpu_env)->regs[R_ECX];
     DPRINTF("commpage: compare_and_swap32(%x,new,%p)\n", old, value);
 
-    if(value && old == tswap32(*value))
+    if(old == tswap32(*value))
     {
         uint32_t new = ((CPUX86State*)cpu_env)->regs[R_EDX];
         *value = tswap32(new);

From 661bfc80e876d32da8befe53ba0234d87fc0bcc2 Mon Sep 17 00:00:00 2001
From: Jan Kiszka <jan.kiszka@web.de>
Date: Sun, 10 Apr 2011 12:53:39 +0200
Subject: [PATCH 347/386] pflash: Restore & fix lazy ROMD switching

Commit 5145b3d1cc revealed a bug in the lazy ROMD switch-back logic, but
resolved it by breaking that feature. This approach addresses the issue
by switching back to ROMD after a certain amount of read accesses
without further unlock sequences.

Signed-off-by: Jan Kiszka <jan.kiszka@web.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/pflash_cfi02.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c
index 370c5eef7b..14bbc34e16 100644
--- a/hw/pflash_cfi02.c
+++ b/hw/pflash_cfi02.c
@@ -50,6 +50,8 @@ do {                                               \
 #define DPRINTF(fmt, ...) do { } while (0)
 #endif
 
+#define PFLASH_LAZY_ROMD_THRESHOLD 42
+
 struct pflash_t {
     BlockDriverState *bs;
     target_phys_addr_t base;
@@ -70,6 +72,7 @@ struct pflash_t {
     ram_addr_t off;
     int fl_mem;
     int rom_mode;
+    int read_counter; /* used for lazy switch-back to rom mode */
     void *storage;
 };
 
@@ -112,10 +115,10 @@ static uint32_t pflash_read (pflash_t *pfl, target_phys_addr_t offset,
 
     DPRINTF("%s: offset " TARGET_FMT_plx "\n", __func__, offset);
     ret = -1;
-    if (!pfl->rom_mode) {
-        /* Lazy reset of to ROMD mode */
-        if (pfl->wcycle == 0)
-            pflash_register_memory(pfl, 1);
+    /* Lazy reset to ROMD mode after a certain amount of read accesses */
+    if (!pfl->rom_mode && pfl->wcycle == 0 &&
+        ++pfl->read_counter > PFLASH_LAZY_ROMD_THRESHOLD) {
+        pflash_register_memory(pfl, 1);
     }
     offset &= pfl->chip_len - 1;
     boff = offset & 0xFF;
@@ -254,6 +257,7 @@ static void pflash_write (pflash_t *pfl, target_phys_addr_t offset,
         /* Set the device in I/O access mode if required */
         if (pfl->rom_mode)
             pflash_register_memory(pfl, 0);
+        pfl->read_counter = 0;
         /* We're in read mode */
     check_unlock0:
         if (boff == 0x55 && cmd == 0x98) {

From 353ac78d495ef976242abd868f68d78420861c2c Mon Sep 17 00:00:00 2001
From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Date: Fri, 28 Jan 2011 18:09:08 +0530
Subject: [PATCH 348/386] virtio-9p: move 9p files around

Now that we start adding more files related to 9pfs
it make sense to move them to a separate directory

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
---
 Makefile.objs                        | 10 +++++++---
 Makefile.target                      |  6 ++++--
 configure                            |  2 ++
 {hw => fsdev}/file-op-9p.h           |  0
 fsdev/qemu-fsdev.h                   |  2 +-
 hw/{ => 9pfs}/virtio-9p-debug.c      |  0
 hw/{ => 9pfs}/virtio-9p-debug.h      |  0
 hw/{ => 9pfs}/virtio-9p-local.c      |  0
 hw/{ => 9pfs}/virtio-9p-posix-acl.c  |  2 +-
 hw/{ => 9pfs}/virtio-9p-xattr-user.c |  2 +-
 hw/{ => 9pfs}/virtio-9p-xattr.c      |  2 +-
 hw/{ => 9pfs}/virtio-9p-xattr.h      |  0
 hw/{ => 9pfs}/virtio-9p.c            |  0
 hw/{ => 9pfs}/virtio-9p.h            |  2 +-
 14 files changed, 18 insertions(+), 10 deletions(-)
 rename {hw => fsdev}/file-op-9p.h (100%)
 rename hw/{ => 9pfs}/virtio-9p-debug.c (100%)
 rename hw/{ => 9pfs}/virtio-9p-debug.h (100%)
 rename hw/{ => 9pfs}/virtio-9p-local.c (100%)
 rename hw/{ => 9pfs}/virtio-9p-posix-acl.c (99%)
 rename hw/{ => 9pfs}/virtio-9p-xattr-user.c (98%)
 rename hw/{ => 9pfs}/virtio-9p-xattr.c (99%)
 rename hw/{ => 9pfs}/virtio-9p-xattr.h (100%)
 rename hw/{ => 9pfs}/virtio-9p.c (100%)
 rename hw/{ => 9pfs}/virtio-9p.h (99%)

diff --git a/Makefile.objs b/Makefile.objs
index 1b446958c5..0cbff4d293 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -285,9 +285,13 @@ sound-obj-$(CONFIG_HDA) += intel-hda.o hda-audio.o
 adlib.o fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0
 hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
 
-hw-obj-$(CONFIG_REALLY_VIRTFS) += virtio-9p-debug.o
-hw-obj-$(CONFIG_VIRTFS) += virtio-9p-local.o virtio-9p-xattr.o
-hw-obj-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o
+9pfs-nested-$(CONFIG_VIRTFS) = virtio-9p-debug.o
+9pfs-nested-$(CONFIG_VIRTFS) +=  virtio-9p-local.o virtio-9p-xattr.o
+9pfs-nested-$(CONFIG_VIRTFS) +=   virtio-9p-xattr-user.o virtio-9p-posix-acl.o
+
+hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
+$(addprefix 9pfs/, $(9pfs-nested-y)): CFLAGS +=  -I$(SRC_PATH)/hw/
+
 
 ######################################################################
 # libdis
diff --git a/Makefile.target b/Makefile.target
index 0e0ef36b97..2501c63bb2 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -194,7 +194,7 @@ obj-$(CONFIG_VIRTIO) += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial
 obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
 obj-y += vhost_net.o
 obj-$(CONFIG_VHOST_NET) += vhost.o
-obj-$(CONFIG_REALLY_VIRTFS) += virtio-9p.o
+obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p.o
 obj-y += rwhandler.o
 obj-$(CONFIG_KVM) += kvm.o kvm-all.o
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
@@ -401,9 +401,11 @@ hmp-commands.h: $(SRC_PATH)/hmp-commands.hx
 qmp-commands.h: $(SRC_PATH)/qmp-commands.hx
 	$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@,"  GEN   $(TARGET_DIR)$@")
 
+9pfs/virtio-9p.o: CFLAGS +=  -I$(SRC_PATH)/hw/
+
 clean:
 	rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o
-	rm -f *.d */*.d tcg/*.o ide/*.o
+	rm -f *.d */*.d tcg/*.o ide/*.o 9pfs/*.o
 	rm -f hmp-commands.h qmp-commands.h gdbstub-xml.c
 ifdef CONFIG_SYSTEMTAP_TRACE
 	rm -f *.stp
diff --git a/configure b/configure
index 35f7e8b7b2..6f75e2eb9f 100755
--- a/configure
+++ b/configure
@@ -3062,6 +3062,7 @@ mkdir -p $target_dir
 mkdir -p $target_dir/fpu
 mkdir -p $target_dir/tcg
 mkdir -p $target_dir/ide
+mkdir -p $target_dir/9pfs
 if test "$target" = "arm-linux-user" -o "$target" = "armeb-linux-user" -o "$target" = "arm-bsd-user" -o "$target" = "armeb-bsd-user" ; then
   mkdir -p $target_dir/nwfpe
 fi
@@ -3488,6 +3489,7 @@ for hwlib in 32 64; do
   mkdir -p $d
   mkdir -p $d/ide
   symlink $source_path/Makefile.hw $d/Makefile
+  mkdir -p $d/9pfs
   echo "QEMU_CFLAGS+=-DTARGET_PHYS_ADDR_BITS=$hwlib" > $d/config.mak
 done
 
diff --git a/hw/file-op-9p.h b/fsdev/file-op-9p.h
similarity index 100%
rename from hw/file-op-9p.h
rename to fsdev/file-op-9p.h
diff --git a/fsdev/qemu-fsdev.h b/fsdev/qemu-fsdev.h
index a704043beb..f9f08d3e1b 100644
--- a/fsdev/qemu-fsdev.h
+++ b/fsdev/qemu-fsdev.h
@@ -13,7 +13,7 @@
 #ifndef QEMU_FSDEV_H
 #define QEMU_FSDEV_H
 #include "qemu-option.h"
-#include "hw/file-op-9p.h"
+#include "file-op-9p.h"
 
 
 /*
diff --git a/hw/virtio-9p-debug.c b/hw/9pfs/virtio-9p-debug.c
similarity index 100%
rename from hw/virtio-9p-debug.c
rename to hw/9pfs/virtio-9p-debug.c
diff --git a/hw/virtio-9p-debug.h b/hw/9pfs/virtio-9p-debug.h
similarity index 100%
rename from hw/virtio-9p-debug.h
rename to hw/9pfs/virtio-9p-debug.h
diff --git a/hw/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
similarity index 100%
rename from hw/virtio-9p-local.c
rename to hw/9pfs/virtio-9p-local.c
diff --git a/hw/virtio-9p-posix-acl.c b/hw/9pfs/virtio-9p-posix-acl.c
similarity index 99%
rename from hw/virtio-9p-posix-acl.c
rename to hw/9pfs/virtio-9p-posix-acl.c
index 3978d0cf71..e4e0777107 100644
--- a/hw/virtio-9p-posix-acl.c
+++ b/hw/9pfs/virtio-9p-posix-acl.c
@@ -15,7 +15,7 @@
 #include <attr/xattr.h>
 #include "virtio.h"
 #include "virtio-9p.h"
-#include "file-op-9p.h"
+#include "fsdev/file-op-9p.h"
 #include "virtio-9p-xattr.h"
 
 #define MAP_ACL_ACCESS "user.virtfs.system.posix_acl_access"
diff --git a/hw/virtio-9p-xattr-user.c b/hw/9pfs/virtio-9p-xattr-user.c
similarity index 98%
rename from hw/virtio-9p-xattr-user.c
rename to hw/9pfs/virtio-9p-xattr-user.c
index faa02a1911..bba13ce643 100644
--- a/hw/virtio-9p-xattr-user.c
+++ b/hw/9pfs/virtio-9p-xattr-user.c
@@ -14,7 +14,7 @@
 #include <sys/types.h>
 #include "virtio.h"
 #include "virtio-9p.h"
-#include "file-op-9p.h"
+#include "fsdev/file-op-9p.h"
 #include "virtio-9p-xattr.h"
 
 
diff --git a/hw/virtio-9p-xattr.c b/hw/9pfs/virtio-9p-xattr.c
similarity index 99%
rename from hw/virtio-9p-xattr.c
rename to hw/9pfs/virtio-9p-xattr.c
index 1aab081de2..03c3d3f6bb 100644
--- a/hw/virtio-9p-xattr.c
+++ b/hw/9pfs/virtio-9p-xattr.c
@@ -13,7 +13,7 @@
 
 #include "virtio.h"
 #include "virtio-9p.h"
-#include "file-op-9p.h"
+#include "fsdev/file-op-9p.h"
 #include "virtio-9p-xattr.h"
 
 
diff --git a/hw/virtio-9p-xattr.h b/hw/9pfs/virtio-9p-xattr.h
similarity index 100%
rename from hw/virtio-9p-xattr.h
rename to hw/9pfs/virtio-9p-xattr.h
diff --git a/hw/virtio-9p.c b/hw/9pfs/virtio-9p.c
similarity index 100%
rename from hw/virtio-9p.c
rename to hw/9pfs/virtio-9p.c
diff --git a/hw/virtio-9p.h b/hw/9pfs/virtio-9p.h
similarity index 99%
rename from hw/virtio-9p.h
rename to hw/9pfs/virtio-9p.h
index 2ae4ce7189..95e4977363 100644
--- a/hw/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -6,7 +6,7 @@
 #include <sys/time.h>
 #include <utime.h>
 
-#include "file-op-9p.h"
+#include "fsdev/file-op-9p.h"
 
 /* The feature bitmap for virtio 9P */
 /* The mount point is specified in a config variable */

From 39792515185350a21ec84b9eb65aafd0bb65525c Mon Sep 17 00:00:00 2001
From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Date: Wed, 27 Apr 2011 12:25:46 +0530
Subject: [PATCH 349/386] virtio-9p: Print the pdu details on return

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
---
 hw/9pfs/virtio-9p.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 7e29535672..18968c25c3 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -596,7 +596,10 @@ static V9fsPDU *alloc_pdu(V9fsState *s)
 static void free_pdu(V9fsState *s, V9fsPDU *pdu)
 {
     if (pdu) {
-	QLIST_INSERT_HEAD(&s->free_list, pdu, next);
+        if (debug_9p_pdu) {
+            pprint_pdu(pdu);
+        }
+        QLIST_INSERT_HEAD(&s->free_list, pdu, next);
     }
 }
 

From a09947617cc3d0035f485d9804cd26c5a895b683 Mon Sep 17 00:00:00 2001
From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Date: Wed, 27 Apr 2011 12:26:43 +0530
Subject: [PATCH 350/386] virtio-9p: removexattr on default acl should return 0

If we don't have default acl, removexattr on default acl
should return 0

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
---
 hw/9pfs/virtio-9p-posix-acl.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/hw/9pfs/virtio-9p-posix-acl.c b/hw/9pfs/virtio-9p-posix-acl.c
index e4e0777107..575abe86b0 100644
--- a/hw/9pfs/virtio-9p-posix-acl.c
+++ b/hw/9pfs/virtio-9p-posix-acl.c
@@ -60,7 +60,7 @@ static int mp_pacl_removexattr(FsContext *ctx,
     ret  = lremovexattr(rpath(ctx, path), MAP_ACL_ACCESS);
     if (ret == -1 && errno == ENODATA) {
         /*
-         * We don't get ENODATA error when trying to remote a
+         * We don't get ENODATA error when trying to remove a
          * posix acl that is not present. So don't throw the error
          * even in case of mapped security model
          */
@@ -103,7 +103,18 @@ static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name,
 static int mp_dacl_removexattr(FsContext *ctx,
                                const char *path, const char *name)
 {
-    return lremovexattr(rpath(ctx, path), MAP_ACL_DEFAULT);
+    int ret;
+    ret  = lremovexattr(rpath(ctx, path), MAP_ACL_DEFAULT);
+    if (ret == -1 && errno == ENODATA) {
+        /*
+         * We don't get ENODATA error when trying to remove a
+         * posix acl that is not present. So don't throw the error
+         * even in case of mapped security model
+         */
+        errno = 0;
+        ret = 0;
+    }
+    return ret;
 }
 
 

From 1d810aeb4eda548e8a875db9e364732b8765d894 Mon Sep 17 00:00:00 2001
From: "M. Mohan Kumar" <mohan@in.ibm.com>
Date: Tue, 1 Feb 2011 14:21:41 +0530
Subject: [PATCH 351/386] virtio-9p: Bugfix to send correct iounit

LCREATE function packs address of iounit in the pdu, fix that to send
actual iounit itself.

Signed-off-by: M. Mohan Kumar <mohan@in.ibm.com>
Acked-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
---
 hw/9pfs/virtio-9p.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 18968c25c3..ca394570ca 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -1771,7 +1771,7 @@ static void v9fs_post_lcreate(V9fsState *s, V9fsLcreateState *vs, int err)
         v9fs_string_copy(&vs->fidp->path, &vs->fullname);
         stat_to_qid(&vs->stbuf, &vs->qid);
         vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid,
-                &vs->iounit);
+                vs->iounit);
         err = vs->offset;
     } else {
         vs->fidp->fid_type = P9_FID_NONE;

From f35bde2f8fb55541d4d7ddca50d64ce5a6ef384c Mon Sep 17 00:00:00 2001
From: Harsh Prateek Bora <harsh@linux.vnet.ibm.com>
Date: Wed, 2 Feb 2011 10:20:33 +0530
Subject: [PATCH 352/386] hw/virtio-9p-local.c: Remove unnecessary null char in
 symlink file

This patch removes the addition of null char in symlink file
which is being appended to file in case of mapped security model.
Without this patch, the extra null char causes LTP testcase lstat03
to fail and hence this fix is required.

Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
---
 hw/9pfs/virtio-9p-local.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index a8e7525bf6..0a015de9a5 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -370,7 +370,7 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
             return fd;
         }
         /* Write the oldpath (target) to the file. */
-        oldpath_size = strlen(oldpath) + 1;
+        oldpath_size = strlen(oldpath);
         do {
             write_size = write(fd, (void *)oldpath, oldpath_size);
         } while (write_size == -1 && errno == EINTR);

From 4f8dee2dec9c6d590c8a7844b2824935542ca122 Mon Sep 17 00:00:00 2001
From: Harsh Prateek Bora <harsh@linux.vnet.ibm.com>
Date: Thu, 14 Apr 2011 14:54:40 +0530
Subject: [PATCH 353/386] v9fs_walk: As per 9p2000 RFC, MAXWELEM >= nwnames >=
 0.

The nwnames field in TWALK message is assumed to be >=0 and <= MAXWELEM
which is defined as macro P9_MAXWELEM (16) in virtio-9p.h as per 9p2000
RFC. Appropriate changes are required in V9fsWalkState and v9fs_walk.

Signed-off-by: Harsh Prateek Bora <harsh@linux.vnet.ibm.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
---
 hw/9pfs/virtio-9p.c | 7 +++++--
 hw/9pfs/virtio-9p.h | 2 +-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index ca394570ca..b5fc52b3eb 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -1482,7 +1482,7 @@ static void v9fs_walk_complete(V9fsState *s, V9fsWalkState *vs, int err)
 {
     complete_pdu(s, vs->pdu, err);
 
-    if (vs->nwnames) {
+    if (vs->nwnames && vs->nwnames <= P9_MAXWELEM) {
         for (vs->name_idx = 0; vs->name_idx < vs->nwnames; vs->name_idx++) {
             v9fs_string_free(&vs->wnames[vs->name_idx]);
         }
@@ -1578,7 +1578,7 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
     vs->offset += pdu_unmarshal(vs->pdu, vs->offset, "ddw", &fid,
                                             &newfid, &vs->nwnames);
 
-    if (vs->nwnames) {
+    if (vs->nwnames && vs->nwnames <= P9_MAXWELEM) {
         vs->wnames = qemu_mallocz(sizeof(vs->wnames[0]) * vs->nwnames);
 
         vs->qids = qemu_mallocz(sizeof(vs->qids[0]) * vs->nwnames);
@@ -1587,6 +1587,9 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
             vs->offset += pdu_unmarshal(vs->pdu, vs->offset, "s",
                                             &vs->wnames[i]);
         }
+    } else if (vs->nwnames > P9_MAXWELEM) {
+        err = -EINVAL;
+        goto out;
     }
 
     vs->fidp = lookup_fid(s, fid);
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 95e4977363..622928fce5 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -282,7 +282,7 @@ typedef struct V9fsStatStateDotl {
 typedef struct V9fsWalkState {
     V9fsPDU *pdu;
     size_t offset;
-    int16_t nwnames;
+    uint16_t nwnames;
     int name_idx;
     V9fsQID *qids;
     V9fsFidState *fidp;

From e14ea479b37d6c6665fae55ea0eb713c4b2d3376 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Date: Wed, 16 Mar 2011 08:31:43 +0000
Subject: [PATCH 354/386] vl.c: Replace -virtfs string manipulation with
 QemuOpts

The -virtfs option creates an fsdev representing the pass-through file
system and a guest-visible virtio-9p-pci device that can access this
file system.  This patch replaces the string manipulation used to build
and reparse option lists with direct QemuOpts calls.  Removing the
string manipulation code makes it easier to maintain and less error
prone.

An error message is also updated to use "mount_tag" instead of
"mnt_tag".

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
---
 vl.c | 54 ++++++++++++++++++------------------------------------
 1 file changed, 18 insertions(+), 36 deletions(-)

diff --git a/vl.c b/vl.c
index b46ee663bf..6b9a2f61e3 100644
--- a/vl.c
+++ b/vl.c
@@ -2447,9 +2447,8 @@ int main(int argc, char **argv, char **envp)
                 }
                 break;
             case QEMU_OPTION_virtfs: {
-                char *arg_fsdev = NULL;
-                char *arg_9p = NULL;
-                int len = 0;
+                QemuOpts *fsdev;
+                QemuOpts *device;
 
                 olist = qemu_find_opts("virtfs");
                 if (!olist) {
@@ -2468,45 +2467,28 @@ int main(int argc, char **argv, char **envp)
                         qemu_opt_get(opts, "security_model") == NULL) {
                     fprintf(stderr, "Usage: -virtfs fstype,path=/share_path/,"
                             "security_model=[mapped|passthrough|none],"
-                            "mnt_tag=tag.\n");
+                            "mount_tag=tag.\n");
                     exit(1);
                 }
 
-                len = strlen(",id=,path=,security_model=");
-                len += strlen(qemu_opt_get(opts, "fstype"));
-                len += strlen(qemu_opt_get(opts, "mount_tag"));
-                len += strlen(qemu_opt_get(opts, "path"));
-                len += strlen(qemu_opt_get(opts, "security_model"));
-                arg_fsdev = qemu_malloc((len + 1) * sizeof(*arg_fsdev));
-
-                snprintf(arg_fsdev, (len + 1) * sizeof(*arg_fsdev),
-                         "%s,id=%s,path=%s,security_model=%s",
-                         qemu_opt_get(opts, "fstype"),
-                         qemu_opt_get(opts, "mount_tag"),
-                         qemu_opt_get(opts, "path"),
-                         qemu_opt_get(opts, "security_model"));
-
-                len = strlen("virtio-9p,fsdev=,mount_tag=");
-                len += 2*strlen(qemu_opt_get(opts, "mount_tag"));
-                arg_9p = qemu_malloc((len + 1) * sizeof(*arg_9p));
-
-                snprintf(arg_9p, (len + 1) * sizeof(*arg_9p),
-                         "virtio-9p,fsdev=%s,mount_tag=%s",
-                         qemu_opt_get(opts, "mount_tag"),
-                         qemu_opt_get(opts, "mount_tag"));
-
-                if (!qemu_opts_parse(qemu_find_opts("fsdev"), arg_fsdev, 1)) {
-                    fprintf(stderr, "parse error [fsdev]: %s\n", optarg);
+                fsdev = qemu_opts_create(qemu_find_opts("fsdev"),
+                                         qemu_opt_get(opts, "mount_tag"), 1);
+                if (!fsdev) {
+                    fprintf(stderr, "duplicate fsdev id: %s\n",
+                            qemu_opt_get(opts, "mount_tag"));
                     exit(1);
                 }
+                qemu_opt_set(fsdev, "fstype", qemu_opt_get(opts, "fstype"));
+                qemu_opt_set(fsdev, "path", qemu_opt_get(opts, "path"));
+                qemu_opt_set(fsdev, "security_model",
+                             qemu_opt_get(opts, "security_model"));
 
-                if (!qemu_opts_parse(qemu_find_opts("device"), arg_9p, 1)) {
-                    fprintf(stderr, "parse error [device]: %s\n", optarg);
-                    exit(1);
-                }
-
-                qemu_free(arg_fsdev);
-                qemu_free(arg_9p);
+                device = qemu_opts_create(qemu_find_opts("device"), NULL, 0);
+                qemu_opt_set(device, "driver", "virtio-9p-pci");
+                qemu_opt_set(device, "fsdev",
+                             qemu_opt_get(opts, "mount_tag"));
+                qemu_opt_set(device, "mount_tag",
+                             qemu_opt_get(opts, "mount_tag"));
                 break;
             }
             case QEMU_OPTION_serial:

From 47f7be394aa7baf7855fe78f56b8ba4c69bf75d9 Mon Sep 17 00:00:00 2001
From: Jan Kiszka <jan.kiszka@web.de>
Date: Sat, 9 Apr 2011 13:18:59 +0200
Subject: [PATCH 355/386] ioapic: Do not set irr for masked edge IRQs

So far we set IRR for edge IRQs even if the pin is masked. If the guest
later on unmasks and switches the pin to level-triggered mode, irr will
remain set, causing an IRQ storm. The point is that setting IRR is not
correct in this case according to the spec, and avoiding this resolves
the issue.

Reported-and-tested-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/ioapic.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/ioapic.c b/hw/ioapic.c
index 569327d1e9..6c26e820e0 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -160,8 +160,9 @@ static void ioapic_set_irq(void *opaque, int vector, int level)
                 s->irr &= ~mask;
             }
         } else {
-            /* edge triggered */
-            if (level) {
+            /* According to the 82093AA manual, we must ignore edge requests
+             * if the input pin is masked. */
+            if (level && !(entry & IOAPIC_LVT_MASKED)) {
                 s->irr |= mask;
                 ioapic_service(s);
             }

From 5856d44eb592e05bb266fb2c7db42926faa22144 Mon Sep 17 00:00:00 2001
From: YuYeon Oh <yuyeon.oh@samsung.com>
Date: Mon, 25 Apr 2011 01:23:58 +0000
Subject: [PATCH 356/386] target-arm: fix LDMIA bug on page boundary
 target-arm: fix LDMIA bug on page boundary

When consecutive memory locations are on page boundary, a base register may be
loaded before page fault occurs. After page fault handling, it losts the memory
location information. To solve this problem, loading a base register has to put back.

Signed-off-by: Yuyeon Oh <yuyeon.oh@samsung.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 8b309d48b8..d8da514599 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -8016,7 +8016,8 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
                     }
                 }
             } else {
-                int i;
+                int i, loaded_base = 0;
+                TCGv loaded_var;
                 /* Load/store multiple.  */
                 addr = load_reg(s, rn);
                 offset = 0;
@@ -8028,6 +8029,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
                     tcg_gen_addi_i32(addr, addr, -offset);
                 }
 
+                TCGV_UNUSED(loaded_var);
                 for (i = 0; i < 16; i++) {
                     if ((insn & (1 << i)) == 0)
                         continue;
@@ -8036,6 +8038,9 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
                         tmp = gen_ld32(addr, IS_USER(s));
                         if (i == 15) {
                             gen_bx(s, tmp);
+                        } else if (i == rn) {
+                            loaded_var = tmp;
+                            loaded_base = 1;
                         } else {
                             store_reg(s, i, tmp);
                         }
@@ -8046,6 +8051,9 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
                     }
                     tcg_gen_addi_i32(addr, addr, 4);
                 }
+                if (loaded_base) {
+                    store_reg(s, rn, loaded_var);
+                }
                 if (insn & (1 << 21)) {
                     /* Base register writeback.  */
                     if (insn & (1 << 24)) {

From a7d3970d0635ebce1412736e7aaf11d387919dc8 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Tue, 26 Apr 2011 18:17:20 +0100
Subject: [PATCH 357/386] target-arm: Don't update base register on abort in
 Thumb T1 LDM

Make sure the base register isn't updated if it is in the load list
for a Thumb LDM (T1 encoding) which aborts partway through the load.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-arm/translate.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index d8da514599..a1af436e34 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -9454,7 +9454,10 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
         break;
 
     case 12:
+    {
         /* load/store multiple */
+        TCGv loaded_var;
+        TCGV_UNUSED(loaded_var);
         rn = (insn >> 8) & 0x7;
         addr = load_reg(s, rn);
         for (i = 0; i < 8; i++) {
@@ -9462,7 +9465,11 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
                 if (insn & (1 << 11)) {
                     /* load */
                     tmp = gen_ld32(addr, IS_USER(s));
-                    store_reg(s, i, tmp);
+                    if (i == rn) {
+                        loaded_var = tmp;
+                    } else {
+                        store_reg(s, i, tmp);
+                    }
                 } else {
                     /* store */
                     tmp = load_reg(s, i);
@@ -9472,14 +9479,18 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
                 tcg_gen_addi_i32(addr, addr, 4);
             }
         }
-        /* Base register writeback.  */
         if ((insn & (1 << rn)) == 0) {
+            /* base reg not in list: base register writeback */
             store_reg(s, rn, addr);
         } else {
+            /* base reg in list: if load, complete it now */
+            if (insn & (1 << 11)) {
+                store_reg(s, rn, loaded_var);
+            }
             tcg_temp_free_i32(addr);
         }
         break;
-
+    }
     case 13:
         /* conditional branch or swi */
         cond = (insn >> 8) & 0xf;

From 7c32c4feebd962960fb160291a426b983e0ae668 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 24 Mar 2011 11:12:02 +0100
Subject: [PATCH 358/386] chardev: Allow frontends to notify backends of guest
 open / close

Some frontends know when the guest has opened the "channel" and is actively
listening to it, for example virtio-serial. This patch adds 2 new qemu-chardev
functions which can be used by frontends to signal guest open / close, and
allows interested backends to listen to this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
 qemu-char.c | 17 +++++++++++++++++
 qemu-char.h |  4 ++++
 2 files changed, 21 insertions(+)

diff --git a/qemu-char.c b/qemu-char.c
index 03858d4ef7..710d98ffc4 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -480,6 +480,9 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
     chr->chr_write = mux_chr_write;
     chr->chr_update_read_handler = mux_chr_update_read_handler;
     chr->chr_accept_input = mux_chr_accept_input;
+    /* Frontend guest-open / -close notification is not support with muxes */
+    chr->chr_guest_open = NULL;
+    chr->chr_guest_close = NULL;
 
     /* Muxes are always open on creation */
     qemu_chr_generic_open(chr);
@@ -2579,6 +2582,20 @@ void qemu_chr_set_echo(struct CharDriverState *chr, bool echo)
     }
 }
 
+void qemu_chr_guest_open(struct CharDriverState *chr)
+{
+    if (chr->chr_guest_open) {
+        chr->chr_guest_open(chr);
+    }
+}
+
+void qemu_chr_guest_close(struct CharDriverState *chr)
+{
+    if (chr->chr_guest_close) {
+        chr->chr_guest_close(chr);
+    }
+}
+
 void qemu_chr_close(CharDriverState *chr)
 {
     QTAILQ_REMOVE(&chardevs, chr, next);
diff --git a/qemu-char.h b/qemu-char.h
index fb96eef3de..2f8512e528 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -65,6 +65,8 @@ struct CharDriverState {
     void (*chr_close)(struct CharDriverState *chr);
     void (*chr_accept_input)(struct CharDriverState *chr);
     void (*chr_set_echo)(struct CharDriverState *chr, bool echo);
+    void (*chr_guest_open)(struct CharDriverState *chr);
+    void (*chr_guest_close)(struct CharDriverState *chr);
     void *opaque;
     QEMUBH *bh;
     char *label;
@@ -79,6 +81,8 @@ CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
                                     void (*init)(struct CharDriverState *s));
 CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s));
 void qemu_chr_set_echo(struct CharDriverState *chr, bool echo);
+void qemu_chr_guest_open(struct CharDriverState *chr);
+void qemu_chr_guest_close(struct CharDriverState *chr);
 void qemu_chr_close(CharDriverState *chr);
 void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);

From 0b6d2266e3ee079c0eab4a5d2facacdcd36a329c Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 24 Mar 2011 11:12:03 +0100
Subject: [PATCH 359/386] virtio-console: notify backend of guest open / close

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
 hw/virtio-console.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 6b5237b3ce..de539c4eac 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -28,6 +28,22 @@ static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
     return qemu_chr_write(vcon->chr, buf, len);
 }
 
+/* Callback function that's called when the guest opens the port */
+static void guest_open(VirtIOSerialPort *port)
+{
+    VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
+
+    qemu_chr_guest_open(vcon->chr);
+}
+
+/* Callback function that's called when the guest closes the port */
+static void guest_close(VirtIOSerialPort *port)
+{
+    VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
+
+    qemu_chr_guest_close(vcon->chr);
+}
+
 /* Readiness of the guest to accept data on a port */
 static int chr_can_read(void *opaque)
 {
@@ -64,6 +80,8 @@ static int generic_port_init(VirtConsole *vcon, VirtIOSerialPort *port)
         qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event,
                               vcon);
         vcon->port.info->have_data = flush_buf;
+        vcon->port.info->guest_open = guest_open;
+        vcon->port.info->guest_close = guest_close;
     }
     return 0;
 }

From cd8f7df2891891c3a6c346892545c4407be6699f Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 24 Mar 2011 11:12:04 +0100
Subject: [PATCH 360/386] spice-chardev: listen to frontend guest open / close

Note the vmc_register_interface() in spice_chr_write is left in place
in case someone uses spice-chardev with a frontend which does not have
guest open / close notification.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
 spice-qemu-char.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/spice-qemu-char.c b/spice-qemu-char.c
index 517f337c43..fa15a71e14 100644
--- a/spice-qemu-char.c
+++ b/spice-qemu-char.c
@@ -131,6 +131,18 @@ static void spice_chr_close(struct CharDriverState *chr)
     qemu_free(s);
 }
 
+static void spice_chr_guest_open(struct CharDriverState *chr)
+{
+    SpiceCharDriver *s = chr->opaque;
+    vmc_register_interface(s);
+}
+
+static void spice_chr_guest_close(struct CharDriverState *chr)
+{
+    SpiceCharDriver *s = chr->opaque;
+    vmc_unregister_interface(s);
+}
+
 static void print_allowed_subtypes(void)
 {
     const char** psubtype;
@@ -183,6 +195,8 @@ CharDriverState *qemu_chr_open_spice(QemuOpts *opts)
     chr->opaque = s;
     chr->chr_write = spice_chr_write;
     chr->chr_close = spice_chr_close;
+    chr->chr_guest_open = spice_chr_guest_open;
+    chr->chr_guest_close = spice_chr_guest_close;
 
     qemu_chr_generic_open(chr);
 

From d5b27167e17e0d9393d6364703cc68e7f018023c Mon Sep 17 00:00:00 2001
From: Kusanagi Kouichi <slash@ac.auone-net.jp>
Date: Tue, 26 Apr 2011 19:19:26 +0900
Subject: [PATCH 361/386] char: Allow devices to use a single multiplexed
 chardev.

This fixes regression caused by commit
2d6c1ef40f3678ab47a4d14fb5dadaa486bfcda6
("char: Prevent multiple devices opening same chardev"):

-nodefaults -nographic -chardev stdio,id=stdio,mux=on,signal=off \
 -mon stdio -device virtio-serial-pci \
 -device virtconsole,chardev=stdio -device isa-serial,chardev=stdio

fails with:

qemu-system-x86_64: -device isa-serial,chardev=stdio: Property 'isa-serial.chardev' can't take value 'stdio', it's in use

Signed-off-by: Kusanagi Kouichi <slash@ac.auone-net.jp>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
 hw/qdev-properties.c | 4 ++--
 qemu-char.c          | 5 ++++-
 qemu-char.h          | 2 +-
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 1088a26f8e..eff2d24945 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -354,10 +354,10 @@ static int parse_chr(DeviceState *dev, Property *prop, const char *str)
     if (*ptr == NULL) {
         return -ENOENT;
     }
-    if ((*ptr)->assigned) {
+    if ((*ptr)->avail_connections < 1) {
         return -EEXIST;
     }
-    (*ptr)->assigned = 1;
+    --(*ptr)->avail_connections;
     return 0;
 }
 
diff --git a/qemu-char.c b/qemu-char.c
index 710d98ffc4..eaf6571ac8 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -199,7 +199,7 @@ void qemu_chr_add_handlers(CharDriverState *s,
 {
     if (!opaque) {
         /* chr driver being released. */
-        s->assigned = 0;
+        ++s->avail_connections;
     }
     s->chr_can_read = fd_can_read;
     s->chr_read = fd_read;
@@ -2547,7 +2547,10 @@ CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
         snprintf(base->label, len, "%s-base", qemu_opts_id(opts));
         chr = qemu_chr_open_mux(base);
         chr->filename = base->filename;
+        chr->avail_connections = MAX_MUX;
         QTAILQ_INSERT_TAIL(&chardevs, chr, next);
+    } else {
+        chr->avail_connections = 1;
     }
     chr->label = qemu_strdup(qemu_opts_id(opts));
     return chr;
diff --git a/qemu-char.h b/qemu-char.h
index 2f8512e528..892c6da9aa 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -72,7 +72,7 @@ struct CharDriverState {
     char *label;
     char *filename;
     int opened;
-    int assigned; /* chardev assigned to a device */
+    int avail_connections;
     QTAILQ_ENTRY(CharDriverState) next;
 };
 

From da7d998bbb80f141ed5743418a4dfa5c1409e75f Mon Sep 17 00:00:00 2001
From: Amit Shah <amit.shah@redhat.com>
Date: Mon, 25 Apr 2011 15:18:22 +0530
Subject: [PATCH 362/386] char: Detect chardev release by NULL handlers as well
 as NULL opaque

Juan says he prefers these extra checks to ensure a user of a chardev is
releasing it.

Requested-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
 qemu-char.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qemu-char.c b/qemu-char.c
index eaf6571ac8..5e04a20b8c 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -197,7 +197,7 @@ void qemu_chr_add_handlers(CharDriverState *s,
                            IOEventHandler *fd_event,
                            void *opaque)
 {
-    if (!opaque) {
+    if (!opaque && !fd_can_read && !fd_read && !fd_event) {
         /* chr driver being released. */
         ++s->avail_connections;
     }

From 5c1c9bb24b20fb5844d01ac67d51c26941db5af1 Mon Sep 17 00:00:00 2001
From: Alexey Kardashevskiy <aik@ozlabs.ru>
Date: Tue, 19 Apr 2011 12:03:46 +1000
Subject: [PATCH 363/386] virtio-serial: Fix endianness bug in the config space

The virtio serial specification requres that the values in the config
space are encoded in native endian of the guest.

The qemu virtio-serial code did not do conversion to the guest endian
format what caused problems when host and guest use different format.

This patch corrects the qemu side, correctly doing host-native <->
guest-native conversions when accessing the config space. This won't
break any setups that aren't already broken, and fixes the case
of different host and guest endianness.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
 hw/virtio-serial-bus.c | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 62273799b6..f10d48fdb0 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -494,7 +494,7 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
     VirtIOSerial *s = opaque;
     VirtIOSerialPort *port;
     uint32_t nr_active_ports;
-    unsigned int i;
+    unsigned int i, max_nr_ports;
 
     /* The virtio device */
     virtio_save(&s->vdev, f);
@@ -506,8 +506,8 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
     qemu_put_be32s(f, &s->config.max_nr_ports);
 
     /* The ports map */
-
-    for (i = 0; i < (s->config.max_nr_ports + 31) / 32; i++) {
+    max_nr_ports = tswap32(s->config.max_nr_ports);
+    for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
         qemu_put_be32s(f, &s->ports_map[i]);
     }
 
@@ -568,7 +568,8 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
     qemu_get_be16s(f, &s->config.rows);
 
     qemu_get_be32s(f, &max_nr_ports);
-    if (max_nr_ports > s->config.max_nr_ports) {
+    tswap32s(&max_nr_ports);
+    if (max_nr_ports > tswap32(s->config.max_nr_ports)) {
         /* Source could have had more ports than us. Fail migration. */
         return -EINVAL;
     }
@@ -670,9 +671,10 @@ static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
 /* This function is only used if a port id is not provided by the user */
 static uint32_t find_free_port_id(VirtIOSerial *vser)
 {
-    unsigned int i;
+    unsigned int i, max_nr_ports;
 
-    for (i = 0; i < (vser->config.max_nr_ports + 31) / 32; i++) {
+    max_nr_ports = tswap32(vser->config.max_nr_ports);
+    for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
         uint32_t map, bit;
 
         map = vser->ports_map[i];
@@ -720,7 +722,7 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
     VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
     VirtIOSerialPortInfo *info = DO_UPCAST(VirtIOSerialPortInfo, qdev, base);
     VirtIOSerialBus *bus = DO_UPCAST(VirtIOSerialBus, qbus, qdev->parent_bus);
-    int ret;
+    int ret, max_nr_ports;
     bool plugging_port0;
 
     port->vser = bus->vser;
@@ -750,9 +752,10 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
         }
     }
 
-    if (port->id >= port->vser->config.max_nr_ports) {
+    max_nr_ports = tswap32(port->vser->config.max_nr_ports);
+    if (port->id >= max_nr_ports) {
         error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u\n",
-                     port->vser->config.max_nr_ports - 1);
+                     max_nr_ports - 1);
         return -1;
     }
 
@@ -863,7 +866,7 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
         vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output);
     }
 
-    vser->config.max_nr_ports = conf->max_virtserial_ports;
+    vser->config.max_nr_ports = tswap32(conf->max_virtserial_ports);
     vser->ports_map = qemu_mallocz(((conf->max_virtserial_ports + 31) / 32)
         * sizeof(vser->ports_map[0]));
     /*

From 642cfd4d31241c0fc65c520cb1e703659af66236 Mon Sep 17 00:00:00 2001
From: Anthony Liguori <aliguori@us.ibm.com>
Date: Thu, 28 Apr 2011 12:40:54 -0500
Subject: [PATCH 364/386] virtfs: fix build due from rename

The latest virtfs pull broke the cris-softmmu target.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 Makefile.objs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Makefile.objs b/Makefile.objs
index 0cbff4d293..9d8851e5d4 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -285,11 +285,11 @@ sound-obj-$(CONFIG_HDA) += intel-hda.o hda-audio.o
 adlib.o fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0
 hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
 
-9pfs-nested-$(CONFIG_VIRTFS) = virtio-9p-debug.o
+9pfs-nested-$(CONFIG_REALLY_VIRTFS) = virtio-9p-debug.o
 9pfs-nested-$(CONFIG_VIRTFS) +=  virtio-9p-local.o virtio-9p-xattr.o
 9pfs-nested-$(CONFIG_VIRTFS) +=   virtio-9p-xattr-user.o virtio-9p-posix-acl.o
 
-hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
+hw-obj-$(CONFIG_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
 $(addprefix 9pfs/, $(9pfs-nested-y)): CFLAGS +=  -I$(SRC_PATH)/hw/
 
 

From 6f11f013a5ef88c42ce2e9060bbaafb39676ca39 Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Wed, 27 Apr 2011 10:44:38 +0200
Subject: [PATCH 365/386] linux-user: Fix compilation for "old" linux versions

Debian Lenny and other installations with older linux versions
failed to compile linux-user because some CLONE_xxx macros are
undefined.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/strace.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index 5d9bb085c7..fe9326aa73 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -477,12 +477,24 @@ UNUSED static struct flags clone_flags[] = {
     FLAG_GENERIC(CLONE_DETACHED),
     FLAG_GENERIC(CLONE_UNTRACED),
     FLAG_GENERIC(CLONE_CHILD_SETTID),
+#if defined(CLONE_NEWUTS)
     FLAG_GENERIC(CLONE_NEWUTS),
+#endif
+#if defined(CLONE_NEWIPC)
     FLAG_GENERIC(CLONE_NEWIPC),
+#endif
+#if defined(CLONE_NEWUSER)
     FLAG_GENERIC(CLONE_NEWUSER),
+#endif
+#if defined(CLONE_NEWPID)
     FLAG_GENERIC(CLONE_NEWPID),
+#endif
+#if defined(CLONE_NEWNET)
     FLAG_GENERIC(CLONE_NEWNET),
+#endif
+#if defined(CLONE_IO)
     FLAG_GENERIC(CLONE_IO),
+#endif
     FLAG_END,
 };
 

From e95d3bf04d8a54af43bb8db3b8eb64d68c9f6927 Mon Sep 17 00:00:00 2001
From: Mike McCormack <mj.mccormack@samsung.com>
Date: Tue, 12 Apr 2011 11:41:00 +0900
Subject: [PATCH 366/386] Fix buffer overrun in sched_getaffinity

Zeroing of the cpu array should start from &cpus[kernel_ret]
not &cpus[num_zeros_to_fill].

This fixes a crash in EFL's edje_cc running under qemu-arm.

Signed-off-by: Mike McCormack <mj.mccormack@samsung.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Acked-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/syscall.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e969d1b61d..5b7b8e2394 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6505,7 +6505,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                     unsigned long zero = arg2 - ret;
                     p = alloca(zero);
                     memset(p, 0, zero);
-                    if (copy_to_user(arg3 + zero, p, zero)) {
+                    if (copy_to_user(arg3 + ret, p, zero)) {
                         goto efault;
                     }
                     arg2 = ret;

From cd18f05e248bb916028021634058da06a4657e26 Mon Sep 17 00:00:00 2001
From: Mike McCormack <mj.mccormack@samsung.com>
Date: Mon, 18 Apr 2011 14:43:36 +0900
Subject: [PATCH 367/386] Don't zero out buffer in sched_getaffinity

The kernel doesn't fill the buffer provided to sched_getaffinity
with zero bytes, so neither should QEMU.

Signed-off-by: Mike McCormack <mj.mccormack@samsung.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/syscall.c | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5b7b8e2394..279cef3cd4 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6500,20 +6500,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
 
             if (!is_error(ret)) {
-                if (arg2 > ret) {
-                    /* Zero out any extra space kernel didn't fill */
-                    unsigned long zero = arg2 - ret;
-                    p = alloca(zero);
-                    memset(p, 0, zero);
-                    if (copy_to_user(arg3 + ret, p, zero)) {
-                        goto efault;
-                    }
-                    arg2 = ret;
-                }
-                if (copy_to_user(arg3, mask, arg2)) {
+                if (copy_to_user(arg3, mask, ret)) {
                     goto efault;
                 }
-                ret = arg2;
             }
         }
         break;

From 0c31b744f606d1c19b698041480eb195b8801747 Mon Sep 17 00:00:00 2001
From: Glauber Costa <glommer@redhat.com>
Date: Thu, 17 Mar 2011 19:42:05 -0300
Subject: [PATCH 368/386] kvm: use kernel-provided para_features instead of
 statically coming up with new capabilities

Use the features provided by KVM_GET_SUPPORTED_CPUID directly to
mask out features from guest-visible cpuid.

The old get_para_features() mechanism is kept for older kernels that do not implement it.

Signed-off-by: Glauber Costa <glommer@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 target-i386/kvm.c | 82 +++++++++++++++++++++++++++++------------------
 1 file changed, 51 insertions(+), 31 deletions(-)

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index a13599db81..485572f82b 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -92,6 +92,35 @@ static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max)
     return cpuid;
 }
 
+#ifdef CONFIG_KVM_PARA
+struct kvm_para_features {
+    int cap;
+    int feature;
+} para_features[] = {
+    { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },
+    { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
+    { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
+#ifdef KVM_CAP_ASYNC_PF
+    { KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF },
+#endif
+    { -1, -1 }
+};
+
+static int get_para_features(CPUState *env)
+{
+    int i, features = 0;
+
+    for (i = 0; i < ARRAY_SIZE(para_features) - 1; i++) {
+        if (kvm_check_extension(env->kvm_state, para_features[i].cap)) {
+            features |= (1 << para_features[i].feature);
+        }
+    }
+
+    return features;
+}
+#endif
+
+
 uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
                                       uint32_t index, int reg)
 {
@@ -99,6 +128,9 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
     int i, max;
     uint32_t ret = 0;
     uint32_t cpuid_1_edx;
+#ifdef CONFIG_KVM_PARA
+    int has_kvm_features = 0;
+#endif
 
     max = 1;
     while ((cpuid = try_get_cpuid(env->kvm_state, max)) == NULL) {
@@ -108,6 +140,11 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
     for (i = 0; i < cpuid->nent; ++i) {
         if (cpuid->entries[i].function == function &&
             cpuid->entries[i].index == index) {
+#ifdef CONFIG_KVM_PARA
+            if (cpuid->entries[i].function == KVM_CPUID_FEATURES) {
+                has_kvm_features = 1;
+            }
+#endif
             switch (reg) {
             case R_EAX:
                 ret = cpuid->entries[i].eax;
@@ -140,39 +177,16 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
 
     qemu_free(cpuid);
 
+#ifdef CONFIG_KVM_PARA
+    /* fallback for older kernels */
+    if (!has_kvm_features && (function == KVM_CPUID_FEATURES)) {
+        ret = get_para_features(env);
+    }
+#endif
+
     return ret;
 }
 
-#ifdef CONFIG_KVM_PARA
-struct kvm_para_features {
-    int cap;
-    int feature;
-} para_features[] = {
-    { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },
-    { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
-    { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
-#ifdef KVM_CAP_ASYNC_PF
-    { KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF },
-#endif
-    { -1, -1 }
-};
-
-static int get_para_features(CPUState *env)
-{
-    int i, features = 0;
-
-    for (i = 0; i < ARRAY_SIZE(para_features) - 1; i++) {
-        if (kvm_check_extension(env->kvm_state, para_features[i].cap)) {
-            features |= (1 << para_features[i].feature);
-        }
-    }
-#ifdef KVM_CAP_ASYNC_PF
-    has_msr_async_pf_en = features & (1 << KVM_FEATURE_ASYNC_PF);
-#endif
-    return features;
-}
-#endif /* CONFIG_KVM_PARA */
-
 typedef struct HWPoisonPage {
     ram_addr_t ram_addr;
     QLIST_ENTRY(HWPoisonPage) list;
@@ -397,7 +411,13 @@ int kvm_arch_init_vcpu(CPUState *env)
     c = &cpuid_data.entries[cpuid_i++];
     memset(c, 0, sizeof(*c));
     c->function = KVM_CPUID_FEATURES;
-    c->eax = env->cpuid_kvm_features & get_para_features(env);
+    c->eax = env->cpuid_kvm_features & kvm_arch_get_supported_cpuid(env,
+                                                KVM_CPUID_FEATURES, 0, R_EAX);
+
+#ifdef KVM_CAP_ASYNC_PF
+    has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);
+#endif
+
 #endif
 
     cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);

From e41e0fc61ae776b9235380fe9570af31ea7bbc86 Mon Sep 17 00:00:00 2001
From: Jan Kiszka <jan.kiszka@siemens.com>
Date: Tue, 19 Apr 2011 13:06:06 +0200
Subject: [PATCH 369/386] x86: Allow multiple cpu feature matches of
 lookup_feature

kvmclock is represented by two feature bits. Therefore, lookup_feature
needs to continue its search even after the first match. Enhance it
accordingly and switch to a bool return type at this chance.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
 target-i386/cpuid.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 814d13e767..0ac592f0c1 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -182,20 +182,22 @@ static int altcmp(const char *s, const char *e, const char *altstr)
 }
 
 /* search featureset for flag *[s..e), if found set corresponding bit in
- * *pval and return success, otherwise return zero
+ * *pval and return true, otherwise return false
  */
-static int lookup_feature(uint32_t *pval, const char *s, const char *e,
-    const char **featureset)
+static bool lookup_feature(uint32_t *pval, const char *s, const char *e,
+                           const char **featureset)
 {
     uint32_t mask;
     const char **ppc;
+    bool found = false;
 
-    for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc)
+    for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) {
         if (*ppc && !altcmp(s, e, *ppc)) {
             *pval |= mask;
-            break;
+            found = true;
         }
-    return (mask ? 1 : 0);
+    }
+    return found;
 }
 
 static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,

From 642258c6c7f386165bc7e79dcd42040fd77df01e Mon Sep 17 00:00:00 2001
From: Glauber Costa <glommer@redhat.com>
Date: Thu, 17 Mar 2011 19:42:06 -0300
Subject: [PATCH 370/386] kvm: add kvmclock to its second bit

We have two bits that can represent kvmclock in cpuid.
They signal the guest which msr set to use. When we tweak flags
involving this value - specially when we use "-", we have to act on both.

Signed-off-by: Glauber Costa <glommer@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 target-i386/cpuid.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 0ac592f0c1..e479a4dbd7 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -73,7 +73,7 @@ static const char *ext3_feature_name[] = {
 };
 
 static const char *kvm_feature_name[] = {
-    "kvmclock", "kvm_nopiodelay", "kvm_mmu", NULL, "kvm_asyncpf", NULL, NULL, NULL,
+    "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock", "kvm_asyncpf", NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,

From 450fb75c478aa4134bc1e6b1655791c0a39ad141 Mon Sep 17 00:00:00 2001
From: Glauber Costa <glommer@redhat.com>
Date: Thu, 17 Mar 2011 19:42:07 -0300
Subject: [PATCH 371/386] kvm: create kvmclock when one of the flags are
 present

kvmclock presence can be signalled by two different flags. So for
device creation, we have to test for both.

Signed-off-by: Glauber Costa <glommer@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 hw/kvmclock.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/kvmclock.c b/hw/kvmclock.c
index b6ceddfba6..004c4add8c 100644
--- a/hw/kvmclock.c
+++ b/hw/kvmclock.c
@@ -103,7 +103,11 @@ static SysBusDeviceInfo kvmclock_info = {
 void kvmclock_create(void)
 {
     if (kvm_enabled() &&
-        first_cpu->cpuid_kvm_features & (1ULL << KVM_FEATURE_CLOCKSOURCE)) {
+        first_cpu->cpuid_kvm_features & ((1ULL << KVM_FEATURE_CLOCKSOURCE)
+#ifdef KVM_FEATURE_CLOCKSOURCE2
+        || (1ULL << KVM_FEATURE_CLOCKSOURCE2)
+#endif
+    )) {
         sysbus_create_simple("kvmclock", -1, NULL);
     }
 }

From 97ffbd8d9d54736dd73227e5330c7f5cdc2d7a96 Mon Sep 17 00:00:00 2001
From: Jan Kiszka <jan.kiszka@siemens.com>
Date: Wed, 13 Apr 2011 01:32:56 +0200
Subject: [PATCH 372/386] Break up user and system cpu_interrupt
 implementations

Both have only two lines in common, and we will convert the system
service into a callback which is of no use for user mode operation.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Riku Voipio <riku.voipio@iki.fi>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
 exec.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/exec.c b/exec.c
index c3dc68ae09..d6d8a89110 100644
--- a/exec.c
+++ b/exec.c
@@ -1629,6 +1629,7 @@ static void cpu_unlink_tb(CPUState *env)
     spin_unlock(&interrupt_lock);
 }
 
+#ifndef CONFIG_USER_ONLY
 /* mask must never be zero, except for A20 change call */
 void cpu_interrupt(CPUState *env, int mask)
 {
@@ -1637,7 +1638,6 @@ void cpu_interrupt(CPUState *env, int mask)
     old_mask = env->interrupt_request;
     env->interrupt_request |= mask;
 
-#ifndef CONFIG_USER_ONLY
     /*
      * If called from iothread context, wake the target cpu in
      * case its halted.
@@ -1646,21 +1646,27 @@ void cpu_interrupt(CPUState *env, int mask)
         qemu_cpu_kick(env);
         return;
     }
-#endif
 
     if (use_icount) {
         env->icount_decr.u16.high = 0xffff;
-#ifndef CONFIG_USER_ONLY
         if (!can_do_io(env)
             && (mask & ~old_mask) != 0) {
             cpu_abort(env, "Raised interrupt while not in I/O function");
         }
-#endif
     } else {
         cpu_unlink_tb(env);
     }
 }
 
+#else /* CONFIG_USER_ONLY */
+
+void cpu_interrupt(CPUState *env, int mask)
+{
+    env->interrupt_request |= mask;
+    cpu_unlink_tb(env);
+}
+#endif /* CONFIG_USER_ONLY */
+
 void cpu_reset_interrupt(CPUState *env, int mask)
 {
     env->interrupt_request &= ~mask;

From ec6959d0466fb240fe4d94d5f525eebf9ba18b84 Mon Sep 17 00:00:00 2001
From: Jan Kiszka <jan.kiszka@siemens.com>
Date: Wed, 13 Apr 2011 01:32:56 +0200
Subject: [PATCH 373/386] Redirect cpu_interrupt to callback handler

This allows to override the interrupt handling of QEMU in system mode.
KVM will make use of it to set a specialized handler.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
 cpu-all.h | 14 +++++++++++++-
 exec.c    |  4 +++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/cpu-all.h b/cpu-all.h
index 0bae6df8ec..88126ea651 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -799,7 +799,19 @@ extern CPUState *cpu_single_env;
 #define CPU_INTERRUPT_SIPI   0x800 /* SIPI pending. */
 #define CPU_INTERRUPT_MCE    0x1000 /* (x86 only) MCE pending. */
 
-void cpu_interrupt(CPUState *s, int mask);
+#ifndef CONFIG_USER_ONLY
+typedef void (*CPUInterruptHandler)(CPUState *, int);
+
+extern CPUInterruptHandler cpu_interrupt_handler;
+
+static inline void cpu_interrupt(CPUState *s, int mask)
+{
+    cpu_interrupt_handler(s, mask);
+}
+#else /* USER_ONLY */
+void cpu_interrupt(CPUState *env, int mask);
+#endif /* USER_ONLY */
+
 void cpu_reset_interrupt(CPUState *env, int mask);
 
 void cpu_exit(CPUState *s);
diff --git a/exec.c b/exec.c
index d6d8a89110..a718d747e7 100644
--- a/exec.c
+++ b/exec.c
@@ -1631,7 +1631,7 @@ static void cpu_unlink_tb(CPUState *env)
 
 #ifndef CONFIG_USER_ONLY
 /* mask must never be zero, except for A20 change call */
-void cpu_interrupt(CPUState *env, int mask)
+static void tcg_handle_interrupt(CPUState *env, int mask)
 {
     int old_mask;
 
@@ -1658,6 +1658,8 @@ void cpu_interrupt(CPUState *env, int mask)
     }
 }
 
+CPUInterruptHandler cpu_interrupt_handler = tcg_handle_interrupt;
+
 #else /* CONFIG_USER_ONLY */
 
 void cpu_interrupt(CPUState *env, int mask)

From aa7f74d1199020a29c677bc80518df5267bfe73f Mon Sep 17 00:00:00 2001
From: Jan Kiszka <jan.kiszka@siemens.com>
Date: Wed, 13 Apr 2011 01:32:56 +0200
Subject: [PATCH 374/386] kvm: Install specialized interrupt handler

KVM only requires to set the raised IRQ in CPUState and to kick the
receiving vcpu if it is remote. Installing a specialized handler allows
potential future changes to the TCG code path without risking KVM side
effects.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
 kvm-all.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/kvm-all.c b/kvm-all.c
index 1d7e8eabf4..fd1fbfec7a 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -651,6 +651,15 @@ static CPUPhysMemoryClient kvm_cpu_phys_memory_client = {
     .log_stop = kvm_log_stop,
 };
 
+static void kvm_handle_interrupt(CPUState *env, int mask)
+{
+    env->interrupt_request |= mask;
+
+    if (!qemu_cpu_is_self(env)) {
+        qemu_cpu_kick(env);
+    }
+}
+
 int kvm_init(void)
 {
     static const char upgrade_note[] =
@@ -759,6 +768,8 @@ int kvm_init(void)
 
     s->many_ioeventfds = kvm_check_many_ioeventfds();
 
+    cpu_interrupt_handler = kvm_handle_interrupt;
+
     return 0;
 
 err:

From 51b0c6065aa6e47a47094d73e24be298a4a7f3a1 Mon Sep 17 00:00:00 2001
From: Michael Tokarev <mjt@tls.msk.ru>
Date: Tue, 26 Apr 2011 20:13:49 +0400
Subject: [PATCH 375/386] fix crash in migration, 32-bit userspace on 64-bit
 host

This change fixes a long-standing immediate crash (memory corruption
and abort in glibc malloc code) in migration on 32bits.

The bug is present since this commit:

  commit 692d9aca97b865b0f7903565274a52606910f129
  Author: Bruce Rogers <brogers@novell.com>
  Date:   Wed Sep 23 16:13:18 2009 -0600

    qemu-kvm: allocate correct size for dirty bitmap

    The dirty bitmap copied out to userspace is stored in a long array,
    and gets copied out to userspace accordingly.  This patch accounts
    for that correctly.  Currently I'm seeing kvm crashing due to writing
    beyond the end of the alloc'd dirty bitmap memory, because the buffer
    has the wrong size.

    Signed-off-by: Bruce Rogers
    Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

 --- a/qemu-kvm.c
 +++ b/qemu-kvm.c
 @@ int kvm_get_dirty_pages_range(kvm_context_t kvm, unsigned long phys_addr,
 -            buf = qemu_malloc((slots[i].len / 4096 + 7) / 8 + 2);
 +            buf = qemu_malloc(BITMAP_SIZE(slots[i].len));
             r = kvm_get_map(kvm, KVM_GET_DIRTY_LOG, i, buf);

BITMAP_SIZE is now open-coded in that function, like this:

 size = ALIGN(((mem->memory_size) >> TARGET_PAGE_BITS), HOST_LONG_BITS) / 8;

The problem is that HOST_LONG_BITS in 32bit userspace is 32
but it's 64 in 64bit kernel.  So userspace aligns this to
32, and kernel to 64, but since no length is passed from
userspace to kernel on ioctl, kernel uses its size calculation
and copies 4 extra bytes to userspace, corrupting memory.

Here's how it looks like during migrate execution:

our=20, kern=24
our=4, kern=8
...
our=4, kern=8
our=4064, kern=4064
our=512, kern=512
our=4, kern=8
our=20, kern=24
our=4, kern=8
...
our=4, kern=8
our=4064, kern=4064
*** glibc detected *** ./x86_64-softmmu/qemu-system-x86_64: realloc(): invalid next size: 0x08f20528 ***

(our is userspace size above, kern is the size as calculated
by the kernel).

Fix this by always aligning to 64 in a hope that no platform will
have sizeof(long)>8 any time soon, and add a comment describing it
all.  It's a small price to pay for bad kernel design.

Alternatively it's possible to fix that in the kernel by using
different size calculation depending on the current process.
But this becomes quite ugly.

Special thanks goes to Stefan Hajnoczi for spotting the fundamental
cause of the issue, and to Alexander Graf for his support in #qemu.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
CC: Bruce Rogers <brogers@novell.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 kvm-all.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/kvm-all.c b/kvm-all.c
index fd1fbfec7a..8b85029de3 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -373,7 +373,20 @@ static int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
             break;
         }
 
-        size = ALIGN(((mem->memory_size) >> TARGET_PAGE_BITS), HOST_LONG_BITS) / 8;
+        /* XXX bad kernel interface alert
+         * For dirty bitmap, kernel allocates array of size aligned to
+         * bits-per-long.  But for case when the kernel is 64bits and
+         * the userspace is 32bits, userspace can't align to the same
+         * bits-per-long, since sizeof(long) is different between kernel
+         * and user space.  This way, userspace will provide buffer which
+         * may be 4 bytes less than the kernel will use, resulting in
+         * userspace memory corruption (which is not detectable by valgrind
+         * too, in most cases).
+         * So for now, let's align to 64 instead of HOST_LONG_BITS here, in
+         * a hope that sizeof(long) wont become >8 any time soon.
+         */
+        size = ALIGN(((mem->memory_size) >> TARGET_PAGE_BITS),
+                     /*HOST_LONG_BITS*/ 64) / 8;
         if (!d.dirty_bitmap) {
             d.dirty_bitmap = qemu_malloc(size);
         } else if (size > allocated_size) {

From 4a043713b34af8947a4e8f40a9f4f43d7a6d2ae9 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Mon, 2 May 2011 09:54:04 +0200
Subject: [PATCH 376/386] kvm: use qemu_free consistently

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
 kvm-all.c         | 4 ++--
 target-i386/kvm.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 8b85029de3..d92c20e340 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1191,7 +1191,7 @@ int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
         bp->use_count = 1;
         err = kvm_arch_insert_sw_breakpoint(current_env, bp);
         if (err) {
-            free(bp);
+            qemu_free(bp);
             return err;
         }
 
@@ -1315,7 +1315,7 @@ int kvm_set_signal_mask(CPUState *env, const sigset_t *sigset)
     sigmask->len = 8;
     memcpy(sigmask->sigset, sigset, sizeof(*sigset));
     r = kvm_vcpu_ioctl(env, KVM_SET_SIGNAL_MASK, sigmask);
-    free(sigmask);
+    qemu_free(sigmask);
 
     return r;
 }
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 485572f82b..faedc6c254 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -572,7 +572,7 @@ static int kvm_get_supported_msrs(KVMState *s)
             }
         }
 
-        free(kvm_msr_list);
+        qemu_free(kvm_msr_list);
     }
 
     return ret;

From ecbe1de82362e73c2b1111770c4a91b675a6fca2 Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Wed, 13 Apr 2011 00:29:33 +0200
Subject: [PATCH 377/386] lm32: fix exception handling

Global interrupt enable bit is already saved within the exception handler
helper routine. Thus remove extra code in translation routines.

Additionally, debug exceptions has always DEBA as base address.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 target-lm32/helper.c    |  6 +-----
 target-lm32/translate.c | 26 --------------------------
 2 files changed, 1 insertion(+), 31 deletions(-)

diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 318e2cf6e0..4f3e7e0fcb 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -76,11 +76,7 @@ void do_interrupt(CPUState *env)
         env->regs[R_BA] = env->pc;
         env->ie |= (env->ie & IE_IE) ? IE_BIE : 0;
         env->ie &= ~IE_IE;
-        if (env->dc & DC_RE) {
-            env->pc = env->deba + (env->exception_index * 32);
-        } else {
-            env->pc = env->eba + (env->exception_index * 32);
-        }
+        env->pc = env->deba + (env->exception_index * 32);
         log_cpu_state_mask(CPU_LOG_INT, env, 0);
         break;
     default:
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 51b4f5a814..bcd52fe73d 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -598,36 +598,10 @@ static void dec_scall(DisasContext *dc)
     t0 = tcg_temp_new();
     l1 = gen_new_label();
 
-    /* save IE.IE */
-    tcg_gen_andi_tl(t0, cpu_ie, IE_IE);
-
-    /* IE.IE = 0 */
-    tcg_gen_andi_tl(cpu_ie, cpu_ie, ~IE_IE);
-
     if (dc->imm5 == 7) {
-        /* IE.EIE = IE.IE */
-        tcg_gen_ori_tl(cpu_ie, cpu_ie, IE_EIE);
-        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, IE_IE, l1);
-        tcg_gen_andi_tl(cpu_ie, cpu_ie, ~IE_EIE);
-        gen_set_label(l1);
-
-        /* gpr[ea] = PC */
-        tcg_gen_movi_tl(cpu_R[R_EA], dc->pc);
-        tcg_temp_free(t0);
-
         tcg_gen_movi_tl(cpu_pc, dc->pc);
         t_gen_raise_exception(dc, EXCP_SYSTEMCALL);
     } else {
-        /* IE.BIE = IE.IE */
-        tcg_gen_ori_tl(cpu_ie, cpu_ie, IE_BIE);
-        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, IE_IE, l1);
-        tcg_gen_andi_tl(cpu_ie, cpu_ie, ~IE_BIE);
-        gen_set_label(l1);
-
-        /* gpr[ba] = PC */
-        tcg_gen_movi_tl(cpu_R[R_BA], dc->pc);
-        tcg_temp_free(t0);
-
         tcg_gen_movi_tl(cpu_pc, dc->pc);
         t_gen_raise_exception(dc, EXCP_BREAKPOINT);
     }

From c07050ddb9659805068b2f1a3686c6f096dd11f9 Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Wed, 13 Apr 2011 00:29:34 +0200
Subject: [PATCH 378/386] milkymist-vgafb: fix console resizing

After enabling the framebuffer, ensure that the console is resized.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 hw/milkymist-vgafb.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
index 8922731511..2e55e42e34 100644
--- a/hw/milkymist-vgafb.c
+++ b/hw/milkymist-vgafb.c
@@ -199,6 +199,9 @@ vgafb_write(void *opaque, target_phys_addr_t addr, uint32_t value)
     addr >>= 2;
     switch (addr) {
     case R_CTRL:
+        s->regs[addr] = value;
+        vgafb_resize(s);
+        break;
     case R_HSYNC_START:
     case R_HSYNC_END:
     case R_HSCAN:

From f3172a0e2e7bd983cada19f11d9bb59400e0dd3d Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Wed, 13 Apr 2011 00:29:35 +0200
Subject: [PATCH 379/386] milkymist-sysctl: fix timers

Prevent timers from firing right after starting.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 hw/milkymist-sysctl.c | 26 +++++++-------------------
 1 file changed, 7 insertions(+), 19 deletions(-)

diff --git a/hw/milkymist-sysctl.c b/hw/milkymist-sysctl.c
index eaea543bf3..6bd0cb9740 100644
--- a/hw/milkymist-sysctl.c
+++ b/hw/milkymist-sysctl.c
@@ -140,24 +140,8 @@ static void sysctl_write(void *opaque, target_phys_addr_t addr, uint32_t value)
     case R_GPIO_OUT:
     case R_GPIO_INTEN:
     case R_TIMER0_COUNTER:
-        if (value > s->regs[R_TIMER0_COUNTER]) {
-            value = s->regs[R_TIMER0_COUNTER];
-            error_report("milkymist_sysctl: timer0: trying to write a "
-                    "value greater than the limit. Clipping.");
-        }
-        /* milkymist timer counts up */
-        value = s->regs[R_TIMER0_COUNTER] - value;
-        ptimer_set_count(s->ptimer0, value);
-        break;
     case R_TIMER1_COUNTER:
-        if (value > s->regs[R_TIMER1_COUNTER]) {
-            value = s->regs[R_TIMER1_COUNTER];
-            error_report("milkymist_sysctl: timer1: trying to write a "
-                    "value greater than the limit. Clipping.");
-        }
-        /* milkymist timer counts up */
-        value = s->regs[R_TIMER1_COUNTER] - value;
-        ptimer_set_count(s->ptimer1, value);
+        s->regs[addr] = value;
         break;
     case R_TIMER0_COMPARE:
         ptimer_set_limit(s->ptimer0, value, 0);
@@ -170,10 +154,12 @@ static void sysctl_write(void *opaque, target_phys_addr_t addr, uint32_t value)
     case R_TIMER0_CONTROL:
         s->regs[addr] = value;
         if (s->regs[R_TIMER0_CONTROL] & CTRL_ENABLE) {
-            trace_milkymist_sysctl_start_timer1();
+            trace_milkymist_sysctl_start_timer0();
+            ptimer_set_count(s->ptimer0,
+                    s->regs[R_TIMER0_COMPARE] - s->regs[R_TIMER0_COUNTER]);
             ptimer_run(s->ptimer0, 0);
         } else {
-            trace_milkymist_sysctl_stop_timer1();
+            trace_milkymist_sysctl_stop_timer0();
             ptimer_stop(s->ptimer0);
         }
         break;
@@ -181,6 +167,8 @@ static void sysctl_write(void *opaque, target_phys_addr_t addr, uint32_t value)
         s->regs[addr] = value;
         if (s->regs[R_TIMER1_CONTROL] & CTRL_ENABLE) {
             trace_milkymist_sysctl_start_timer1();
+            ptimer_set_count(s->ptimer1,
+                    s->regs[R_TIMER1_COMPARE] - s->regs[R_TIMER1_COUNTER]);
             ptimer_run(s->ptimer1, 0);
         } else {
             trace_milkymist_sysctl_stop_timer1();

From 57aa265d462a64a06268be26d49020729cff56c1 Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Wed, 13 Apr 2011 00:29:36 +0200
Subject: [PATCH 380/386] lm32: add Milkymist Minimac2 support

This patch adds support for Milkymist's minimal Ethernet MAC v2. It
superseds minimac1.

Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
---
 Makefile.target                               |   2 +-
 hw/milkymist-hw.h                             |  20 ++
 ...lkymist-minimac.c => milkymist-minimac2.c} | 297 ++++++++----------
 hw/milkymist.c                                |   2 +-
 trace-events                                  |  23 +-
 5 files changed, 168 insertions(+), 176 deletions(-)
 rename hw/{milkymist-minimac.c => milkymist-minimac2.c} (55%)

diff --git a/Makefile.target b/Makefile.target
index 2501c63bb2..21f864afd2 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -271,7 +271,7 @@ obj-lm32-y += lm32_sys.o
 obj-lm32-y += milkymist-ac97.o
 obj-lm32-y += milkymist-hpdmc.o
 obj-lm32-y += milkymist-memcard.o
-obj-lm32-y += milkymist-minimac.o
+obj-lm32-y += milkymist-minimac2.o
 obj-lm32-y += milkymist-pfpu.o
 obj-lm32-y += milkymist-softusb.o
 obj-lm32-y += milkymist-sysctl.o
diff --git a/hw/milkymist-hw.h b/hw/milkymist-hw.h
index 15acdbccd6..20de68ecce 100644
--- a/hw/milkymist-hw.h
+++ b/hw/milkymist-hw.h
@@ -1,6 +1,9 @@
 #ifndef QEMU_HW_MILKYMIST_H
 #define QEMU_HW_MILKYMIST_H
 
+#include "qdev.h"
+#include "qdev-addr.h"
+
 static inline DeviceState *milkymist_uart_create(target_phys_addr_t base,
         qemu_irq rx_irq, qemu_irq tx_irq)
 {
@@ -183,6 +186,23 @@ static inline DeviceState *milkymist_minimac_create(target_phys_addr_t base,
     return dev;
 }
 
+static inline DeviceState *milkymist_minimac2_create(target_phys_addr_t base,
+        target_phys_addr_t buffers_base, qemu_irq rx_irq, qemu_irq tx_irq)
+{
+    DeviceState *dev;
+
+    qemu_check_nic_model(&nd_table[0], "minimac2");
+    dev = qdev_create(NULL, "milkymist-minimac2");
+    qdev_prop_set_taddr(dev, "buffers_base", buffers_base);
+    qdev_set_nic_properties(dev, &nd_table[0]);
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 0, rx_irq);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 1, tx_irq);
+
+    return dev;
+}
+
 static inline DeviceState *milkymist_softusb_create(target_phys_addr_t base,
         qemu_irq irq, uint32_t pmem_base, uint32_t pmem_size,
         uint32_t dmem_base, uint32_t dmem_size)
diff --git a/hw/milkymist-minimac.c b/hw/milkymist-minimac2.c
similarity index 55%
rename from hw/milkymist-minimac.c
rename to hw/milkymist-minimac2.c
index b07f18d8a7..c4e28187b3 100644
--- a/hw/milkymist-minimac.c
+++ b/hw/milkymist-minimac2.c
@@ -1,7 +1,7 @@
 /*
- *  QEMU model of the Milkymist minimac block.
+ *  QEMU model of the Milkymist minimac2 block.
  *
- *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *  Copyright (c) 2011 Michael Walle <michael@walle.cc>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,7 +18,7 @@
  *
  *
  * Specification available at:
- *   http://www.milkymist.org/socdoc/minimac.pdf
+ *   not available yet
  *
  */
 
@@ -27,6 +27,7 @@
 #include "trace.h"
 #include "net.h"
 #include "qemu-error.h"
+#include "qdev-addr.h"
 
 #include <zlib.h>
 
@@ -34,25 +35,15 @@ enum {
     R_SETUP = 0,
     R_MDIO,
     R_STATE0,
-    R_ADDR0,
     R_COUNT0,
     R_STATE1,
-    R_ADDR1,
     R_COUNT1,
-    R_STATE2,
-    R_ADDR2,
-    R_COUNT2,
-    R_STATE3,
-    R_ADDR3,
-    R_COUNT3,
-    R_TXADDR,
     R_TXCOUNT,
     R_MAX
 };
 
 enum {
-    SETUP_RX_RST = (1<<0),
-    SETUP_TX_RST = (1<<2),
+    SETUP_PHY_RST = (1<<0),
 };
 
 enum {
@@ -85,9 +76,10 @@ enum {
     R_PHY_MAX  = 32
 };
 
-#define MINIMAC_MTU 1530
+#define MINIMAC2_MTU 1530
+#define MINIMAC2_BUFFER_SIZE 2048
 
-struct MilkymistMinimacMdioState {
+struct MilkymistMinimac2MdioState {
     int last_clk;
     int count;
     uint32_t data;
@@ -97,50 +89,55 @@ struct MilkymistMinimacMdioState {
     uint8_t phy_addr;
     uint8_t reg_addr;
 };
-typedef struct MilkymistMinimacMdioState MilkymistMinimacMdioState;
+typedef struct MilkymistMinimac2MdioState MilkymistMinimac2MdioState;
 
-struct MilkymistMinimacState {
+struct MilkymistMinimac2State {
     SysBusDevice busdev;
     NICState *nic;
     NICConf conf;
     char *phy_model;
+    target_phys_addr_t buffers_base;
 
     qemu_irq rx_irq;
     qemu_irq tx_irq;
 
     uint32_t regs[R_MAX];
 
-    MilkymistMinimacMdioState mdio;
+    MilkymistMinimac2MdioState mdio;
 
     uint16_t phy_regs[R_PHY_MAX];
+
+    uint8_t *rx0_buf;
+    uint8_t *rx1_buf;
+    uint8_t *tx_buf;
 };
-typedef struct MilkymistMinimacState MilkymistMinimacState;
+typedef struct MilkymistMinimac2State MilkymistMinimac2State;
 
 static const uint8_t preamble_sfd[] = {
         0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5
 };
 
-static void minimac_mdio_write_reg(MilkymistMinimacState *s,
+static void minimac2_mdio_write_reg(MilkymistMinimac2State *s,
         uint8_t phy_addr, uint8_t reg_addr, uint16_t value)
 {
-    trace_milkymist_minimac_mdio_write(phy_addr, reg_addr, value);
+    trace_milkymist_minimac2_mdio_write(phy_addr, reg_addr, value);
 
     /* nop */
 }
 
-static uint16_t minimac_mdio_read_reg(MilkymistMinimacState *s,
+static uint16_t minimac2_mdio_read_reg(MilkymistMinimac2State *s,
         uint8_t phy_addr, uint8_t reg_addr)
 {
     uint16_t r = s->phy_regs[reg_addr];
 
-    trace_milkymist_minimac_mdio_read(phy_addr, reg_addr, r);
+    trace_milkymist_minimac2_mdio_read(phy_addr, reg_addr, r);
 
     return r;
 }
 
-static void minimac_update_mdio(MilkymistMinimacState *s)
+static void minimac2_update_mdio(MilkymistMinimac2State *s)
 {
-    MilkymistMinimacMdioState *m = &s->mdio;
+    MilkymistMinimac2MdioState *m = &s->mdio;
 
     /* detect rising clk edge */
     if (m->last_clk == 0 && (s->regs[R_MDIO] & MDIO_CLK)) {
@@ -173,7 +170,7 @@ static void minimac_update_mdio(MilkymistMinimacState *s)
             }
 
             if (m->state == MDIO_STATE_READING) {
-                m->data_out = minimac_mdio_read_reg(s, m->phy_addr,
+                m->data_out = minimac2_mdio_read_reg(s, m->phy_addr,
                         m->reg_addr);
             }
         }
@@ -192,7 +189,7 @@ static void minimac_update_mdio(MilkymistMinimacState *s)
         if (m->count == 0 && m->state) {
             if (m->state == MDIO_STATE_WRITING) {
                 uint16_t data = m->data & 0xffff;
-                minimac_mdio_write_reg(s, m->phy_addr, m->reg_addr, data);
+                minimac2_mdio_write_reg(s, m->phy_addr, m->reg_addr, data);
             }
             m->state = MDIO_STATE_IDLE;
         }
@@ -208,7 +205,7 @@ static size_t assemble_frame(uint8_t *buf, size_t size,
     uint32_t crc;
 
     if (size < payload_size + 12) {
-        error_report("milkymist_minimac: received too big ethernet frame");
+        error_report("milkymist_minimac2: received too big ethernet frame");
         return 0;
     }
 
@@ -231,115 +228,102 @@ static size_t assemble_frame(uint8_t *buf, size_t size,
     return payload_size + 12;
 }
 
-static void minimac_tx(MilkymistMinimacState *s)
+static void minimac2_tx(MilkymistMinimac2State *s)
 {
-    uint8_t buf[MINIMAC_MTU];
     uint32_t txcount = s->regs[R_TXCOUNT];
-
-    /* do nothing if transmission logic is in reset */
-    if (s->regs[R_SETUP] & SETUP_TX_RST) {
-        return;
-    }
+    uint8_t *buf = s->tx_buf;
 
     if (txcount < 64) {
-        error_report("milkymist_minimac: ethernet frame too small (%u < %u)\n",
+        error_report("milkymist_minimac2: ethernet frame too small (%u < %u)\n",
                 txcount, 64);
-        return;
+        goto err;
     }
 
-    if (txcount > MINIMAC_MTU) {
-        error_report("milkymist_minimac: MTU exceeded (%u > %u)\n",
-                txcount, MINIMAC_MTU);
-        return;
+    if (txcount > MINIMAC2_MTU) {
+        error_report("milkymist_minimac2: MTU exceeded (%u > %u)\n",
+                txcount, MINIMAC2_MTU);
+        goto err;
     }
 
-    /* dma */
-    cpu_physical_memory_read(s->regs[R_TXADDR], buf, txcount);
-
     if (memcmp(buf, preamble_sfd, 8) != 0) {
-        error_report("milkymist_minimac: frame doesn't contain the preamble "
+        error_report("milkymist_minimac2: frame doesn't contain the preamble "
                 "and/or the SFD (%02x %02x %02x %02x %02x %02x %02x %02x)\n",
                 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
-        return;
+        goto err;
     }
 
-    trace_milkymist_minimac_tx_frame(txcount - 12);
+    trace_milkymist_minimac2_tx_frame(txcount - 12);
 
     /* send packet, skipping preamble and sfd */
     qemu_send_packet_raw(&s->nic->nc, buf + 8, txcount - 12);
 
     s->regs[R_TXCOUNT] = 0;
 
-    trace_milkymist_minimac_pulse_irq_tx();
+err:
+    trace_milkymist_minimac2_pulse_irq_tx();
     qemu_irq_pulse(s->tx_irq);
 }
 
-static ssize_t minimac_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
+static void update_rx_interrupt(MilkymistMinimac2State *s)
 {
-    MilkymistMinimacState *s = DO_UPCAST(NICState, nc, nc)->opaque;
+    if (s->regs[R_STATE0] == STATE_PENDING
+            || s->regs[R_STATE1] == STATE_PENDING) {
+        trace_milkymist_minimac2_raise_irq_rx();
+        qemu_irq_raise(s->rx_irq);
+    } else {
+        trace_milkymist_minimac2_lower_irq_rx();
+        qemu_irq_lower(s->rx_irq);
+    }
+}
+
+static ssize_t minimac2_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
+{
+    MilkymistMinimac2State *s = DO_UPCAST(NICState, nc, nc)->opaque;
 
-    uint32_t r_addr;
     uint32_t r_count;
     uint32_t r_state;
+    uint8_t *rx_buf;
 
-    uint8_t frame_buf[MINIMAC_MTU];
     size_t frame_size;
 
-    trace_milkymist_minimac_rx_frame(buf, size);
-
-    /* discard frames if nic is in reset */
-    if (s->regs[R_SETUP] & SETUP_RX_RST) {
-        return size;
-    }
+    trace_milkymist_minimac2_rx_frame(buf, size);
 
     /* choose appropriate slot */
     if (s->regs[R_STATE0] == STATE_LOADED) {
-        r_addr = R_ADDR0;
         r_count = R_COUNT0;
         r_state = R_STATE0;
+        rx_buf = s->rx0_buf;
     } else if (s->regs[R_STATE1] == STATE_LOADED) {
-        r_addr = R_ADDR1;
         r_count = R_COUNT1;
         r_state = R_STATE1;
-    } else if (s->regs[R_STATE2] == STATE_LOADED) {
-        r_addr = R_ADDR2;
-        r_count = R_COUNT2;
-        r_state = R_STATE2;
-    } else if (s->regs[R_STATE3] == STATE_LOADED) {
-        r_addr = R_ADDR3;
-        r_count = R_COUNT3;
-        r_state = R_STATE3;
+        rx_buf = s->rx1_buf;
     } else {
-        trace_milkymist_minimac_drop_rx_frame(buf);
+        trace_milkymist_minimac2_drop_rx_frame(buf);
         return size;
     }
 
     /* assemble frame */
-    frame_size = assemble_frame(frame_buf, sizeof(frame_buf), buf, size);
+    frame_size = assemble_frame(rx_buf, MINIMAC2_BUFFER_SIZE, buf, size);
 
     if (frame_size == 0) {
         return size;
     }
 
-    trace_milkymist_minimac_rx_transfer(buf, frame_size);
-
-    /* do dma */
-    cpu_physical_memory_write(s->regs[r_addr], frame_buf, frame_size);
+    trace_milkymist_minimac2_rx_transfer(rx_buf, frame_size);
 
     /* update slot */
     s->regs[r_count] = frame_size;
     s->regs[r_state] = STATE_PENDING;
 
-    trace_milkymist_minimac_pulse_irq_rx();
-    qemu_irq_pulse(s->rx_irq);
+    update_rx_interrupt(s);
 
     return size;
 }
 
 static uint32_t
-minimac_read(void *opaque, target_phys_addr_t addr)
+minimac2_read(void *opaque, target_phys_addr_t addr)
 {
-    MilkymistMinimacState *s = opaque;
+    MilkymistMinimac2State *s = opaque;
     uint32_t r = 0;
 
     addr >>= 2;
@@ -347,39 +331,30 @@ minimac_read(void *opaque, target_phys_addr_t addr)
     case R_SETUP:
     case R_MDIO:
     case R_STATE0:
-    case R_ADDR0:
     case R_COUNT0:
     case R_STATE1:
-    case R_ADDR1:
     case R_COUNT1:
-    case R_STATE2:
-    case R_ADDR2:
-    case R_COUNT2:
-    case R_STATE3:
-    case R_ADDR3:
-    case R_COUNT3:
-    case R_TXADDR:
     case R_TXCOUNT:
         r = s->regs[addr];
         break;
 
     default:
-        error_report("milkymist_minimac: read access to unknown register 0x"
+        error_report("milkymist_minimac2: read access to unknown register 0x"
                 TARGET_FMT_plx, addr << 2);
         break;
     }
 
-    trace_milkymist_minimac_memory_read(addr << 2, r);
+    trace_milkymist_minimac2_memory_read(addr << 2, r);
 
     return r;
 }
 
 static void
-minimac_write(void *opaque, target_phys_addr_t addr, uint32_t value)
+minimac2_write(void *opaque, target_phys_addr_t addr, uint32_t value)
 {
-    MilkymistMinimacState *s = opaque;
+    MilkymistMinimac2State *s = opaque;
 
-    trace_milkymist_minimac_memory_read(addr, value);
+    trace_milkymist_minimac2_memory_read(addr, value);
 
     addr >>= 2;
     switch (addr) {
@@ -394,58 +369,47 @@ minimac_write(void *opaque, target_phys_addr_t addr, uint32_t value)
             s->regs[R_MDIO] &= ~mdio_di;
         }
 
-        minimac_update_mdio(s);
+        minimac2_update_mdio(s);
     } break;
     case R_TXCOUNT:
         s->regs[addr] = value;
         if (value > 0) {
-            minimac_tx(s);
+            minimac2_tx(s);
         }
         break;
-    case R_SETUP:
     case R_STATE0:
-    case R_ADDR0:
-    case R_COUNT0:
     case R_STATE1:
-    case R_ADDR1:
+        s->regs[addr] = value;
+        update_rx_interrupt(s);
+        break;
+    case R_SETUP:
+    case R_COUNT0:
     case R_COUNT1:
-    case R_STATE2:
-    case R_ADDR2:
-    case R_COUNT2:
-    case R_STATE3:
-    case R_ADDR3:
-    case R_COUNT3:
-    case R_TXADDR:
         s->regs[addr] = value;
         break;
 
     default:
-        error_report("milkymist_minimac: write access to unknown register 0x"
+        error_report("milkymist_minimac2: write access to unknown register 0x"
                 TARGET_FMT_plx, addr << 2);
         break;
     }
 }
 
-static CPUReadMemoryFunc * const minimac_read_fn[] = {
+static CPUReadMemoryFunc * const minimac2_read_fn[] = {
     NULL,
     NULL,
-    &minimac_read,
+    &minimac2_read,
 };
 
-static CPUWriteMemoryFunc * const minimac_write_fn[] = {
+static CPUWriteMemoryFunc * const minimac2_write_fn[] = {
     NULL,
     NULL,
-    &minimac_write,
+    &minimac2_write,
 };
 
-static int minimac_can_rx(VLANClientState *nc)
+static int minimac2_can_rx(VLANClientState *nc)
 {
-    MilkymistMinimacState *s = DO_UPCAST(NICState, nc, nc)->opaque;
-
-    /* discard frames if nic is in reset */
-    if (s->regs[R_SETUP] & SETUP_RX_RST) {
-        return 1;
-    }
+    MilkymistMinimac2State *s = DO_UPCAST(NICState, nc, nc)->opaque;
 
     if (s->regs[R_STATE0] == STATE_LOADED) {
         return 1;
@@ -453,27 +417,21 @@ static int minimac_can_rx(VLANClientState *nc)
     if (s->regs[R_STATE1] == STATE_LOADED) {
         return 1;
     }
-    if (s->regs[R_STATE2] == STATE_LOADED) {
-        return 1;
-    }
-    if (s->regs[R_STATE3] == STATE_LOADED) {
-        return 1;
-    }
 
     return 0;
 }
 
-static void minimac_cleanup(VLANClientState *nc)
+static void minimac2_cleanup(VLANClientState *nc)
 {
-    MilkymistMinimacState *s = DO_UPCAST(NICState, nc, nc)->opaque;
+    MilkymistMinimac2State *s = DO_UPCAST(NICState, nc, nc)->opaque;
 
     s->nic = NULL;
 }
 
-static void milkymist_minimac_reset(DeviceState *d)
+static void milkymist_minimac2_reset(DeviceState *d)
 {
-    MilkymistMinimacState *s =
-            container_of(d, MilkymistMinimacState, busdev.qdev);
+    MilkymistMinimac2State *s =
+            container_of(d, MilkymistMinimac2State, busdev.qdev);
     int i;
 
     for (i = 0; i < R_MAX; i++) {
@@ -488,81 +446,94 @@ static void milkymist_minimac_reset(DeviceState *d)
     s->phy_regs[R_PHY_ID2] = 0x161a;
 }
 
-static NetClientInfo net_milkymist_minimac_info = {
+static NetClientInfo net_milkymist_minimac2_info = {
     .type = NET_CLIENT_TYPE_NIC,
     .size = sizeof(NICState),
-    .can_receive = minimac_can_rx,
-    .receive = minimac_rx,
-    .cleanup = minimac_cleanup,
+    .can_receive = minimac2_can_rx,
+    .receive = minimac2_rx,
+    .cleanup = minimac2_cleanup,
 };
 
-static int milkymist_minimac_init(SysBusDevice *dev)
+static int milkymist_minimac2_init(SysBusDevice *dev)
 {
-    MilkymistMinimacState *s = FROM_SYSBUS(typeof(*s), dev);
+    MilkymistMinimac2State *s = FROM_SYSBUS(typeof(*s), dev);
     int regs;
+    ram_addr_t buffers;
+    size_t buffers_size = TARGET_PAGE_ALIGN(3 * MINIMAC2_BUFFER_SIZE);
 
     sysbus_init_irq(dev, &s->rx_irq);
     sysbus_init_irq(dev, &s->tx_irq);
 
-    regs = cpu_register_io_memory(minimac_read_fn, minimac_write_fn, s,
+    regs = cpu_register_io_memory(minimac2_read_fn, minimac2_write_fn, s,
             DEVICE_NATIVE_ENDIAN);
     sysbus_init_mmio(dev, R_MAX * 4, regs);
 
+    /* register buffers memory */
+    buffers = qemu_ram_alloc(NULL, "milkymist_minimac2.buffers", buffers_size);
+    s->rx0_buf = qemu_get_ram_ptr(buffers);
+    s->rx1_buf = s->rx0_buf + MINIMAC2_BUFFER_SIZE;
+    s->tx_buf = s->rx1_buf + MINIMAC2_BUFFER_SIZE;
+
+    cpu_register_physical_memory(s->buffers_base, buffers_size,
+            buffers | IO_MEM_RAM);
+
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
-    s->nic = qemu_new_nic(&net_milkymist_minimac_info, &s->conf,
+    s->nic = qemu_new_nic(&net_milkymist_minimac2_info, &s->conf,
                           dev->qdev.info->name, dev->qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
 
     return 0;
 }
 
-static const VMStateDescription vmstate_milkymist_minimac_mdio = {
-    .name = "milkymist_minimac_mdio",
+static const VMStateDescription vmstate_milkymist_minimac2_mdio = {
+    .name = "milkymist-minimac2-mdio",
     .version_id = 1,
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
     .fields      = (VMStateField[]) {
-        VMSTATE_INT32(last_clk, MilkymistMinimacMdioState),
-        VMSTATE_INT32(count, MilkymistMinimacMdioState),
-        VMSTATE_UINT32(data, MilkymistMinimacMdioState),
-        VMSTATE_UINT16(data_out, MilkymistMinimacMdioState),
-        VMSTATE_INT32(state, MilkymistMinimacMdioState),
-        VMSTATE_UINT8(phy_addr, MilkymistMinimacMdioState),
-        VMSTATE_UINT8(reg_addr, MilkymistMinimacMdioState),
+        VMSTATE_INT32(last_clk, MilkymistMinimac2MdioState),
+        VMSTATE_INT32(count, MilkymistMinimac2MdioState),
+        VMSTATE_UINT32(data, MilkymistMinimac2MdioState),
+        VMSTATE_UINT16(data_out, MilkymistMinimac2MdioState),
+        VMSTATE_INT32(state, MilkymistMinimac2MdioState),
+        VMSTATE_UINT8(phy_addr, MilkymistMinimac2MdioState),
+        VMSTATE_UINT8(reg_addr, MilkymistMinimac2MdioState),
         VMSTATE_END_OF_LIST()
     }
 };
 
-static const VMStateDescription vmstate_milkymist_minimac = {
-    .name = "milkymist-minimac",
+static const VMStateDescription vmstate_milkymist_minimac2 = {
+    .name = "milkymist-minimac2",
     .version_id = 1,
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
     .fields      = (VMStateField[]) {
-        VMSTATE_UINT32_ARRAY(regs, MilkymistMinimacState, R_MAX),
-        VMSTATE_UINT16_ARRAY(phy_regs, MilkymistMinimacState, R_PHY_MAX),
-        VMSTATE_STRUCT(mdio, MilkymistMinimacState, 0,
-                vmstate_milkymist_minimac_mdio, MilkymistMinimacMdioState),
+        VMSTATE_UINT32_ARRAY(regs, MilkymistMinimac2State, R_MAX),
+        VMSTATE_UINT16_ARRAY(phy_regs, MilkymistMinimac2State, R_PHY_MAX),
+        VMSTATE_STRUCT(mdio, MilkymistMinimac2State, 0,
+                vmstate_milkymist_minimac2_mdio, MilkymistMinimac2MdioState),
         VMSTATE_END_OF_LIST()
     }
 };
 
-static SysBusDeviceInfo milkymist_minimac_info = {
-    .init = milkymist_minimac_init,
-    .qdev.name  = "milkymist-minimac",
-    .qdev.size  = sizeof(MilkymistMinimacState),
-    .qdev.vmsd  = &vmstate_milkymist_minimac,
-    .qdev.reset = milkymist_minimac_reset,
+static SysBusDeviceInfo milkymist_minimac2_info = {
+    .init = milkymist_minimac2_init,
+    .qdev.name  = "milkymist-minimac2",
+    .qdev.size  = sizeof(MilkymistMinimac2State),
+    .qdev.vmsd  = &vmstate_milkymist_minimac2,
+    .qdev.reset = milkymist_minimac2_reset,
     .qdev.props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(MilkymistMinimacState, conf),
-        DEFINE_PROP_STRING("phy_model", MilkymistMinimacState, phy_model),
+        DEFINE_PROP_TADDR("buffers_base", MilkymistMinimac2State,
+                buffers_base, 0),
+        DEFINE_NIC_PROPERTIES(MilkymistMinimac2State, conf),
+        DEFINE_PROP_STRING("phy_model", MilkymistMinimac2State, phy_model),
         DEFINE_PROP_END_OF_LIST(),
     }
 };
 
-static void milkymist_minimac_register(void)
+static void milkymist_minimac2_register(void)
 {
-    sysbus_register_withprop(&milkymist_minimac_info);
+    sysbus_register_withprop(&milkymist_minimac2_info);
 }
 
-device_init(milkymist_minimac_register)
+device_init(milkymist_minimac2_register)
diff --git a/hw/milkymist.c b/hw/milkymist.c
index 8defad8024..787984040f 100644
--- a/hw/milkymist.c
+++ b/hw/milkymist.c
@@ -156,7 +156,7 @@ milkymist_init(ram_addr_t ram_size_not_used,
     milkymist_ac97_create(0x60005000, irq[5], irq[6], irq[7], irq[8]);
     milkymist_pfpu_create(0x60006000, irq[9]);
     milkymist_tmu2_create(0x60007000, irq[10]);
-    milkymist_minimac_create(0x60008000, irq[11], irq[12]);
+    milkymist_minimac2_create(0x60008000, 0x30000000, irq[11], irq[12]);
     milkymist_softusb_create(0x6000f000, irq[17],
             0x20000000, 0x1000, 0x20020000, 0x2000);
 
diff --git a/trace-events b/trace-events
index 77c96a5978..4f965e2ebd 100644
--- a/trace-events
+++ b/trace-events
@@ -308,17 +308,18 @@ disable milkymist_hpdmc_memory_write(uint32_t addr, uint32_t value) "addr=%08x v
 disable milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
 disable milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
 
-# hw/milkymist-minimac.c
-disable milkymist_minimac_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_minimac_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_minimac_mdio_write(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
-disable milkymist_minimac_mdio_read(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
-disable milkymist_minimac_tx_frame(uint32_t length) "length %u"
-disable milkymist_minimac_rx_frame(const void *buf, uint32_t length) "buf %p length %u"
-disable milkymist_minimac_drop_rx_frame(const void *buf) "buf %p"
-disable milkymist_minimac_rx_transfer(const void *buf, uint32_t length) "buf %p length %d"
-disable milkymist_minimac_pulse_irq_rx(void) "Pulse IRQ RX"
-disable milkymist_minimac_pulse_irq_tx(void) "Pulse IRQ TX"
+# hw/milkymist-minimac2.c
+disable milkymist_minimac2_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_minimac2_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+disable milkymist_minimac2_mdio_write(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
+disable milkymist_minimac2_mdio_read(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
+disable milkymist_minimac2_tx_frame(uint32_t length) "length %u"
+disable milkymist_minimac2_rx_frame(const void *buf, uint32_t length) "buf %p length %u"
+disable milkymist_minimac2_drop_rx_frame(const void *buf) "buf %p"
+disable milkymist_minimac2_rx_transfer(const void *buf, uint32_t length) "buf %p length %d"
+disable milkymist_minimac2_raise_irq_rx(void) "Raise IRQ RX"
+disable milkymist_minimac2_lower_irq_rx(void) "Lower IRQ RX"
+disable milkymist_minimac2_pulse_irq_tx(void) "Pulse IRQ TX"
 
 # hw/milkymist-pfpu.c
 disable milkymist_pfpu_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"

From e80fec7feb62c741df5360c1841ca49e4087c1cd Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Fri, 29 Apr 2011 10:58:12 +0200
Subject: [PATCH 381/386] qemu-img resize: Fix option parsing

For shrinking images, you're supposed to use a negative size. However, the
leading minus makes getopt think that it's an option and so you get the help
text if you don't use -- like in 'qemu-img resize test.img -- -1G'.

This patch handles the size first and removes it from the argument list so that
getopt won't even try to interpret it and you don't need -- any more.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qemu-img.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index ed5ba91117..e8251234b1 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1442,6 +1442,16 @@ static int img_resize(int argc, char **argv)
         { NULL }
     };
 
+    /* Remove size from argv manually so that negative numbers are not treated
+     * as options by getopt. */
+    if (argc < 3) {
+        help();
+        return 1;
+    }
+
+    size = argv[--argc];
+
+    /* Parse getopt arguments */
     fmt = NULL;
     for(;;) {
         c = getopt(argc, argv, "f:h");
@@ -1458,11 +1468,10 @@ static int img_resize(int argc, char **argv)
             break;
         }
     }
-    if (optind + 1 >= argc) {
+    if (optind >= argc) {
         help();
     }
     filename = argv[optind++];
-    size = argv[optind++];
 
     /* Choose grow, shrink, or absolute resize mode */
     switch (size[0]) {

From a7acf552e2cfb42ea1b27966b7f318eca2cc478a Mon Sep 17 00:00:00 2001
From: Amit Shah <amit.shah@redhat.com>
Date: Thu, 28 Apr 2011 20:04:40 +0530
Subject: [PATCH 382/386] atapi: Move comment to proper place

Move misplaced comment for media_is_dvd()

Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/atapi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 690a0abdda..86b18d894c 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -71,12 +71,12 @@ static void lba_to_msf(uint8_t *buf, int lba)
     buf[2] = lba % 75;
 }
 
-/* XXX: DVDs that could fit on a CD will be reported as a CD */
 static inline int media_present(IDEState *s)
 {
     return (s->nb_sectors > 0);
 }
 
+/* XXX: DVDs that could fit on a CD will be reported as a CD */
 static inline int media_is_dvd(IDEState *s)
 {
     return (media_present(s) && s->nb_sectors > CD_MAX_SECTORS);

From 4a737d14d0788412eead23330b554eb75900af04 Mon Sep 17 00:00:00 2001
From: Amit Shah <amit.shah@redhat.com>
Date: Thu, 28 Apr 2011 20:04:41 +0530
Subject: [PATCH 383/386] atapi: Explain why we need a 'media not present'
 state

After the re-org of the atapi code, it might not be intuitive for a
reader of the code to understand why we're inserting a 'media not
present' state between cd changes.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/atapi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 86b18d894c..58febc0285 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -1106,7 +1106,13 @@ void ide_atapi_cmd(IDEState *s)
         ide_atapi_cmd_check_status(s);
         return;
     }
-
+    /*
+     * When a CD gets changed, we have to report an ejected state and
+     * then a loaded state to guests so that they detect tray
+     * open/close and media change events.  Guests that do not use
+     * GET_EVENT_STATUS_NOTIFICATION to detect such tray open/close
+     * states rely on this behavior.
+     */
     if (bdrv_is_inserted(s->bs) && s->cdrom_changed) {
         ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
 

From ab71982716928577826b9aa7fc9a5102bfce5f0e Mon Sep 17 00:00:00 2001
From: Alon Levy <alevy@redhat.com>
Date: Thu, 28 Apr 2011 16:34:39 +0300
Subject: [PATCH 384/386] ide/atapi: fix set but unused

Signed-off-by: Alon Levy <alevy@redhat.com>
Acked-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/atapi.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 58febc0285..fe2fb0b806 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -1080,17 +1080,15 @@ static const struct {
 
 void ide_atapi_cmd(IDEState *s)
 {
-    const uint8_t *packet;
     uint8_t *buf;
 
-    packet = s->io_buffer;
     buf = s->io_buffer;
 #ifdef DEBUG_IDE_ATAPI
     {
         int i;
         printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
         for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
-            printf(" %02x", packet[i]);
+            printf(" %02x", buf[i]);
         }
         printf("\n");
     }

From 2ab3cb8c0ae79c96f38f6bfd35620cc18ddba19f Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@redhat.com>
Date: Thu, 28 Apr 2011 13:58:30 +0200
Subject: [PATCH 385/386] qemu-progress.c: printf isn't signal safe

Change the signal handling to indicate a signal is pending, rather
then printing directly from the signal handler.

In addition make the signal prints go to stderr, rather than stdout.

Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qemu-progress.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/qemu-progress.c b/qemu-progress.c
index e1feb89614..a4894c0dfc 100644
--- a/qemu-progress.c
+++ b/qemu-progress.c
@@ -37,6 +37,7 @@ struct progress_state {
 };
 
 static struct progress_state state;
+static volatile sig_atomic_t print_pending;
 
 /*
  * Simple progress print function.
@@ -63,12 +64,16 @@ static void progress_simple_init(void)
 #ifdef CONFIG_POSIX
 static void sigusr_print(int signal)
 {
-    printf("    (%3.2f/100%%)\n", state.current);
+    print_pending = 1;
 }
 #endif
 
 static void progress_dummy_print(void)
 {
+    if (print_pending) {
+        fprintf(stderr, "    (%3.2f/100%%)\n", state.current);
+        print_pending = 0;
+    }
 }
 
 static void progress_dummy_end(void)

From d2d979c628e4b2c4a3cb71a31841875795c79043 Mon Sep 17 00:00:00 2001
From: Nick Thomas <nick@bytemark.co.uk>
Date: Thu, 28 Apr 2011 16:20:01 +0100
Subject: [PATCH 386/386] NBD: Avoid leaking a couple of strings when the NBD
 device is closed

Signed-off-by: Nick Thomas <nick@bytemark.co.uk>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/nbd.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/block/nbd.c b/block/nbd.c
index 1d6b22561b..7a52f62e7e 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -239,6 +239,10 @@ static int nbd_write(BlockDriverState *bs, int64_t sector_num,
 
 static void nbd_close(BlockDriverState *bs)
 {
+    BDRVNBDState *s = bs->opaque;
+    qemu_free(s->export_name);
+    qemu_free(s->host_spec);
+
     nbd_teardown_connection(bs);
 }