Re: [Qemu-devel] [Bug?]When close VM the hugepage not freed

2014-10-15 Thread Daniel P. Berrange
On Tue, Oct 14, 2014 at 07:28:39PM +0300, Michael S. Tsirkin wrote:
> On Tue, Oct 14, 2014 at 01:08:15PM +0100, Daniel P. Berrange wrote:
> > On Tue, Oct 14, 2014 at 08:02:38PM +0800, Linhaifeng wrote:
> > > Hi,all
> > > 
> > > I was trying to use hugepage with VM and found that the hugepage not 
> > > freed when close VM.
> > > 
> > > 
> > > 1.Before start VM the /proc/meminfo is:
> > > AnonHugePages:124928 kB
> > > HugePages_Total:4096
> > > HugePages_Free: 3072
> > > HugePages_Rsvd:0
> > > HugePages_Surp:0
> > > Hugepagesize:   2048 kB
> > > 
> > > 2.Start VM the /proc/meminfo is:
> > > AnonHugePages:139264 kB
> > > HugePages_Total:4096
> > > HugePages_Free: 2048
> > > HugePages_Rsvd:0
> > > HugePages_Surp:0
> > > Hugepagesize:   2048 kB
> > > 
> > > 3.Close VM the /proc/meminfo is:
> > > AnonHugePages:124928 kB
> > > HugePages_Total:4096
> > > HugePages_Free: 2048
> > > HugePages_Rsvd:0
> > > HugePages_Surp:0
> > > Hugepagesize:   2048 kB
> > > 
> > > We can see there are 1024 hugepage leak!
> > > 
> > > I try to found which function used to free hugepage but i'm not sure
> > > where the qemu_ram_free is the function to free hugepage.
> > > I found that the qemu_ram_free function not call unlink and we know
> > > unlink is used to free hugepage(see example of hugepage-mmap.c in
> > > kernel source).
> > 
> > We can't rely on 'qemu_ram_free' ever executing because we must
> > ensure hugepages are freed upon QEMU crash.
> > 
> > It seems we should rely on UNIX filesytstem semantics and simply
> > unlink the memory segment the moment we create it & open the FD.
> > That way the kernel will automatically free it when the FD is
> > closed when QEMU process exits.
> > 
> We being libvirt?

No, QEMU is responsible for creating the mmap file, so QEMU should
take care of unlinking it after opening it.

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|



[Qemu-devel] [PATCH] target-arm: A64: remove redundant store

2014-10-15 Thread Alex Bennée
There is not much point storing the same value twice in a row.

Reported-by: Laurent Desnogues 
Signed-off-by: Alex Bennée 
Reviewed-by: Laurent Desnogues 
---
 target-arm/translate-a64.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 35ae3ea..337f4d4 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -748,7 +748,6 @@ static void do_fp_st(DisasContext *s, int srcidx, TCGv_i64 
tcg_addr, int size)
 } else {
 TCGv_i64 tcg_hiaddr = tcg_temp_new_i64();
 tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s), MO_TEQ);
-tcg_gen_qemu_st64(tmp, tcg_addr, get_mem_index(s));
 tcg_gen_ld_i64(tmp, cpu_env, fp_reg_hi_offset(s, srcidx));
 tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
 tcg_gen_qemu_st_i64(tmp, tcg_hiaddr, get_mem_index(s), MO_TEQ);
-- 
2.1.1




Re: [Qemu-devel] [PATCH 0/2] Here are 2 patches to enable sPAPR NVRAM migration.

2014-10-15 Thread Alexander Graf


On 02.10.14 11:56, Alexey Kardashevskiy wrote:
> Please comment. Thanks!
> 
> Changes:
> v2:
> * reworked to always have a copy of NVRAM in RAM and use file only for writes

Thanks, applied to ppc-next.


Alex



[Qemu-devel] [PATCH] glib: add compatibility interface for g_get_monotonic_time()

2014-10-15 Thread Stefan Hajnoczi
This patch fixes compilation errors when building against glib <2.28.0
due to the missing g_get_monotonic_time() function.

The compilation error in tests/libqos/virtio.c was introduced in commit
70556264a89a268efba1d7e8e341adcdd7881eb4 ("libqos: use microseconds
instead of iterations for virtio timeout").

Add a simple g_get_monotonic_time() implementation to compat-glib.h
based on code from vhost-user-test.c.

Signed-off-by: Stefan Hajnoczi 
---
 include/glib-compat.h   | 14 ++
 tests/vhost-user-test.c | 18 +-
 2 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/include/glib-compat.h b/include/glib-compat.h
index 4ae0671..9343742 100644
--- a/include/glib-compat.h
+++ b/include/glib-compat.h
@@ -26,6 +26,20 @@ static inline guint g_timeout_add_seconds(guint interval, 
GSourceFunc function,
 }
 #endif
 
+#if !GLIB_CHECK_VERSION(2, 28, 0)
+static inline gint64 g_get_monotonic_time(void)
+{
+/* g_get_monotonic_time() is best-effort so we can use the wall clock as a
+ * fallback.
+ */
+
+GTimeVal time;
+g_get_current_time(&time);
+
+return time.tv_sec * G_TIME_SPAN_SECOND + time.tv_usec;
+}
+#endif
+
 #ifdef _WIN32
 /*
  * g_poll has a problem on Windows when using
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index 75fedf0..af4012e 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -26,10 +26,6 @@
 #define G_TIME_SPAN_SECOND  (G_GINT64_CONSTANT(100))
 #endif
 
-#if GLIB_CHECK_VERSION(2, 28, 0)
-#define HAVE_MONOTONIC_TIME
-#endif
-
 #if GLIB_CHECK_VERSION(2, 32, 0)
 #define HAVE_MUTEX_INIT
 #define HAVE_COND_INIT
@@ -116,18 +112,6 @@ static VhostUserMemory memory;
 static GMutex *data_mutex;
 static GCond *data_cond;
 
-static gint64 _get_time(void)
-{
-#ifdef HAVE_MONOTONIC_TIME
-return g_get_monotonic_time();
-#else
-GTimeVal time;
-g_get_current_time(&time);
-
-return time.tv_sec * G_TIME_SPAN_SECOND + time.tv_usec;
-#endif
-}
-
 static GMutex *_mutex_new(void)
 {
 GMutex *mutex;
@@ -210,7 +194,7 @@ static void read_guest_mem(void)
 
 g_mutex_lock(data_mutex);
 
-end_time = _get_time() + 5 * G_TIME_SPAN_SECOND;
+end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
 while (!fds_num) {
 if (!_cond_wait_until(data_cond, data_mutex, end_time)) {
 /* timeout has passed */
-- 
1.9.3




Re: [Qemu-devel] [PATCH] glib: add compatibility interface for g_get_monotonic_time()

2014-10-15 Thread Igor Mammedov
On Wed, 15 Oct 2014 09:24:28 +0200
Stefan Hajnoczi  wrote:

> This patch fixes compilation errors when building against glib <2.28.0
> due to the missing g_get_monotonic_time() function.
> 
> The compilation error in tests/libqos/virtio.c was introduced in
> commit 70556264a89a268efba1d7e8e341adcdd7881eb4 ("libqos: use
> microseconds instead of iterations for virtio timeout").
> 
> Add a simple g_get_monotonic_time() implementation to compat-glib.h
> based on code from vhost-user-test.c.
> 
> Signed-off-by: Stefan Hajnoczi 
> ---
>  include/glib-compat.h   | 14 ++
>  tests/vhost-user-test.c | 18 +-
>  2 files changed, 15 insertions(+), 17 deletions(-)
> 
> diff --git a/include/glib-compat.h b/include/glib-compat.h
> index 4ae0671..9343742 100644
> --- a/include/glib-compat.h
> +++ b/include/glib-compat.h
> @@ -26,6 +26,20 @@ static inline guint g_timeout_add_seconds(guint
> interval, GSourceFunc function, }
>  #endif
>  
> +#if !GLIB_CHECK_VERSION(2, 28, 0)
> +static inline gint64 g_get_monotonic_time(void)
> +{
> +/* g_get_monotonic_time() is best-effort so we can use the wall
> clock as a
> + * fallback.
> + */
> +
> +GTimeVal time;
> +g_get_current_time(&time);
> +
> +return time.tv_sec * G_TIME_SPAN_SECOND + time.tv_usec;
 G_TIME_SPAN_SECOND needs to be moved from tests/vhost-user-test.c to
 here as well.


> +}
> +#endif
> +
>  #ifdef _WIN32
>  /*
>   * g_poll has a problem on Windows when using
> diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
> index 75fedf0..af4012e 100644
> --- a/tests/vhost-user-test.c
> +++ b/tests/vhost-user-test.c
> @@ -26,10 +26,6 @@
>  #define G_TIME_SPAN_SECOND  (G_GINT64_CONSTANT(100))
>  #endif
>  
> -#if GLIB_CHECK_VERSION(2, 28, 0)
> -#define HAVE_MONOTONIC_TIME
> -#endif
> -
>  #if GLIB_CHECK_VERSION(2, 32, 0)
>  #define HAVE_MUTEX_INIT
>  #define HAVE_COND_INIT
> @@ -116,18 +112,6 @@ static VhostUserMemory memory;
>  static GMutex *data_mutex;
>  static GCond *data_cond;
>  
> -static gint64 _get_time(void)
> -{
> -#ifdef HAVE_MONOTONIC_TIME
> -return g_get_monotonic_time();
> -#else
> -GTimeVal time;
> -g_get_current_time(&time);
> -
> -return time.tv_sec * G_TIME_SPAN_SECOND + time.tv_usec;
> -#endif
> -}
> -
>  static GMutex *_mutex_new(void)
>  {
>  GMutex *mutex;
> @@ -210,7 +194,7 @@ static void read_guest_mem(void)
>  
>  g_mutex_lock(data_mutex);
>  
> -end_time = _get_time() + 5 * G_TIME_SPAN_SECOND;
> +end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
>  while (!fds_num) {
>  if (!_cond_wait_until(data_cond, data_mutex, end_time)) {
>  /* timeout has passed */




Re: [Qemu-devel] [Bug?]When close VM the hugepage not freed

2014-10-15 Thread Linhaifeng


On 2014/10/14 20:02, Linhaifeng wrote:
> Hi,all
> 
> I was trying to use hugepage with VM and found that the hugepage not freed 
> when close VM.
> 
> 
> 1.Before start VM the /proc/meminfo is:
> AnonHugePages:124928 kB
> HugePages_Total:4096
> HugePages_Free: 3072
> HugePages_Rsvd:0
> HugePages_Surp:0
> Hugepagesize:   2048 kB
> 
> 2.Start VM the /proc/meminfo is:
> AnonHugePages:139264 kB
> HugePages_Total:4096
> HugePages_Free: 2048
> HugePages_Rsvd:0
> HugePages_Surp:0
> Hugepagesize:   2048 kB
> 
> 3.Close VM the /proc/meminfo is:
> AnonHugePages:124928 kB
> HugePages_Total:4096
> HugePages_Free: 2048
> HugePages_Rsvd:0
> HugePages_Surp:0
> Hugepagesize:   2048 kB
> 
> We can see there are 1024 hugepage leak!
> 
> I try to found which function used to free hugepage but i'm not sure where 
> the qemu_ram_free is the function to free hugepage.
> I found that the qemu_ram_free function not call unlink and we know unlink is 
> used to free hugepage(see example of hugepage-mmap.c in kernel source).
> 
> void qemu_ram_free(ram_addr_t addr)
> {
> RAMBlock *block;
> 
> /* This assumes the iothread lock is taken here too.  */
> qemu_mutex_lock_ramlist();
> QTAILQ_FOREACH(block, &ram_list.blocks, next) {
> if (addr == block->offset) {
> QTAILQ_REMOVE(&ram_list.blocks, block, next);
> ram_list.mru_block = NULL;
> ram_list.version++;
> if (block->flags & RAM_PREALLOC) {
> ;
> } else if (xen_enabled()) {
> xen_invalidate_map_cache_entry(block->host);
> #ifndef _WIN32
> } else if (block->fd >= 0) {
> munmap(block->host, block->length);
> close(block->fd);
>   // should we add unlink here to free hugepage?
> #endif
> } else {
> qemu_anon_ram_free(block->host, block->length);
> }
> g_free(block);
> break;
> }
> }
> qemu_mutex_unlock_ramlist();
> 
> }
> 
> 
> 
> 

When i run the QEMU with tap backend the hugepage will be freed but not the 
vhost-user backend.
Maybe the vhost-user process should close the hugefile.

-- 
Regards,
Haifeng




[Qemu-devel] [PATCH v2] target-i386: move generic memory hotplug methods to DSDTs

2014-10-15 Thread Paolo Bonzini
This makes it simpler to keep the SSDT byte-for-byte identical for a
given machine type, which is a goal we want to have for 2.2 and newer
types.

Signed-off-by: Paolo Bonzini 
---
v1->v2: do not define the same Device twice (Igor)

 hw/i386/acpi-dsdt-mem-hotplug.dsl   | 176 
 hw/i386/acpi-dsdt.dsl   |   3 +-
 hw/i386/acpi-dsdt.hex.generated | 795 +-
 hw/i386/q35-acpi-dsdt.dsl   |   3 +-
 hw/i386/q35-acpi-dsdt.hex.generated | 797 +-
 hw/i386/ssdt-mem.hex.generated  |   8 +-
 hw/i386/ssdt-misc.dsl   | 165 +--
 hw/i386/ssdt-misc.hex.generated | 834 ++--
 tests/acpi-test-data/pc/DSDT| Bin 2807 -> 3592 bytes
 tests/acpi-test-data/pc/SSDT| Bin 3065 -> 2279 bytes
 tests/acpi-test-data/q35/DSDT   | Bin 7397 -> 8182 bytes
 tests/acpi-test-data/q35/SSDT   | Bin 1346 -> 560 bytes
 12 files changed, 1789 insertions(+), 992 deletions(-)
 create mode 100644 hw/i386/acpi-dsdt-mem-hotplug.dsl

diff --git a/hw/i386/acpi-dsdt-mem-hotplug.dsl 
b/hw/i386/acpi-dsdt-mem-hotplug.dsl
new file mode 100644
index 000..2a36c47
--- /dev/null
+++ b/hw/i386/acpi-dsdt-mem-hotplug.dsl
@@ -0,0 +1,176 @@
+/*
+ * 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 .
+ */
+
+External(MEMORY_SLOT_NOTIFY_METHOD, MethodObj)
+
+Scope(\_SB.PCI0) {
+Device(MEMORY_HOTPLUG_DEVICE) {
+Name(_HID, "PNP0A06")
+Name(_UID, "Memory hotplug resources")
+External(MEMORY_SLOTS_NUMBER, IntObj)
+
+/* Memory hotplug IO registers */
+OperationRegion(MEMORY_HOTPLUG_IO_REGION, SystemIO,
+ACPI_MEMORY_HOTPLUG_BASE,
+ACPI_MEMORY_HOTPLUG_IO_LEN)
+
+Name(_CRS, ResourceTemplate() {
+IO(Decode16, ACPI_MEMORY_HOTPLUG_BASE, 
ACPI_MEMORY_HOTPLUG_BASE,
+   0, ACPI_MEMORY_HOTPLUG_IO_LEN, IO)
+})
+
+Method(_STA, 0) {
+If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
+Return(0x0)
+}
+/* present, functioning, decoding, not shown in UI */
+Return(0xB)
+}
+
+Field(MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
+MEMORY_SLOT_ADDR_LOW, 32,  // read only
+MEMORY_SLOT_ADDR_HIGH, 32, // read only
+MEMORY_SLOT_SIZE_LOW, 32,  // read only
+MEMORY_SLOT_SIZE_HIGH, 32, // read only
+MEMORY_SLOT_PROXIMITY, 32, // read only
+}
+Field(MEMORY_HOTPLUG_IO_REGION, ByteAcc, NoLock, Preserve) {
+Offset(20),
+MEMORY_SLOT_ENABLED,  1, // 1 if enabled, read only
+MEMORY_SLOT_INSERT_EVENT, 1, // (read) 1 if has a insert 
event. (write) 1 to clear event
+}
+
+Mutex (MEMORY_SLOT_LOCK, 0)
+Field (MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
+MEMORY_SLOT_SLECTOR, 32,  // DIMM selector, write only
+MEMORY_SLOT_OST_EVENT, 32,  // _OST event code, write only
+MEMORY_SLOT_OST_STATUS, 32,  // _OST status code, write only
+}
+
+Method(MEMORY_SLOT_SCAN_METHOD, 0) {
+If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
+ Return(Zero)
+}
+
+Store(Zero, Local0) // Mem devs iterrator
+Acquire(MEMORY_SLOT_LOCK, 0x)
+while (LLess(Local0, MEMORY_SLOTS_NUMBER)) {
+Store(Local0, MEMORY_SLOT_SLECTOR) // select Local0 DIMM
+If (LEqual(MEMORY_SLOT_INSERT_EVENT, One)) { // Memory 
device needs check
+MEMORY_SLOT_NOTIFY_METHOD(Local0, 1)
+Store(1, MEMORY_SLOT_INSERT_EVENT)
+}
+// TODO: handle memory eject request
+Add(Local0, One, Local0) // goto next DIMM
+}
+Release(MEMORY_SLOT_LOCK)
+Return(One)
+}
+
+Method(MEMORY_SLOT_STATUS_METHOD, 1) {
+Store(Zero, Local0)
+
+Acquire(MEMORY_SLOT_LOCK, 0x)
+Store(ToInteger(Arg0), MEMORY_SLOT_SLECT

[Qemu-devel] [PATCH] tests: fix rebuild-expected-aml.sh for acpi-test rename

2014-10-15 Thread Paolo Bonzini
This is now called bios-tables-test.

Signed-off-by: Paolo Bonzini 
---
 tests/acpi-test-data/rebuild-expected-aml.sh | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/acpi-test-data/rebuild-expected-aml.sh 
b/tests/acpi-test-data/rebuild-expected-aml.sh
index ab98498..11bf743 100755
--- a/tests/acpi-test-data/rebuild-expected-aml.sh
+++ b/tests/acpi-test-data/rebuild-expected-aml.sh
@@ -23,13 +23,13 @@ else
 exit 1;
 fi
 
-if [ ! -e "tests/acpi-test" ]; then
-echo "Test: acpi-test is required! Run make check before this script."
+if [ ! -e "tests/bios-tables-test" ]; then
+echo "Test: bios-tables-test is required! Run make check before this 
script."
 echo "Run this script from the build directory."
 exit 1;
 fi
 
-TEST_ACPI_REBUILD_AML=y QTEST_QEMU_BINARY=$qemu tests/acpi-test
+TEST_ACPI_REBUILD_AML=y QTEST_QEMU_BINARY=$qemu tests/bios-tables-test
 
 echo "The files were rebuilt and can be added to git."
 echo "However, if new files were created, please copy them manually" \
-- 
2.1.0




[Qemu-devel] [PATCH 3/7] runstate: create runstate_index function

2014-10-15 Thread Juan Quintela
Given a string state, we need a way to get the RunState for that string.

Signed-off-by: Juan Quintela 
---
 include/sysemu/sysemu.h |  1 +
 vl.c| 13 +
 2 files changed, 14 insertions(+)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index ae217da..2a6e669 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -29,6 +29,7 @@ void runstate_set(RunState new_state);
 int runstate_is_running(void);
 bool runstate_needs_reset(void);
 int runstate_store(char *str, int size);
+RunState runstate_index(char *str);
 typedef struct vm_change_state_entry VMChangeStateEntry;
 typedef void VMChangeStateHandler(void *opaque, int running, RunState state);

diff --git a/vl.c b/vl.c
index ce8e28b..c4bc43c 100644
--- a/vl.c
+++ b/vl.c
@@ -687,6 +687,19 @@ int runstate_store(char *str, int size)
 return 0;
 }

+RunState runstate_index(char *str)
+{
+RunState i = 0;
+
+while (i != RUN_STATE_MAX) {
+if (strcmp(str, RunState_lookup[i]) == 0) {
+return i;
+}
+i++;
+}
+return -1;
+}
+
 static void runstate_init(void)
 {
 const RunStateTransition *p;
-- 
2.1.0




[Qemu-devel] [RFC 0/7] Optional toplevel sections

2014-10-15 Thread Juan Quintela
Hi

by popular demand, and after too many time, this series.  This is an
RFC to know what people think about how to use them, the interface
proposed, whatever.

* simplify optional subsections moving the "needed" function to
  vmstate description.  I think that this simplification makes sense
  by itself, it is indipendent of the rest of the patches.

* runstate: To make an example of an optional section, I decided to
  use current runstate.  Right now, we have a problem when:
  - we start destination without -S
  - we run migration, and it causes an ioerror on source, but migration finishes
  - we try to run migration on destination anyways, when it is
possible that we could get disk corruption (the ioerror was there for a 
reason)
  Luiz: You can see any obvious improvement about how we use runstates?
  Laine: Could you told me if you (libvirt) like this or would want
 something a bit different?

* I sent that option indpendently for new machine types.

* For old machine types I use this as one example of optional section.
  We only sent it when the state is different from "running" or "paused".

  So, the only case where we fail is if we migrate to an old qemu and
  there is one error.

* On the runstate subsection "postload" we can send any event for
  anything that libvirt wants when migration finishes.
  Laine, can you told us what libvirt would preffer for this?

Kevin: You asked for optional sections in the past for the block
   layer, would this proposal be enough for you?

Please review, comment.

Thanks, Juan.

PD.  Yes, on proper submission, patches 6 and 7 are on the wrong order.

Juan Quintela (7):
  migration: Create optional sections
  runstate: Add runstate store
  runstate: create runstate_index function
  runstate: migration allows more transitions now
  migration: create now section to store global state
  global_state: Make section optional
  vmstate: Create optional sections

 cpus.c|  11 ++--
 docs/migration.txt|  11 ++--
 exec.c|  11 ++--
 hw/acpi/ich9.c|  10 ++--
 hw/acpi/piix4.c   |  10 ++--
 hw/block/fdc.c|  37 +
 hw/char/serial.c  |  41 ++-
 hw/display/qxl.c  |  11 ++--
 hw/display/vga.c  |  11 ++--
 hw/i386/pc_piix.c |   2 +
 hw/ide/core.c |  32 +---
 hw/ide/pci.c  |  16 +++---
 hw/input/pckbd.c  |  22 
 hw/input/ps2.c|  11 ++--
 hw/isa/lpc_ich9.c |  10 ++--
 hw/net/e1000.c|  11 ++--
 hw/net/rtl8139.c  |  11 ++--
 hw/net/vmxnet3.c  |  12 ++---
 hw/pci-host/piix.c|  10 ++--
 hw/scsi/scsi-bus.c|  11 ++--
 hw/timer/hpet.c   |  11 ++--
 hw/timer/mc146818rtc.c|  23 -
 hw/usb/hcd-ohci.c |  11 ++--
 hw/usb/redirect.c |  34 ++--
 hw/virtio/virtio.c|  10 ++--
 include/migration/migration.h |   4 ++
 include/migration/vmstate.h   |  10 ++--
 include/sysemu/sysemu.h   |   2 +
 migration.c   | 117 --
 savevm.c  |  14 +++--
 target-arm/machine.c  |  26 --
 target-i386/machine.c |  71 ++---
 target-ppc/machine.c  |  62 +-
 vl.c  |  26 ++
 vmstate.c |  27 +++---
 35 files changed, 393 insertions(+), 356 deletions(-)

-- 
2.1.0




[Qemu-devel] [PATCH 1/7] migration: Create optional sections

2014-10-15 Thread Juan Quintela
We create optional sections with this patch.  But we already have
optional subsections.  Instead of having two mechanism that do the
same, we can just generalize it.

For subsections we just change:

- Add a needed function to VMStateDescription
- Remove VMStateSubsection (after removal of the needed function
  it is just a VMStateDescription)
- Adjust the whole tree, moving the needed function to the corresponding
  VMStateDescription

Signed-off-by: Juan Quintela 
---
 cpus.c  | 11 +++
 docs/migration.txt  | 11 +++
 exec.c  | 11 +++
 hw/acpi/ich9.c  | 10 +++
 hw/acpi/piix4.c | 10 +++
 hw/block/fdc.c  | 37 +--
 hw/char/serial.c| 41 ++
 hw/display/qxl.c| 11 +++
 hw/display/vga.c| 11 +++
 hw/ide/core.c   | 32 
 hw/ide/pci.c| 16 --
 hw/input/pckbd.c| 22 +++---
 hw/input/ps2.c  | 11 +++
 hw/isa/lpc_ich9.c   | 10 +++
 hw/net/e1000.c  | 11 +++
 hw/net/rtl8139.c| 11 +++
 hw/net/vmxnet3.c| 12 +++-
 hw/pci-host/piix.c  | 10 +++
 hw/scsi/scsi-bus.c  | 11 +++
 hw/timer/hpet.c | 11 +++
 hw/timer/mc146818rtc.c  | 23 +++
 hw/usb/hcd-ohci.c   | 11 +++
 hw/usb/redirect.c   | 34 ++
 hw/virtio/virtio.c  | 10 +++
 include/migration/vmstate.h |  8 ++---
 savevm.c| 10 +++
 target-arm/machine.c| 26 +++--
 target-i386/machine.c   | 71 ++---
 target-ppc/machine.c| 62 +++
 vmstate.c   | 16 +-
 30 files changed, 228 insertions(+), 353 deletions(-)

diff --git a/cpus.c b/cpus.c
index 0c33458..f67c400 100644
--- a/cpus.c
+++ b/cpus.c
@@ -466,6 +466,7 @@ static const VMStateDescription icount_vmstate_timers = {
 .name = "timer/icount",
 .version_id = 1,
 .minimum_version_id = 1,
+.needed = icount_state_needed,
 .fields = (VMStateField[]) {
 VMSTATE_INT64(qemu_icount_bias, TimersState),
 VMSTATE_INT64(qemu_icount, TimersState),
@@ -483,13 +484,9 @@ static const VMStateDescription vmstate_timers = {
 VMSTATE_INT64_V(cpu_clock_offset, TimersState, 2),
 VMSTATE_END_OF_LIST()
 },
-.subsections = (VMStateSubsection[]) {
-{
-.vmsd = &icount_vmstate_timers,
-.needed = icount_state_needed,
-}, {
-/* empty */
-}
+.subsections = (const VMStateDescription *[]) {
+&icount_vmstate_timers,
+NULL
 }
 };

diff --git a/docs/migration.txt b/docs/migration.txt
index 0492a45..ebe656b 100644
--- a/docs/migration.txt
+++ b/docs/migration.txt
@@ -257,6 +257,7 @@ const VMStateDescription vmstate_ide_drive_pio_state = {
 .minimum_version_id = 1,
 .pre_save = ide_drive_pio_pre_save,
 .post_load = ide_drive_pio_post_load,
+.needed = ide_drive_pio_state_needed,
 .fields = (VMStateField[]) {
 VMSTATE_INT32(req_nb_sectors, IDEState),
 VMSTATE_VARRAY_INT32(io_buffer, IDEState, io_buffer_total_len, 1,
@@ -279,13 +280,9 @@ const VMStateDescription vmstate_ide_drive = {
  several fields 
 VMSTATE_END_OF_LIST()
 },
-.subsections = (VMStateSubsection []) {
-{
-.vmsd = &vmstate_ide_drive_pio_state,
-.needed = ide_drive_pio_state_needed,
-}, {
-/* empty */
-}
+.subsections = (const VMStateDescription *[]) {
+&vmstate_ide_drive_pio_state,
+NULL
 }
 };

diff --git a/exec.c b/exec.c
index 759055d..226ba95 100644
--- a/exec.c
+++ b/exec.c
@@ -450,6 +450,7 @@ static const VMStateDescription 
vmstate_cpu_common_exception_index = {
 .name = "cpu_common/exception_index",
 .version_id = 1,
 .minimum_version_id = 1,
+.needed = cpu_common_exception_index_needed,
 .fields = (VMStateField[]) {
 VMSTATE_INT32(exception_index, CPUState),
 VMSTATE_END_OF_LIST()
@@ -467,13 +468,9 @@ const VMStateDescription vmstate_cpu_common = {
 VMSTATE_UINT32(interrupt_request, CPUState),
 VMSTATE_END_OF_LIST()
 },
-.subsections = (VMStateSubsection[]) {
-{
-.vmsd = &vmstate_cpu_common_exception_index,
-.needed = cpu_common_exception_index_needed,
-} , {
-/* empty */
-}
+.subsections = (const VMStateDescription *[]) {
+&vmstate_cpu_common_exception_index,
+NULL
 }
 };

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 7b14bbb..a78fc5b 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -151,6 +151,7 @@ static const VMStateDescription vmstate_memhp_state = {
 .version_id

[Qemu-devel] [PATCH 5/7] migration: create now section to store global state

2014-10-15 Thread Juan Quintela
This includes a new section that for now just stores the current qemu state.

Right now, there are only one way to control what is the state of the
target after migration.

- If you run the target qemu with -S, it would start stopped.
- If you run the target qemu without -S, it would run just after migration 
finishes.

The problem here is what happens if we start the target without -S and
there happens one error during migration that puts current state as
-EIO.  Migration would ends (notice that the error happend doing block
IO, network IO, i.e. nothing related with migration), and when
migration finish, we would just "continue" running on destination,
probably hanging the guest/corruption data, whatever.

Signed-off-by: Juan Quintela 
---
 include/migration/migration.h |  4 ++
 migration.c   | 88 +--
 vl.c  |  1 +
 3 files changed, 90 insertions(+), 3 deletions(-)

diff --git a/include/migration/migration.h b/include/migration/migration.h
index 3cb5ba8..bc1069b 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -174,4 +174,8 @@ size_t ram_control_save_page(QEMUFile *f, ram_addr_t 
block_offset,
  ram_addr_t offset, size_t size,
  int *bytes_sent);

+void register_global_state(void);
+void global_state_store(void);
+char *global_state_get_runstate(void);
+
 #endif
diff --git a/migration.c b/migration.c
index 8d675b3..6f7e50e 100644
--- a/migration.c
+++ b/migration.c
@@ -112,10 +112,20 @@ static void process_incoming_migration_co(void *opaque)
 exit(EXIT_FAILURE);
 }

-if (autostart) {
+/* runstate == "" means that we haven't received it through the
+ * wire, so we obey autostart.  runstate == runing means that we
+ * need to run it, we need to make sure that we do it after
+ * everything else has finished.  Every other state change is done
+ * at the post_load function */
+
+if (strcmp(global_state_get_runstate(), "running") == 0 ) {
 vm_start();
-} else {
-runstate_set(RUN_STATE_PAUSED);
+} else if (strcmp(global_state_get_runstate(), "") == 0 ) {
+if (autostart) {
+vm_start();
+} else {
+runstate_set(RUN_STATE_PAUSED);
+}
 }
 }

@@ -608,6 +618,7 @@ static void *migration_thread(void *opaque)
 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
 old_vm_running = runstate_is_running();

+global_state_store();
 ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
 if (ret >= 0) {
 qemu_file_set_rate_limit(s->file, INT64_MAX);
@@ -699,3 +710,74 @@ void migrate_fd_connect(MigrationState *s)
 qemu_thread_create(&s->thread, "migration", migration_thread, s,
QEMU_THREAD_JOINABLE);
 }
+
+typedef struct {
+int32_t size;
+uint8_t runstate[100];
+} GlobalState;
+
+static GlobalState global_state;
+
+void global_state_store(void)
+{
+if (runstate_store((char*)global_state.runstate,
+   sizeof(global_state.runstate)) == -1) {
+printf("Runstate is too big\n");
+exit(-1);
+}
+}
+
+char *global_state_get_runstate(void)
+{
+return (char *)global_state.runstate;
+}
+
+static int global_state_post_load(void *opaque, int version_id)
+{
+GlobalState *s = opaque;
+int ret = 0;
+char *runstate = (char*)s->runstate;
+
+printf("loaded state: %s\n", runstate);
+
+if (strcmp(runstate, "running") != 0) {
+
+RunState r = runstate_index(runstate);
+
+if (r == -1) {
+printf("Unknown received state %s\n", runstate);
+return -1;
+}
+ret = vm_stop_force_state(r);
+}
+
+   return ret;
+}
+
+static void global_state_pre_save(void *opaque)
+{
+GlobalState *s = opaque;
+
+s->size = strlen((char*)s->runstate) + 1;
+printf("saved state: %s\n", s->runstate);
+}
+
+static const VMStateDescription vmstate_globalstate = {
+.name = "globalstate",
+.version_id = 1,
+.minimum_version_id = 1,
+.post_load = global_state_post_load,
+.pre_save = global_state_pre_save,
+.fields = (VMStateField[]) {
+VMSTATE_INT32(size, GlobalState),
+VMSTATE_BUFFER(runstate, GlobalState),
+VMSTATE_END_OF_LIST()
+},
+};
+
+void register_global_state(void)
+{
+/* We would use it independently that we receive it */
+strcpy((char*)&global_state.runstate, "");
+vmstate_register(NULL, 0, &vmstate_globalstate, &global_state);
+}
diff --git a/vl.c b/vl.c
index 1788b6a..75e855e 100644
--- a/vl.c
+++ b/vl.c
@@ -4511,6 +4511,7 @@ int main(int argc, char **argv, char **envp)
 return 0;
 }

+register_global_state();
 if (incoming) {
 Error *local_err = NULL;
 qemu_start_incoming_migration(incoming, &local_err);
-- 
2.1.0




[Qemu-devel] [PATCH 2/7] runstate: Add runstate store

2014-10-15 Thread Juan Quintela
This allows us to store the current state to send it through migration.

Signed-off-by: Juan Quintela 
---
 include/sysemu/sysemu.h |  1 +
 vl.c| 10 ++
 2 files changed, 11 insertions(+)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index d8539fd..ae217da 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -28,6 +28,7 @@ bool runstate_check(RunState state);
 void runstate_set(RunState new_state);
 int runstate_is_running(void);
 bool runstate_needs_reset(void);
+int runstate_store(char *str, int size);
 typedef struct vm_change_state_entry VMChangeStateEntry;
 typedef void VMChangeStateHandler(void *opaque, int running, RunState state);

diff --git a/vl.c b/vl.c
index 964d634..ce8e28b 100644
--- a/vl.c
+++ b/vl.c
@@ -677,6 +677,16 @@ bool runstate_check(RunState state)
 return current_run_state == state;
 }

+int runstate_store(char *str, int size)
+{
+const char *state = RunState_lookup[current_run_state];
+
+if (strlen(state)+1 > size)
+return -1;
+strncpy(str, state, strlen(state)+1);
+return 0;
+}
+
 static void runstate_init(void)
 {
 const RunStateTransition *p;
-- 
2.1.0




[Qemu-devel] [PATCH 4/7] runstate: migration allows more transitions now

2014-10-15 Thread Juan Quintela
Next commit would allow to move from incoming migration to error happening on 
source.

Should we add more states to this transition?  Luiz?

Signed-off-by: Juan Quintela 
---
 vl.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/vl.c b/vl.c
index c4bc43c..1788b6a 100644
--- a/vl.c
+++ b/vl.c
@@ -618,6 +618,8 @@ static const RunStateTransition runstate_transitions_def[] 
= {

 { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING },
 { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED },
+{ RUN_STATE_INMIGRATE, RUN_STATE_INTERNAL_ERROR },
+{ RUN_STATE_INMIGRATE, RUN_STATE_IO_ERROR },

 { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED },
 { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE },
-- 
2.1.0




[Qemu-devel] [PATCH 6/7] global_state: Make section optional

2014-10-15 Thread Juan Quintela
This section would be sent:

a- for all new machine types
b- for old achine types if section state is different form {running,paused}
   that were the only giving us troubles.

So, in new qemus: it is alwasy there.  In old qemus: they are only
there if it an error has happened, basically stoping on target.

Signed-off-by: Juan Quintela 
---
 hw/i386/pc_piix.c |  2 ++
 include/migration/migration.h |  2 +-
 migration.c   | 31 ++-
 3 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 4384633..078fbfb 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -52,6 +52,7 @@
 #ifdef CONFIG_XEN
 #  include 
 #endif
+#include "migration/migration.h"

 #define MAX_IDE_BUS 2

@@ -323,6 +324,7 @@ static void pc_compat_2_0(MachineState *machine)
 legacy_acpi_table_size = 6652;
 smbios_legacy_mode = true;
 has_reserved_memory = false;
+global_state_set_optional();
 pc_set_legacy_acpi_data_size();
 }

diff --git a/include/migration/migration.h b/include/migration/migration.h
index bc1069b..475ed48 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -177,5 +177,5 @@ size_t ram_control_save_page(QEMUFile *f, ram_addr_t 
block_offset,
 void register_global_state(void);
 void global_state_store(void);
 char *global_state_get_runstate(void);
-
+void global_state_set_optional(void);
 #endif
diff --git a/migration.c b/migration.c
index 6f7e50e..7379073 100644
--- a/migration.c
+++ b/migration.c
@@ -712,6 +712,7 @@ void migrate_fd_connect(MigrationState *s)
 }

 typedef struct {
+bool optional;
 int32_t size;
 uint8_t runstate[100];
 } GlobalState;
@@ -732,6 +733,33 @@ char *global_state_get_runstate(void)
 return (char *)global_state.runstate;
 }

+void global_state_set_optional(void)
+{
+global_state.optional = true;
+}
+
+static bool global_state_needed(void *opaque)
+{
+GlobalState *s = opaque;
+char *runstate = (char*)s->runstate;
+
+/* If it is not optional, it is mandatory */
+
+if (s->optional == false) {
+return true;
+}
+
+/* If state is running or paused, it is not needed */
+
+if (strcmp(runstate, "running") == 0 ||
+strcmp(runstate, "paused") == 0) {
+return false;
+}
+
+/* for any other state it is needed */
+return true;
+}
+
 static int global_state_post_load(void *opaque, int version_id)
 {
 GlobalState *s = opaque;
@@ -759,7 +787,7 @@ static void global_state_pre_save(void *opaque)
 GlobalState *s = opaque;

 s->size = strlen((char*)s->runstate) + 1;
-printf("saved state: %s\n", s->runstate);
+printf("saved state: %s optional (%d)\n", s->runstate, s->optional);
 }

 static const VMStateDescription vmstate_globalstate = {
@@ -768,6 +796,7 @@ static const VMStateDescription vmstate_globalstate = {
 .minimum_version_id = 1,
 .post_load = global_state_post_load,
 .pre_save = global_state_pre_save,
+.needed = global_state_needed,
 .fields = (VMStateField[]) {
 VMSTATE_INT32(size, GlobalState),
 VMSTATE_BUFFER(runstate, GlobalState),
-- 
2.1.0




[Qemu-devel] [PATCH 7/7] vmstate: Create optional sections

2014-10-15 Thread Juan Quintela
To make sections optional, we need to do it at the beggining of the code.

Signed-off-by: Juan Quintela 
---
 include/migration/vmstate.h |  2 ++
 savevm.c|  4 
 vmstate.c   | 11 +++
 3 files changed, 17 insertions(+)

diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 3556924..a5155be 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -766,6 +766,8 @@ int vmstate_load_state(QEMUFile *f, const 
VMStateDescription *vmsd,
 void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
 void *opaque);

+bool vmstate_save_needed(const VMStateDescription *vmsd, void *opaque);
+
 int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
const VMStateDescription *vmsd,
void *base, int alias_id,
diff --git a/savevm.c b/savevm.c
index eed43e6..3884e0b 100644
--- a/savevm.c
+++ b/savevm.c
@@ -727,6 +727,10 @@ void qemu_savevm_state_complete(QEMUFile *f)
 if ((!se->ops || !se->ops->save_state) && !se->vmsd) {
 continue;
 }
+if (se->vmsd && !vmstate_save_needed(se->vmsd, se->opaque)) {
+continue;
+}
+
 trace_savevm_section_start(se->idstr, se->section_id);
 /* Section type */
 qemu_put_byte(f, QEMU_VM_SECTION_FULL);
diff --git a/vmstate.c b/vmstate.c
index bb02b7d..b8914ac 100644
--- a/vmstate.c
+++ b/vmstate.c
@@ -131,6 +131,17 @@ int vmstate_load_state(QEMUFile *f, const 
VMStateDescription *vmsd,
 return 0;
 }

+
+bool vmstate_save_needed(const VMStateDescription *vmsd, void *opaque)
+{
+if (vmsd->needed && !vmsd->needed(opaque)) {
+/* optional section not needed */
+return false;
+}
+return true;
+}
+
+
 void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
 void *opaque)
 {
-- 
2.1.0




[Qemu-devel] [Bug 921208] Re: win7/x64 installer hangs on startup with 0x0000005d.

2014-10-15 Thread Eduardo Habkost
Alessandro: see comment #14. If somebody can confirm that Windows 7
works with TCG when using "-cpu kvm64,+nx", I believe we can fix this in
qemu64 soon, when we finally make TCG-qemu64 different from KVM-qemu64.
If it still doesn't work, that means we still have the same status from
comment #11 (TCG not supporting all the features required by Windows 7).

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/921208

Title:
  win7/x64 installer hangs on startup with 0x005d.

Status in QEMU:
  Confirmed
Status in “qemu” package in Ubuntu:
  Triaged

Bug description:
  hi,

  during booting win7/x64 installer i'm observing a bsod with 0x005d
  ( msdn: unsupported_processor ).

  used command line: qemu-system-x86_64 -m 2048 -hda w7-system.img
  -cdrom win7_x64.iso -boot d

  adding '-machine accel=kvm' instead of default tcg accel helps to
  boot.

  
  installed software:

  qemu-1.0
  linux-3.2.1
  glibc-2.14.1
  gcc-4.6.2

  hw cpu:

  processor   : 0..7
  vendor_id   : GenuineIntel
  cpu family  : 6
  model   : 42
  model name  : Intel(R) Core(TM) i7-2630QM CPU @ 2.00GHz
  stepping: 7
  microcode   : 0x14
  cpu MHz : 1995.739
  cache size  : 6144 KB
  physical id : 0
  siblings: 8
  core id : 3
  cpu cores   : 4
  apicid  : 7
  initial apicid  : 7
  fpu : yes
  fpu_exception   : yes
  cpuid level : 13
  wp  : yes
  flags   : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca 
cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx 
rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology 
nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 
cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer xsave avx 
lahf_lm ida arat epb xsaveopt pln pts dts tpr_shadow vnmi flexpriority ept vpid
  bogomips: 3992.23
  clflush size: 64
  cache_alignment : 64
  address sizes   : 36 bits physical, 48 bits virtual

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/921208/+subscriptions



[Qemu-devel] [PULL 00/10] Migration pull request

2014-10-15 Thread Juan Quintela
From: Juan Quintela 

Hi

This patches have been on the list for a while:

- ram flags from Peter Lieven
- qemu-file cleanups from Eduardo (just code movement)
- QEMUSizedBuffer from David (they have already have 6 versions)
- VBUFFER (new macro, can't break old things) (Alexey)
- invalidate state (Alexey)

Please, apply.

The following changes since commit b1d28ec6a7dbdaadda39d29322f0de694aeb0b74:

  Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20141010' into 
staging (2014-10-10 14:55:29 +0100)

are available in the git repository at:

  git://github.com/juanquintela/qemu.git migration/20141015

for you to fetch changes up to 5b0e9dd46fbda5152566a4a26fd96bc0d0452bf7:

  migration: catch unknown flag combinations in ram_load (2014-10-14 11:24:20 
+0200)


migration/next for 20141015


Alexey Kardashevskiy (2):
  block/migration: Disable cache invalidate for incoming migration
  vmstate: Allow dynamic allocation for VBUFFER during migration

Dr. David Alan Gilbert (2):
  QEMUSizedBuffer based QEMUFile
  Tests: QEMUSizedBuffer/QEMUBuffer

Eduardo Habkost (5):
  qemu-file: Add copyright header to qemu-file.c
  qemu-file: Make qemu_file_is_writable() non-static
  qemu-file: Use qemu_file_is_writable() on stdio_fclose()
  qemu-file: Move unix and socket implementations to qemu-file-unix.c
  qemu-file: Move stdio implementation to qemu-file-stdio.c

Peter Lieven (1):
  migration: catch unknown flag combinations in ram_load

 Makefile.objs |   2 +-
 arch_init.c   |  62 ++--
 block.c   |  18 +-
 include/migration/qemu-file.h |  27 ++
 include/migration/vmstate.h   |  11 +
 include/qemu/typedefs.h   |   1 +
 migration.c   |   1 -
 nbd.c |   6 +
 qemu-file-stdio.c | 194 ++
 qemu-file-unix.c  | 223 +++
 qemu-file.c   | 843 --
 tests/Makefile|   4 +-
 tests/test-vmstate.c  |  74 ++--
 vmstate.c |  13 +-
 14 files changed, 1029 insertions(+), 450 deletions(-)
 create mode 100644 qemu-file-stdio.c
 create mode 100644 qemu-file-unix.c



[Qemu-devel] [PULL 02/10] Tests: QEMUSizedBuffer/QEMUBuffer

2014-10-15 Thread Juan Quintela
From: "Dr. David Alan Gilbert" 

Modify some of tests/test-vmstate.c to use the in memory file based
on QEMUSizedBuffer to provide basic testing of QEMUSizedBuffer and
the associated memory backed QEMUFile type.

Only some of the tests are changed so that the fd backed QEMUFile is
still tested.

Signed-off-by: Dr. David Alan Gilbert 
Reviewed-by: Eric Blake 
Signed-off-by: Juan Quintela 
---
 tests/Makefile   |  2 +-
 tests/test-vmstate.c | 74 +++-
 2 files changed, 39 insertions(+), 37 deletions(-)

diff --git a/tests/Makefile b/tests/Makefile
index ffa8312..31e867f 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -259,7 +259,7 @@ tests/test-qdev-global-props$(EXESUF): 
tests/test-qdev-global-props.o \
libqemuutil.a libqemustub.a
 tests/test-vmstate$(EXESUF): tests/test-vmstate.o \
vmstate.o qemu-file.o \
-   libqemuutil.a
+   libqemuutil.a libqemustub.a

 tests/test-qapi-types.c tests/test-qapi-types.h :\
 $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json 
$(SRC_PATH)/scripts/qapi-types.py
diff --git a/tests/test-vmstate.c b/tests/test-vmstate.c
index d72c64c..5e0fd13 100644
--- a/tests/test-vmstate.c
+++ b/tests/test-vmstate.c
@@ -43,6 +43,12 @@ void yield_until_fd_readable(int fd)
 select(fd + 1, &fds, NULL, NULL, NULL);
 }

+/*
+ * Some tests use 'open_test_file' to work on a real fd, some use
+ * an in memory file (QEMUSizedBuffer+qemu_bufopen); we could pick one
+ * but this way we test both.
+ */
+
 /* Duplicate temp_fd and seek to the beginning of the file */
 static QEMUFile *open_test_file(bool write)
 {
@@ -54,6 +60,30 @@ static QEMUFile *open_test_file(bool write)
 return qemu_fdopen(fd, write ? "wb" : "rb");
 }

+/* Open a read-only qemu-file from an existing memory block */
+static QEMUFile *open_mem_file_read(const void *data, size_t len)
+{
+/* The qsb gets freed by qemu_fclose */
+QEMUSizedBuffer *qsb = qsb_create(data, len);
+g_assert(qsb);
+
+return qemu_bufopen("r", qsb);
+}
+
+/*
+ * Check that the contents of the memory-buffered file f match
+ * the given size/data.
+ */
+static void check_mem_file(QEMUFile *f, void *data, size_t size)
+{
+uint8_t *result = g_malloc(size);
+const QEMUSizedBuffer *qsb = qemu_buf_get(f);
+g_assert_cmpint(qsb_get_length(qsb), ==, size);
+g_assert_cmpint(qsb_get_buffer(qsb, 0, size, result), ==, size);
+g_assert_cmpint(memcmp(result, data, size), ==, 0);
+g_free(result);
+}
+
 #define SUCCESS(val) \
 g_assert_cmpint((val), ==, 0)

@@ -371,14 +401,12 @@ static const VMStateDescription vmstate_skipping = {

 static void test_save_noskip(void)
 {
-QEMUFile *fsave = open_test_file(true);
+QEMUFile *fsave = qemu_bufopen("w", NULL);
 TestStruct obj = { .a = 1, .b = 2, .c = 3, .d = 4, .e = 5, .f = 6,
.skip_c_e = false };
 vmstate_save_state(fsave, &vmstate_skipping, &obj);
 g_assert(!qemu_file_get_error(fsave));
-qemu_fclose(fsave);

-QEMUFile *loading = open_test_file(false);
 uint8_t expected[] = {
 0, 0, 0, 1, /* a */
 0, 0, 0, 2, /* b */
@@ -387,52 +415,31 @@ static void test_save_noskip(void)
 0, 0, 0, 5, /* e */
 0, 0, 0, 0, 0, 0, 0, 6, /* f */
 };
-uint8_t result[sizeof(expected)];
-g_assert_cmpint(qemu_get_buffer(loading, result, sizeof(result)), ==,
-sizeof(result));
-g_assert(!qemu_file_get_error(loading));
-g_assert_cmpint(memcmp(result, expected, sizeof(result)), ==, 0);
-
-/* Must reach EOF */
-qemu_get_byte(loading);
-g_assert_cmpint(qemu_file_get_error(loading), ==, -EIO);
-
-qemu_fclose(loading);
+check_mem_file(fsave, expected, sizeof(expected));
+qemu_fclose(fsave);
 }

 static void test_save_skip(void)
 {
-QEMUFile *fsave = open_test_file(true);
+QEMUFile *fsave = qemu_bufopen("w", NULL);
 TestStruct obj = { .a = 1, .b = 2, .c = 3, .d = 4, .e = 5, .f = 6,
.skip_c_e = true };
 vmstate_save_state(fsave, &vmstate_skipping, &obj);
 g_assert(!qemu_file_get_error(fsave));
-qemu_fclose(fsave);

-QEMUFile *loading = open_test_file(false);
 uint8_t expected[] = {
 0, 0, 0, 1, /* a */
 0, 0, 0, 2, /* b */
 0, 0, 0, 0, 0, 0, 0, 4, /* d */
 0, 0, 0, 0, 0, 0, 0, 6, /* f */
 };
-uint8_t result[sizeof(expected)];
-g_assert_cmpint(qemu_get_buffer(loading, result, sizeof(result)), ==,
-sizeof(result));
-g_assert(!qemu_file_get_error(loading));
-g_assert_cmpint(memcmp(result, expected, sizeof(result)), ==, 0);
-
-
-/* Must reach EOF */
-qemu_get_byte(loading);
-g_assert_cmpint(qemu_file_get_error(loading), ==, -EIO);
+check_mem_file(fsave, expected, sizeof(expected));

-qemu_fclose(loading);
+qemu_fclose(fsave);
 }

 static void test_load_noskip(void)
 {
-QEMUFile *fsa

[Qemu-devel] [PULL 07/10] qemu-file: Use qemu_file_is_writable() on stdio_fclose()

2014-10-15 Thread Juan Quintela
From: Eduardo Habkost 

Use the existing function which checks if writev_buffer() or
put_buffer() are set, instead of duplicating it.

Signed-off-by: Eduardo Habkost 
Reviewed-by: Markus Armbruster 
Signed-off-by: Juan Quintela 
---
 qemu-file.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qemu-file.c b/qemu-file.c
index c303b61..9cb1223 100644
--- a/qemu-file.c
+++ b/qemu-file.c
@@ -175,7 +175,7 @@ static int stdio_fclose(void *opaque)
 QEMUFileStdio *s = opaque;
 int ret = 0;

-if (s->file->ops->put_buffer || s->file->ops->writev_buffer) {
+if (qemu_file_is_writable(s->file)) {
 int fd = fileno(s->stdio_file);
 struct stat st;

-- 
2.1.0




[Qemu-devel] [PULL 04/10] vmstate: Allow dynamic allocation for VBUFFER during migration

2014-10-15 Thread Juan Quintela
From: Alexey Kardashevskiy 

This extends use of VMS_ALLOC flag from arrays to VBUFFER as well.

This defines VMSTATE_VBUFFER_ALLOC_UINT32 which makes use of VMS_ALLOC
and uses uint32_t type for a size.

Signed-off-by: Alexey Kardashevskiy 
Signed-off-by: Juan Quintela 
---
 include/migration/vmstate.h | 11 +++
 vmstate.c   | 13 ++---
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 9a001bd..e45fc49 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -484,6 +484,17 @@ extern const VMStateInfo vmstate_info_bitmap;
 .start= (_start),\
 }

+#define VMSTATE_VBUFFER_ALLOC_UINT32(_field, _state, _version, _test, _start, 
_field_size) { \
+.name = (stringify(_field)), \
+.version_id   = (_version),  \
+.field_exists = (_test), \
+.size_offset  = vmstate_offset_value(_state, _field_size, uint32_t),\
+.info = &vmstate_info_buffer,\
+.flags= VMS_VBUFFER|VMS_POINTER|VMS_ALLOC,   \
+.offset   = offsetof(_state, _field),\
+.start= (_start),\
+}
+
 #define VMSTATE_BUFFER_UNSAFE_INFO(_field, _state, _version, _info, _size) { \
 .name   = (stringify(_field)),   \
 .version_id = (_version),\
diff --git a/vmstate.c b/vmstate.c
index ef2f87b..3dde574 100644
--- a/vmstate.c
+++ b/vmstate.c
@@ -49,9 +49,16 @@ static void *vmstate_base_addr(void *opaque, VMStateField 
*field, bool alloc)

 if (field->flags & VMS_POINTER) {
 if (alloc && (field->flags & VMS_ALLOC)) {
-int n_elems = vmstate_n_elems(opaque, field);
-if (n_elems) {
-gsize size = n_elems * field->size;
+gsize size = 0;
+if (field->flags & VMS_VBUFFER) {
+size = vmstate_size(opaque, field);
+} else {
+int n_elems = vmstate_n_elems(opaque, field);
+if (n_elems) {
+size = n_elems * field->size;
+}
+}
+if (size) {
 *((void **)base_addr + field->start) = g_malloc(size);
 }
 }
-- 
2.1.0




[Qemu-devel] [PULL 01/10] QEMUSizedBuffer based QEMUFile

2014-10-15 Thread Juan Quintela
From: "Dr. David Alan Gilbert" 

This is based on Stefan and Joel's patch that creates a QEMUFile that goes
to a memory buffer; from:

http://lists.gnu.org/archive/html/qemu-devel/2013-03/msg05036.html

Using the QEMUFile interface, this patch adds support functions for
operating on in-memory sized buffers that can be written to or read from.

Signed-off-by: Stefan Berger 
Signed-off-by: Joel Schopp 

For fixes/tweeks I've done:
Signed-off-by: Dr. David Alan Gilbert 

Reviewed-by: Eric Blake 
Signed-off-by: Juan Quintela 
---
 include/migration/qemu-file.h |  26 +++
 include/qemu/typedefs.h   |   1 +
 qemu-file.c   | 455 ++
 3 files changed, 482 insertions(+)

diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h
index c90f529..70ff347 100644
--- a/include/migration/qemu-file.h
+++ b/include/migration/qemu-file.h
@@ -25,6 +25,8 @@
 #define QEMU_FILE_H 1
 #include "exec/cpu-common.h"

+#include 
+
 /* This function writes a chunk of data to a file at the given position.
  * The pos argument can be ignored if the file is only being used for
  * streaming.  The handler should try to write all of the data it can.
@@ -94,11 +96,19 @@ typedef struct QEMUFileOps {
 QEMURamSaveFunc *save_page;
 } QEMUFileOps;

+struct QEMUSizedBuffer {
+struct iovec *iov;
+size_t n_iov;
+size_t size; /* total allocated size in all iov's */
+size_t used; /* number of used bytes */
+};
+
 QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops);
 QEMUFile *qemu_fopen(const char *filename, const char *mode);
 QEMUFile *qemu_fdopen(int fd, const char *mode);
 QEMUFile *qemu_fopen_socket(int fd, const char *mode);
 QEMUFile *qemu_popen_cmd(const char *command, const char *mode);
+QEMUFile *qemu_bufopen(const char *mode, QEMUSizedBuffer *input);
 int qemu_get_fd(QEMUFile *f);
 int qemu_fclose(QEMUFile *f);
 int64_t qemu_ftell(QEMUFile *f);
@@ -111,6 +121,22 @@ void qemu_put_byte(QEMUFile *f, int v);
 void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, int size);
 bool qemu_file_mode_is_not_valid(const char *mode);

+QEMUSizedBuffer *qsb_create(const uint8_t *buffer, size_t len);
+QEMUSizedBuffer *qsb_clone(const QEMUSizedBuffer *);
+void qsb_free(QEMUSizedBuffer *);
+size_t qsb_set_length(QEMUSizedBuffer *qsb, size_t length);
+size_t qsb_get_length(const QEMUSizedBuffer *qsb);
+ssize_t qsb_get_buffer(const QEMUSizedBuffer *, off_t start, size_t count,
+   uint8_t *buf);
+ssize_t qsb_write_at(QEMUSizedBuffer *qsb, const uint8_t *buf,
+ off_t pos, size_t count);
+
+
+/*
+ * For use on files opened with qemu_bufopen
+ */
+const QEMUSizedBuffer *qemu_buf_get(QEMUFile *f);
+
 static inline void qemu_put_ubyte(QEMUFile *f, unsigned int v)
 {
 qemu_put_byte(f, (int)v);
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 04df51b..168a408 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -71,6 +71,7 @@ typedef struct SSIBus SSIBus;
 typedef struct EventNotifier EventNotifier;
 typedef struct VirtIODevice VirtIODevice;
 typedef struct QEMUSGList QEMUSGList;
+typedef struct QEMUSizedBuffer QEMUSizedBuffer;
 typedef struct SHPCDevice SHPCDevice;
 typedef struct FWCfgState FWCfgState;
 typedef struct PcGuestInfo PcGuestInfo;
diff --git a/qemu-file.c b/qemu-file.c
index a8e3912..cdda745 100644
--- a/qemu-file.c
+++ b/qemu-file.c
@@ -878,3 +878,458 @@ uint64_t qemu_get_be64(QEMUFile *f)
 v |= qemu_get_be32(f);
 return v;
 }
+
+#define QSB_CHUNK_SIZE  (1 << 10)
+#define QSB_MAX_CHUNK_SIZE  (16 * QSB_CHUNK_SIZE)
+
+/**
+ * Create a QEMUSizedBuffer
+ * This type of buffer uses scatter-gather lists internally and
+ * can grow to any size. Any data array in the scatter-gather list
+ * can hold different amount of bytes.
+ *
+ * @buffer: Optional buffer to copy into the QSB
+ * @len: size of initial buffer; if @buffer is given, buffer must
+ *   hold at least len bytes
+ *
+ * Returns a pointer to a QEMUSizedBuffer or NULL on allocation failure
+ */
+QEMUSizedBuffer *qsb_create(const uint8_t *buffer, size_t len)
+{
+QEMUSizedBuffer *qsb;
+size_t alloc_len, num_chunks, i, to_copy;
+size_t chunk_size = (len > QSB_MAX_CHUNK_SIZE)
+? QSB_MAX_CHUNK_SIZE
+: QSB_CHUNK_SIZE;
+
+num_chunks = DIV_ROUND_UP(len ? len : QSB_CHUNK_SIZE, chunk_size);
+alloc_len = num_chunks * chunk_size;
+
+qsb = g_try_new0(QEMUSizedBuffer, 1);
+if (!qsb) {
+return NULL;
+}
+
+qsb->iov = g_try_new0(struct iovec, num_chunks);
+if (!qsb->iov) {
+g_free(qsb);
+return NULL;
+}
+
+qsb->n_iov = num_chunks;
+
+for (i = 0; i < num_chunks; i++) {
+qsb->iov[i].iov_base = g_try_malloc0(chunk_size);
+if (!qsb->iov[i].iov_base) {
+/* qsb_free is safe since g_free can cope with NULL */
+qsb_free(qsb);
+return NULL;
+ 

[Qemu-devel] [PULL 05/10] qemu-file: Add copyright header to qemu-file.c

2014-10-15 Thread Juan Quintela
From: Eduardo Habkost 

The person who created qemu-file.c (me, on commit
093c455a8c6d8f715eabd8c8d346f08f17d686ec) didn't add a copyright/license
header to the file, even though the whole code was copied from savevm.c
(which had a copyright/license header).

To correct this, copy the copyright information and license from
savevm.c, that's where the original code came from.

Luckily, very few changes were made on qemu-file.c after it was created.
All the authors who touched the code are being CCed, so they can confirm
if they are OK with the copyright/license information being added.

Cc: Dr. David Alan Gilbert 
Cc: Alexey Kardashevskiy 
Cc: Markus Armbruster 
Cc: Juan Quintela 
Signed-off-by: Eduardo Habkost 
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Markus Armbruster 
Acked-by: Alexey Kardashevskiy 
Reviewed-by: Juan Quintela 
Signed-off-by: Juan Quintela 
---
 qemu-file.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/qemu-file.c b/qemu-file.c
index cdda745..a5bbe7e 100644
--- a/qemu-file.c
+++ b/qemu-file.c
@@ -1,3 +1,26 @@
+/*
+ * QEMU System Emulator
+ *
+ * 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 "qemu-common.h"
 #include "qemu/iov.h"
 #include "qemu/sockets.h"
-- 
2.1.0




[Qemu-devel] [PULL 06/10] qemu-file: Make qemu_file_is_writable() non-static

2014-10-15 Thread Juan Quintela
From: Eduardo Habkost 

The QEMUFileStdio code will use qemu_file_is_writable() and will be
moved to a separate file.

Signed-off-by: Eduardo Habkost 
Reviewed-by: Markus Armbruster 
Signed-off-by: Juan Quintela 
---
 include/migration/qemu-file.h | 1 +
 qemu-file.c   | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h
index 70ff347..401676b 100644
--- a/include/migration/qemu-file.h
+++ b/include/migration/qemu-file.h
@@ -120,6 +120,7 @@ void qemu_put_byte(QEMUFile *f, int v);
  */
 void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, int size);
 bool qemu_file_mode_is_not_valid(const char *mode);
+bool qemu_file_is_writable(QEMUFile *f);

 QEMUSizedBuffer *qsb_create(const uint8_t *buffer, size_t len);
 QEMUSizedBuffer *qsb_clone(const QEMUSizedBuffer *);
diff --git a/qemu-file.c b/qemu-file.c
index a5bbe7e..c303b61 100644
--- a/qemu-file.c
+++ b/qemu-file.c
@@ -456,7 +456,7 @@ void qemu_file_set_error(QEMUFile *f, int ret)
 }
 }

-static inline bool qemu_file_is_writable(QEMUFile *f)
+bool qemu_file_is_writable(QEMUFile *f)
 {
 return f->ops->writev_buffer || f->ops->put_buffer;
 }
-- 
2.1.0




[Qemu-devel] [PULL 09/10] qemu-file: Move stdio implementation to qemu-file-stdio.c

2014-10-15 Thread Juan Quintela
From: Eduardo Habkost 

Separate the QEMUFile interface from the stdio-specific implementation,
to reduce dependencies from code using QEMUFile.

The code that is being moved is similar to the one that was on savevm.c before
it was moved in commit 093c455a8c6d8f715eabd8c8d346f08f17d686ec, except for
some changes done by Markus, Juan, and myself. So, I am using the copyright and
license header from savevm.c, but CCing Juan and Markus so they can review the
copyright/license header.

Cc: Markus Armbruster 
Cc: Juan Quintela 
Signed-off-by: Eduardo Habkost 
Reviewed-by: Markus Armbruster 
Signed-off-by: Juan Quintela 
---
 Makefile.objs |   2 +-
 qemu-file-stdio.c | 194 ++
 qemu-file.c   | 168 --
 3 files changed, 195 insertions(+), 169 deletions(-)
 create mode 100644 qemu-file-stdio.c

diff --git a/Makefile.objs b/Makefile.objs
index 957e56c..18fd35c 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -50,7 +50,7 @@ common-obj-$(CONFIG_LINUX) += fsdev/

 common-obj-y += migration.o migration-tcp.o
 common-obj-y += vmstate.o
-common-obj-y += qemu-file.o qemu-file-unix.o
+common-obj-y += qemu-file.o qemu-file-unix.o qemu-file-stdio.o
 common-obj-$(CONFIG_RDMA) += migration-rdma.o
 common-obj-y += qemu-char.o #aio.o
 common-obj-y += block-migration.o
diff --git a/qemu-file-stdio.c b/qemu-file-stdio.c
new file mode 100644
index 000..285068b
--- /dev/null
+++ b/qemu-file-stdio.c
@@ -0,0 +1,194 @@
+/*
+ * QEMU System Emulator
+ *
+ * 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 "qemu-common.h"
+#include "block/coroutine.h"
+#include "migration/qemu-file.h"
+
+typedef struct QEMUFileStdio {
+FILE *stdio_file;
+QEMUFile *file;
+} QEMUFileStdio;
+
+static int stdio_get_fd(void *opaque)
+{
+QEMUFileStdio *s = opaque;
+
+return fileno(s->stdio_file);
+}
+
+static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos,
+int size)
+{
+QEMUFileStdio *s = opaque;
+int res;
+
+res = fwrite(buf, 1, size, s->stdio_file);
+
+if (res != size) {
+return -errno;
+}
+return res;
+}
+
+static int stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
+{
+QEMUFileStdio *s = opaque;
+FILE *fp = s->stdio_file;
+int bytes;
+
+for (;;) {
+clearerr(fp);
+bytes = fread(buf, 1, size, fp);
+if (bytes != 0 || !ferror(fp)) {
+break;
+}
+if (errno == EAGAIN) {
+yield_until_fd_readable(fileno(fp));
+} else if (errno != EINTR) {
+break;
+}
+}
+return bytes;
+}
+
+static int stdio_pclose(void *opaque)
+{
+QEMUFileStdio *s = opaque;
+int ret;
+ret = pclose(s->stdio_file);
+if (ret == -1) {
+ret = -errno;
+} else if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) {
+/* close succeeded, but non-zero exit code: */
+ret = -EIO; /* fake errno value */
+}
+g_free(s);
+return ret;
+}
+
+static int stdio_fclose(void *opaque)
+{
+QEMUFileStdio *s = opaque;
+int ret = 0;
+
+if (qemu_file_is_writable(s->file)) {
+int fd = fileno(s->stdio_file);
+struct stat st;
+
+ret = fstat(fd, &st);
+if (ret == 0 && S_ISREG(st.st_mode)) {
+/*
+ * If the file handle is a regular file make sure the
+ * data is flushed to disk before signaling success.
+ */
+ret = fsync(fd);
+if (ret != 0) {
+ret = -errno;
+return ret;
+}
+}
+}
+if (fclose(s->stdio_file) == EOF) {
+ret = -errno;
+}
+g_free(s);
+return ret;
+}
+
+static const QEMUFileOps stdio_pipe_read_ops = {
+.get_fd = stdio_get_fd,
+.get_buffer = stdio_get_buffer,
+ 

[Qemu-devel] [PULL 03/10] block/migration: Disable cache invalidate for incoming migration

2014-10-15 Thread Juan Quintela
From: Alexey Kardashevskiy 

When migrated using libvirt with "--copy-storage-all", at the end of
migration there is race between NBD mirroring task trying to do flush
and migration completion, both end up invalidating cache. Since qcow2
driver does not handle this situation very well, random crashes happen.

This disables the BDRV_O_INCOMING flag for the block device being migrated
once the cache has been invalidated.

Signed-off-by: Alexey Kardashevskiy 
Reviewed-by: Paolo Bonzini 

--

fixed parens by hand
Signed-off-by: Juan Quintela 
---
 block.c | 18 +-
 migration.c |  1 -
 nbd.c   |  6 ++
 3 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/block.c b/block.c
index d3aebeb..27533f3 100644
--- a/block.c
+++ b/block.c
@@ -5043,6 +5043,11 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Error 
**errp)
 return;
 }

+if (!(bs->open_flags & BDRV_O_INCOMING)) {
+return;
+}
+bs->open_flags &= ~BDRV_O_INCOMING;
+
 if (bs->drv->bdrv_invalidate_cache) {
 bs->drv->bdrv_invalidate_cache(bs, &local_err);
 } else if (bs->file) {
@@ -5078,19 +5083,6 @@ void bdrv_invalidate_cache_all(Error **errp)
 }
 }

-void bdrv_clear_incoming_migration_all(void)
-{
-BlockDriverState *bs;
-
-QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
-AioContext *aio_context = bdrv_get_aio_context(bs);
-
-aio_context_acquire(aio_context);
-bs->open_flags = bs->open_flags & ~(BDRV_O_INCOMING);
-aio_context_release(aio_context);
-}
-}
-
 int bdrv_flush(BlockDriverState *bs)
 {
 Coroutine *co;
diff --git a/migration.c b/migration.c
index 8d675b3..c49a05a 100644
--- a/migration.c
+++ b/migration.c
@@ -103,7 +103,6 @@ static void process_incoming_migration_co(void *opaque)
 }
 qemu_announce_self();

-bdrv_clear_incoming_migration_all();
 /* Make sure all file formats flush their mutable metadata */
 bdrv_invalidate_cache_all(&local_err);
 if (local_err) {
diff --git a/nbd.c b/nbd.c
index e9b539b..a7bce45 100644
--- a/nbd.c
+++ b/nbd.c
@@ -972,6 +972,12 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t 
dev_offset,
 exp->ctx = bdrv_get_aio_context(bs);
 bdrv_ref(bs);
 bdrv_add_aio_context_notifier(bs, bs_aio_attached, bs_aio_detach, exp);
+/*
+ * NBD exports are used for non-shared storage migration.  Make sure
+ * that BDRV_O_INCOMING is cleared and the image is ready for write
+ * access since the export could be available before migration handover.
+ */
+bdrv_invalidate_cache(bs, NULL);
 return exp;
 }

-- 
2.1.0




[Qemu-devel] [PULL 08/10] qemu-file: Move unix and socket implementations to qemu-file-unix.c

2014-10-15 Thread Juan Quintela
From: Eduardo Habkost 

Separate the QEMUFile interface from the implementation, to reduce
dependencies from code using QEMUFile.

All the code that is being moved to the new file is exactly the same
code that was on savevm.c (moved by commit
093c455a8c6d8f715eabd8c8d346f08f17d686ec), so I am using the copyright
and license header from savevm.c for the new file.

Signed-off-by: Eduardo Habkost 
Reviewed-by: Markus Armbruster 
Signed-off-by: Juan Quintela 
---
 Makefile.objs|   2 +-
 qemu-file-unix.c | 223 +++
 qemu-file.c  | 195 
 tests/Makefile   |   2 +-
 4 files changed, 225 insertions(+), 197 deletions(-)
 create mode 100644 qemu-file-unix.c

diff --git a/Makefile.objs b/Makefile.objs
index add8375..957e56c 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -50,7 +50,7 @@ common-obj-$(CONFIG_LINUX) += fsdev/

 common-obj-y += migration.o migration-tcp.o
 common-obj-y += vmstate.o
-common-obj-y += qemu-file.o
+common-obj-y += qemu-file.o qemu-file-unix.o
 common-obj-$(CONFIG_RDMA) += migration-rdma.o
 common-obj-y += qemu-char.o #aio.o
 common-obj-y += block-migration.o
diff --git a/qemu-file-unix.c b/qemu-file-unix.c
new file mode 100644
index 000..9682396
--- /dev/null
+++ b/qemu-file-unix.c
@@ -0,0 +1,223 @@
+/*
+ * QEMU System Emulator
+ *
+ * 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 "qemu-common.h"
+#include "qemu/iov.h"
+#include "qemu/sockets.h"
+#include "block/coroutine.h"
+#include "migration/qemu-file.h"
+
+typedef struct QEMUFileSocket {
+int fd;
+QEMUFile *file;
+} QEMUFileSocket;
+
+static ssize_t socket_writev_buffer(void *opaque, struct iovec *iov, int 
iovcnt,
+int64_t pos)
+{
+QEMUFileSocket *s = opaque;
+ssize_t len;
+ssize_t size = iov_size(iov, iovcnt);
+
+len = iov_send(s->fd, iov, iovcnt, 0, size);
+if (len < size) {
+len = -socket_error();
+}
+return len;
+}
+
+static int socket_get_fd(void *opaque)
+{
+QEMUFileSocket *s = opaque;
+
+return s->fd;
+}
+
+static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
+{
+QEMUFileSocket *s = opaque;
+ssize_t len;
+
+for (;;) {
+len = qemu_recv(s->fd, buf, size, 0);
+if (len != -1) {
+break;
+}
+if (socket_error() == EAGAIN) {
+yield_until_fd_readable(s->fd);
+} else if (socket_error() != EINTR) {
+break;
+}
+}
+
+if (len == -1) {
+len = -socket_error();
+}
+return len;
+}
+
+static int socket_close(void *opaque)
+{
+QEMUFileSocket *s = opaque;
+closesocket(s->fd);
+g_free(s);
+return 0;
+}
+
+static ssize_t unix_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
+  int64_t pos)
+{
+QEMUFileSocket *s = opaque;
+ssize_t len, offset;
+ssize_t size = iov_size(iov, iovcnt);
+ssize_t total = 0;
+
+assert(iovcnt > 0);
+offset = 0;
+while (size > 0) {
+/* Find the next start position; skip all full-sized vector elements  
*/
+while (offset >= iov[0].iov_len) {
+offset -= iov[0].iov_len;
+iov++, iovcnt--;
+}
+
+/* skip `offset' bytes from the (now) first element, undo it on exit */
+assert(iovcnt > 0);
+iov[0].iov_base += offset;
+iov[0].iov_len -= offset;
+
+do {
+len = writev(s->fd, iov, iovcnt);
+} while (len == -1 && errno == EINTR);
+if (len == -1) {
+return -errno;
+}
+
+/* Undo the changes above */
+iov[0].iov_base -= offset;
+iov[0].iov_len += offset;
+
+/* Prepare for the next iteration */
+offset += len;
+total += len;
+size -= len;
+}
+
+ 

[Qemu-devel] [PULL 10/10] migration: catch unknown flag combinations in ram_load

2014-10-15 Thread Juan Quintela
From: Peter Lieven 

this patch extends commit db80fac by not only checking
for unknown flags, but also filtering out unknown flag
combinations.

Suggested-by: Eric Blake 
Signed-off-by: Peter Lieven 
Signed-off-by: Juan Quintela 
---
 arch_init.c | 62 +++--
 1 file changed, 32 insertions(+), 30 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index 9b3e25d..88a5ba0 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -1040,8 +1040,7 @@ void ram_handle_compressed(void *host, uint8_t ch, 
uint64_t size)

 static int ram_load(QEMUFile *f, void *opaque, int version_id)
 {
-ram_addr_t addr;
-int flags, ret = 0;
+int flags = 0, ret = 0;
 static uint64_t seq_iter;

 seq_iter++;
@@ -1050,21 +1049,24 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)
 ret = -EINVAL;
 }

-while (!ret) {
-addr = qemu_get_be64(f);
+while (!ret && !(flags & RAM_SAVE_FLAG_EOS)) {
+ram_addr_t addr, total_ram_bytes;
+void *host;
+uint8_t ch;

+addr = qemu_get_be64(f);
 flags = addr & ~TARGET_PAGE_MASK;
 addr &= TARGET_PAGE_MASK;

-if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
+switch (flags & ~RAM_SAVE_FLAG_CONTINUE) {
+case RAM_SAVE_FLAG_MEM_SIZE:
 /* Synchronize RAM block list */
-char id[256];
-ram_addr_t length;
-ram_addr_t total_ram_bytes = addr;
-
-while (total_ram_bytes) {
+total_ram_bytes = addr;
+while (!ret && total_ram_bytes) {
 RAMBlock *block;
 uint8_t len;
+char id[256];
+ram_addr_t length;

 len = qemu_get_byte(f);
 qemu_get_buffer(f, (uint8_t *)id, len);
@@ -1088,16 +1090,11 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)
  "accept migration", id);
 ret = -EINVAL;
 }
-if (ret) {
-break;
-}

 total_ram_bytes -= length;
 }
-} else if (flags & RAM_SAVE_FLAG_COMPRESS) {
-void *host;
-uint8_t ch;
-
+break;
+case RAM_SAVE_FLAG_COMPRESS:
 host = host_from_stream_offset(f, addr, flags);
 if (!host) {
 error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
@@ -1107,9 +1104,8 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)

 ch = qemu_get_byte(f);
 ram_handle_compressed(host, ch, TARGET_PAGE_SIZE);
-} else if (flags & RAM_SAVE_FLAG_PAGE) {
-void *host;
-
+break;
+case RAM_SAVE_FLAG_PAGE:
 host = host_from_stream_offset(f, addr, flags);
 if (!host) {
 error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
@@ -1118,8 +1114,9 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)
 }

 qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
-} else if (flags & RAM_SAVE_FLAG_XBZRLE) {
-void *host = host_from_stream_offset(f, addr, flags);
+break;
+case RAM_SAVE_FLAG_XBZRLE:
+host = host_from_stream_offset(f, addr, flags);
 if (!host) {
 error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
 ret = -EINVAL;
@@ -1132,17 +1129,22 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)
 ret = -EINVAL;
 break;
 }
-} else if (flags & RAM_SAVE_FLAG_HOOK) {
-ram_control_load_hook(f, flags);
-} else if (flags & RAM_SAVE_FLAG_EOS) {
-/* normal exit */
 break;
-} else {
-error_report("Unknown migration flags: %#x", flags);
-ret = -EINVAL;
+case RAM_SAVE_FLAG_EOS:
+/* normal exit */
 break;
+default:
+if (flags & RAM_SAVE_FLAG_HOOK) {
+ram_control_load_hook(f, flags);
+} else {
+error_report("Unknown combination of migration flags: %#x",
+ flags);
+ret = -EINVAL;
+}
+}
+if (!ret) {
+ret = qemu_file_get_error(f);
 }
-ret = qemu_file_get_error(f);
 }

 DPRINTF("Completed load of VM with exit code %d seq iteration "
-- 
2.1.0




[Qemu-devel] [PATCH] Add Migration maintainer

2014-10-15 Thread Juan Quintela
From: Juan Quintela 

Signed-off-by: Juan Quintela 
---
 MAINTAINERS | 9 +
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 206bf7e..9fc0b54 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -865,6 +865,15 @@ M: Blue Swirl 
 S: Odd Fixes
 F: scripts/checkpatch.pl

+Migration
+M: Juan Quintela 
+S: Maintained
+F: include/migration/
+F: migration*
+F: savevm.c
+F: arch_init.c
+F: vmstate.c
+
 Seccomp
 M: Eduardo Otubo 
 S: Supported
-- 
2.1.0




[Qemu-devel] [PATCH] vga: drop unused dmask16 and dmask4 to avoid compiler warnings

2014-10-15 Thread Igor Mammedov
Signed-off-by: Igor Mammedov 
---
 hw/display/vga.c | 26 --
 1 file changed, 26 deletions(-)

diff --git a/hw/display/vga.c b/hw/display/vga.c
index 19e7f23..52eaf05 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -136,32 +136,6 @@ static const uint32_t mask16[16] = {
 #define PAT(x) cbswap_32(x)
 #endif
 
-static const uint32_t dmask16[16] = {
-PAT(0x),
-PAT(0x00ff),
-PAT(0xff00),
-PAT(0x),
-PAT(0x00ff),
-PAT(0x00ff00ff),
-PAT(0x0000),
-PAT(0x00ff),
-PAT(0xff00),
-PAT(0xffff),
-PAT(0xff00ff00),
-PAT(0xff00),
-PAT(0x),
-PAT(0x00ff),
-PAT(0xff00),
-PAT(0x),
-};
-
-static const uint32_t dmask4[4] = {
-PAT(0x),
-PAT(0x),
-PAT(0x),
-PAT(0x),
-};
-
 static uint32_t expand4[256];
 static uint16_t expand2[256];
 static uint8_t expand4to8[16];
-- 
1.9.3 (Apple Git-50)




[Qemu-devel] [PULL 23/34] isa-fdc: remove bootindexA/B property from qdev to qom

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Remove bootindexA/B form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/block/fdc.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 6c86a6b..9f9484c 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -2291,8 +2291,6 @@ static Property isa_fdc_properties[] = {
 DEFINE_PROP_UINT32("dma", FDCtrlISABus, dma, 2),
 DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].bs),
 DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].bs),
-DEFINE_PROP_INT32("bootindexA", FDCtrlISABus, bootindexA, -1),
-DEFINE_PROP_INT32("bootindexB", FDCtrlISABus, bootindexB, -1),
 DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate,
 0, true),
 DEFINE_PROP_END_OF_LIST(),
@@ -2310,11 +2308,24 @@ static void isabus_fdc_class_init(ObjectClass *klass, 
void *data)
 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 }
 
+static void isabus_fdc_instance_init(Object *obj)
+{
+FDCtrlISABus *isa = ISA_FDC(obj);
+
+device_add_bootindex_property(obj, &isa->bootindexA,
+  "bootindexA", "/floppy@0",
+  DEVICE(obj), NULL);
+device_add_bootindex_property(obj, &isa->bootindexB,
+  "bootindexB", "/floppy@1",
+  DEVICE(obj), NULL);
+}
+
 static const TypeInfo isa_fdc_info = {
 .name  = TYPE_ISA_FDC,
 .parent= TYPE_ISA_DEVICE,
 .instance_size = sizeof(FDCtrlISABus),
 .class_init= isabus_fdc_class_init,
+.instance_init = isabus_fdc_instance_init,
 };
 
 static const VMStateDescription vmstate_sysbus_fdc ={
-- 
1.8.3.1




[Qemu-devel] [PULL 00/34] allow changing bootorder via monitor

2014-10-15 Thread Gerd Hoffmann
  Hi,

It's finally sorted, here comes the pull request for the bootindex patch
series which turns bootindex into a writable qom property and thereby
allows changing the bootorder at runtime via monitor.

please pull,
  Gerd

The following changes since commit b1d28ec6a7dbdaadda39d29322f0de694aeb0b74:

  Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20141010' into 
staging (2014-10-10 14:55:29 +0100)

are available in the git repository at:


  git://git.kraxel.org/qemu tags/pull-bootindex-20141015-1

for you to fetch changes up to 54086fe5d2c562a3173126d9991bd064faf1e884:

  bootindex: change fprintf to error_report (2014-10-15 10:46:01 +0200)


allow changing bootorder via monitor at runtime,
by making bootindex a writable qom property.


Gonglei (34):
  bootdevice: move bootdevice related code to new file bootdevice.c
  bootindex: add check bootindex function
  bootindex: add del_boot_device_path function
  fw_cfg: add fw_cfg_machine_reset function
  bootindex: rework add_boot_device_path function
  bootindex: support to set a existent device's bootindex to -1
  bootindex: add a setter/getter functions wrapper for bootindex property
  virtio-net: add bootindex to qom property
  e1000: add bootindex to qom property
  eepro100: add bootindex to qom property
  ne2000: add bootindex to qom property
  pcnet: add bootindex to qom property
  rtl8139: add bootindex to qom property
  spapr_lian: add bootindex to qom property
  vmxnet3: add bootindex to qom property
  usb-net: add bootindex to qom property
  net: remove bootindex property from qdev to qom
  virtio-net: alias bootindex property explicitly for virt-net-pci/ccw/s390
  host-libusb: remove bootindex property from qdev to qom
  pci-assign: remove bootindex property from qdev to qom
  vfio: remove bootindex property from qdev to qom
  redirect: remove bootindex property from qdev to qom
  isa-fdc: remove bootindexA/B property from qdev to qom
  scsi: add bootindex to qom property
  ide: add bootindex to qom property
  virtio-blk: add bootindex to qom property
  block: remove bootindex property from qdev to qom
  virtio-blk: alias bootindex property explicitly for virt-blk-pci/ccw/s390
  usb-storage: add bootindex to qom property
  nvma: ide: add bootindex to qom property
  ide: add calling add_boot_device_patch in bootindex setter function
  bootindex: move calling add_boot_device_patch to bootindex setter function
  bootindex: delete bootindex when device is removed
  bootindex: change fprintf to error_report

 Makefile.target|   2 +-
 bootdevice.c   | 258 +
 hw/block/fdc.c |  18 +++-
 hw/block/nvme.c|  44 
 hw/block/virtio-blk.c  |   5 +-
 hw/i386/kvm/pci-assign.c   |  14 ++-
 hw/ide/qdev.c  |  47 +
 hw/misc/vfio.c |  13 ++-
 hw/net/e1000.c |  12 ++-
 hw/net/eepro100.c  |  13 ++-
 hw/net/lance.c |  12 +++
 hw/net/ne2000-isa.c|  44 
 hw/net/ne2000.c|  14 ++-
 hw/net/pcnet-pci.c |  12 +++
 hw/net/pcnet.c |   2 -
 hw/net/pcnet.h |   1 -
 hw/net/rtl8139.c   |  12 ++-
 hw/net/spapr_llan.c|  12 ++-
 hw/net/virtio-net.c|   5 +-
 hw/net/vmxnet3.c   |  10 +-
 hw/nvram/fw_cfg.c  |  55 +-
 hw/s390x/s390-virtio-bus.c |   4 +
 hw/s390x/virtio-ccw.c  |   4 +
 hw/scsi/scsi-bus.c |  14 ++-
 hw/scsi/scsi-disk.c|   2 -
 hw/scsi/scsi-generic.c |   4 -
 hw/usb/dev-network.c   |  11 +-
 hw/usb/dev-storage.c   |  52 +
 hw/usb/host-libusb.c   |  13 ++-
 hw/usb/redirect.c  |  13 ++-
 hw/virtio/virtio-pci.c |   4 +
 include/hw/block/block.h   |   1 -
 include/hw/nvram/fw_cfg.h  |   2 +
 include/net/net.h  |   3 +-
 include/sysemu/sysemu.h|   6 ++
 vl.c   | 118 +
 36 files changed, 690 insertions(+), 166 deletions(-)
 create mode 100644 bootdevice.c



[Qemu-devel] [PULL 02/34] bootindex: add check bootindex function

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Determine whether a given bootindex exists or not.
If exists, we report an error.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 bootdevice.c| 15 +++
 include/sysemu/sysemu.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/bootdevice.c b/bootdevice.c
index d5b8789..f5399df 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -36,6 +36,21 @@ struct FWBootEntry {
 static QTAILQ_HEAD(, FWBootEntry) fw_boot_order =
 QTAILQ_HEAD_INITIALIZER(fw_boot_order);
 
+void check_boot_index(int32_t bootindex, Error **errp)
+{
+FWBootEntry *i;
+
+if (bootindex >= 0) {
+QTAILQ_FOREACH(i, &fw_boot_order, link) {
+if (i->bootindex == bootindex) {
+error_setg(errp, "The bootindex %d has already been used",
+   bootindex);
+return;
+}
+}
+}
+}
+
 void add_boot_device_path(int32_t bootindex, DeviceState *dev,
   const char *suffix)
 {
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 8de5100..72463de 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -213,6 +213,7 @@ void add_boot_device_path(int32_t bootindex, DeviceState 
*dev,
 char *get_boot_devices_list(size_t *size, bool ignore_suffixes);
 
 DeviceState *get_boot_device(uint32_t position);
+void check_boot_index(int32_t bootindex, Error **errp);
 
 QemuOpts *qemu_get_machine_opts(void);
 
-- 
1.8.3.1




[Qemu-devel] [PULL 01/34] bootdevice: move bootdevice related code to new file bootdevice.c

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 Makefile.target |   2 +-
 bootdevice.c| 142 
 include/sysemu/sysemu.h |   1 +
 vl.c| 118 +---
 4 files changed, 145 insertions(+), 118 deletions(-)
 create mode 100644 bootdevice.c

diff --git a/Makefile.target b/Makefile.target
index 1e8d7ab..e9ff1ee 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -127,7 +127,7 @@ endif #CONFIG_BSD_USER
 # System emulator target
 ifdef CONFIG_SOFTMMU
 obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o numa.o
-obj-y += qtest.o
+obj-y += qtest.o bootdevice.o
 obj-y += hw/
 obj-$(CONFIG_FDT) += device_tree.o
 obj-$(CONFIG_KVM) += kvm-all.o
diff --git a/bootdevice.c b/bootdevice.c
new file mode 100644
index 000..d5b8789
--- /dev/null
+++ b/bootdevice.c
@@ -0,0 +1,142 @@
+/*
+ * QEMU Boot Device Implement
+ *
+ * Copyright (c) 2014 HUAWEI TECHNOLOGIES CO.,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 "sysemu/sysemu.h"
+
+typedef struct FWBootEntry FWBootEntry;
+
+struct FWBootEntry {
+QTAILQ_ENTRY(FWBootEntry) link;
+int32_t bootindex;
+DeviceState *dev;
+char *suffix;
+};
+
+static QTAILQ_HEAD(, FWBootEntry) fw_boot_order =
+QTAILQ_HEAD_INITIALIZER(fw_boot_order);
+
+void add_boot_device_path(int32_t bootindex, DeviceState *dev,
+  const char *suffix)
+{
+FWBootEntry *node, *i;
+
+if (bootindex < 0) {
+return;
+}
+
+assert(dev != NULL || suffix != NULL);
+
+node = g_malloc0(sizeof(FWBootEntry));
+node->bootindex = bootindex;
+node->suffix = g_strdup(suffix);
+node->dev = dev;
+
+QTAILQ_FOREACH(i, &fw_boot_order, link) {
+if (i->bootindex == bootindex) {
+fprintf(stderr, "Two devices with same boot index %d\n", 
bootindex);
+exit(1);
+} else if (i->bootindex < bootindex) {
+continue;
+}
+QTAILQ_INSERT_BEFORE(i, node, link);
+return;
+}
+QTAILQ_INSERT_TAIL(&fw_boot_order, node, link);
+}
+
+DeviceState *get_boot_device(uint32_t position)
+{
+uint32_t counter = 0;
+FWBootEntry *i = NULL;
+DeviceState *res = NULL;
+
+if (!QTAILQ_EMPTY(&fw_boot_order)) {
+QTAILQ_FOREACH(i, &fw_boot_order, link) {
+if (counter == position) {
+res = i->dev;
+break;
+}
+counter++;
+}
+}
+return res;
+}
+
+/*
+ * This function returns null terminated string that consist of new line
+ * separated device paths.
+ *
+ * memory pointed by "size" is assigned total length of the array in bytes
+ *
+ */
+char *get_boot_devices_list(size_t *size, bool ignore_suffixes)
+{
+FWBootEntry *i;
+size_t total = 0;
+char *list = NULL;
+
+QTAILQ_FOREACH(i, &fw_boot_order, link) {
+char *devpath = NULL, *bootpath;
+size_t len;
+
+if (i->dev) {
+devpath = qdev_get_fw_dev_path(i->dev);
+assert(devpath);
+}
+
+if (i->suffix && !ignore_suffixes && devpath) {
+size_t bootpathlen = strlen(devpath) + strlen(i->suffix) + 1;
+
+bootpath = g_malloc(bootpathlen);
+snprintf(bootpath, bootpathlen, "%s%s", devpath, i->suffix);
+g_free(devpath);
+} else if (devpath) {
+bootpath = devpath;
+} else if (!ignore_suffixes) {
+assert(i->suffix);
+bootpath = g_strdup(i->suffix);
+} else {
+bootpath = g_strdup("");
+}
+
+if (total) {
+list[total-1] = '\n';
+}
+len = strlen(bootpath) + 1;
+list = g_realloc(list, total + len);
+memcpy(&list[total], bootpath, len);
+total += len;
+g_free(bootpath);
+  

[Qemu-devel] [PULL 03/34] bootindex: add del_boot_device_path function

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Introduce del_boot_device_path() to clean up fw_cfg content when
hot-unplugging a device that refers to a bootindex or update a
existent devcie's bootindex.

Signed-off-by: Gonglei 
Signed-off-by: Chenliang 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 bootdevice.c| 20 
 include/sysemu/sysemu.h |  1 +
 2 files changed, 21 insertions(+)

diff --git a/bootdevice.c b/bootdevice.c
index f5399df..7167fbc 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -51,6 +51,26 @@ void check_boot_index(int32_t bootindex, Error **errp)
 }
 }
 
+void del_boot_device_path(DeviceState *dev, const char *suffix)
+{
+FWBootEntry *i;
+
+if (dev == NULL) {
+return;
+}
+
+QTAILQ_FOREACH(i, &fw_boot_order, link) {
+if ((!suffix || !g_strcmp0(i->suffix, suffix)) &&
+ i->dev == dev) {
+QTAILQ_REMOVE(&fw_boot_order, i, link);
+g_free(i->suffix);
+g_free(i);
+
+break;
+}
+}
+}
+
 void add_boot_device_path(int32_t bootindex, DeviceState *dev,
   const char *suffix)
 {
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 72463de..b3489be 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -214,6 +214,7 @@ char *get_boot_devices_list(size_t *size, bool 
ignore_suffixes);
 
 DeviceState *get_boot_device(uint32_t position);
 void check_boot_index(int32_t bootindex, Error **errp);
+void del_boot_device_path(DeviceState *dev, const char *suffix);
 
 QemuOpts *qemu_get_machine_opts(void);
 
-- 
1.8.3.1




[Qemu-devel] [PULL 24/34] scsi: add bootindex to qom property

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/scsi/scsi-bus.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 0f3e039..59e8f90 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -2016,6 +2016,16 @@ static void scsi_device_class_init(ObjectClass *klass, 
void *data)
 k->props = scsi_props;
 }
 
+static void scsi_dev_instance_init(Object *obj)
+{
+DeviceState *dev = DEVICE(obj);
+SCSIDevice *s = DO_UPCAST(SCSIDevice, qdev, dev);
+
+device_add_bootindex_property(obj, &s->conf.bootindex,
+  "bootindex", NULL,
+  &s->qdev, NULL);
+}
+
 static const TypeInfo scsi_device_type_info = {
 .name = TYPE_SCSI_DEVICE,
 .parent = TYPE_DEVICE,
@@ -2023,6 +2033,7 @@ static const TypeInfo scsi_device_type_info = {
 .abstract = true,
 .class_size = sizeof(SCSIDeviceClass),
 .class_init = scsi_device_class_init,
+.instance_init = scsi_dev_instance_init,
 };
 
 static void scsi_register_types(void)
-- 
1.8.3.1




[Qemu-devel] [PULL 26/34] virtio-blk: add bootindex to qom property

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/block/virtio-blk.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 45e0c8f..fd1ad3a 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -794,6 +794,9 @@ static void virtio_blk_instance_init(Object *obj)
  (Object **)&s->blk.iothread,
  qdev_prop_allow_set_link_before_realize,
  OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
+device_add_bootindex_property(obj, &s->blk.conf.bootindex,
+  "bootindex", "/disk@0,0",
+  DEVICE(obj), NULL);
 }
 
 static Property virtio_blk_properties[] = {
-- 
1.8.3.1




[Qemu-devel] [PULL 11/34] ne2000: add bootindex to qom property

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

At present, isa_ne2000 device does not support to boot
os, so we register two seprate qom getter/setter functions.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/net/ne2000-isa.c | 44 
 hw/net/ne2000.c | 12 
 2 files changed, 56 insertions(+)

diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c
index 6eb1dac..82e2ba1 100644
--- a/hw/net/ne2000-isa.c
+++ b/hw/net/ne2000-isa.c
@@ -28,6 +28,7 @@
 #include "net/net.h"
 #include "ne2000.h"
 #include "exec/address-spaces.h"
+#include "qapi/visitor.h"
 
 #define TYPE_ISA_NE2000 "ne2k_isa"
 #define ISA_NE2000(obj) OBJECT_CHECK(ISANE2000State, (obj), TYPE_ISA_NE2000)
@@ -101,11 +102,54 @@ static void isa_ne2000_class_initfn(ObjectClass *klass, 
void *data)
 set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
 }
 
+static void isa_ne2000_get_bootindex(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ISANE2000State *isa = ISA_NE2000(obj);
+NE2000State *s = &isa->ne2000;
+
+visit_type_int32(v, &s->c.bootindex, name, errp);
+}
+
+static void isa_ne2000_set_bootindex(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ISANE2000State *isa = ISA_NE2000(obj);
+NE2000State *s = &isa->ne2000;
+int32_t boot_index;
+Error *local_err = NULL;
+
+visit_type_int32(v, &boot_index, name, &local_err);
+if (local_err) {
+goto out;
+}
+/* check whether bootindex is present in fw_boot_order list  */
+check_boot_index(boot_index, &local_err);
+if (local_err) {
+goto out;
+}
+/* change bootindex to a new one */
+s->c.bootindex = boot_index;
+
+out:
+if (local_err) {
+error_propagate(errp, local_err);
+}
+}
+
+static void isa_ne2000_instance_init(Object *obj)
+{
+object_property_add(obj, "bootindex", "int32",
+isa_ne2000_get_bootindex,
+isa_ne2000_set_bootindex, NULL, NULL, NULL);
+object_property_set_int(obj, -1, "bootindex", NULL);
+}
 static const TypeInfo ne2000_isa_info = {
 .name  = TYPE_ISA_NE2000,
 .parent= TYPE_ISA_DEVICE,
 .instance_size = sizeof(ISANE2000State),
 .class_init= isa_ne2000_class_initfn,
+.instance_init = isa_ne2000_instance_init,
 };
 
 static void ne2000_isa_register_types(void)
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index a62d12d..62b86af 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -752,6 +752,17 @@ static void pci_ne2000_exit(PCIDevice *pci_dev)
 qemu_free_irq(s->irq);
 }
 
+static void ne2000_instance_init(Object *obj)
+{
+PCIDevice *pci_dev = PCI_DEVICE(obj);
+PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
+NE2000State *s = &d->ne2000;
+
+device_add_bootindex_property(obj, &s->c.bootindex,
+  "bootindex", "/ethernet-phy@0",
+  &pci_dev->qdev, NULL);
+}
+
 static Property ne2000_properties[] = {
 DEFINE_NIC_PROPERTIES(PCINE2000State, ne2000.c),
 DEFINE_PROP_END_OF_LIST(),
@@ -778,6 +789,7 @@ static const TypeInfo ne2000_info = {
 .parent= TYPE_PCI_DEVICE,
 .instance_size = sizeof(PCINE2000State),
 .class_init= ne2000_class_init,
+.instance_init = ne2000_instance_init,
 };
 
 static void ne2000_register_types(void)
-- 
1.8.3.1




[Qemu-devel] [PULL 13/34] rtl8139: add bootindex to qom property

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/net/rtl8139.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 6e59f38..138a03a 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -3543,6 +3543,15 @@ static int pci_rtl8139_init(PCIDevice *dev)
 return 0;
 }
 
+static void rtl8139_instance_init(Object *obj)
+{
+RTL8139State *s = RTL8139(obj);
+
+device_add_bootindex_property(obj, &s->conf.bootindex,
+  "bootindex", "/ethernet-phy@0",
+  DEVICE(obj), NULL);
+}
+
 static Property rtl8139_properties[] = {
 DEFINE_NIC_PROPERTIES(RTL8139State, conf),
 DEFINE_PROP_END_OF_LIST(),
@@ -3571,6 +3580,7 @@ static const TypeInfo rtl8139_info = {
 .parent= TYPE_PCI_DEVICE,
 .instance_size = sizeof(RTL8139State),
 .class_init= rtl8139_class_init,
+.instance_init = rtl8139_instance_init,
 };
 
 static void rtl8139_register_types(void)
-- 
1.8.3.1




[Qemu-devel] [PULL 18/34] virtio-net: alias bootindex property explicitly for virt-net-pci/ccw/s390

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Since the "bootindex" property is a QOM property and not a qdev property
now, we must alias it explicitly for virtio-net-pci, as well as CCW and
s390-virtio.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/s390x/s390-virtio-bus.c | 2 ++
 hw/s390x/virtio-ccw.c  | 2 ++
 hw/virtio/virtio-pci.c | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c
index f451ca1..168acfd 100644
--- a/hw/s390x/s390-virtio-bus.c
+++ b/hw/s390x/s390-virtio-bus.c
@@ -162,6 +162,8 @@ static void s390_virtio_net_instance_init(Object *obj)
 
 virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
 TYPE_VIRTIO_NET);
+object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
+  "bootindex", &error_abort);
 }
 
 static int s390_virtio_blk_init(VirtIOS390Device *s390_dev)
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 18ba29f..6b99fc9 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -795,6 +795,8 @@ static void virtio_ccw_net_instance_init(Object *obj)
 
 virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
 TYPE_VIRTIO_NET);
+object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
+  "bootindex", &error_abort);
 }
 
 static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev)
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 390f824..20f1ef2 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1466,6 +1466,8 @@ static void virtio_net_pci_instance_init(Object *obj)
 
 virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
 TYPE_VIRTIO_NET);
+object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
+  "bootindex", &error_abort);
 }
 
 static const TypeInfo virtio_net_pci_info = {
-- 
1.8.3.1




[Qemu-devel] [PULL 25/34] ide: add bootindex to qom property

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/ide/qdev.c | 42 ++
 1 file changed, 42 insertions(+)

diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index efab95b..7e69020 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -23,6 +23,7 @@
 #include "sysemu/blockdev.h"
 #include "hw/block/block.h"
 #include "sysemu/sysemu.h"
+#include "qapi/visitor.h"
 
 /* - */
 
@@ -191,6 +192,46 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind 
kind)
 return 0;
 }
 
+static void ide_dev_get_bootindex(Object *obj, Visitor *v, void *opaque,
+  const char *name, Error **errp)
+{
+IDEDevice *d = IDE_DEVICE(obj);
+
+visit_type_int32(v, &d->conf.bootindex, name, errp);
+}
+
+static void ide_dev_set_bootindex(Object *obj, Visitor *v, void *opaque,
+  const char *name, Error **errp)
+{
+IDEDevice *d = IDE_DEVICE(obj);
+int32_t boot_index;
+Error *local_err = NULL;
+
+visit_type_int32(v, &boot_index, name, &local_err);
+if (local_err) {
+goto out;
+}
+/* check whether bootindex is present in fw_boot_order list  */
+check_boot_index(boot_index, &local_err);
+if (local_err) {
+goto out;
+}
+/* change bootindex to a new one */
+d->conf.bootindex = boot_index;
+
+out:
+if (local_err) {
+error_propagate(errp, local_err);
+}
+}
+
+static void ide_dev_instance_init(Object *obj)
+{
+object_property_add(obj, "bootindex", "int32",
+ide_dev_get_bootindex,
+ide_dev_set_bootindex, NULL, NULL, NULL);
+}
+
 static int ide_hd_initfn(IDEDevice *dev)
 {
 return ide_dev_initfn(dev, IDE_HD);
@@ -300,6 +341,7 @@ static const TypeInfo ide_device_type_info = {
 .abstract = true,
 .class_size = sizeof(IDEDeviceClass),
 .class_init = ide_device_class_init,
+.instance_init = ide_dev_instance_init,
 };
 
 static void ide_register_types(void)
-- 
1.8.3.1




[Qemu-devel] [PULL 21/34] vfio: remove bootindex property from qdev to qom

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/misc/vfio.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index d66f3d2..b37f41c 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -4365,13 +4365,22 @@ post_reset:
 vfio_pci_post_reset(vdev);
 }
 
+static void vfio_instance_init(Object *obj)
+{
+PCIDevice *pci_dev = PCI_DEVICE(obj);
+VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, PCI_DEVICE(obj));
+
+device_add_bootindex_property(obj, &vdev->bootindex,
+  "bootindex", NULL,
+  &pci_dev->qdev, NULL);
+}
+
 static Property vfio_pci_dev_properties[] = {
 DEFINE_PROP_PCI_HOST_DEVADDR("host", VFIODevice, host),
 DEFINE_PROP_UINT32("x-intx-mmap-timeout-ms", VFIODevice,
intx.mmap_timeout, 1100),
 DEFINE_PROP_BIT("x-vga", VFIODevice, features,
 VFIO_FEATURE_ENABLE_VGA_BIT, false),
-DEFINE_PROP_INT32("bootindex", VFIODevice, bootindex, -1),
 /*
  * TODO - support passed fds... is this necessary?
  * DEFINE_PROP_STRING("vfiofd", VFIODevice, vfiofd_name),
@@ -4407,6 +4416,7 @@ static const TypeInfo vfio_pci_dev_info = {
 .parent = TYPE_PCI_DEVICE,
 .instance_size = sizeof(VFIODevice),
 .class_init = vfio_pci_dev_class_init,
+.instance_init = vfio_instance_init,
 };
 
 static void register_vfio_pci_dev_type(void)
-- 
1.8.3.1




[Qemu-devel] [PULL 33/34] bootindex: delete bootindex when device is removed

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Device should be removed from global boot list when
it is hot-unplugged.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 bootdevice.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/bootdevice.c b/bootdevice.c
index 79c2327..56b1952 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -225,6 +225,8 @@ static void property_release_bootindex(Object *obj, const 
char *name,
 
 {
 BootIndexProperty *prop = opaque;
+
+del_boot_device_path(prop->dev, prop->suffix);
 g_free(prop);
 }
 
-- 
1.8.3.1




[Qemu-devel] [PULL 15/34] vmxnet3: add bootindex to qom property

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/net/vmxnet3.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index f246fa1..88e9d9c 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -2177,6 +2177,13 @@ static int vmxnet3_pci_init(PCIDevice *pci_dev)
 return 0;
 }
 
+static void vmxnet3_instance_init(Object *obj)
+{
+VMXNET3State *s = VMXNET3(obj);
+device_add_bootindex_property(obj, &s->conf.bootindex,
+  "bootindex", "/ethernet-phy@0",
+  DEVICE(obj), NULL);
+}
 
 static void vmxnet3_pci_uninit(PCIDevice *pci_dev)
 {
@@ -2524,6 +2531,7 @@ static const TypeInfo vmxnet3_info = {
 .parent= TYPE_PCI_DEVICE,
 .instance_size = sizeof(VMXNET3State),
 .class_init= vmxnet3_class_init,
+.instance_init = vmxnet3_instance_init,
 };
 
 static void vmxnet3_register_types(void)
-- 
1.8.3.1




[Qemu-devel] [PULL 14/34] spapr_lian: add bootindex to qom property

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/net/spapr_llan.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
index 23c47d3..0ff159b 100644
--- a/hw/net/spapr_llan.c
+++ b/hw/net/spapr_llan.c
@@ -226,6 +226,15 @@ static int spapr_vlan_init(VIOsPAPRDevice *sdev)
 return 0;
 }
 
+static void spapr_vlan_instance_init(Object *obj)
+{
+VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(obj);
+
+device_add_bootindex_property(obj, &dev->nicconf.bootindex,
+  "bootindex", "",
+  DEVICE(dev), NULL);
+}
+
 void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd)
 {
 DeviceState *dev;
@@ -553,6 +562,7 @@ static const TypeInfo spapr_vlan_info = {
 .parent= TYPE_VIO_SPAPR_DEVICE,
 .instance_size = sizeof(VIOsPAPRVLANDevice),
 .class_init= spapr_vlan_class_init,
+.instance_init = spapr_vlan_instance_init,
 };
 
 static void spapr_vlan_register_types(void)
-- 
1.8.3.1




[Qemu-devel] [PULL 06/34] bootindex: support to set a existent device's bootindex to -1

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

When set a device's bootindex to -1, we remove it from global
fw_boot_order list.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 bootdevice.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/bootdevice.c b/bootdevice.c
index aac0ffb..a38479a 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -77,6 +77,7 @@ void add_boot_device_path(int32_t bootindex, DeviceState *dev,
 FWBootEntry *node, *i;
 
 if (bootindex < 0) {
+del_boot_device_path(dev, suffix);
 return;
 }
 
-- 
1.8.3.1




[Qemu-devel] [PULL 31/34] ide: add calling add_boot_device_patch in bootindex setter function

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

On this way, we can assure the new bootindex take effect
during vm rebooting. Meanwhile set the initial value of
bootindex to -1.

Because ide devcies's unit property maybe
do not initialize when set_bootindex function is called,
so that we don't know its suffix. So we have to save the
call add_boot_device_path() on ide realize/init function.
When we want to change bootindex during vm rebooting, we
can call it in setter function.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/ide/qdev.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 7e69020..9814ef0 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -219,6 +219,10 @@ static void ide_dev_set_bootindex(Object *obj, Visitor *v, 
void *opaque,
 /* change bootindex to a new one */
 d->conf.bootindex = boot_index;
 
+if (d->unit != -1) {
+add_boot_device_path(d->conf.bootindex, &d->qdev,
+ d->unit ? "/disk@1" : "/disk@0");
+}
 out:
 if (local_err) {
 error_propagate(errp, local_err);
@@ -230,6 +234,7 @@ static void ide_dev_instance_init(Object *obj)
 object_property_add(obj, "bootindex", "int32",
 ide_dev_get_bootindex,
 ide_dev_set_bootindex, NULL, NULL, NULL);
+object_property_set_int(obj, -1, "bootindex", NULL);
 }
 
 static int ide_hd_initfn(IDEDevice *dev)
-- 
1.8.3.1




[Qemu-devel] [PULL 04/34] fw_cfg: add fw_cfg_machine_reset function

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

We must assure that the changed bootindex can take effect
when guest is rebooted. So we introduce fw_cfg_machine_reset(),
which change the fw_cfg file's bootindex data using the new
global fw_boot_order list.

Signed-off-by: Chenliang 
Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Acked-by: Paolo Bonzini 
Signed-off-by: Gerd Hoffmann 
---
 hw/nvram/fw_cfg.c | 55 ---
 include/hw/nvram/fw_cfg.h |  2 ++
 2 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index b71d251..e7ed27e 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -402,6 +402,26 @@ static void fw_cfg_add_bytes_read_callback(FWCfgState *s, 
uint16_t key,
 s->entries[arch][key].callback_opaque = callback_opaque;
 }
 
+static void *fw_cfg_modify_bytes_read(FWCfgState *s, uint16_t key,
+  void *data, size_t len)
+{
+void *ptr;
+int arch = !!(key & FW_CFG_ARCH_LOCAL);
+
+key &= FW_CFG_ENTRY_MASK;
+
+assert(key < FW_CFG_MAX_ENTRY && len < UINT32_MAX);
+
+/* return the old data to the function caller, avoid memory leak */
+ptr = s->entries[arch][key].data;
+s->entries[arch][key].data = data;
+s->entries[arch][key].len = len;
+s->entries[arch][key].callback_opaque = NULL;
+s->entries[arch][key].callback = NULL;
+
+return ptr;
+}
+
 void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len)
 {
 fw_cfg_add_bytes_read_callback(s, key, NULL, NULL, data, len);
@@ -499,13 +519,42 @@ void fw_cfg_add_file(FWCfgState *s,  const char *filename,
 fw_cfg_add_file_callback(s, filename, NULL, NULL, data, len);
 }
 
-static void fw_cfg_machine_ready(struct Notifier *n, void *data)
+void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
+void *data, size_t len)
+{
+int i, index;
+
+assert(s->files);
+
+index = be32_to_cpu(s->files->count);
+assert(index < FW_CFG_FILE_SLOTS);
+
+for (i = 0; i < index; i++) {
+if (strcmp(filename, s->files->f[i].name) == 0) {
+return fw_cfg_modify_bytes_read(s, FW_CFG_FILE_FIRST + i,
+ data, len);
+}
+}
+/* add new one */
+fw_cfg_add_file_callback(s, filename, NULL, NULL, data, len);
+return NULL;
+}
+
+static void fw_cfg_machine_reset(void *opaque)
 {
+void *ptr;
 size_t len;
-FWCfgState *s = container_of(n, FWCfgState, machine_ready);
+FWCfgState *s = opaque;
 char *bootindex = get_boot_devices_list(&len, false);
 
-fw_cfg_add_file(s, "bootorder", (uint8_t*)bootindex, len);
+ptr = fw_cfg_modify_file(s, "bootorder", (uint8_t *)bootindex, len);
+g_free(ptr);
+}
+
+static void fw_cfg_machine_ready(struct Notifier *n, void *data)
+{
+FWCfgState *s = container_of(n, FWCfgState, machine_ready);
+qemu_register_reset(fw_cfg_machine_reset, s);
 }
 
 FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
index 72b1549..56e1ed7 100644
--- a/include/hw/nvram/fw_cfg.h
+++ b/include/hw/nvram/fw_cfg.h
@@ -76,6 +76,8 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename, 
void *data,
 void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
   FWCfgReadCallback callback, void 
*callback_opaque,
   void *data, size_t len);
+void *fw_cfg_modify_file(FWCfgState *s, const char *filename, void *data,
+ size_t len);
 FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
 hwaddr crl_addr, hwaddr data_addr);
 
-- 
1.8.3.1




[Qemu-devel] [PULL 32/34] bootindex: move calling add_boot_device_patch to bootindex setter function

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

On this way, we can assure the new bootindex take effect
during vm rebooting.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 bootdevice.c | 2 ++
 hw/block/fdc.c   | 3 ---
 hw/block/virtio-blk.c| 2 --
 hw/i386/kvm/pci-assign.c | 2 --
 hw/misc/vfio.c   | 1 -
 hw/net/e1000.c   | 2 --
 hw/net/eepro100.c| 2 --
 hw/net/ne2000.c  | 2 --
 hw/net/pcnet.c   | 2 --
 hw/net/rtl8139.c | 2 --
 hw/net/spapr_llan.c  | 2 --
 hw/net/virtio-net.c  | 2 --
 hw/net/vmxnet3.c | 2 --
 hw/scsi/scsi-disk.c  | 1 -
 hw/scsi/scsi-generic.c   | 3 ---
 hw/usb/dev-network.c | 2 --
 hw/usb/host-libusb.c | 1 -
 hw/usb/redirect.c| 1 -
 18 files changed, 2 insertions(+), 32 deletions(-)

diff --git a/bootdevice.c b/bootdevice.c
index 69cffd8..79c2327 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -212,6 +212,8 @@ static void device_set_bootindex(Object *obj, Visitor *v, 
void *opaque,
 /* change bootindex to a new one */
 *prop->bootindex = boot_index;
 
+add_boot_device_path(*prop->bootindex, prop->dev, prop->suffix);
+
 out:
 if (local_err) {
 error_propagate(errp, local_err);
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 9f9484c..34c1d8f 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -2216,9 +2216,6 @@ static void isabus_fdc_realize(DeviceState *dev, Error 
**errp)
 error_propagate(errp, err);
 return;
 }
-
-add_boot_device_path(isa->bootindexA, dev, "/floppy@0");
-add_boot_device_path(isa->bootindexB, dev, "/floppy@1");
 }
 
 static void sysbus_fdc_initfn(Object *obj)
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index fd1ad3a..1fa9770 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -768,8 +768,6 @@ static void virtio_blk_device_realize(DeviceState *dev, 
Error **errp)
 bdrv_set_guest_block_size(s->bs, s->conf->logical_block_size);
 
 bdrv_iostatus_enable(s->bs);
-
-add_boot_device_path(s->conf->bootindex, dev, "/disk@0,0");
 }
 
 static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
index 1e976c8..bb206da 100644
--- a/hw/i386/kvm/pci-assign.c
+++ b/hw/i386/kvm/pci-assign.c
@@ -1825,8 +1825,6 @@ static int assigned_initfn(struct PCIDevice *pci_dev)
 
 assigned_dev_load_option_rom(dev);
 
-add_boot_device_path(dev->bootindex, &pci_dev->qdev, NULL);
-
 return 0;
 
 assigned_out:
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index b37f41c..b5e7981 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -4296,7 +4296,6 @@ static int vfio_initfn(PCIDevice *pdev)
 }
 }
 
-add_boot_device_path(vdev->bootindex, &pdev->qdev, NULL);
 vfio_register_err_notifier(vdev);
 
 return 0;
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 0edbfa6..e33a4da 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -1569,8 +1569,6 @@ static int pci_e1000_init(PCIDevice *pci_dev)
 
 qemu_format_nic_info_str(qemu_get_queue(d->nic), macaddr);
 
-add_boot_device_path(d->conf.bootindex, dev, "/ethernet-phy@0");
-
 d->autoneg_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, e1000_autoneg_timer, 
d);
 d->mit_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000_mit_timer, d);
 
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index fb9c944..4877bfd 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -1901,8 +1901,6 @@ static int e100_nic_init(PCIDevice *pci_dev)
 s->vmstate->name = qemu_get_queue(s->nic)->model;
 vmstate_register(&pci_dev->qdev, -1, s->vmstate, s);
 
-add_boot_device_path(s->conf.bootindex, &pci_dev->qdev, "/ethernet-phy@0");
-
 return 0;
 }
 
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index 62b86af..3ab2d03 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -738,8 +738,6 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
   object_get_typename(OBJECT(pci_dev)), 
pci_dev->qdev.id, s);
 qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
 
-add_boot_device_path(s->c.bootindex, &pci_dev->qdev, "/ethernet-phy@0");
-
 return 0;
 }
 
diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
index 5299d52..d344c15 100644
--- a/hw/net/pcnet.c
+++ b/hw/net/pcnet.c
@@ -1735,8 +1735,6 @@ int pcnet_common_init(DeviceState *dev, PCNetState *s, 
NetClientInfo *info)
 s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), 
dev->id, s);
 qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
 
-add_boot_device_path(s->conf.bootindex, dev, "/ethernet-phy@0");
-
 /* Initialize the PROM */
 
 /*
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 138a03a..8b8a1b1 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -3538,8 +3538,6 @@ static int pci_rtl8139_init(PCIDevice *dev)
 s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, rtl8139_timer, s);
 rtl8139_set_next_tctr_ti

[Qemu-devel] [PULL 17/34] net: remove bootindex property from qdev to qom

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 include/net/net.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index ed594f9..008d610 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -36,8 +36,7 @@ typedef struct NICConf {
 #define DEFINE_NIC_PROPERTIES(_state, _conf)\
 DEFINE_PROP_MACADDR("mac",   _state, _conf.macaddr),\
 DEFINE_PROP_VLAN("vlan", _state, _conf.peers),   \
-DEFINE_PROP_NETDEV("netdev", _state, _conf.peers),   \
-DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1)
+DEFINE_PROP_NETDEV("netdev", _state, _conf.peers)
 
 
 /* Net clients */
-- 
1.8.3.1




[Qemu-devel] [PULL 12/34] pcnet: add bootindex to qom property

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/net/lance.c | 12 
 hw/net/pcnet-pci.c | 12 
 hw/net/pcnet.h |  1 -
 3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/hw/net/lance.c b/hw/net/lance.c
index 7811a9e..a1c49f1 100644
--- a/hw/net/lance.c
+++ b/hw/net/lance.c
@@ -42,6 +42,7 @@
 #include "hw/sparc/sun4m.h"
 #include "pcnet.h"
 #include "trace.h"
+#include "sysemu/sysemu.h"
 
 #define TYPE_LANCE "lance"
 #define SYSBUS_PCNET(obj) \
@@ -143,6 +144,16 @@ static void lance_reset(DeviceState *dev)
 pcnet_h_reset(&d->state);
 }
 
+static void lance_instance_init(Object *obj)
+{
+SysBusPCNetState *d = SYSBUS_PCNET(obj);
+PCNetState *s = &d->state;
+
+device_add_bootindex_property(obj, &s->conf.bootindex,
+  "bootindex", "/ethernet-phy@0",
+  DEVICE(obj), NULL);
+}
+
 static Property lance_properties[] = {
 DEFINE_PROP_PTR("dma", SysBusPCNetState, state.dma_opaque),
 DEFINE_NIC_PROPERTIES(SysBusPCNetState, state.conf),
@@ -169,6 +180,7 @@ static const TypeInfo lance_info = {
 .parent= TYPE_SYS_BUS_DEVICE,
 .instance_size = sizeof(SysBusPCNetState),
 .class_init= lance_class_init,
+.instance_init = lance_instance_init,
 };
 
 static void lance_register_types(void)
diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c
index 50ffe91..fb5f5d6 100644
--- a/hw/net/pcnet-pci.c
+++ b/hw/net/pcnet-pci.c
@@ -32,6 +32,7 @@
 #include "hw/loader.h"
 #include "qemu/timer.h"
 #include "sysemu/dma.h"
+#include "sysemu/sysemu.h"
 
 #include "pcnet.h"
 
@@ -344,6 +345,16 @@ static void pci_reset(DeviceState *dev)
 pcnet_h_reset(&d->state);
 }
 
+static void pcnet_instance_init(Object *obj)
+{
+PCIPCNetState *d = PCI_PCNET(obj);
+PCNetState *s = &d->state;
+
+device_add_bootindex_property(obj, &s->conf.bootindex,
+  "bootindex", "/ethernet-phy@0",
+  DEVICE(obj), NULL);
+}
+
 static Property pcnet_properties[] = {
 DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
 DEFINE_PROP_END_OF_LIST(),
@@ -372,6 +383,7 @@ static const TypeInfo pcnet_info = {
 .parent= TYPE_PCI_DEVICE,
 .instance_size = sizeof(PCIPCNetState),
 .class_init= pcnet_class_init,
+.instance_init = pcnet_instance_init,
 };
 
 static void pci_pcnet_register_types(void)
diff --git a/hw/net/pcnet.h b/hw/net/pcnet.h
index 9dee6f3..f8e8a6f 100644
--- a/hw/net/pcnet.h
+++ b/hw/net/pcnet.h
@@ -66,5 +66,4 @@ void pcnet_set_link_status(NetClientState *nc);
 void pcnet_common_cleanup(PCNetState *d);
 int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info);
 extern const VMStateDescription vmstate_pcnet;
-
 #endif
-- 
1.8.3.1




[Qemu-devel] [PULL 16/34] usb-net: add bootindex to qom property

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/usb/dev-network.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 23e3c45..f341b33 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -1375,6 +1375,16 @@ static void usb_net_realize(USBDevice *dev, Error 
**errrp)
 add_boot_device_path(s->conf.bootindex, &dev->qdev, "/ethernet@0");
 }
 
+static void usb_net_instance_init(Object *obj)
+{
+USBDevice *dev = USB_DEVICE(obj);
+USBNetState *s = DO_UPCAST(USBNetState, dev, dev);
+
+device_add_bootindex_property(obj, &s->conf.bootindex,
+  "bootindex", "/ethernet-phy@0",
+  &dev->qdev, NULL);
+}
+
 static USBDevice *usb_net_init(USBBus *bus, const char *cmdline)
 {
 Error *local_err = NULL;
@@ -1438,6 +1448,7 @@ static const TypeInfo net_info = {
 .parent= TYPE_USB_DEVICE,
 .instance_size = sizeof(USBNetState),
 .class_init= usb_net_class_initfn,
+.instance_init = usb_net_instance_init,
 };
 
 static void usb_net_register_types(void)
-- 
1.8.3.1




[Qemu-devel] [PULL 05/34] bootindex: rework add_boot_device_path function

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Add the function of updating bootindex about fw_boot_order list
in add_boot_device_path(). We should delete the old one if a
device has existed in global fw_boot_order list.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 bootdevice.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/bootdevice.c b/bootdevice.c
index 7167fbc..aac0ffb 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -82,6 +82,8 @@ void add_boot_device_path(int32_t bootindex, DeviceState *dev,
 
 assert(dev != NULL || suffix != NULL);
 
+del_boot_device_path(dev, suffix);
+
 node = g_malloc0(sizeof(FWBootEntry));
 node->bootindex = bootindex;
 node->suffix = g_strdup(suffix);
-- 
1.8.3.1




[Qemu-devel] [PULL 08/34] virtio-net: add bootindex to qom property

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/net/virtio-net.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 2040eac..f5ead97 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1714,6 +1714,9 @@ static void virtio_net_instance_init(Object *obj)
  * Can be overriden with virtio_net_set_config_size.
  */
 n->config_size = sizeof(struct virtio_net_config);
+device_add_bootindex_property(obj, &n->nic_conf.bootindex,
+  "bootindex", "/ethernet-phy@0",
+  DEVICE(n), NULL);
 }
 
 static Property virtio_net_properties[] = {
-- 
1.8.3.1




[Qemu-devel] [PULL 34/34] bootindex: change fprintf to error_report

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

The function may be called by qmp command, we should
report error message to the caller.

Signed-off-by: Gonglei 
Signed-off-by: Gerd Hoffmann 
---
 bootdevice.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/bootdevice.c b/bootdevice.c
index 56b1952..b29970c 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -24,6 +24,7 @@
 
 #include "sysemu/sysemu.h"
 #include "qapi/visitor.h"
+#include "qemu/error-report.h"
 
 typedef struct FWBootEntry FWBootEntry;
 
@@ -93,7 +94,7 @@ void add_boot_device_path(int32_t bootindex, DeviceState *dev,
 
 QTAILQ_FOREACH(i, &fw_boot_order, link) {
 if (i->bootindex == bootindex) {
-fprintf(stderr, "Two devices with same boot index %d\n", 
bootindex);
+error_report("Two devices with same boot index %d", bootindex);
 exit(1);
 } else if (i->bootindex < bootindex) {
 continue;
-- 
1.8.3.1




[Qemu-devel] [PULL 09/34] e1000: add bootindex to qom property

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/net/e1000.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 272df00..0edbfa6 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -1621,10 +1621,19 @@ static void e1000_class_init(ObjectClass *klass, void 
*data)
 dc->props = e1000_properties;
 }
 
+static void e1000_instance_init(Object *obj)
+{
+E1000State *n = E1000(obj);
+device_add_bootindex_property(obj, &n->conf.bootindex,
+  "bootindex", "/ethernet-phy@0",
+  DEVICE(n), NULL);
+}
+
 static const TypeInfo e1000_base_info = {
 .name  = TYPE_E1000_BASE,
 .parent= TYPE_PCI_DEVICE,
 .instance_size = sizeof(E1000State),
+.instance_init = e1000_instance_init,
 .class_size= sizeof(E1000BaseClass),
 .abstract  = true,
 };
@@ -1668,6 +1677,7 @@ static void e1000_register_types(void)
 type_info.parent = TYPE_E1000_BASE;
 type_info.class_data = (void *)info;
 type_info.class_init = e1000_class_init;
+type_info.instance_init = e1000_instance_init;
 
 type_register(&type_info);
 }
-- 
1.8.3.1




[Qemu-devel] [PULL 29/34] usb-storage: add bootindex to qom property

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Because usb-storage rely on scsi-disk which is created
in usb_msg_realize_storage(), so we should store the SCSIDevice
pointer in MSDState struct. Only in this way, we can change
the global boot_order_list when we want to change the bootindex
during vm rebooting by calling object_property_set_int(Object(SCSIDevice),).

Signed-off-by: Gonglei 
Signed-off-by: Gerd Hoffmann 
---
 hw/usb/dev-storage.c | 52 
 1 file changed, 52 insertions(+)

diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index bd7cc53..7406fdd 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -17,6 +17,7 @@
 #include "monitor/monitor.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/blockdev.h"
+#include "qapi/visitor.h"
 
 //#define DEBUG_MSD
 
@@ -59,6 +60,7 @@ typedef struct {
 /* usb-storage only */
 BlockConf conf;
 uint32_t removable;
+SCSIDevice *scsi_dev;
 } MSDState;
 
 struct usb_msd_cbw {
@@ -634,6 +636,7 @@ static void usb_msd_realize_storage(USBDevice *dev, Error 
**errp)
 }
 s->bus.qbus.allow_hotplug = 0;
 usb_msd_handle_reset(dev);
+s->scsi_dev = scsi_dev;
 
 if (bdrv_key_required(bs)) {
 if (cur_mon) {
@@ -767,6 +770,54 @@ static void usb_msd_class_initfn_storage(ObjectClass 
*klass, void *data)
 usb_msd_class_initfn_common(klass);
 }
 
+static void usb_msd_get_bootindex(Object *obj, Visitor *v, void *opaque,
+  const char *name, Error **errp)
+{
+USBDevice *dev = USB_DEVICE(obj);
+MSDState *s = DO_UPCAST(MSDState, dev, dev);
+
+visit_type_int32(v, &s->conf.bootindex, name, errp);
+}
+
+static void usb_msd_set_bootindex(Object *obj, Visitor *v, void *opaque,
+  const char *name, Error **errp)
+{
+USBDevice *dev = USB_DEVICE(obj);
+MSDState *s = DO_UPCAST(MSDState, dev, dev);
+int32_t boot_index;
+Error *local_err = NULL;
+
+visit_type_int32(v, &boot_index, name, &local_err);
+if (local_err) {
+goto out;
+}
+/* check whether bootindex is present in fw_boot_order list  */
+check_boot_index(boot_index, &local_err);
+if (local_err) {
+goto out;
+}
+/* change bootindex to a new one */
+s->conf.bootindex = boot_index;
+
+if (s->scsi_dev) {
+object_property_set_int(OBJECT(s->scsi_dev), boot_index, "bootindex",
+&error_abort);
+}
+
+out:
+if (local_err) {
+error_propagate(errp, local_err);
+}
+}
+
+static void usb_msd_instance_init(Object *obj)
+{
+object_property_add(obj, "bootindex", "int32",
+usb_msd_get_bootindex,
+usb_msd_set_bootindex, NULL, NULL, NULL);
+object_property_set_int(obj, -1, "bootindex", NULL);
+}
+
 static void usb_msd_class_initfn_bot(ObjectClass *klass, void *data)
 {
 USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
@@ -780,6 +831,7 @@ static const TypeInfo msd_info = {
 .parent= TYPE_USB_DEVICE,
 .instance_size = sizeof(MSDState),
 .class_init= usb_msd_class_initfn_storage,
+.instance_init = usb_msd_instance_init,
 };
 
 static const TypeInfo bot_info = {
-- 
1.8.3.1




[Qemu-devel] [PULL 28/34] virtio-blk: alias bootindex property explicitly for virt-blk-pci/ccw/s390

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Since the "bootindex" property is a QOM property and not a qdev property
now, we must alias it explicitly for virtio-blk-pci, as well as CCW and
s390-virtio.

Signed-off-by: Gonglei 
Signed-off-by: Gerd Hoffmann 
---
 hw/s390x/s390-virtio-bus.c | 2 ++
 hw/s390x/virtio-ccw.c  | 2 ++
 hw/virtio/virtio-pci.c | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c
index 168acfd..fabde37 100644
--- a/hw/s390x/s390-virtio-bus.c
+++ b/hw/s390x/s390-virtio-bus.c
@@ -185,6 +185,8 @@ static void s390_virtio_blk_instance_init(Object *obj)
 TYPE_VIRTIO_BLK);
 object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
   &error_abort);
+object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
+  "bootindex", &error_abort);
 }
 
 static int s390_virtio_serial_init(VirtIOS390Device *s390_dev)
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 6b99fc9..6bb8708 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -819,6 +819,8 @@ static void virtio_ccw_blk_instance_init(Object *obj)
 TYPE_VIRTIO_BLK);
 object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
   &error_abort);
+object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
+  "bootindex", &error_abort);
 }
 
 static int virtio_ccw_serial_init(VirtioCcwDevice *ccw_dev)
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 20f1ef2..3f219ae 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1115,6 +1115,8 @@ static void virtio_blk_pci_instance_init(Object *obj)
 TYPE_VIRTIO_BLK);
 object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
   &error_abort);
+object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
+  "bootindex", &error_abort);
 }
 
 static const TypeInfo virtio_blk_pci_info = {
-- 
1.8.3.1




[Qemu-devel] [PULL 20/34] pci-assign: remove bootindex property from qdev to qom

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/i386/kvm/pci-assign.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
index 13b9de0..1e976c8 100644
--- a/hw/i386/kvm/pci-assign.c
+++ b/hw/i386/kvm/pci-assign.c
@@ -1850,13 +1850,22 @@ static void assigned_exitfn(struct PCIDevice *pci_dev)
 free_assigned_device(dev);
 }
 
+static void assigned_dev_instance_init(Object *obj)
+{
+PCIDevice *pci_dev = PCI_DEVICE(obj);
+AssignedDevice *d = DO_UPCAST(AssignedDevice, dev, PCI_DEVICE(obj));
+
+device_add_bootindex_property(obj, &d->bootindex,
+  "bootindex", NULL,
+  &pci_dev->qdev, NULL);
+}
+
 static Property assigned_dev_properties[] = {
 DEFINE_PROP_PCI_HOST_DEVADDR("host", AssignedDevice, host),
 DEFINE_PROP_BIT("prefer_msi", AssignedDevice, features,
 ASSIGNED_DEVICE_PREFER_MSI_BIT, false),
 DEFINE_PROP_BIT("share_intx", AssignedDevice, features,
 ASSIGNED_DEVICE_SHARE_INTX_BIT, true),
-DEFINE_PROP_INT32("bootindex", AssignedDevice, bootindex, -1),
 DEFINE_PROP_STRING("configfd", AssignedDevice, configfd_name),
 DEFINE_PROP_END_OF_LIST(),
 };
@@ -1882,6 +1891,7 @@ static const TypeInfo assign_info = {
 .parent = TYPE_PCI_DEVICE,
 .instance_size  = sizeof(AssignedDevice),
 .class_init = assign_class_init,
+.instance_init  = assigned_dev_instance_init,
 };
 
 static void assign_register_types(void)
-- 
1.8.3.1




[Qemu-devel] [PULL 07/34] bootindex: add a setter/getter functions wrapper for bootindex property

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

when we remove bootindex form qdev.property to qom.property,
we can use those functions set/get bootindex property for all
correlative devices. Meanwhile set the initial value of
bootindex to -1.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Acked-by: Paolo Bonzini 
Signed-off-by: Gerd Hoffmann 
---
 bootdevice.c| 73 +
 include/sysemu/sysemu.h |  3 ++
 2 files changed, 76 insertions(+)

diff --git a/bootdevice.c b/bootdevice.c
index a38479a..69cffd8 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -23,6 +23,7 @@
  */
 
 #include "sysemu/sysemu.h"
+#include "qapi/visitor.h"
 
 typedef struct FWBootEntry FWBootEntry;
 
@@ -178,3 +179,75 @@ char *get_boot_devices_list(size_t *size, bool 
ignore_suffixes)
 }
 return list;
 }
+
+typedef struct {
+int32_t *bootindex;
+const char *suffix;
+DeviceState *dev;
+} BootIndexProperty;
+
+static void device_get_bootindex(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+BootIndexProperty *prop = opaque;
+visit_type_int32(v, prop->bootindex, name, errp);
+}
+
+static void device_set_bootindex(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+BootIndexProperty *prop = opaque;
+int32_t boot_index;
+Error *local_err = NULL;
+
+visit_type_int32(v, &boot_index, name, &local_err);
+if (local_err) {
+goto out;
+}
+/* check whether bootindex is present in fw_boot_order list  */
+check_boot_index(boot_index, &local_err);
+if (local_err) {
+goto out;
+}
+/* change bootindex to a new one */
+*prop->bootindex = boot_index;
+
+out:
+if (local_err) {
+error_propagate(errp, local_err);
+}
+}
+
+static void property_release_bootindex(Object *obj, const char *name,
+   void *opaque)
+
+{
+BootIndexProperty *prop = opaque;
+g_free(prop);
+}
+
+void device_add_bootindex_property(Object *obj, int32_t *bootindex,
+   const char *name, const char *suffix,
+   DeviceState *dev, Error **errp)
+{
+Error *local_err = NULL;
+BootIndexProperty *prop = g_malloc0(sizeof(*prop));
+
+prop->bootindex = bootindex;
+prop->suffix = suffix;
+prop->dev = dev;
+
+object_property_add(obj, name, "int32",
+device_get_bootindex,
+device_set_bootindex,
+property_release_bootindex,
+prop, &local_err);
+
+if (local_err) {
+error_propagate(errp, local_err);
+g_free(prop);
+return;
+}
+/* initialize devices' bootindex property to -1 */
+object_property_set_int(obj, -1, name, NULL);
+}
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index b3489be..0037a69 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -215,6 +215,9 @@ char *get_boot_devices_list(size_t *size, bool 
ignore_suffixes);
 DeviceState *get_boot_device(uint32_t position);
 void check_boot_index(int32_t bootindex, Error **errp);
 void del_boot_device_path(DeviceState *dev, const char *suffix);
+void device_add_bootindex_property(Object *obj, int32_t *bootindex,
+   const char *name, const char *suffix,
+   DeviceState *dev, Error **errp);
 
 QemuOpts *qemu_get_machine_opts(void);
 
-- 
1.8.3.1




[Qemu-devel] [PULL 22/34] redirect: remove bootindex property from qdev to qom

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/usb/redirect.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index e2c9896..95f1aa2 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -2471,7 +2471,6 @@ static Property usbredir_properties[] = {
 DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
 DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, usbredirparser_warning),
 DEFINE_PROP_STRING("filter", USBRedirDevice, filter_str),
-DEFINE_PROP_INT32("bootindex", USBRedirDevice, bootindex, -1),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -2496,11 +2495,22 @@ static void usbredir_class_initfn(ObjectClass *klass, 
void *data)
 set_bit(DEVICE_CATEGORY_MISC, dc->categories);
 }
 
+static void usbredir_instance_init(Object *obj)
+{
+USBDevice *udev = USB_DEVICE(obj);
+USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
+
+device_add_bootindex_property(obj, &dev->bootindex,
+  "bootindex", NULL,
+  &udev->qdev, NULL);
+}
+
 static const TypeInfo usbredir_dev_info = {
 .name  = "usb-redir",
 .parent= TYPE_USB_DEVICE,
 .instance_size = sizeof(USBRedirDevice),
 .class_init= usbredir_class_initfn,
+.instance_init = usbredir_instance_init,
 };
 
 static void usbredir_register_types(void)
-- 
1.8.3.1




[Qemu-devel] [PULL 30/34] nvma: ide: add bootindex to qom property

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

At present, nvma cannot boot. However, it provides already
a bootindex property, so change bootindex to qom for nvma
device, but not call add_boot_device_path.

Signed-off-by: Gonglei 
Signed-off-by: Gerd Hoffmann 
---
 hw/block/nvme.c | 44 
 1 file changed, 44 insertions(+)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index b010c9b..9a95f75 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -24,6 +24,8 @@
 #include 
 #include 
 #include 
+#include "sysemu/sysemu.h"
+#include "qapi/visitor.h"
 
 #include "nvme.h"
 
@@ -871,11 +873,53 @@ static void nvme_class_init(ObjectClass *oc, void *data)
 dc->vmsd = &nvme_vmstate;
 }
 
+static void nvme_get_bootindex(Object *obj, Visitor *v, void *opaque,
+  const char *name, Error **errp)
+{
+NvmeCtrl *s = NVME(obj);
+
+visit_type_int32(v, &s->conf.bootindex, name, errp);
+}
+
+static void nvme_set_bootindex(Object *obj, Visitor *v, void *opaque,
+  const char *name, Error **errp)
+{
+NvmeCtrl *s = NVME(obj);
+int32_t boot_index;
+Error *local_err = NULL;
+
+visit_type_int32(v, &boot_index, name, &local_err);
+if (local_err) {
+goto out;
+}
+/* check whether bootindex is present in fw_boot_order list  */
+check_boot_index(boot_index, &local_err);
+if (local_err) {
+goto out;
+}
+/* change bootindex to a new one */
+s->conf.bootindex = boot_index;
+
+out:
+if (local_err) {
+error_propagate(errp, local_err);
+}
+}
+
+static void nvme_instance_init(Object *obj)
+{
+object_property_add(obj, "bootindex", "int32",
+nvme_get_bootindex,
+nvme_set_bootindex, NULL, NULL, NULL);
+object_property_set_int(obj, -1, "bootindex", NULL);
+}
+
 static const TypeInfo nvme_info = {
 .name  = "nvme",
 .parent= TYPE_PCI_DEVICE,
 .instance_size = sizeof(NvmeCtrl),
 .class_init= nvme_class_init,
+.instance_init = nvme_instance_init,
 };
 
 static void nvme_register_types(void)
-- 
1.8.3.1




[Qemu-devel] [PULL 10/34] eepro100: add bootindex to qom property

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/net/eepro100.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index 3cd826a..fb9c944 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -1906,6 +1906,14 @@ static int e100_nic_init(PCIDevice *pci_dev)
 return 0;
 }
 
+static void eepro100_instance_init(Object *obj)
+{
+EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, PCI_DEVICE(obj));
+device_add_bootindex_property(obj, &s->conf.bootindex,
+  "bootindex", "/ethernet-phy@0",
+  DEVICE(s), NULL);
+}
+
 static E100PCIDeviceInfo e100_devices[] = {
 {
 .name = "i82550",
@@ -2104,7 +2112,8 @@ static void eepro100_register_types(void)
 type_info.parent = TYPE_PCI_DEVICE;
 type_info.class_init = eepro100_class_init;
 type_info.instance_size = sizeof(EEPRO100State);
-
+type_info.instance_init = eepro100_instance_init;
+
 type_register(&type_info);
 }
 }
-- 
1.8.3.1




[Qemu-devel] [PULL 19/34] host-libusb: remove bootindex property from qdev to qom

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/usb/host-libusb.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index 45b74e5..906e429 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -982,6 +982,16 @@ static void usb_host_realize(USBDevice *udev, Error **errp)
 usb_host_auto_check(NULL);
 }
 
+static void usb_host_instance_init(Object *obj)
+{
+USBDevice *udev = USB_DEVICE(obj);
+USBHostDevice *s = USB_HOST_DEVICE(udev);
+
+device_add_bootindex_property(obj, &s->bootindex,
+  "bootindex", NULL,
+  &udev->qdev, NULL);
+}
+
 static void usb_host_handle_destroy(USBDevice *udev)
 {
 USBHostDevice *s = USB_HOST_DEVICE(udev);
@@ -1465,7 +1475,6 @@ static Property usb_host_dev_properties[] = {
 DEFINE_PROP_UINT32("productid", USBHostDevice, match.product_id, 0),
 DEFINE_PROP_UINT32("isobufs",  USBHostDevice, iso_urb_count,4),
 DEFINE_PROP_UINT32("isobsize", USBHostDevice, iso_urb_frames,   32),
-DEFINE_PROP_INT32("bootindex", USBHostDevice, bootindex,-1),
 DEFINE_PROP_UINT32("loglevel",  USBHostDevice, loglevel,
LIBUSB_LOG_LEVEL_WARNING),
 DEFINE_PROP_BIT("pipeline",USBHostDevice, options,
@@ -1498,6 +1507,7 @@ static TypeInfo usb_host_dev_info = {
 .parent= TYPE_USB_DEVICE,
 .instance_size = sizeof(USBHostDevice),
 .class_init= usb_host_class_initfn,
+.instance_init = usb_host_instance_init,
 };
 
 static void usb_host_register_types(void)
-- 
1.8.3.1




[Qemu-devel] [PULL 27/34] block: remove bootindex property from qdev to qom

2014-10-15 Thread Gerd Hoffmann
From: Gonglei 

Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Gerd Hoffmann 
---
 hw/scsi/scsi-bus.c   | 3 ++-
 hw/scsi/scsi-disk.c  | 1 -
 hw/scsi/scsi-generic.c   | 1 -
 include/hw/block/block.h | 1 -
 4 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 59e8f90..e7b1cf6 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -231,7 +231,8 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, 
BlockDriverState *bdrv,
 dev = qdev_create(&bus->qbus, driver);
 qdev_prop_set_uint32(dev, "scsi-id", unit);
 if (bootindex >= 0) {
-qdev_prop_set_int32(dev, "bootindex", bootindex);
+object_property_set_int(OBJECT(dev), bootindex, "bootindex",
+&error_abort);
 }
 if (object_property_find(OBJECT(dev), "removable", NULL)) {
 qdev_prop_set_bit(dev, "removable", removable);
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 7a7938a..9cd3445 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2662,7 +2662,6 @@ static const TypeInfo scsi_cd_info = {
 #ifdef __linux__
 static Property scsi_block_properties[] = {
 DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.bs),
-DEFINE_PROP_INT32("bootindex", SCSIDiskState, qdev.conf.bootindex, -1),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 01bca08..03b980c 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -463,7 +463,6 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, 
uint32_t tag, uint32_t lun,
 
 static Property scsi_generic_properties[] = {
 DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.bs),
-DEFINE_PROP_INT32("bootindex", SCSIDevice, conf.bootindex, -1),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index 3a01488..867a226 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -49,7 +49,6 @@ static inline unsigned int get_physical_block_exp(BlockConf 
*conf)
   _conf.physical_block_size, 512),  \
 DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0),  \
 DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0),\
-DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1),\
 DEFINE_PROP_UINT32("discard_granularity", _state, \
_conf.discard_granularity, -1)
 
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH] vga: drop unused dmask16 and dmask4 to avoid compiler warnings

2014-10-15 Thread Gonglei
On 2014/10/15 17:04, Igor Mammedov wrote:

> Signed-off-by: Igor Mammedov 
> ---
>  hw/display/vga.c | 26 --
>  1 file changed, 26 deletions(-)
> 

AFAICT, Peter had posted this patch, which had queued in vga-next branch by 
Gerd. :)

[PATCH] hw/display/vga: Remove unused arrays dmask4 and dmask16

Best regards,
-Gonglei




[Qemu-devel] [PATCH v3 2/2] Xen: Use the ioreq-server API when available

2014-10-15 Thread Paul Durrant
The ioreq-server API added to Xen 4.5 offers better security than
the existing Xen/QEMU interface because the shared pages that are
used to pass emulation request/results back and forth are removed
from the guest's memory space before any requests are serviced.
This prevents the guest from mapping these pages (they are in a
well known location) and attempting to attack QEMU by synthesizing
its own request structures. Hence, this patch modifies configure
to detect whether the API is available, and adds the necessary
code to use the API if it is.

Signed-off-by: Paul Durrant 
Cc: Stefano Stabellini 
Cc: Peter Maydell 
Cc: Paolo Bonzini 
Cc: Michael Tokarev 
Cc: Stefan Hajnoczi 
Cc: Stefan Weil 
Cc: Olaf Hering 
Cc: Gerd Hoffmann 
Cc: Alexey Kardashevskiy 
Cc: Alexander Graf 
---
 configure   |   29 ++
 include/hw/xen/xen_common.h |  222 +++
 trace-events|8 ++
 xen-hvm.c   |  174 +
 4 files changed, 412 insertions(+), 21 deletions(-)

diff --git a/configure b/configure
index 9ac2600..c2db574 100755
--- a/configure
+++ b/configure
@@ -1876,6 +1876,32 @@ int main(void) {
   xc_gnttab_open(NULL, 0);
   xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0);
   xc_hvm_inject_msi(xc, 0, 0xf000, 0x);
+  xc_hvm_create_ioreq_server(xc, 0, 0, NULL);
+  return 0;
+}
+EOF
+  compile_prog "" "$xen_libs"
+then
+xen_ctrl_version=450
+xen=yes
+
+  elif
+  cat > $TMPC <
+#include 
+#include 
+#include 
+#if !defined(HVM_MAX_VCPUS)
+# error HVM_MAX_VCPUS not defined
+#endif
+int main(void) {
+  xc_interface *xc;
+  xs_daemon_open();
+  xc = xc_interface_open(0, 0, 0);
+  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
+  xc_gnttab_open(NULL, 0);
+  xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0);
+  xc_hvm_inject_msi(xc, 0, 0xf000, 0x);
   return 0;
 }
 EOF
@@ -4282,6 +4308,9 @@ if test -n "$sparc_cpu"; then
 echo "Target Sparc Arch $sparc_cpu"
 fi
 echo "xen support   $xen"
+if test "$xen" = "yes" ; then
+  echo "xen ctrl version  $xen_ctrl_version"
+fi
 echo "brlapi support$brlapi"
 echo "bluez  support$bluez"
 echo "Documentation $docs"
diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
index 07731b9..7040506 100644
--- a/include/hw/xen/xen_common.h
+++ b/include/hw/xen/xen_common.h
@@ -16,7 +16,9 @@
 
 #include "hw/hw.h"
 #include "hw/xen/xen.h"
+#include "hw/pci/pci.h"
 #include "qemu/queue.h"
+#include "trace.h"
 
 /*
  * We don't support Xen prior to 3.3.0.
@@ -164,4 +166,224 @@ void destroy_hvm_domain(bool reboot);
 /* shutdown/destroy current domain because of an error */
 void xen_shutdown_fatal_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
 
+/* Xen before 4.5 */
+#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 450
+
+#ifndef HVM_PARAM_BUFIOREQ_EVTCHN
+#define HVM_PARAM_BUFIOREQ_EVTCHN 26
+#endif
+
+#define IOREQ_TYPE_PCI_CONFIG 2
+
+typedef uint32_t ioservid_t;
+
+static inline void xen_map_memory_section(XenXC xc, domid_t dom,
+  ioservid_t ioservid,
+  MemoryRegionSection *section)
+{
+}
+
+static inline void xen_unmap_memory_section(XenXC xc, domid_t dom,
+ioservid_t ioservid,
+MemoryRegionSection *section)
+{
+}
+
+static inline void xen_map_io_section(XenXC xc, domid_t dom,
+  ioservid_t ioservid,
+  MemoryRegionSection *section)
+{
+}
+
+static inline void xen_unmap_io_section(XenXC xc, domid_t dom,
+ioservid_t ioservid,
+MemoryRegionSection *section)
+{
+}
+
+static inline void xen_map_pcidev(XenXC xc, domid_t dom,
+  ioservid_t ioservid,
+  PCIDevice *pci_dev)
+{
+}
+
+static inline void xen_unmap_pcidev(XenXC xc, domid_t dom,
+ioservid_t ioservid,
+PCIDevice *pci_dev)
+{
+}
+
+static inline int xen_create_ioreq_server(XenXC xc, domid_t dom,
+  ioservid_t *ioservid)
+{
+return 0;
+}
+
+static inline void xen_destroy_ioreq_server(XenXC xc, domid_t dom,
+ioservid_t ioservid)
+{
+}
+
+static inline int xen_get_ioreq_server_info(XenXC xc, domid_t dom,
+ioservid_t ioservid,
+xen_pfn_t *ioreq_pfn,
+xen_pfn_t *bufioreq_pfn,
+evtchn_port_t *bufioreq_evtchn)
+{
+unsigned long param;
+int rc;
+
+rc = xc_get_hvm_param(xc, dom, HVM_PARAM_IOREQ_PFN, ¶m);
+if (rc < 0) {
+fprintf(st

[Qemu-devel] [PATCH v3 1/2] Add device listener interface

2014-10-15 Thread Paul Durrant
The Xen ioreq-server API, introduced in Xen 4.5, requires that PCI device
models explicitly register with Xen for config space accesses. This patch
adds a listener interface into qdev-core which can be used by the Xen
interface code to monitor for arrival and departure of PCI devices.

Signed-off-by: Paul Durrant 
Cc: Michael S. Tsirkin 
Cc: Andreas Faerber" 
Cc: Paolo Bonzini 
Cc: Peter Crosthwaite 
Cc: Igor Mammedov 
Cc: Markus Armbruster 
Cc: Thomas Huth 
Cc: Christian Borntraeger 
---
 hw/core/qdev.c  |   54 +++
 include/hw/qdev-core.h  |   10 +
 include/qemu/typedefs.h |1 +
 3 files changed, 65 insertions(+)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index fcb1638..4a9c1f6 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -175,6 +175,56 @@ int qdev_init(DeviceState *dev)
 return 0;
 }
 
+static QTAILQ_HEAD(qdev_listeners, DeviceListener) qdev_listeners
+= QTAILQ_HEAD_INITIALIZER(qdev_listeners);
+
+enum ListenerDirection { Forward, Reverse };
+
+#define QDEV_LISTENER_CALL(_callback, _direction, _args...) \
+do {\
+DeviceListener *_listener;  \
+\
+switch (_direction) {   \
+case Forward:   \
+QTAILQ_FOREACH(_listener, &qdev_listeners, link) {  \
+if (_listener->_callback) { \
+_listener->_callback(_listener, ##_args);   \
+}   \
+}   \
+break;  \
+case Reverse:   \
+QTAILQ_FOREACH_REVERSE(_listener, &qdev_listeners,  \
+   qdev_listeners, link) {  \
+if (_listener->_callback) { \
+_listener->_callback(_listener, ##_args);   \
+}   \
+}   \
+break;  \
+default:\
+abort();\
+}   \
+} while (0)
+
+static int qdev_listener_add(DeviceState *dev, void *opaque)
+{
+QDEV_LISTENER_CALL(realize, Forward, dev);
+
+return 0;
+}
+
+void qdev_listener_register(DeviceListener *listener)
+{
+QTAILQ_INSERT_TAIL(&qdev_listeners, listener, link);
+
+qbus_walk_children(sysbus_get_default(), NULL, NULL, qdev_listener_add,
+   NULL, NULL);
+}
+
+void qdev_listener_unregister(DeviceListener *listener)
+{
+QTAILQ_REMOVE(&qdev_listeners, listener, link);
+}
+
 static void device_realize(DeviceState *dev, Error **errp)
 {
 DeviceClass *dc = DEVICE_GET_CLASS(dev);
@@ -186,12 +236,16 @@ static void device_realize(DeviceState *dev, Error **errp)
 return;
 }
 }
+
+QDEV_LISTENER_CALL(realize, Forward, dev);
 }
 
 static void device_unrealize(DeviceState *dev, Error **errp)
 {
 DeviceClass *dc = DEVICE_GET_CLASS(dev);
 
+QDEV_LISTENER_CALL(unrealize, Reverse, dev);
+
 if (dc->exit) {
 int rc = dc->exit(dev);
 if (rc < 0) {
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 178fee2..f2dc267 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -167,6 +167,12 @@ struct DeviceState {
 int alias_required_for_version;
 };
 
+struct DeviceListener {
+void (*realize)(DeviceListener *listener, DeviceState *dev);
+void (*unrealize)(DeviceListener *listener, DeviceState *dev);
+QTAILQ_ENTRY(DeviceListener) link;
+};
+
 #define TYPE_BUS "bus"
 #define BUS(obj) OBJECT_CHECK(BusState, (obj), TYPE_BUS)
 #define BUS_CLASS(klass) OBJECT_CLASS_CHECK(BusClass, (klass), TYPE_BUS)
@@ -368,4 +374,8 @@ static inline void qbus_set_hotplug_handler(BusState *bus, 
DeviceState *handler,
  QDEV_HOTPLUG_HANDLER_PROPERTY, errp);
 bus->allow_hotplug = 1;
 }
+
+void qdev_listener_register(DeviceListener *listener);
+void qdev_listener_unregister(DeviceListener *listener);
+
 #endif
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 04df51b..e32bca2 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -20,6 +20,7 @@ typedef struct Property Property;
 typedef struct PropertyInfo PropertyInfo;
 typedef struct CompatProperty CompatProperty;
 typedef struct DeviceState DeviceState;
+typedef struct DeviceListener DeviceListener;
 typedef struct BusState BusState;
 typedef struct BusClass BusClass;
 
-- 

Re: [Qemu-devel] [PATCH v4] pc-dimm/numa: Fix stat of memory size in node when hotplug memory

2014-10-15 Thread zhanghailiang

Hi Igor,

Ping...,

Is this meet your request?;)

Thanks,
zhanghailiang

On 2014/10/9 20:21, zhanghailiang wrote:

When do memory hotplug, if there is numa node, we should add
the memory size to the corresponding node memory size.

For now, it mainly affects the result of hmp command "info numa".

Signed-off-by: zhanghailiang 
---
  v4:
- s/pc_dimm_stat_node_mem/numa_stat_memory_devices/ (Igor Mammedov)
- rewrite numa_stat_memory_devices as Igor's suggestion, and this will also fix 
compile
   error for targets that don't support memory hotplug
  v3:
- cold-plugged memory should not be excluded (Igor Mammedov)
  v2:
- Don't modify the numa_info.node_mem directly when treating hotplug memory,
   fix the "info numa" instead (Igor Mammedov)

Thanks for review!;)
---
  include/sysemu/sysemu.h |  1 +
  monitor.c   |  6 +-
  numa.c  | 43 +++
  3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index d8539fd..cfc1592 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -160,6 +160,7 @@ typedef struct node_info {
  extern NodeInfo numa_info[MAX_NODES];
  void set_numa_nodes(void);
  void set_numa_modes(void);
+int query_numa_node_mem(uint64_t *node_mem);
  extern QemuOptsList qemu_numa_opts;
  int numa_init_func(QemuOpts *opts, void *opaque);

diff --git a/monitor.c b/monitor.c
index 2d14f39..d45b0a3 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1949,7 +1949,10 @@ static void do_info_numa(Monitor *mon, const QDict 
*qdict)
  {
  int i;
  CPUState *cpu;
+uint64_t *node_mem;

+node_mem = g_new0(uint64_t, nb_numa_nodes);
+query_numa_node_mem(node_mem);
  monitor_printf(mon, "%d nodes\n", nb_numa_nodes);
  for (i = 0; i < nb_numa_nodes; i++) {
  monitor_printf(mon, "node %d cpus:", i);
@@ -1960,8 +1963,9 @@ static void do_info_numa(Monitor *mon, const QDict *qdict)
  }
  monitor_printf(mon, "\n");
  monitor_printf(mon, "node %d size: %" PRId64 " MB\n", i,
-numa_info[i].node_mem >> 20);
+   node_mem[i] >> 20);
  }
+g_free(node_mem);
  }

  #ifdef CONFIG_PROFILER
diff --git a/numa.c b/numa.c
index 3b98135..f8ea327 100644
--- a/numa.c
+++ b/numa.c
@@ -35,6 +35,7 @@
  #include "hw/boards.h"
  #include "sysemu/hostmem.h"
  #include "qmp-commands.h"
+#include "hw/mem/pc-dimm.h"

  QemuOptsList qemu_numa_opts = {
  .name = "numa",
@@ -315,6 +316,48 @@ void memory_region_allocate_system_memory(MemoryRegion 
*mr, Object *owner,
  }
  }

+static void numa_stat_memory_devices(uint64_t *node_mem)
+{
+MemoryDeviceInfoList *info_list = NULL;
+MemoryDeviceInfoList **prev = &info_list;
+MemoryDeviceInfoList *info;
+
+qmp_pc_dimm_device_list(qdev_get_machine(), &prev);
+for (info = info_list; info; info = info->next) {
+MemoryDeviceInfo *value = info->value;
+
+if (value) {
+switch (value->kind) {
+case MEMORY_DEVICE_INFO_KIND_DIMM:{
+PCDIMMDeviceInfo *di = value->dimm;
+
+node_mem[di->node] += di->size;
+break;
+}
+default:
+break;
+}
+}
+}
+
+qapi_free_MemoryDeviceInfoList(info_list);
+}
+
+int query_numa_node_mem(uint64_t *node_mem)
+{
+int i;
+
+if (nb_numa_nodes <= 0) {
+return 0;
+}
+
+numa_stat_memory_devices(node_mem);
+for (i = 0; i < nb_numa_nodes; i++) {
+node_mem[i] += numa_info[i].node_mem;
+}
+return 0;
+}
+
  static int query_memdev(Object *obj, void *opaque)
  {
  MemdevList **list = opaque;







[Qemu-devel] [PATCH v3 0/2] Xen: Use ioreq-server API

2014-10-15 Thread Paul Durrant
This patch series is v3 of what was originally the single patch
"Xen: Use the ioreq-server API when available".

v2 of the series moved the code that added the PCI bus listener
to patch #1 and the remainder of the changes to patch #2. Patch #2
was then re-worked to constrain the #ifdefing to xen_common.h, as
requested by Stefano.

v3 of the series modifies patch #1 to add the listener interface
into the core qdev, rather than the PCI bus code. This change only
requires trivial modification to patch #2, to only act on realize/
unrealize of PCI devices. Patch #2 was also modified at Stefano's
request to remove an extra identity check of memory sections
against the ram region.




[Qemu-devel] [PULL 2/2] hw/display/vga: Remove unused arrays dmask4 and dmask16

2014-10-15 Thread Gerd Hoffmann
From: Peter Maydell 

Following cleanup of the vga device code in commit d2e043a8041,
the arrays dmask4 and dmask16 are now unused. gcc doesn't warn
about this, but clang does; remove them.

Signed-off-by: Peter Maydell 
Reviewed-by: David Gibson 
Signed-off-by: Gerd Hoffmann 
---
 hw/display/vga.c | 26 --
 1 file changed, 26 deletions(-)

diff --git a/hw/display/vga.c b/hw/display/vga.c
index 19e7f23..52eaf05 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -136,32 +136,6 @@ static const uint32_t mask16[16] = {
 #define PAT(x) cbswap_32(x)
 #endif
 
-static const uint32_t dmask16[16] = {
-PAT(0x),
-PAT(0x00ff),
-PAT(0xff00),
-PAT(0x),
-PAT(0x00ff),
-PAT(0x00ff00ff),
-PAT(0x0000),
-PAT(0x00ff),
-PAT(0xff00),
-PAT(0xffff),
-PAT(0xff00ff00),
-PAT(0xff00),
-PAT(0x),
-PAT(0x00ff),
-PAT(0xff00),
-PAT(0x),
-};
-
-static const uint32_t dmask4[4] = {
-PAT(0x),
-PAT(0x),
-PAT(0x),
-PAT(0x),
-};
-
 static uint32_t expand4[256];
 static uint16_t expand2[256];
 static uint8_t expand4to8[16];
-- 
1.8.3.1




[Qemu-devel] [PULL 0/2] vga patch queue

2014-10-15 Thread Gerd Hoffmann
  Hi,

vga patch queue with two patches, one deleting some unused bits and one
adding the qext region to stdvga mmio to allow switching vga framebuffer
endianess (needed for ppc64le).

please pull,
  Gerd

The following changes since commit b1d28ec6a7dbdaadda39d29322f0de694aeb0b74:

  Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20141010' into 
staging (2014-10-10 14:55:29 +0100)

are available in the git repository at:


  git://git.kraxel.org/qemu tags/pull-vga-20141015-1

for you to fetch changes up to 98792325435d8b46f2035eb93fa02373c7ceda44:

  hw/display/vga: Remove unused arrays dmask4 and dmask16 (2014-10-15 11:10:50 
+0200)


vga-pci: add qext region to mmio
vga: Remove unused arrays dmask4 and dmask16


Gerd Hoffmann (1):
  vga-pci: add qext region to mmio

Peter Maydell (1):
  hw/display/vga: Remove unused arrays dmask4 and dmask16

 docs/specs/standard-vga.txt |  9 ++
 hw/display/vga-pci.c| 70 +
 hw/display/vga.c| 26 -
 include/hw/i386/pc.h|  8 ++
 4 files changed, 87 insertions(+), 26 deletions(-)



[Qemu-devel] [PULL 1/2] vga-pci: add qext region to mmio

2014-10-15 Thread Gerd Hoffmann
Add a qemu extented register range to the standard vga mmio bar.
Right nowe there are two registers:  One readonly register returning the
size of the region (so we can easily add more registers there if needed)
and one endian control register, so guests (especially ppc) can flip
the framebuffer endianness as they need it.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: David Gibson 
---
 docs/specs/standard-vga.txt |  9 ++
 hw/display/vga-pci.c| 70 +
 include/hw/i386/pc.h|  8 ++
 3 files changed, 87 insertions(+)

diff --git a/docs/specs/standard-vga.txt b/docs/specs/standard-vga.txt
index f82773e..19d2a74 100644
--- a/docs/specs/standard-vga.txt
+++ b/docs/specs/standard-vga.txt
@@ -70,3 +70,12 @@ Likewise applies to the pci variant only for obvious reasons.
 0500 - 0515 : bochs dispi interface registers, mapped flat
   without index/data ports.  Use (index << 1)
   as offset for (16bit) register access.
+
+0600 - 0607 : qemu extended registers.  qemu 2.2+ only.
+  The pci revision is 2 (or greater) when
+  these registers are present.  The registers
+  are 32bit.
+  0600  : qemu extended register region size, in bytes.
+  0604  : framebuffer endianness register.
+  - 0xbebebebe indicates big endian.
+  - 0x1e1e1e1e indicates little endian.
diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c
index 0351d94..db922f1 100644
--- a/hw/display/vga-pci.c
+++ b/hw/display/vga-pci.c
@@ -35,10 +35,18 @@
 #define PCI_VGA_IOPORT_SIZE   (0x3e0 - 0x3c0)
 #define PCI_VGA_BOCHS_OFFSET  0x500
 #define PCI_VGA_BOCHS_SIZE(0x0b * 2)
+#define PCI_VGA_QEXT_OFFSET   0x600
+#define PCI_VGA_QEXT_SIZE (2 * 4)
 #define PCI_VGA_MMIO_SIZE 0x1000
 
+#define PCI_VGA_QEXT_REG_SIZE (0 * 4)
+#define PCI_VGA_QEXT_REG_BYTEORDER(1 * 4)
+#define  PCI_VGA_QEXT_LITTLE_ENDIAN   0x1e1e1e1e
+#define  PCI_VGA_QEXT_BIG_ENDIAN  0xbebebebe
+
 enum vga_pci_flags {
 PCI_VGA_FLAG_ENABLE_MMIO = 1,
+PCI_VGA_FLAG_ENABLE_QEXT = 2,
 };
 
 typedef struct PCIVGAState {
@@ -48,6 +56,7 @@ typedef struct PCIVGAState {
 MemoryRegion mmio;
 MemoryRegion ioport;
 MemoryRegion bochs;
+MemoryRegion qext;
 } PCIVGAState;
 
 static const VMStateDescription vmstate_vga_pci = {
@@ -140,6 +149,46 @@ static const MemoryRegionOps pci_vga_bochs_ops = {
 .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
+static uint64_t pci_vga_qext_read(void *ptr, hwaddr addr, unsigned size)
+{
+PCIVGAState *d = ptr;
+
+switch (addr) {
+case PCI_VGA_QEXT_REG_SIZE:
+return PCI_VGA_QEXT_SIZE;
+case PCI_VGA_QEXT_REG_BYTEORDER:
+return d->vga.big_endian_fb ?
+PCI_VGA_QEXT_BIG_ENDIAN : PCI_VGA_QEXT_LITTLE_ENDIAN;
+default:
+return 0;
+}
+}
+
+static void pci_vga_qext_write(void *ptr, hwaddr addr,
+   uint64_t val, unsigned size)
+{
+PCIVGAState *d = ptr;
+
+switch (addr) {
+case PCI_VGA_QEXT_REG_BYTEORDER:
+if (val == PCI_VGA_QEXT_BIG_ENDIAN) {
+d->vga.big_endian_fb = true;
+}
+if (val == PCI_VGA_QEXT_LITTLE_ENDIAN) {
+d->vga.big_endian_fb = false;
+}
+break;
+}
+}
+
+static const MemoryRegionOps pci_vga_qext_ops = {
+.read = pci_vga_qext_read,
+.write = pci_vga_qext_write,
+.valid.min_access_size = 4,
+.valid.max_access_size = 4,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static int pci_std_vga_initfn(PCIDevice *dev)
 {
 PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
@@ -167,6 +216,15 @@ static int pci_std_vga_initfn(PCIDevice *dev)
 &d->ioport);
 memory_region_add_subregion(&d->mmio, PCI_VGA_BOCHS_OFFSET,
 &d->bochs);
+
+if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_QEXT)) {
+memory_region_init_io(&d->qext, NULL, &pci_vga_qext_ops, d,
+  "qemu extended regs", PCI_VGA_QEXT_SIZE);
+memory_region_add_subregion(&d->mmio, PCI_VGA_QEXT_OFFSET,
+&d->qext);
+pci_set_byte(&d->dev.config[PCI_REVISION_ID], 2);
+}
+
 pci_register_bar(&d->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
 }
 
@@ -199,6 +257,14 @@ static int pci_secondary_vga_initfn(PCIDevice *dev)
 memory_region_add_subregion(&d->mmio, PCI_VGA_BOCHS_OFFSET,
 &d->bochs);
 
+if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_QEXT)) {
+memory_region_init_io(&d->qext, NULL, &pci_vga_qext_ops, d,
+  "qemu extended regs", PCI_VGA_QEXT_SIZE);
+memory_region_add_subregion(&d->mmio, PCI_VGA_QEXT_OFFSET,
+&d->qext);
+pci_set_byte(&d->dev.config[PCI_REVISION_ID], 2);
+}
+
 pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PR

Re: [Qemu-devel] [Qemu-trivial] [PATCH v2] libvixl: a64: Skip "-Wunused-variable" for gcc 5.0.0 or higher

2014-10-15 Thread Chen Gang
On 10/15/14 4:47, Chen Gang wrote:
> On 10/15/2014 03:58 AM, Michael Tokarev wrote:
>>
>> That's what I'm after too (after trying to fix it properly).
>> And no, at this time I dont know how gcc5 handles this.
>>
> 
> At present, I have sent the related information to gcc upstream mailing
> list for gcc5, we are just discussing about it.
> 
>  - Some gcc members stick to what gcc5 has done is correct (need still
>report warning).
> 
>  - But for me, I am just trying to get another gcc members' confirmation.
>I am not quite familiar with C++, for me it is a complex language, so
>I need additional confirmation by another gcc members, at least.
> 

After consult the gcc related members, we are sure what gcc has done is
correct, and need process this warning in our qemu or 'libvixl'.

The related mail is below:


 Forwarded Message 
Subject: Re: [Consult] g++: About "-Wunused-variable" for constant variable in 
header file
Date: Wed, 15 Oct 2014 10:18:44 +0100
From: Jonathan Wakely 
To: Chen Gang 
CC: gcc-help , Jeff Law , Peter Maydell 


On 14 October 2014 22:57, Chen Gang  wrote:
> Hello All:
>
> At present, I met one warning issue about gcc 5.0.0.
>
>  - For "const float a = 3.4 - 2.1 / 3;", if it is unused, gcc5 will not
>report warning.

Because there is no cost to initializing the variable.

>  - "const char n() {return 1;}; const a = n();", if 'a' is unused, gcc5
>will report warning.

Because it requires dynamic initialization, running a function at
startup, which has a cost. If you don't use the variable then you
might not want to run the initialization code at startup, so you get a
warning.

> For gcc old version (e.g. gcc4), it will not report warning. Is it the
> new feature for gcc5, or just a gcc5's bug?

I think this behaviour is intended and is not a bug.




-- 
Chen Gang

Open, share, and attitude like air, water, and life which God blessed



[Qemu-devel] [PATCH] sparse: fix build

2014-10-15 Thread Gerd Hoffmann
c++ compiler isn't wrapped with cgcc, resulting in gcc complaining about
the sparse compiler flags which it doesn't know in case qemu is built
with --enable-sparse.

Signed-off-by: Gerd Hoffmann 
---
 configure | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configure b/configure
index 9ac2600..90349f3 100755
--- a/configure
+++ b/configure
@@ -4908,6 +4908,7 @@ echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak
 echo "QEMU_INCLUDES=$QEMU_INCLUDES" >> $config_host_mak
 if test "$sparse" = "yes" ; then
   echo "CC   := REAL_CC=\"\$(CC)\" cgcc"   >> $config_host_mak
+  echo "CXX  := REAL_CC=\"\$(CXX)\" cgcc"  >> $config_host_mak
   echo "HOST_CC  := REAL_CC=\"\$(HOST_CC)\" cgcc"  >> $config_host_mak
   echo "QEMU_CFLAGS  += -Wbitwise -Wno-transparent-union -Wno-old-initializer 
-Wno-non-pointer-null" >> $config_host_mak
 fi
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH v3 1/2] Add device listener interface

2014-10-15 Thread Igor Mammedov
On Wed, 15 Oct 2014 10:16:38 +0100
Paul Durrant  wrote:

> The Xen ioreq-server API, introduced in Xen 4.5, requires that PCI
> device models explicitly register with Xen for config space accesses.
> This patch adds a listener interface into qdev-core which can be used
> by the Xen interface code to monitor for arrival and departure of PCI
> devices.

If you need only one listener handler for your case, why you couldn't
use hotplug interface instead of listerners?
to me it looks like it should work for this case.
To make it work xen code would need to override default plug/unplug
handlers on PCI bus and do register/unregister from there.

One thing is that unplug handler is not defined for PCI bus yet,
to get it work one would need to refactor pcihp/bridge/pcie unplug
path to call unplug handler before object_unparent().


> 
> Signed-off-by: Paul Durrant 
> Cc: Michael S. Tsirkin 
> Cc: Andreas Faerber" 
> Cc: Paolo Bonzini 
> Cc: Peter Crosthwaite 
> Cc: Igor Mammedov 
> Cc: Markus Armbruster 
> Cc: Thomas Huth 
> Cc: Christian Borntraeger 
> ---
>  hw/core/qdev.c  |   54
> +++
> include/hw/qdev-core.h  |   10 + include/qemu/typedefs.h |
> 1 + 3 files changed, 65 insertions(+)
> 
> diff --git a/hw/core/qdev.c b/hw/core/qdev.c
> index fcb1638..4a9c1f6 100644
> --- a/hw/core/qdev.c
> +++ b/hw/core/qdev.c
> @@ -175,6 +175,56 @@ int qdev_init(DeviceState *dev)
>  return 0;
>  }
>  
> +static QTAILQ_HEAD(qdev_listeners, DeviceListener) qdev_listeners
> += QTAILQ_HEAD_INITIALIZER(qdev_listeners);
> +
> +enum ListenerDirection { Forward, Reverse };
> +
> +#define QDEV_LISTENER_CALL(_callback, _direction, _args...) \
> +do {\
> +DeviceListener *_listener;  \
> +\
> +switch (_direction) {   \
> +case Forward:   \
> +QTAILQ_FOREACH(_listener, &qdev_listeners, link) {  \
> +if (_listener->_callback) { \
> +_listener->_callback(_listener, ##_args);   \
> +}   \
> +}   \
> +break;  \
> +case Reverse:   \
> +QTAILQ_FOREACH_REVERSE(_listener, &qdev_listeners,  \
> +   qdev_listeners, link) {  \
> +if (_listener->_callback) { \
> +_listener->_callback(_listener, ##_args);   \
> +}   \
> +}   \
> +break;  \
> +default:\
> +abort();\
> +}   \
> +} while (0)
> +
> +static int qdev_listener_add(DeviceState *dev, void *opaque)
> +{
> +QDEV_LISTENER_CALL(realize, Forward, dev);
> +
> +return 0;
> +}
> +
> +void qdev_listener_register(DeviceListener *listener)
> +{
> +QTAILQ_INSERT_TAIL(&qdev_listeners, listener, link);
> +
> +qbus_walk_children(sysbus_get_default(), NULL, NULL,
> qdev_listener_add,
> +   NULL, NULL);
> +}
> +
> +void qdev_listener_unregister(DeviceListener *listener)
> +{
> +QTAILQ_REMOVE(&qdev_listeners, listener, link);
> +}
> +
>  static void device_realize(DeviceState *dev, Error **errp)
>  {
>  DeviceClass *dc = DEVICE_GET_CLASS(dev);
> @@ -186,12 +236,16 @@ static void device_realize(DeviceState *dev,
> Error **errp) return;
>  }
>  }
> +
> +QDEV_LISTENER_CALL(realize, Forward, dev);
>  }
>  
>  static void device_unrealize(DeviceState *dev, Error **errp)
>  {
>  DeviceClass *dc = DEVICE_GET_CLASS(dev);
>  
> +QDEV_LISTENER_CALL(unrealize, Reverse, dev);
> +
>  if (dc->exit) {
>  int rc = dc->exit(dev);
>  if (rc < 0) {
> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> index 178fee2..f2dc267 100644
> --- a/include/hw/qdev-core.h
> +++ b/include/hw/qdev-core.h
> @@ -167,6 +167,12 @@ struct DeviceState {
>  int alias_required_for_version;
>  };
>  
> +struct DeviceListener {
> +void (*realize)(DeviceListener *listener, DeviceState *dev);
> +void (*unrealize)(DeviceListener *listener, DeviceState *dev);
> +QTAILQ_ENTRY(DeviceListener) link;
> +};
> +
>  #define TYPE_BUS "bus"
>  #define BUS(obj) OBJECT_CHECK(BusState, (obj), TYPE_BUS)
>  #define BUS_CLASS(klass) OBJECT_CLASS_CHECK(BusClass, (klass),
> TYPE_BUS) @@ -368,4 +374,8 @@ static inli

[Qemu-devel] [PULL 01/28] target-mips: define ISA_MIPS64R6

2014-10-15 Thread Leon Alrae
Signed-off-by: Leon Alrae 
Reviewed-by: Aurelien Jarno 
---
 target-mips/mips-defs.h | 28 +++-
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h
index 9dfa516..6cb62b2 100644
--- a/target-mips/mips-defs.h
+++ b/target-mips/mips-defs.h
@@ -30,17 +30,21 @@
 #defineISA_MIPS64  0x0080
 #defineISA_MIPS64R20x0100
 #define   ISA_MIPS32R3  0x0200
-#define   ISA_MIPS32R5  0x0400
+#define   ISA_MIPS64R3  0x0400
+#define   ISA_MIPS32R5  0x0800
+#define   ISA_MIPS64R5  0x1000
+#define   ISA_MIPS32R6  0x2000
+#define   ISA_MIPS64R6  0x4000
 
 /* MIPS ASEs. */
-#defineASE_MIPS16  0x1000
-#defineASE_MIPS3D  0x2000
-#defineASE_MDMX0x4000
-#defineASE_DSP 0x8000
-#defineASE_DSPR2   0x0001
-#defineASE_MT  0x0002
-#defineASE_SMARTMIPS   0x0004
-#defineASE_MICROMIPS   0x0008
+#define   ASE_MIPS160x0001
+#define   ASE_MIPS3D0x0002
+#define   ASE_MDMX  0x0004
+#define   ASE_DSP   0x0008
+#define   ASE_DSPR2 0x0010
+#define   ASE_MT0x0020
+#define   ASE_SMARTMIPS 0x0040
+#define   ASE_MICROMIPS 0x0080
 
 /* Chip specific instructions. */
 #defineINSN_LOONGSON2E  0x2000
@@ -68,9 +72,15 @@
 
 /* MIPS Technologies "Release 3" */
 #define CPU_MIPS32R3 (CPU_MIPS32R2 | ISA_MIPS32R3)
+#define CPU_MIPS64R3 (CPU_MIPS64R2 | CPU_MIPS32R3 | ISA_MIPS64R3)
 
 /* MIPS Technologies "Release 5" */
 #define CPU_MIPS32R5 (CPU_MIPS32R3 | ISA_MIPS32R5)
+#define CPU_MIPS64R5 (CPU_MIPS64R3 | CPU_MIPS32R5 | ISA_MIPS64R5)
+
+/* MIPS Technologies "Release 6" */
+#define CPU_MIPS32R6 (CPU_MIPS32R5 | ISA_MIPS32R6)
+#define CPU_MIPS64R6 (CPU_MIPS64R5 | CPU_MIPS32R6 | ISA_MIPS64R6)
 
 /* Strictly follow the architecture standard:
- Disallow "special" instruction handling for PMON/SPIM.
-- 
2.1.0




[Qemu-devel] [PULL 00/28] target-mips queue

2014-10-15 Thread Leon Alrae
Hi,

This pull request has been assembled from pending target-mips patches which
look good to me and received in my opinion sufficient review comments. They
were tested mainly in context of MIPS. Please have a look and pull.

Thanks,
Leon

Cc: Peter Maydell 
Cc: Aurelien Jarno 

The following changes since commit b1d28ec6a7dbdaadda39d29322f0de694aeb0b74:

  Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20141010' into 
staging (2014-10-10 14:55:29 +0100)

are available in the git repository at:

  git://github.com/lalrae/qemu.git tags/mips-20141015

for you to fetch changes up to 340fff722d8a7cf9c0d4f1e1b4fad03a145a9657:

  target-mips: Remove unused gen_load_ACX, gen_store_ACX and cpu_ACX 
(2014-10-14 13:29:15 +0100)


MIPS patches 2014-10-15

Changes:
* MIPS64R6 (unprivileged) support
* fix for broken MIPS16 and microMIPS
* SYNCI improvement
* unused MIPS code removal


Dongxue Zhang (1):
  target-mips/translate.c: Update OPC_SYNCI

Leon Alrae (17):
  target-mips: define ISA_MIPS64R6
  target-mips: signal RI Exception on instructions removed in R6
  target-mips: add SELEQZ and SELNEZ instructions
  target-mips: move LL and SC instructions
  target-mips: extract decode_opc_special* from decode_opc
  target-mips: split decode_opc_special* into *_r6 and *_legacy
  target-mips: signal RI Exception on DSP and Loongson instructions
  target-mips: move PREF, CACHE, LLD and SCD instructions
  target-mips: redefine Integer Multiply and Divide instructions
  target-mips: move CLO, DCLO, CLZ, DCLZ, SDBBP and free special2 in R6
  target-mips: Status.UX/SX/KX enable 32-bit address wrapping
  target-mips: add AUI, LSA and PCREL instruction families
  softfloat: add functions corresponding to IEEE-2008 min/maxNumMag
  target-mips: add new Floating Point instructions
  target-mips: do not allow Status.FR=0 mode in 64-bit FPU
  mips_malta: update malta's pseudo-bootloader - replace JR with JALR
  target-mips: define a new generic CPU supporting MIPS64 Release 6 ISA

Peter Maydell (5):
  target-mips/dsp_helper.c: Remove unused function get_DSPControl_24()
  target-mips/op_helper.c: Remove unused do_lbu() function
  target-mips/translate.c: Add ifdef guard around check_mips64()
  target-mips/dsp_helper.c: Add ifdef guards around various functions
  target-mips: Remove unused gen_load_ACX, gen_store_ACX and cpu_ACX

Yongbok Kim (5):
  target-mips: add ALIGN, DALIGN, BITSWAP and DBITSWAP instructions
  target-mips: add compact and CP1 branches
  target-mips: add new Floating Point Comparison instructions
  target-mips: remove JR, BLTZAL, BGEZAL and add NAL, BAL instructions
  target-mips: fix broken MIPS16 and microMIPS

 disas/mips.c |  211 ++-
 fpu/softfloat.c  |   37 +-
 hw/mips/mips_malta.c |   10 +-
 include/fpu/softfloat.h  |4 +
 target-mips/cpu.h|   31 +-
 target-mips/dsp_helper.c |   26 +-
 target-mips/helper.h |   52 +
 target-mips/mips-defs.h  |   28 +-
 target-mips/op_helper.c  |  239 ++-
 target-mips/translate.c  | 4114 ++
 target-mips/translate_init.c |   30 +
 11 files changed, 3563 insertions(+), 1219 deletions(-)



[Qemu-devel] [PULL 03/28] target-mips: add SELEQZ and SELNEZ instructions

2014-10-15 Thread Leon Alrae
Signed-off-by: Leon Alrae 
Reviewed-by: Aurelien Jarno 
Reviewed-by: James Hogan 
---
 disas/mips.c|  8 
 target-mips/translate.c | 18 --
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/disas/mips.c b/disas/mips.c
index 2106b57..b950e53 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -521,6 +521,8 @@ struct mips_opcode
 #define INSN_ISA640x0040
 #define INSN_ISA32R2  0x0080
 #define INSN_ISA64R2  0x0100
+#define INSN_ISA32R6  0x0200
+#define INSN_ISA64R6  0x0400
 
 /* Masks used for MIPS-defined ASEs.  */
 #define INSN_ASE_MASK0xf000
@@ -585,6 +587,8 @@ struct mips_opcode
 #define   ISA_MIPS32R2(ISA_MIPS32 | INSN_ISA32R2)
 #define   ISA_MIPS64R2(ISA_MIPS64 | INSN_ISA32R2 | INSN_ISA64R2)
 
+#define   ISA_MIPS32R6(ISA_MIPS32R2 | INSN_ISA32R6)
+#define   ISA_MIPS64R6(ISA_MIPS64R2 | INSN_ISA32R6 | INSN_ISA64R6)
 
 /* CPU defines, use instead of hardcoding processor number. Keep this
in sync with bfd/archures.c in order for machine selection to work.  */
@@ -1121,6 +1125,8 @@ extern const int bfd_mips16_num_opcodes;
 #define I64 INSN_ISA64
 #define I33INSN_ISA32R2
 #define I65INSN_ISA64R2
+#define I32R6   INSN_ISA32R6
+#define I64R6   INSN_ISA64R6
 
 /* MIPS64 MIPS-3D ASE support.  */
 #define I16 INSN_MIPS16
@@ -1209,6 +1215,8 @@ const struct mips_opcode mips_builtin_opcodes[] =
them first.  The assemblers uses a hash table based on the
instruction name anyhow.  */
 /* name,args,  match,  mask,   pinfo,  
membership */
+{"seleqz",  "d,v,t",0x0035, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
+{"selnez",  "d,v,t",0x0037, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
 {"pref","k,o(b)",   0xcc00, 0xfc00, RD_b,  0,  
I4|I32|G3   },
 {"prefx",   "h,t(b)",  0x4c0f, 0xfc0007ff, RD_b|RD_t,  0,  
I4|I33  },
 {"nop", "", 0x, 0x, 0, 
INSN2_ALIAS,I1  }, /* sll */
diff --git a/target-mips/translate.c b/target-mips/translate.c
index de11747..ba9daac 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -193,6 +193,9 @@ enum {
 OPC_MOVZ = 0x0A | OPC_SPECIAL,
 OPC_MOVN = 0x0B | OPC_SPECIAL,
 
+OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
+OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
+
 OPC_MOVCI= 0x01 | OPC_SPECIAL,
 
 /* Special */
@@ -205,8 +208,6 @@ enum {
 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
-OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
-OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
 };
@@ -2412,6 +2413,14 @@ static void gen_cond_move(DisasContext *ctx, uint32_t 
opc,
 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
 opn = "movz";
 break;
+case OPC_SELNEZ:
+tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
+opn = "selnez";
+break;
+case OPC_SELEQZ:
+tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
+opn = "seleqz";
+break;
 }
 tcg_temp_free(t2);
 tcg_temp_free(t1);
@@ -14533,6 +14542,11 @@ static void decode_opc (CPUMIPSState *env, 
DisasContext *ctx)
  INSN_LOONGSON2E | INSN_LOONGSON2F);
 gen_cond_move(ctx, op1, rd, rs, rt);
 break;
+case OPC_SELEQZ:
+case OPC_SELNEZ:
+check_insn(ctx, ISA_MIPS32R6);
+gen_cond_move(ctx, op1, rd, rs, rt);
+break;
 case OPC_ADD ... OPC_SUBU:
 gen_arith(ctx, op1, rd, rs, rt);
 break;
-- 
2.1.0




[Qemu-devel] [PULL 08/28] target-mips: move PREF, CACHE, LLD and SCD instructions

2014-10-15 Thread Leon Alrae
The encoding of PREF, CACHE, LLD and SCD instruction changed in MIPS32R6.
Additionally, the hint codes in PREF instruction greater than or
equal to 24 generate Reserved Instruction Exception.

Signed-off-by: Leon Alrae 
Reviewed-by: Aurelien Jarno 
---
 disas/mips.c|  4 
 target-mips/translate.c | 29 -
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/disas/mips.c b/disas/mips.c
index f0efa8b..cae76ed 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -1219,6 +1219,10 @@ const struct mips_opcode mips_builtin_opcodes[] =
 /* name,args,  match,  mask,   pinfo,  
membership */
 {"ll",  "t,o(b)",   0x7c36, 0xfc7f, LDD|RD_b|WR_t,0, 
I32R6},
 {"sc",  "t,o(b)",   0x7c26, 0xfc7f, LDD|RD_b|WR_t,0, 
I32R6},
+{"lld", "t,o(b)",   0x7c37, 0xfc7f, LDD|RD_b|WR_t,0, 
I64R6},
+{"scd", "t,o(b)",   0x7c27, 0xfc7f, LDD|RD_b|WR_t,0, 
I64R6},
+{"pref","h,o(b)",   0x7c35, 0xfc7f, RD_b, 0, 
I32R6},
+{"cache",   "k,o(b)",   0x7c25, 0xfc7f, RD_b, 0, 
I32R6},
 {"seleqz",  "d,v,t",0x0035, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
 {"selnez",  "d,v,t",0x0037, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
 {"pref","k,o(b)",   0xcc00, 0xfc00, RD_b,  0,  
I4|I32|G3   },
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 11967a0..f50d906 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -349,8 +349,12 @@ enum {
 OPC_DEXTR_W_DSP= 0x3C | OPC_SPECIAL3,
 
 /* R6 */
+R6_OPC_PREF= 0x35 | OPC_SPECIAL3,
+R6_OPC_CACHE   = 0x25 | OPC_SPECIAL3,
 R6_OPC_LL  = 0x36 | OPC_SPECIAL3,
 R6_OPC_SC  = 0x26 | OPC_SPECIAL3,
+R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
+R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
 };
 
 /* BSHFL opcodes */
@@ -1645,6 +1649,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
 opn = "ld";
 break;
 case OPC_LLD:
+case R6_OPC_LLD:
 save_cpu_state(ctx, 1);
 op_ld_lld(t0, t0, ctx);
 gen_store_gpr(t0, rt);
@@ -1867,6 +1872,7 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, 
int rt,
 switch (opc) {
 #if defined(TARGET_MIPS64)
 case OPC_SCD:
+case R6_OPC_SCD:
 save_cpu_state(ctx, 1);
 op_st_scd(t1, t0, rt, ctx);
 opn = "scd";
@@ -14866,12 +14872,30 @@ static void decode_opc_special3_r6(CPUMIPSState *env, 
DisasContext *ctx)
 
 op1 = MASK_SPECIAL3(ctx->opcode);
 switch (op1) {
+case R6_OPC_PREF:
+if (rt >= 24) {
+/* hint codes 24-31 are reserved and signal RI */
+generate_exception(ctx, EXCP_RI);
+}
+/* Treat as NOP. */
+break;
+case R6_OPC_CACHE:
+/* Treat as NOP. */
+break;
 case R6_OPC_SC:
 gen_st_cond(ctx, op1, rt, rs, imm);
 break;
 case R6_OPC_LL:
 gen_ld(ctx, op1, rt, rs, imm);
 break;
+#if defined(TARGET_MIPS64)
+case R6_OPC_SCD:
+gen_st_cond(ctx, op1, rt, rs, imm);
+break;
+case R6_OPC_LLD:
+gen_ld(ctx, op1, rt, rs, imm);
+break;
+#endif
 default:/* Invalid */
 MIPS_INVAL("special3_r6");
 generate_exception(ctx, EXCP_RI);
@@ -15686,11 +15710,13 @@ static void decode_opc (CPUMIPSState *env, 
DisasContext *ctx)
  gen_st_cond(ctx, op, rt, rs, imm);
  break;
 case OPC_CACHE:
+check_insn_opc_removed(ctx, ISA_MIPS32R6);
 check_cp0_enabled(ctx);
 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
 /* Treat as NOP. */
 break;
 case OPC_PREF:
+check_insn_opc_removed(ctx, ISA_MIPS32R6);
 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
 /* Treat as NOP. */
 break;
@@ -15813,9 +15839,9 @@ static void decode_opc (CPUMIPSState *env, DisasContext 
*ctx)
 #if defined(TARGET_MIPS64)
 /* MIPS64 opcodes */
 case OPC_LDL ... OPC_LDR:
+case OPC_LLD:
 check_insn_opc_removed(ctx, ISA_MIPS32R6);
 case OPC_LWU:
-case OPC_LLD:
 case OPC_LD:
 check_insn(ctx, ISA_MIPS3);
 check_mips_64(ctx);
@@ -15829,6 +15855,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext 
*ctx)
 gen_st(ctx, op, rt, rs, imm);
 break;
 case OPC_SCD:
+check_insn_opc_removed(ctx, ISA_MIPS32R6);
 check_insn(ctx, ISA_MIPS3);
 check_mips_64(ctx);
 gen_st_cond(ctx, op, rt, rs, imm);
-- 
2.1.0




[Qemu-devel] [PULL 11/28] target-mips: Status.UX/SX/KX enable 32-bit address wrapping

2014-10-15 Thread Leon Alrae
In R6 the special behaviour for data references is also specified for Kernel
and Supervisor mode. Therefore MIPS_HFLAG_UX is replaced by generic
MIPS_HFLAG_AWRAP indicating enabled 32-bit address wrapping.

Signed-off-by: Leon Alrae 
Reviewed-by: Aurelien Jarno 
---
 target-mips/cpu.h   | 18 ++
 target-mips/translate.c |  6 +-
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 8b9a92e..51a8331 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -450,7 +450,7 @@ struct CPUMIPSState {
and RSQRT.D.  */
 #define MIPS_HFLAG_COP1X  0x00080 /* COP1X instructions enabled */
 #define MIPS_HFLAG_RE 0x00100 /* Reversed endianness*/
-#define MIPS_HFLAG_UX 0x00200 /* 64-bit user mode   */
+#define MIPS_HFLAG_AWRAP  0x00200 /* 32-bit compatibility address wrapping */
 #define MIPS_HFLAG_M160x00400 /* MIPS16 mode flag   */
 #define MIPS_HFLAG_M16_SHIFT 10
 /* If translation is interrupted between the branch instruction and
@@ -725,7 +725,7 @@ static inline void compute_hflags(CPUMIPSState *env)
 {
 env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
  MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
- MIPS_HFLAG_UX | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2);
+ MIPS_HFLAG_AWRAP | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2);
 if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
 !(env->CP0_Status & (1 << CP0St_ERL)) &&
 !(env->hflags & MIPS_HFLAG_DM)) {
@@ -737,8 +737,18 @@ static inline void compute_hflags(CPUMIPSState *env)
 (env->CP0_Status & (1 << CP0St_UX))) {
 env->hflags |= MIPS_HFLAG_64;
 }
-if (env->CP0_Status & (1 << CP0St_UX)) {
-env->hflags |= MIPS_HFLAG_UX;
+
+if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
+!(env->CP0_Status & (1 << CP0St_UX))) {
+env->hflags |= MIPS_HFLAG_AWRAP;
+} else if (env->insn_flags & ISA_MIPS32R6) {
+/* Address wrapping for Supervisor and Kernel is specified in R6 */
+if env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_SM) &&
+ !(env->CP0_Status & (1 << CP0St_SX))) ||
+(((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_KM) &&
+ !(env->CP0_Status & (1 << CP0St_KX {
+env->hflags |= MIPS_HFLAG_AWRAP;
+}
 }
 #endif
 if ((env->CP0_Status & (1 << CP0St_CU0)) ||
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 34d63ea..7420485 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -1383,11 +1383,7 @@ static inline void gen_op_addr_add (DisasContext *ctx, 
TCGv ret, TCGv arg0, TCGv
 tcg_gen_add_tl(ret, arg0, arg1);
 
 #if defined(TARGET_MIPS64)
-/* For compatibility with 32-bit code, data reference in user mode
-   with Status_UX = 0 should be casted to 32-bit and sign extended.
-   See the MIPS64 PRA manual, section 4.10. */
-if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
-!(ctx->hflags & MIPS_HFLAG_UX)) {
+if (ctx->hflags & MIPS_HFLAG_AWRAP) {
 tcg_gen_ext32s_i64(ret, ret);
 }
 #endif
-- 
2.1.0




[Qemu-devel] [PULL 05/28] target-mips: extract decode_opc_special* from decode_opc

2014-10-15 Thread Leon Alrae
Creating separate decode functions for special, special2 and special3
instructions to ease adding new R6 instructions and removing legacy
instructions.

Signed-off-by: Leon Alrae 
Reviewed-by: Aurelien Jarno 
---
 target-mips/translate.c | 1678 ---
 1 file changed, 859 insertions(+), 819 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 8606f32..5b8f762 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -14482,911 +14482,950 @@ static void gen_mipsdsp_accinsn(DisasContext *ctx, 
uint32_t op1, uint32_t op2,
 
 /* End MIPSDSP functions. */
 
-static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
+static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
 {
-int32_t offset;
 int rs, rt, rd, sa;
-uint32_t op, op1, op2;
-int16_t imm;
-
-/* make sure instructions are on a word boundary */
-if (ctx->pc & 0x3) {
-env->CP0_BadVAddr = ctx->pc;
-generate_exception(ctx, EXCP_AdEL);
-return;
-}
-
-/* Handle blikely not taken case */
-if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
-int l1 = gen_new_label();
-
-MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
-tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
-tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
-gen_goto_tb(ctx, 1, ctx->pc + 4);
-gen_set_label(l1);
-}
-
-if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
-tcg_gen_debug_insn_start(ctx->pc);
-}
+uint32_t op1;
 
-op = MASK_OP_MAJOR(ctx->opcode);
 rs = (ctx->opcode >> 21) & 0x1f;
 rt = (ctx->opcode >> 16) & 0x1f;
 rd = (ctx->opcode >> 11) & 0x1f;
 sa = (ctx->opcode >> 6) & 0x1f;
-imm = (int16_t)ctx->opcode;
-switch (op) {
-case OPC_SPECIAL:
-op1 = MASK_SPECIAL(ctx->opcode);
-switch (op1) {
-case OPC_SLL:  /* Shift with immediate */
-case OPC_SRA:
-gen_shift_imm(ctx, op1, rd, rt, sa);
-break;
-case OPC_SRL:
-switch ((ctx->opcode >> 21) & 0x1f) {
-case 1:
-/* rotr is decoded as srl on non-R2 CPUs */
-if (ctx->insn_flags & ISA_MIPS32R2) {
-op1 = OPC_ROTR;
-}
-/* Fallthrough */
-case 0:
-gen_shift_imm(ctx, op1, rd, rt, sa);
-break;
-default:
-generate_exception(ctx, EXCP_RI);
-break;
+
+op1 = MASK_SPECIAL(ctx->opcode);
+switch (op1) {
+case OPC_SLL:  /* Shift with immediate */
+case OPC_SRA:
+gen_shift_imm(ctx, op1, rd, rt, sa);
+break;
+case OPC_SRL:
+switch ((ctx->opcode >> 21) & 0x1f) {
+case 1:
+/* rotr is decoded as srl on non-R2 CPUs */
+if (ctx->insn_flags & ISA_MIPS32R2) {
+op1 = OPC_ROTR;
 }
+/* Fallthrough */
+case 0:
+gen_shift_imm(ctx, op1, rd, rt, sa);
 break;
-case OPC_MOVN: /* Conditional move */
-case OPC_MOVZ:
-check_insn_opc_removed(ctx, ISA_MIPS32R6);
-check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
- INSN_LOONGSON2E | INSN_LOONGSON2F);
-gen_cond_move(ctx, op1, rd, rs, rt);
-break;
-case OPC_SELEQZ:
-case OPC_SELNEZ:
-check_insn(ctx, ISA_MIPS32R6);
-gen_cond_move(ctx, op1, rd, rs, rt);
-break;
-case OPC_ADD ... OPC_SUBU:
-gen_arith(ctx, op1, rd, rs, rt);
-break;
-case OPC_SLLV: /* Shifts */
-case OPC_SRAV:
-gen_shift(ctx, op1, rd, rs, rt);
-break;
-case OPC_SRLV:
-switch ((ctx->opcode >> 6) & 0x1f) {
-case 1:
-/* rotrv is decoded as srlv on non-R2 CPUs */
-if (ctx->insn_flags & ISA_MIPS32R2) {
-op1 = OPC_ROTRV;
-}
-/* Fallthrough */
-case 0:
-gen_shift(ctx, op1, rd, rs, rt);
-break;
-default:
-generate_exception(ctx, EXCP_RI);
-break;
-}
+default:
+generate_exception(ctx, EXCP_RI);
 break;
-case OPC_SLT:  /* Set on less than */
-case OPC_SLTU:
-gen_slt(ctx, op1, rd, rs, rt);
-break;
-case OPC_AND:  /* Logic*/
-case OPC_OR:
-case OPC_NOR:
-case OPC_XOR:
-gen_logic(ctx, op1, rd, rs, rt);
-break;
-case OPC_MULT:
-case OPC_MULTU:
-if (sa) {
-check_insn(ctx, INSN_VR54XX);
-op1 = MASK_MUL_VR54XX(ctx->opcode);
-

[Qemu-devel] [PULL 02/28] target-mips: signal RI Exception on instructions removed in R6

2014-10-15 Thread Leon Alrae
Signal Reserved Instruction Exception on instructions that do not exist in R6.
In this commit the following groups of preR6 instructions are marked as deleted:
- Floating Point Paired Single
- Floating Point Compare
- conditional moves / branches on FPU conditions
- branch likelies
- unaligned loads / stores
- traps
- legacy accumulator instructions
- COP1X
- MIPS-3D

Signed-off-by: Leon Alrae 
Reviewed-by: Aurelien Jarno 
---
 target-mips/translate.c | 64 ++---
 1 file changed, 56 insertions(+), 8 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 06db150..de11747 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -1436,6 +1436,16 @@ static inline void check_insn(DisasContext *ctx, int 
flags)
 }
 }
 
+/* This code generates a "reserved instruction" exception if the
+   CPU has corresponding flag set which indicates that the instruction
+   has been removed. */
+static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
+{
+if (unlikely(ctx->insn_flags & flags)) {
+generate_exception(ctx, EXCP_RI);
+}
+}
+
 /* This code generates a "reserved instruction" exception if 64-bit
instructions are not enabled. */
 static inline void check_mips_64(DisasContext *ctx)
@@ -7712,10 +7722,12 @@ static void gen_farith (DisasContext *ctx, enum fopcode 
op1,
 opn = "floor.w.s";
 break;
 case OPC_MOVCF_S:
+check_insn_opc_removed(ctx, ISA_MIPS32R6);
 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
 opn = "movcf.s";
 break;
 case OPC_MOVZ_S:
+check_insn_opc_removed(ctx, ISA_MIPS32R6);
 {
 int l1 = gen_new_label();
 TCGv_i32 fp0;
@@ -7732,6 +7744,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode 
op1,
 opn = "movz.s";
 break;
 case OPC_MOVN_S:
+check_insn_opc_removed(ctx, ISA_MIPS32R6);
 {
 int l1 = gen_new_label();
 TCGv_i32 fp0;
@@ -7865,6 +7878,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode 
op1,
 opn = "cvt.l.s";
 break;
 case OPC_CVT_PS_S:
+check_insn_opc_removed(ctx, ISA_MIPS32R6);
 check_cp1_64bitmode(ctx);
 {
 TCGv_i64 fp64 = tcg_temp_new_i64();
@@ -7897,6 +7911,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode 
op1,
 case OPC_CMP_NGE_S:
 case OPC_CMP_LE_S:
 case OPC_CMP_NGT_S:
+check_insn_opc_removed(ctx, ISA_MIPS32R6);
 if (ctx->opcode & (1 << 6)) {
 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
 opn = condnames_abs[func-48];
@@ -8121,10 +8136,12 @@ static void gen_farith (DisasContext *ctx, enum fopcode 
op1,
 opn = "floor.w.d";
 break;
 case OPC_MOVCF_D:
+check_insn_opc_removed(ctx, ISA_MIPS32R6);
 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
 opn = "movcf.d";
 break;
 case OPC_MOVZ_D:
+check_insn_opc_removed(ctx, ISA_MIPS32R6);
 {
 int l1 = gen_new_label();
 TCGv_i64 fp0;
@@ -8141,6 +8158,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode 
op1,
 opn = "movz.d";
 break;
 case OPC_MOVN_D:
+check_insn_opc_removed(ctx, ISA_MIPS32R6);
 {
 int l1 = gen_new_label();
 TCGv_i64 fp0;
@@ -8250,6 +8268,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode 
op1,
 case OPC_CMP_NGE_D:
 case OPC_CMP_LE_D:
 case OPC_CMP_NGT_D:
+check_insn_opc_removed(ctx, ISA_MIPS32R6);
 if (ctx->opcode & (1 << 6)) {
 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
 opn = condnames_abs[func-48];
@@ -8350,6 +8369,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode 
op1,
 opn = "cvt.d.l";
 break;
 case OPC_CVT_PS_PW:
+check_insn_opc_removed(ctx, ISA_MIPS32R6);
 check_cp1_64bitmode(ctx);
 {
 TCGv_i64 fp0 = tcg_temp_new_i64();
@@ -14508,6 +14528,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext 
*ctx)
 break;
 case OPC_MOVN: /* Conditional move */
 case OPC_MOVZ:
+check_insn_opc_removed(ctx, ISA_MIPS32R6);
 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
  INSN_LOONGSON2E | INSN_LOONGSON2F);
 gen_cond_move(ctx, op1, rd, rs, rt);
@@ -14568,10 +14589,12 @@ static void decode_opc (CPUMIPSState *env, 
DisasContext *ctx)
 break;
 case OPC_MFHI:  /* Move from HI/LO */
 case OPC_MFLO:
+check_insn_opc_removed(ctx, ISA_MIPS32R6);
 gen_HILO(ctx, op1, rs & 3, rd);
 break;
 case OPC_MTHI:
 case OPC_MTLO:  /* Move to HI/LO */
+check_insn_opc_removed(ctx, ISA_MIPS32R6);
 gen_HILO(ctx, op1, rd & 3, rs);
 break;
 case O

[Qemu-devel] [PULL 04/28] target-mips: move LL and SC instructions

2014-10-15 Thread Leon Alrae
The encoding of LL and SC instruction has changed in MIPS32 Release 6.

Signed-off-by: Leon Alrae 
Reviewed-by: Aurelien Jarno 
Reviewed-by: James Hogan 
---
 disas/mips.c|  9 -
 target-mips/translate.c | 28 ++--
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/disas/mips.c b/disas/mips.c
index b950e53..f0efa8b 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -119,6 +119,8 @@ see .  */
 #define OP_SH_IMMEDIATE0
 #define OP_MASK_DELTA  0x
 #define OP_SH_DELTA0
+#define OP_MASK_DELTA_R60x1ff
+#define OP_SH_DELTA_R6  7
 #define OP_MASK_FUNCT  0x3f
 #define OP_SH_FUNCT0
 #define OP_MASK_SPEC   0x3f
@@ -1215,6 +1217,8 @@ const struct mips_opcode mips_builtin_opcodes[] =
them first.  The assemblers uses a hash table based on the
instruction name anyhow.  */
 /* name,args,  match,  mask,   pinfo,  
membership */
+{"ll",  "t,o(b)",   0x7c36, 0xfc7f, LDD|RD_b|WR_t,0, 
I32R6},
+{"sc",  "t,o(b)",   0x7c26, 0xfc7f, LDD|RD_b|WR_t,0, 
I32R6},
 {"seleqz",  "d,v,t",0x0035, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
 {"selnez",  "d,v,t",0x0037, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
 {"pref","k,o(b)",   0xcc00, 0xfc00, RD_b,  0,  
I4|I32|G3   },
@@ -3734,7 +3738,10 @@ print_insn_args (const char *d,
 
case 'j': /* Same as i, but sign-extended.  */
case 'o':
- delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
+delta = (opp->membership == I32R6) ?
+(l >> OP_SH_DELTA_R6) & OP_MASK_DELTA_R6 :
+(l >> OP_SH_DELTA) & OP_MASK_DELTA;
+
  if (delta & 0x8000)
delta |= ~0x;
  (*info->fprintf_func) (info->stream, "%d",
diff --git a/target-mips/translate.c b/target-mips/translate.c
index ba9daac..8606f32 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -347,6 +347,10 @@ enum {
 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
 OPC_DEXTR_W_DSP= 0x3C | OPC_SPECIAL3,
+
+/* R6 */
+R6_OPC_LL  = 0x36 | OPC_SPECIAL3,
+R6_OPC_SC  = 0x26 | OPC_SPECIAL3,
 };
 
 /* BSHFL opcodes */
@@ -1775,6 +1779,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
 opn = "lwr";
 break;
 case OPC_LL:
+case R6_OPC_LL:
 save_cpu_state(ctx, 1);
 op_ld_ll(t0, t0, ctx);
 gen_store_gpr(t0, rt);
@@ -1868,6 +1873,7 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, 
int rt,
 break;
 #endif
 case OPC_SC:
+case R6_OPC_SC:
 save_cpu_state(ctx, 1);
 op_st_sc(t1, t0, rt, ctx);
 opn = "sc";
@@ -14804,6 +14810,10 @@ static void decode_opc (CPUMIPSState *env, 
DisasContext *ctx)
 case OPC_SPECIAL3:
 op1 = MASK_SPECIAL3(ctx->opcode);
 switch (op1) {
+case R6_OPC_LL:
+check_insn(ctx, ISA_MIPS32R6);
+gen_ld(ctx, op1, rt, rs, imm >> 7);
+break;
 case OPC_EXT:
 case OPC_INS:
 check_insn(ctx, ISA_MIPS32R2);
@@ -15108,6 +15118,19 @@ static void decode_opc (CPUMIPSState *env, 
DisasContext *ctx)
 break;
 }
 break;
+case R6_OPC_SC: /* OPC_DMOD_G_2E */
+if (ctx->insn_flags & ISA_MIPS32R6) {
+gen_st_cond(ctx, op1, rt, rs, imm >> 7);
+} else {
+#if defined(TARGET_MIPS64)
+check_insn(ctx, INSN_LOONGSON2E);
+gen_loongson_integer(ctx, op1, rd, rs, rt);
+#else
+/* Invalid in MIPS32 */
+generate_exception(ctx, EXCP_RI);
+#endif
+}
+break;
 #if defined(TARGET_MIPS64)
 case OPC_DEXTM ... OPC_DEXT:
 case OPC_DINSM ... OPC_DINS:
@@ -15123,7 +15146,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext 
*ctx)
 break;
 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
-case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
+case OPC_DMODU_G_2E:
 check_insn(ctx, INSN_LOONGSON2E);
 gen_loongson_integer(ctx, op1, rd, rs, rt);
 break;
@@ -15512,10 +15535,10 @@ static void decode_opc (CPUMIPSState *env, 
DisasContext *ctx)
  break;
 case OPC_LWL: /* Load and stores */
 case OPC_LWR:
+case OPC_LL:
 check_insn_opc_removed(ctx, ISA_MIPS32R6);
 case OPC_LB ... OPC_LH:
 case OPC_LW ... OPC_LHU:
-case OPC_LL:
  gen_ld(ctx, op, rt, rs, imm);
  break;
 case OPC_SWL:
@@ -15526,6 +15549,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext 
*ctx)
  gen_st(ctx, op, rt, rs, imm);
  break;
 case OPC_SC:
+ check_insn_opc_re

[Qemu-devel] [PULL 09/28] target-mips: redefine Integer Multiply and Divide instructions

2014-10-15 Thread Leon Alrae
Use "R6_" prefix in front of all new Multiply / Divide instructions for
easier differentiation between R6 and preR6.

Signed-off-by: Leon Alrae 
Reviewed-by: Aurelien Jarno 
---
 disas/mips.c|  16 +++
 target-mips/translate.c | 343 +---
 2 files changed, 338 insertions(+), 21 deletions(-)

diff --git a/disas/mips.c b/disas/mips.c
index cae76ed..16cb2ac 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -1217,6 +1217,22 @@ const struct mips_opcode mips_builtin_opcodes[] =
them first.  The assemblers uses a hash table based on the
instruction name anyhow.  */
 /* name,args,  match,  mask,   pinfo,  
membership */
+{"mul", "d,s,t",0x0098, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
+{"muh", "d,s,t",0x00d8, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
+{"mulu","d,s,t",0x0099, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
+{"muhu","d,s,t",0x00d9, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
+{"div", "d,s,t",0x009a, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
+{"mod", "d,s,t",0x00da, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
+{"divu","d,s,t",0x009b, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
+{"modu","d,s,t",0x00db, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
+{"dmul","d,s,t",0x009c, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I64R6},
+{"dmuh","d,s,t",0x00dc, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I64R6},
+{"dmulu",   "d,s,t",0x009d, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I64R6},
+{"dmuhu",   "d,s,t",0x00dd, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I64R6},
+{"ddiv","d,s,t",0x009e, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I64R6},
+{"dmod","d,s,t",0x00de, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I64R6},
+{"ddivu",   "d,s,t",0x009f, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I64R6},
+{"dmodu",   "d,s,t",0x00df, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I64R6},
 {"ll",  "t,o(b)",   0x7c36, 0xfc7f, LDD|RD_b|WR_t,0, 
I32R6},
 {"sc",  "t,o(b)",   0x7c26, 0xfc7f, LDD|RD_b|WR_t,0, 
I32R6},
 {"lld", "t,o(b)",   0x7c37, 0xfc7f, LDD|RD_b|WR_t,0, 
I64R6},
diff --git a/target-mips/translate.c b/target-mips/translate.c
index f50d906..3ce9641 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -157,6 +157,7 @@ enum {
 OPC_DMULTU   = 0x1D | OPC_SPECIAL,
 OPC_DDIV = 0x1E | OPC_SPECIAL,
 OPC_DDIVU= 0x1F | OPC_SPECIAL,
+
 /* 2 registers arithmetic / logic */
 OPC_ADD  = 0x20 | OPC_SPECIAL,
 OPC_ADDU = 0x21 | OPC_SPECIAL,
@@ -212,6 +213,30 @@ enum {
 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
 };
 
+/* R6 Multiply and Divide instructions have the same Opcode
+   and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
+#define MASK_R6_MULDIV(op)   (MASK_SPECIAL(op) | (op & (0x7ff)))
+
+enum {
+R6_OPC_MUL   = OPC_MULT  | (2 << 6),
+R6_OPC_MUH   = OPC_MULT  | (3 << 6),
+R6_OPC_MULU  = OPC_MULTU | (2 << 6),
+R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
+R6_OPC_DIV   = OPC_DIV   | (2 << 6),
+R6_OPC_MOD   = OPC_DIV   | (3 << 6),
+R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
+R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
+
+R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
+R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
+R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
+R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
+R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
+R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
+R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
+R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
+};
+
 /* Multiplication variants of the vr54xx. */
 #define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
 
@@ -2691,6 +2716,238 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, 
int acc, int reg)
 MIPS_DEBUG("%s %s", opn, regnames[reg]);
 }
 
+static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
+{
+const char *opn = "r6 mul/div";
+TCGv t0, t1;
+
+if (rd == 0) {
+/* Treat as NOP. */
+MIPS_DEBUG("NOP");
+return;
+}
+
+t0 = tcg_temp_new();
+t1 = tcg_temp_new();
+
+gen_load_gpr(t0, rs);
+gen_load_gpr(t1, rt);
+
+switch (opc) {
+case R6_OPC_DIV:
+{
+TCGv t2 = tcg_temp_new();
+TCGv t3 = tcg_temp_new();
+tcg_gen_ext32s_tl(t0, t0);
+tcg_gen_ext32s_tl(t1, t1);
+tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
+tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
+tcg_gen_and_tl(t2, t2, t3);
+tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
+tcg_gen_or_tl(t2, t2, t3);
+tcg_gen_movi_tl(t3, 0);
+tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
+tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
+tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
+

[Qemu-devel] [PULL 15/28] softfloat: add functions corresponding to IEEE-2008 min/maxNumMag

2014-10-15 Thread Leon Alrae
Add abs argument to the existing softfloat minmax() function and define
new float{32,64}_{min,max}nummag functions.

minnummag(x,y) returns x if |x| < |y|,
   returns y if |y| < |x|,
   otherwise minnum(x,y)

maxnummag(x,y) returns x if |x| > |y|,
   returns y if |y| > |x|,
   otherwise maxnum(x,y)

Signed-off-by: Leon Alrae 
Reviewed-by: Aurelien Jarno 
---
 fpu/softfloat.c | 37 +++--
 include/fpu/softfloat.h |  4 
 2 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 9274ebf..16b21eb 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -7240,13 +7240,17 @@ int float128_compare_quiet( float128 a, float128 b 
STATUS_PARAM )
  * minnum() and maxnum correspond to the IEEE 754-2008 minNum()
  * and maxNum() operations. min() and max() are the typical min/max
  * semantics provided by many CPUs which predate that specification.
+ *
+ * minnummag() and maxnummag() functions correspond to minNumMag()
+ * and minNumMag() from the IEEE-754 2008.
  */
 #define MINMAX(s)   \
 static inline float ## s float ## s ## _minmax(float ## s a, float ## s b, 
\
-int ismin, int isieee STATUS_PARAM) \
+   int ismin, int isieee,   \
+   int ismag STATUS_PARAM)  \
 {   \
 flag aSign, bSign;  \
-uint ## s ## _t av, bv; \
+uint ## s ## _t av, bv, aav, abv;   \
 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) || \
@@ -7266,6 +7270,17 @@ static inline float ## s float ## s ## _minmax(float ## 
s a, float ## s b, \
 bSign = extractFloat ## s ## Sign(b);   \
 av = float ## s ## _val(a); \
 bv = float ## s ## _val(b); \
+if (ismag) {\
+aav = float ## s ## _abs(av);   \
+abv = float ## s ## _abs(bv);   \
+if (aav != abv) {   \
+if (ismin) {\
+return (aav < abv) ? a : b; \
+} else {\
+return (aav < abv) ? b : a; \
+}   \
+}   \
+}   \
 if (aSign != bSign) {   \
 if (ismin) {\
 return aSign ? a : b;   \
@@ -7283,22 +7298,32 @@ static inline float ## s float ## s ## _minmax(float ## 
s a, float ## s b, \
 \
 float ## s float ## s ## _min(float ## s a, float ## s b STATUS_PARAM)  \
 {   \
-return float ## s ## _minmax(a, b, 1, 0 STATUS_VAR);\
+return float ## s ## _minmax(a, b, 1, 0, 0 STATUS_VAR); \
 }   \
 \
 float ## s float ## s ## _max(float ## s a, float ## s b STATUS_PARAM)  \
 {   \
-return float ## s ## _minmax(a, b, 0, 0 STATUS_VAR);\
+return float ## s ## _minmax(a, b, 0, 0, 0 STATUS_VAR); \
 }   \
 \
 float ## s float ## s ## _minnum(float ## s a, float ## s b STATUS_PARAM) \
 {   \
-return float ## s ## _minmax(a, b, 1, 1 STATUS_VAR);\
+return float ## s ## _minmax(a, b, 1, 1, 0 STATUS_VAR); \
 }   \
 \
 float ## s float ## s ## _maxnum(float ## s a, float ## s b STATUS_PARAM

[Qemu-devel] [PULL 06/28] target-mips: split decode_opc_special* into *_r6 and *_legacy

2014-10-15 Thread Leon Alrae
For better code readability and to avoid 'if' statements for all R6 and preR6
instructions whose opcodes are the same - decode_opc_special* functions are
split into functions with _r6 and _legacy suffixes.

*_r6 functions will contain instructions which were introduced in R6.
*_legacy functions will contain instructions which were removed in R6.

Signed-off-by: Leon Alrae 
Reviewed-by: Aurelien Jarno 
---
 target-mips/translate.c | 228 +---
 1 file changed, 160 insertions(+), 68 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 5b8f762..0c64aeb 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -14482,6 +14482,70 @@ static void gen_mipsdsp_accinsn(DisasContext *ctx, 
uint32_t op1, uint32_t op2,
 
 /* End MIPSDSP functions. */
 
+static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
+{
+int rs, rt, rd;
+uint32_t op1;
+
+rs = (ctx->opcode >> 21) & 0x1f;
+rt = (ctx->opcode >> 16) & 0x1f;
+rd = (ctx->opcode >> 11) & 0x1f;
+
+op1 = MASK_SPECIAL(ctx->opcode);
+switch (op1) {
+case OPC_SELEQZ:
+case OPC_SELNEZ:
+gen_cond_move(ctx, op1, rd, rs, rt);
+break;
+default:/* Invalid */
+MIPS_INVAL("special_r6");
+generate_exception(ctx, EXCP_RI);
+break;
+}
+}
+
+static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
+{
+int rs, rt, rd;
+uint32_t op1;
+
+rs = (ctx->opcode >> 21) & 0x1f;
+rt = (ctx->opcode >> 16) & 0x1f;
+rd = (ctx->opcode >> 11) & 0x1f;
+
+op1 = MASK_SPECIAL(ctx->opcode);
+switch (op1) {
+case OPC_MOVN: /* Conditional move */
+case OPC_MOVZ:
+check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
+   INSN_LOONGSON2E | INSN_LOONGSON2F);
+gen_cond_move(ctx, op1, rd, rs, rt);
+break;
+case OPC_MFHI:  /* Move from HI/LO */
+case OPC_MFLO:
+gen_HILO(ctx, op1, rs & 3, rd);
+break;
+case OPC_MTHI:
+case OPC_MTLO:  /* Move to HI/LO */
+gen_HILO(ctx, op1, rd & 3, rs);
+break;
+case OPC_MOVCI:
+check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
+if (env->CP0_Config1 & (1 << CP0C1_FP)) {
+check_cp1_enabled(ctx);
+gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
+  (ctx->opcode >> 16) & 1);
+} else {
+generate_exception_err(ctx, EXCP_CpU, 1);
+}
+break;
+default:/* Invalid */
+MIPS_INVAL("special_legacy");
+generate_exception(ctx, EXCP_RI);
+break;
+}
+}
+
 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
 {
 int rs, rt, rd, sa;
@@ -14514,18 +14578,6 @@ static void decode_opc_special(CPUMIPSState *env, 
DisasContext *ctx)
 break;
 }
 break;
-case OPC_MOVN: /* Conditional move */
-case OPC_MOVZ:
-check_insn_opc_removed(ctx, ISA_MIPS32R6);
-check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
-   INSN_LOONGSON2E | INSN_LOONGSON2F);
-gen_cond_move(ctx, op1, rd, rs, rt);
-break;
-case OPC_SELEQZ:
-case OPC_SELNEZ:
-check_insn(ctx, ISA_MIPS32R6);
-gen_cond_move(ctx, op1, rd, rs, rt);
-break;
 case OPC_ADD ... OPC_SUBU:
 gen_arith(ctx, op1, rd, rs, rt);
 break;
@@ -14580,16 +14632,6 @@ static void decode_opc_special(CPUMIPSState *env, 
DisasContext *ctx)
 case OPC_TNE:
 gen_trap(ctx, op1, rs, rt, -1);
 break;
-case OPC_MFHI:  /* Move from HI/LO */
-case OPC_MFLO:
-check_insn_opc_removed(ctx, ISA_MIPS32R6);
-gen_HILO(ctx, op1, rs & 3, rd);
-break;
-case OPC_MTHI:
-case OPC_MTLO:  /* Move to HI/LO */
-check_insn_opc_removed(ctx, ISA_MIPS32R6);
-gen_HILO(ctx, op1, rd & 3, rs);
-break;
 case OPC_PMON:  /* Pmon entry point, also R4010 selsl */
 #ifdef MIPS_STRICT_STANDARD
 MIPS_INVAL("PMON / selsl");
@@ -14619,18 +14661,6 @@ static void decode_opc_special(CPUMIPSState *env, 
DisasContext *ctx)
 /* Treat as NOP. */
 break;
 
-case OPC_MOVCI:
-check_insn_opc_removed(ctx, ISA_MIPS32R6);
-check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
-if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
-check_cp1_enabled(ctx);
-gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
-  (ctx->opcode >> 16) & 1);
-} else {
-generate_exception_err(ctx, EXCP_CpU, 1);
-}
-break;
-
 #if defined(TARGET_MIPS64)
 /* MIPS64 specific opcodes */
 case OPC_DSLL:
@@ -14712,14 +14742,29 @@ static void decode_opc_special(CPUMIPSState *env, 
DisasContext *ctx)
 gen_muldiv(ctx, op1, 0, rs, rt);
 break;
 #endif
+default:
+if (ctx->insn_flags & ISA_MIPS32R6) {
+   

[Qemu-devel] [PULL 10/28] target-mips: move CLO, DCLO, CLZ, DCLZ, SDBBP and free special2 in R6

2014-10-15 Thread Leon Alrae
Also consider OPC_SPIM instruction as deleted in R6 because it is overlaping
with MIPS32R6 SDBBP.

Signed-off-by: Leon Alrae 
Reviewed-by: Aurelien Jarno 
---
 disas/mips.c|   5 ++
 target-mips/translate.c | 121 +---
 2 files changed, 67 insertions(+), 59 deletions(-)

diff --git a/disas/mips.c b/disas/mips.c
index 16cb2ac..8ee8758 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -1217,6 +1217,11 @@ const struct mips_opcode mips_builtin_opcodes[] =
them first.  The assemblers uses a hash table based on the
instruction name anyhow.  */
 /* name,args,  match,  mask,   pinfo,  
membership */
+{"clz", "U,s",  0x0050, 0xfc1f07ff, WR_d|RD_s,0, 
I32R6},
+{"clo", "U,s",  0x0051, 0xfc1f07ff, WR_d|RD_s,0, 
I32R6},
+{"dclz","U,s",  0x0052, 0xfc1f07ff, WR_d|RD_s,0, 
I64R6},
+{"dclo","U,s",  0x0053, 0xfc1f07ff, WR_d|RD_s,0, 
I64R6},
+{"sdbbp",   "B",0x000e, 0xfc3f, TRAP, 0, 
I32R6},
 {"mul", "d,s,t",0x0098, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
 {"muh", "d,s,t",0x00d8, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
 {"mulu","d,s,t",0x0099, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 3ce9641..34d63ea 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -235,6 +235,12 @@ enum {
 R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
 R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
 R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
+
+R6_OPC_CLZ  = 0x10 | OPC_SPECIAL,
+R6_OPC_CLO  = 0x11 | OPC_SPECIAL,
+R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
+R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
+R6_OPC_SDBBP= 0x0e | OPC_SPECIAL,
 };
 
 /* Multiplication variants of the vr54xx. */
@@ -3263,19 +3269,23 @@ static void gen_cl (DisasContext *ctx, uint32_t opc,
 gen_load_gpr(t0, rs);
 switch (opc) {
 case OPC_CLO:
+case R6_OPC_CLO:
 gen_helper_clo(cpu_gpr[rd], t0);
 opn = "clo";
 break;
 case OPC_CLZ:
+case R6_OPC_CLZ:
 gen_helper_clz(cpu_gpr[rd], t0);
 opn = "clz";
 break;
 #if defined(TARGET_MIPS64)
 case OPC_DCLO:
+case R6_OPC_DCLO:
 gen_helper_dclo(cpu_gpr[rd], t0);
 opn = "dclo";
 break;
 case OPC_DCLZ:
+case R6_OPC_DCLZ:
 gen_helper_dclz(cpu_gpr[rd], t0);
 opn = "dclz";
 break;
@@ -14747,12 +14757,13 @@ static void gen_mipsdsp_accinsn(DisasContext *ctx, 
uint32_t op1, uint32_t op2,
 
 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
 {
-int rs, rt, rd;
+int rs, rt, rd, sa;
 uint32_t op1, op2;
 
 rs = (ctx->opcode >> 21) & 0x1f;
 rt = (ctx->opcode >> 16) & 0x1f;
 rd = (ctx->opcode >> 11) & 0x1f;
+sa = (ctx->opcode >> 6) & 0x1f;
 
 op1 = MASK_SPECIAL(ctx->opcode);
 switch (op1) {
@@ -14779,7 +14790,31 @@ static void decode_opc_special_r6(CPUMIPSState *env, 
DisasContext *ctx)
 case OPC_SELNEZ:
 gen_cond_move(ctx, op1, rd, rs, rt);
 break;
+case R6_OPC_CLO:
+case R6_OPC_CLZ:
+if (rt == 0 && sa == 1) {
+/* Major opcode and function field is shared with preR6 MFHI/MTHI.
+   We need additionally to check other fields */
+gen_cl(ctx, op1, rd, rs);
+} else {
+generate_exception(ctx, EXCP_RI);
+}
+break;
+case R6_OPC_SDBBP:
+generate_exception(ctx, EXCP_DBp);
+break;
 #if defined(TARGET_MIPS64)
+case R6_OPC_DCLO:
+case R6_OPC_DCLZ:
+if (rt == 0 && sa == 1) {
+/* Major opcode and function field is shared with preR6 MFHI/MTHI.
+   We need additionally to check other fields */
+check_mips_64(ctx);
+gen_cl(ctx, op1, rd, rs);
+} else {
+generate_exception(ctx, EXCP_RI);
+}
+break;
 case OPC_DMULT ... OPC_DDIVU:
 op2 = MASK_R6_MULDIV(ctx->opcode);
 switch (op2) {
@@ -14865,6 +14900,16 @@ static void decode_opc_special_legacy(CPUMIPSState 
*env, DisasContext *ctx)
 gen_muldiv(ctx, op1, 0, rs, rt);
 break;
 #endif
+case OPC_SPIM:
+#ifdef MIPS_STRICT_STANDARD
+MIPS_INVAL("SPIM");
+generate_exception(ctx, EXCP_RI);
+#else
+/* Implemented as RI exception for now. */
+MIPS_INVAL("spim (unofficial)");
+generate_exception(ctx, EXCP_RI);
+#endif
+break;
 default:/* Invalid */
 MIPS_INVAL("special_legacy");
 generate_exception(ctx, EXCP_RI);
@@ -14959,16 +15004,6 @@ static void decode_opc_special(CPUMIPSState *env, 
DisasContext *ctx)
 case OPC_BREAK:
 generate_exception(ctx, EXCP_BREAK);
 break;
-case OPC_SPIM:
-#ifdef MIPS_STRICT_STANDARD
-M

[Qemu-devel] [PULL 07/28] target-mips: signal RI Exception on DSP and Loongson instructions

2014-10-15 Thread Leon Alrae
Move DSP and Loongson instruction to *_legacy functions as they have been
removed in R6.

Signed-off-by: Leon Alrae 
Reviewed-by: Aurelien Jarno 
---
 target-mips/translate.c | 195 
 1 file changed, 98 insertions(+), 97 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 0c64aeb..11967a0 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -14783,6 +14783,26 @@ static void decode_opc_special2_legacy(CPUMIPSState 
*env, DisasContext *ctx)
 case OPC_MUL:
 gen_arith(ctx, op1, rd, rs, rt);
 break;
+case OPC_DIV_G_2F:
+case OPC_DIVU_G_2F:
+case OPC_MULT_G_2F:
+case OPC_MULTU_G_2F:
+case OPC_MOD_G_2F:
+case OPC_MODU_G_2F:
+check_insn(ctx, INSN_LOONGSON2F);
+gen_loongson_integer(ctx, op1, rd, rs, rt);
+break;
+#if defined(TARGET_MIPS64)
+case OPC_DMULT_G_2F:
+case OPC_DMULTU_G_2F:
+case OPC_DDIV_G_2F:
+case OPC_DDIVU_G_2F:
+case OPC_DMOD_G_2F:
+case OPC_DMODU_G_2F:
+check_insn(ctx, INSN_LOONGSON2F);
+gen_loongson_integer(ctx, op1, rd, rs, rt);
+break;
+#endif
 default:/* Invalid */
 MIPS_INVAL("special2_legacy");
 generate_exception(ctx, EXCP_RI);
@@ -14792,11 +14812,10 @@ static void decode_opc_special2_legacy(CPUMIPSState 
*env, DisasContext *ctx)
 
 static void decode_opc_special2(CPUMIPSState *env, DisasContext *ctx)
 {
-int rs, rt, rd;
+int rs, rd;
 uint32_t op1;
 
 rs = (ctx->opcode >> 21) & 0x1f;
-rt = (ctx->opcode >> 16) & 0x1f;
 rd = (ctx->opcode >> 11) & 0x1f;
 
 op1 = MASK_SPECIAL2(ctx->opcode);
@@ -14818,15 +14837,6 @@ static void decode_opc_special2(CPUMIPSState *env, 
DisasContext *ctx)
 }
 /* Treat as NOP. */
 break;
-case OPC_DIV_G_2F:
-case OPC_DIVU_G_2F:
-case OPC_MULT_G_2F:
-case OPC_MULTU_G_2F:
-case OPC_MOD_G_2F:
-case OPC_MODU_G_2F:
-check_insn(ctx, INSN_LOONGSON2F);
-gen_loongson_integer(ctx, op1, rd, rs, rt);
-break;
 #if defined(TARGET_MIPS64)
 case OPC_DCLO:
 case OPC_DCLZ:
@@ -14834,15 +14844,6 @@ static void decode_opc_special2(CPUMIPSState *env, 
DisasContext *ctx)
 check_mips_64(ctx);
 gen_cl(ctx, op1, rd, rs);
 break;
-case OPC_DMULT_G_2F:
-case OPC_DMULTU_G_2F:
-case OPC_DDIV_G_2F:
-case OPC_DDIVU_G_2F:
-case OPC_DMOD_G_2F:
-case OPC_DMODU_G_2F:
-check_insn(ctx, INSN_LOONGSON2F);
-gen_loongson_integer(ctx, op1, rd, rs, rt);
-break;
 #endif
 default:
 if (ctx->insn_flags & ISA_MIPS32R6) {
@@ -14880,80 +14881,15 @@ static void decode_opc_special3_r6(CPUMIPSState *env, 
DisasContext *ctx)
 
 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
 {
-uint32_t op1;
-#if defined(TARGET_MIPS64)
-int rd = (ctx->opcode >> 11) & 0x1f;
-int rs = (ctx->opcode >> 21) & 0x1f;
-int rt = (ctx->opcode >> 16) & 0x1f;
-#endif
-
-op1 = MASK_SPECIAL3(ctx->opcode);
-switch (op1) {
-#if defined(TARGET_MIPS64)
-case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
-case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
-case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
-check_insn(ctx, INSN_LOONGSON2E);
-gen_loongson_integer(ctx, op1, rd, rs, rt);
-break;
-#endif
-default:/* Invalid */
-MIPS_INVAL("special3_legacy");
-generate_exception(ctx, EXCP_RI);
-break;
-}
-}
-
-static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
-{
-int rs, rt, rd, sa;
+int rs, rt, rd;
 uint32_t op1, op2;
 
 rs = (ctx->opcode >> 21) & 0x1f;
 rt = (ctx->opcode >> 16) & 0x1f;
 rd = (ctx->opcode >> 11) & 0x1f;
-sa = (ctx->opcode >> 6) & 0x1f;
 
 op1 = MASK_SPECIAL3(ctx->opcode);
 switch (op1) {
-case OPC_EXT:
-case OPC_INS:
-check_insn(ctx, ISA_MIPS32R2);
-gen_bitops(ctx, op1, rt, rs, sa, rd);
-break;
-case OPC_BSHFL:
-check_insn(ctx, ISA_MIPS32R2);
-op2 = MASK_BSHFL(ctx->opcode);
-gen_bshfl(ctx, op2, rt, rd);
-break;
-case OPC_RDHWR:
-gen_rdhwr(ctx, rt, rd);
-break;
-case OPC_FORK:
-check_insn(ctx, ASE_MT);
-{
-TCGv t0 = tcg_temp_new();
-TCGv t1 = tcg_temp_new();
-
-gen_load_gpr(t0, rt);
-gen_load_gpr(t1, rs);
-gen_helper_fork(t0, t1);
-tcg_temp_free(t0);
-tcg_temp_free(t1);
-}
-break;
-case OPC_YIELD:
-check_insn(ctx, ASE_MT);
-{
-TCGv t0 = tcg_temp_new();
-
-save_cpu_state(ctx, 1);
-gen_load_gpr(t0, rs);
-gen_helper_yield(t0, cpu_env, t0);
-gen_store_gpr(t0, rd);
-tcg_temp_free(t0);
-}
-break;
 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
 case OPC_MOD_G_2E

[Qemu-devel] [PULL 19/28] target-mips: remove JR, BLTZAL, BGEZAL and add NAL, BAL instructions

2014-10-15 Thread Leon Alrae
From: Yongbok Kim 

Signed-off-by: Yongbok Kim 
Signed-off-by: Leon Alrae 
Reviewed-by: Aurelien Jarno 
---
 disas/mips.c|  2 ++
 target-mips/translate.c | 18 --
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/disas/mips.c b/disas/mips.c
index 5ebb5fd..7297825 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -1313,6 +1313,8 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"bgtzalc", "s,t,p",0x1c00, 0xffe0, CBD|RD_s|RD_t,0, 
I32R6},
 {"bltzalc", "s,t,p",0x1c00, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
 {"bltuc",   "s,t,p",0x1c00, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
+{"nal", "p",0x0410, 0x, WR_31,0, 
I32R6},
+{"bal", "p",0x0411, 0x, UBD|WR_31,0, 
I32R6},
 {"bc1eqz",  "T,p",  0x4520, 0xffe0, CBD|RD_T|FP_S|FP_D,   0, 
I32R6},
 {"bc1nez",  "T,p",  0x45a0, 0xffe0, CBD|RD_T|FP_S|FP_D,   0, 
I32R6},
 {"bc2eqz",  "E,p",  0x4920, 0xffe0, CBD|RD_C2,0, 
I32R6},
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 8088781..57c2d41 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15851,6 +15851,9 @@ static void decode_opc_special_legacy(CPUMIPSState 
*env, DisasContext *ctx)
 gen_muldiv(ctx, op1, 0, rs, rt);
 break;
 #endif
+case OPC_JR:
+gen_compute_branch(ctx, op1, 4, rs, rd, sa);
+break;
 case OPC_SPIM:
 #ifdef MIPS_STRICT_STANDARD
 MIPS_INVAL("SPIM");
@@ -15933,7 +15936,7 @@ static void decode_opc_special(CPUMIPSState *env, 
DisasContext *ctx)
 case OPC_XOR:
 gen_logic(ctx, op1, rd, rs, rt);
 break;
-case OPC_JR ... OPC_JALR:
+case OPC_JALR:
 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
 break;
 case OPC_TGE ... OPC_TEQ: /* Traps */
@@ -16903,9 +16906,20 @@ static void decode_opc (CPUMIPSState *env, 
DisasContext *ctx)
 check_insn_opc_removed(ctx, ISA_MIPS32R6);
 case OPC_BLTZ:
 case OPC_BGEZ:
+gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
+break;
 case OPC_BLTZAL:
 case OPC_BGEZAL:
-gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
+if (ctx->insn_flags & ISA_MIPS32R6) {
+if (rs == 0) {
+/* OPC_NAL, OPC_BAL */
+gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2);
+} else {
+generate_exception(ctx, EXCP_RI);
+}
+} else {
+gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
+}
 break;
 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
 case OPC_TNEI:
-- 
2.1.0




[Qemu-devel] [PULL 12/28] target-mips: add ALIGN, DALIGN, BITSWAP and DBITSWAP instructions

2014-10-15 Thread Leon Alrae
From: Yongbok Kim 

Signed-off-by: Yongbok Kim 
Signed-off-by: Leon Alrae 
Reviewed-by: Aurelien Jarno 
---
 disas/mips.c|   4 ++
 target-mips/helper.h|   5 ++
 target-mips/op_helper.c |  23 ++
 target-mips/translate.c | 120 +++-
 4 files changed, 140 insertions(+), 12 deletions(-)

diff --git a/disas/mips.c b/disas/mips.c
index 8ee8758..61313f4 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -1246,6 +1246,10 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"cache",   "k,o(b)",   0x7c25, 0xfc7f, RD_b, 0, 
I32R6},
 {"seleqz",  "d,v,t",0x0035, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
 {"selnez",  "d,v,t",0x0037, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
+{"align",   "d,v,t",0x7c000220, 0xfc00073f, WR_d|RD_s|RD_t,   0, 
I32R6},
+{"dalign",  "d,v,t",0x7c000224, 0xfc00063f, WR_d|RD_s|RD_t,   0, 
I64R6},
+{"bitswap", "d,w",  0x7c20, 0xffe007ff, WR_d|RD_t,0, 
I32R6},
+{"dbitswap","d,w",  0x7c24, 0xffe007ff, WR_d|RD_t,0, 
I64R6},
 {"pref","k,o(b)",   0xcc00, 0xfc00, RD_b,  0,  
I4|I32|G3   },
 {"prefx",   "h,t(b)",  0x4c0f, 0xfc0007ff, RD_b|RD_t,  0,  
I4|I33  },
 {"nop", "", 0x, 0x, 0, 
INSN2_ALIAS,I1  }, /* sll */
diff --git a/target-mips/helper.h b/target-mips/helper.h
index 74ef094..5511dfc 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -39,6 +39,11 @@ DEF_HELPER_3(macchiu, tl, env, tl, tl)
 DEF_HELPER_3(msachi, tl, env, tl, tl)
 DEF_HELPER_3(msachiu, tl, env, tl, tl)
 
+DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl)
+#ifdef TARGET_MIPS64
+DEF_HELPER_FLAGS_1(dbitswap, TCG_CALL_NO_RWG_SE, tl, tl)
+#endif
+
 #ifndef CONFIG_USER_ONLY
 /* CP0 helpers */
 DEF_HELPER_1(mfc0_mvpcontrol, tl, env)
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index df97b35..c9841e2 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -266,6 +266,29 @@ target_ulong helper_mulshiu(CPUMIPSState *env, 
target_ulong arg1,
(uint64_t)(uint32_t)arg2);
 }
 
+static inline target_ulong bitswap(target_ulong v)
+{
+v = ((v >> 1) & (target_ulong)0x) |
+  ((v & (target_ulong)0x) << 1);
+v = ((v >> 2) & (target_ulong)0x) |
+  ((v & (target_ulong)0x) << 2);
+v = ((v >> 4) & (target_ulong)0x0F0F0F0F0F0F0F0F) |
+  ((v & (target_ulong)0x0F0F0F0F0F0F0F0F) << 4);
+return v;
+}
+
+#ifdef TARGET_MIPS64
+target_ulong helper_dbitswap(target_ulong rt)
+{
+return bitswap(rt);
+}
+#endif
+
+target_ulong helper_bitswap(target_ulong rt)
+{
+return (int32_t)bitswap(rt);
+}
+
 #ifndef CONFIG_USER_ONLY
 
 static inline hwaddr do_translate_address(CPUMIPSState *env,
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 7420485..0052e24 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -392,17 +392,23 @@ enum {
 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
 
 enum {
-OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
-OPC_SEB  = (0x10 << 6) | OPC_BSHFL,
-OPC_SEH  = (0x18 << 6) | OPC_BSHFL,
+OPC_WSBH  = (0x02 << 6) | OPC_BSHFL,
+OPC_SEB   = (0x10 << 6) | OPC_BSHFL,
+OPC_SEH   = (0x18 << 6) | OPC_BSHFL,
+OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
+OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
+OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 0 */
 };
 
 /* DBSHFL opcodes */
 #define MASK_DBSHFL(op)MASK_SPECIAL3(op) | (op & (0x1F << 6))
 
 enum {
-OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
-OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
+OPC_DSBH   = (0x02 << 6) | OPC_DBSHFL,
+OPC_DSHD   = (0x05 << 6) | OPC_DBSHFL,
+OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
+OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
+OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 0 */
 };
 
 /* MIPS DSP REGIMM opcodes */
@@ -15162,12 +15168,14 @@ static void decode_opc_special2_legacy(CPUMIPSState 
*env, DisasContext *ctx)
 
 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
 {
-int rs, rt;
-uint32_t op1;
+int rs, rt, rd, sa;
+uint32_t op1, op2;
 int16_t imm;
 
 rs = (ctx->opcode >> 21) & 0x1f;
 rt = (ctx->opcode >> 16) & 0x1f;
+rd = (ctx->opcode >> 11) & 0x1f;
+sa = (ctx->opcode >> 6) & 0x1f;
 imm = (int16_t)ctx->opcode >> 7;
 
 op1 = MASK_SPECIAL3(ctx->opcode);
@@ -15188,6 +15196,43 @@ static void decode_opc_special3_r6(CPUMIPSState *env, 
DisasContext *ctx)
 case R6_OPC_LL:
 gen_ld(ctx, op1, rt, rs, imm);
 break;
+case OPC_BSHFL:
+{
+if (rd == 0) {
+/* Treat as NOP. */
+  

[Qemu-devel] [PULL 21/28] target-mips: define a new generic CPU supporting MIPS64 Release 6 ISA

2014-10-15 Thread Leon Alrae
Signed-off-by: Leon Alrae 
Reviewed-by: Yongbok Kim 
---
 target-mips/translate_init.c | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index 29dc2ef..67b7837 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -516,6 +516,36 @@ static const mips_def_t mips_defs[] =
 .mmu_type = MMU_TYPE_R4000,
 },
 {
+/* A generic CPU supporting MIPS64 Release 6 ISA.
+   FIXME: It does not support all the MIPS64R6 features yet.
+  Eventually this should be replaced by a real CPU model. */
+.name = "MIPS64R6-generic",
+.CP0_PRid = 0x0001,
+.CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AR) | (0x2 << CP0C0_AT) |
+   (MMU_TYPE_R4000 << CP0C0_MT),
+.CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) |
+   (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) |
+   (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
+   (0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
+.CP0_Config2 = MIPS_CONFIG2,
+.CP0_Config3 = MIPS_CONFIG3,
+.CP0_LLAddr_rw_bitmask = 0,
+.CP0_LLAddr_shift = 0,
+.SYNCI_Step = 32,
+.CCRes = 2,
+.CP0_Status_rw_bitmask = 0x30D8,
+.CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
+(1 << FCR0_D) | (1 << FCR0_S) | (0x00 << FCR0_PRID) |
+(0x0 << FCR0_REV),
+.SEGBITS = 42,
+/* The architectural limit is 59, but we have hardcoded 36 bit
+   in some places...
+.PABITS = 59, */ /* the architectural limit */
+.PABITS = 36,
+.insn_flags = CPU_MIPS64R6,
+.mmu_type = MMU_TYPE_R4000,
+},
+{
 .name = "Loongson-2E",
 .CP0_PRid = 0x6302,
 /*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/
-- 
2.1.0




[Qemu-devel] [PULL 13/28] target-mips: add compact and CP1 branches

2014-10-15 Thread Leon Alrae
From: Yongbok Kim 

Introduce MIPS32R6 Compact Branch instructions which do not have delay slot -
they have forbidden slot instead. However, current implementation does not
support forbidden slot yet.

Add also BC1EQZ and BC1NEZ instructions.

Signed-off-by: Yongbok Kim 
Signed-off-by: Leon Alrae 
---
 disas/mips.c|  67 ++-
 target-mips/translate.c | 473 ++--
 2 files changed, 523 insertions(+), 17 deletions(-)

diff --git a/disas/mips.c b/disas/mips.c
index 61313f4..8234369 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -1250,6 +1250,34 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"dalign",  "d,v,t",0x7c000224, 0xfc00063f, WR_d|RD_s|RD_t,   0, 
I64R6},
 {"bitswap", "d,w",  0x7c20, 0xffe007ff, WR_d|RD_t,0, 
I32R6},
 {"dbitswap","d,w",  0x7c24, 0xffe007ff, WR_d|RD_t,0, 
I64R6},
+{"balc","+p",   0xe800, 0xfc00, UBD|WR_31,0, 
I32R6},
+{"bc",  "+p",   0xc800, 0xfc00, UBD|WR_31,0, 
I32R6},
+{"jic", "t,o",  0xd800, 0xffe0, UBD|RD_t, 0, 
I32R6},
+{"beqzc",   "s,+p", 0xd800, 0xfc00, CBD|RD_s, 0, 
I32R6},
+{"jialc",   "t,o",  0xf800, 0xffe0, UBD|RD_t, 0, 
I32R6},
+{"bnezc",   "s,+p", 0xf800, 0xfc00, CBD|RD_s, 0, 
I32R6},
+{"beqzalc", "s,t,p",0x2000, 0xffe0, CBD|RD_s|RD_t,0, 
I32R6},
+{"bovc","s,t,p",0x2000, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
+{"beqc","s,t,p",0x2000, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
+{"bnezalc", "s,t,p",0x6000, 0xffe0, CBD|RD_s|RD_t,0, 
I32R6},
+{"bnvc","s,t,p",0x6000, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
+{"bnec","s,t,p",0x6000, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
+{"blezc",   "s,t,p",0x5800, 0xffe0, CBD|RD_s|RD_t,0, 
I32R6},
+{"bgezc",   "s,t,p",0x5800, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
+{"bgec","s,t,p",0x5800, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
+{"bgtzc",   "s,t,p",0x5c00, 0xffe0, CBD|RD_s|RD_t,0, 
I32R6},
+{"bltzc",   "s,t,p",0x5c00, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
+{"bltc","s,t,p",0x5c00, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
+{"blezalc", "s,t,p",0x1800, 0xffe0, CBD|RD_s|RD_t,0, 
I32R6},
+{"bgezalc", "s,t,p",0x1800, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
+{"bgeuc",   "s,t,p",0x1800, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
+{"bgtzalc", "s,t,p",0x1c00, 0xffe0, CBD|RD_s|RD_t,0, 
I32R6},
+{"bltzalc", "s,t,p",0x1c00, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
+{"bltuc",   "s,t,p",0x1c00, 0xfc00, CBD|RD_s|RD_t,0, 
I32R6},
+{"bc1eqz",  "T,p",  0x4520, 0xffe0, CBD|RD_T|FP_S|FP_D,   0, 
I32R6},
+{"bc1nez",  "T,p",  0x45a0, 0xffe0, CBD|RD_T|FP_S|FP_D,   0, 
I32R6},
+{"bc2eqz",  "E,p",  0x4920, 0xffe0, CBD|RD_C2,0, 
I32R6},
+{"bc2nez",  "E,p",  0x49a0, 0xffe0, CBD|RD_C2,0, 
I32R6},
 {"pref","k,o(b)",   0xcc00, 0xfc00, RD_b,  0,  
I4|I32|G3   },
 {"prefx",   "h,t(b)",  0x4c0f, 0xfc0007ff, RD_b|RD_t,  0,  
I4|I33  },
 {"nop", "", 0x, 0x, 0, 
INSN2_ALIAS,I1  }, /* sll */
@@ -3616,6 +3644,24 @@ print_insn_args (const char *d,
  (*info->fprintf_func) (info->stream, "0x%x", msbd + 1);
  break;
 
+case 'o':
+delta = (l >> OP_SH_DELTA_R6) & OP_MASK_DELTA_R6;
+if (delta & 0x8000) {
+delta |= ~0x;
+}
+(*info->fprintf_func) (info->stream, "%d", delta);
+break;
+
+case 'p':
+/* Sign extend the displacement with 26 bits.  */
+delta = (l >> OP_SH_DELTA) & OP_MASK_TARGET;
+if (delta & 0x200) {
+delta |= ~0x3FF;
+}
+info->target = (delta << 2) + pc + INSNLEN;
+(*info->print_address_func) (info->target, info);
+break;
+
case 't': /* Coprocessor 0 reg name */
  (*info->fprintf_func) (info->stream, "%s",
 mips_cp0_names[(l >> OP_SH_RT) &
@@ -3767,9 +3813,7 @@ print_insn_args (const char *d,
 
case 'j': /* Same as i, but sign-extended.  */
case 'o':
-delta = (opp->membership == I32R6) ?
-(l >> OP_SH_DELTA_R6) & OP_MASK_DELTA_R6 :
-(l >> OP_SH_DELTA) & OP_MASK_DELTA;
+delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
 
  if (delta & 0x8000)
delta |= ~0x;
@@ -4096,6 +4140,23 @@ 

[Qemu-devel] [PULL 14/28] target-mips: add AUI, LSA and PCREL instruction families

2014-10-15 Thread Leon Alrae
Signed-off-by: Leon Alrae 
Reviewed-by: Yongbok Kim 
---
 disas/mips.c|  42 +-
 target-mips/translate.c | 203 
 2 files changed, 228 insertions(+), 17 deletions(-)

diff --git a/disas/mips.c b/disas/mips.c
index 8234369..850cb65 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -407,6 +407,12 @@ struct mips_opcode
"+3" UDI immediate bits 6-20
"+4" UDI immediate bits 6-25
 
+   R6 immediates/displacements :
+   (adding suffix to 'o' to avoid adding new characters)
+   "+o"  9 bits immediate/displacement (shift = 7)
+   "+o1" 18 bits immediate/displacement (shift = 0)
+   "+o2" 19 bits immediate/displacement (shift = 0)
+
Other:
"()" parens surrounding optional value
","  separates operands
@@ -1217,6 +1223,17 @@ const struct mips_opcode mips_builtin_opcodes[] =
them first.  The assemblers uses a hash table based on the
instruction name anyhow.  */
 /* name,args,  match,  mask,   pinfo,  
membership */
+{"lwpc","s,+o2",0xec08, 0xfc18, WR_d, 0, 
I32R6},
+{"lwupc",   "s,+o2",0xec10, 0xfc18, WR_d, 0, 
I64R6},
+{"ldpc","s,+o1",0xec18, 0xfc1c, WR_d, 0, 
I64R6},
+{"addiupc", "s,+o2",0xec00, 0xfc18, WR_d, 0, 
I32R6},
+{"auipc",   "s,u",  0xec1e, 0xfc1f, WR_d, 0, 
I32R6},
+{"aluipc",  "s,u",  0xec1f, 0xfc1f, WR_d, 0, 
I32R6},
+{"daui","s,t,u",0x7400, 0xfc00, RD_s|WR_t,0, 
I64R6},
+{"dahi","s,u",  0x0406, 0xfc1f, RD_s, 0, 
I64R6},
+{"dati","s,u",  0x041e, 0xfc1f, RD_s, 0, 
I64R6},
+{"lsa", "d,s,t",0x0005, 0xfc00073f, WR_d|RD_s|RD_t,   0, 
I32R6},
+{"dlsa","d,s,t",0x0015, 0xfc00073f, WR_d|RD_s|RD_t,   0, 
I64R6},
 {"clz", "U,s",  0x0050, 0xfc1f07ff, WR_d|RD_s,0, 
I32R6},
 {"clo", "U,s",  0x0051, 0xfc1f07ff, WR_d|RD_s,0, 
I32R6},
 {"dclz","U,s",  0x0052, 0xfc1f07ff, WR_d|RD_s,0, 
I64R6},
@@ -1822,6 +1839,7 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"lld","t,o(b)",   0xd000, 0xfc00, LDD|RD_b|WR_t,  
0,  I3  },
 {"lld", "t,A(b)",  0,(int) M_LLD_AB,   INSN_MACRO, 0,  
I3  },
 {"lui", "t,u", 0x3c00, 0xffe0, WR_t,   0,  
I1  },
+{"aui", "s,t,u",0x3c00, 0xfc00, RD_s|WR_t,0, 
I32R6},
 {"luxc1",   "D,t(b)",  0x4c05, 0xfc00f83f, LDD|WR_D|RD_t|RD_b|FP_D, 0, 
I5|I33|N55},
 {"lw",  "t,o(b)",  0x8c00, 0xfc00, LDD|RD_b|WR_t,  0,  
I1  },
 {"lw",  "t,A(b)",  0,(int) M_LW_AB,INSN_MACRO, 0,  
I1  },
@@ -3645,10 +3663,28 @@ print_insn_args (const char *d,
  break;
 
 case 'o':
-delta = (l >> OP_SH_DELTA_R6) & OP_MASK_DELTA_R6;
-if (delta & 0x8000) {
-delta |= ~0x;
+switch (*(d+1)) {
+case '1':
+d++;
+delta = l & ((1 << 18) - 1);
+if (delta & 0x2) {
+delta |= ~0x1;
+}
+break;
+case '2':
+d++;
+delta = l & ((1 << 19) - 1);
+if (delta & 0x4) {
+delta |= ~0x3;
+}
+break;
+default:
+delta = (l >> OP_SH_DELTA_R6) & OP_MASK_DELTA_R6;
+if (delta & 0x8000) {
+delta |= ~0x;
+}
 }
+
 (*info->fprintf_func) (info->stream, "%d", delta);
 break;
 
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 06ececb..45ff5fc 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -75,6 +75,7 @@ enum {
 OPC_BGTZ = (0x07 << 26),
 OPC_BGTZL= (0x17 << 26),
 OPC_JALX = (0x1D << 26),  /* MIPS 16 only */
+OPC_DAUI = (0x1D << 26),
 OPC_JALXS= OPC_JALX | 0x5,
 /* Load and stores */
 OPC_LDL  = (0x1A << 26),
@@ -141,8 +142,25 @@ enum {
 /* Cache and prefetch */
 OPC_CACHE= (0x2F << 26),
 OPC_PREF = (0x33 << 26),
-/* Reserved major opcode */
-OPC_MAJOR3B_RESERVED = (0x3B << 26),
+/* PC-relative address computation / loads */
+OPC_PCREL= (0x3B << 26),
+};
+
+/* PC-relative address computation / loads  */
+#define MASK_OPC_PCREL_TOP2BITS(op)  (MASK_OP_MAJOR(op) | (op & (3 << 19)))
+#define MASK_OPC_PCREL_TOP5BITS(op)  (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
+enum {
+/* I

[Qemu-devel] [PULL 24/28] target-mips/dsp_helper.c: Remove unused function get_DSPControl_24()

2014-10-15 Thread Leon Alrae
From: Peter Maydell 

The function get_DSPControl_24() is unused; remove it.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Signed-off-by: Leon Alrae 
---
 target-mips/dsp_helper.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index 94083fb..2ea94a7 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -76,15 +76,6 @@ static inline void set_DSPControl_24(uint32_t flag, int len, 
CPUMIPSState *env)
   env->active_tc.DSPControl |= (target_ulong)flag << 24;
 }
 
-static inline uint32_t get_DSPControl_24(int len, CPUMIPSState *env)
-{
-  uint32_t filter;
-
-  filter = (0x01 << len) - 1;
-
-  return (env->active_tc.DSPControl >> 24) & filter;
-}
-
 static inline void set_DSPControl_pos(uint32_t pos, CPUMIPSState *env)
 {
 target_ulong dspc;
-- 
2.1.0




[Qemu-devel] [PULL 25/28] target-mips/op_helper.c: Remove unused do_lbu() function

2014-10-15 Thread Leon Alrae
From: Peter Maydell 

The do_lbu() function defined by the expansion of HELPER_LD() is
never used, so don't define it.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Signed-off-by: Leon Alrae 
---
 target-mips/op_helper.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index c48ee7f..5204ed8 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -90,7 +90,6 @@ static inline type do_##name(CPUMIPSState *env, target_ulong 
addr,  \
 }   \
 }
 #endif
-HELPER_LD(lbu, ldub, uint8_t)
 HELPER_LD(lw, ldl, int32_t)
 #ifdef TARGET_MIPS64
 HELPER_LD(ld, ldq, int64_t)
-- 
2.1.0




[Qemu-devel] [PULL 18/28] target-mips: do not allow Status.FR=0 mode in 64-bit FPU

2014-10-15 Thread Leon Alrae
Status.FR bit must be ignored on write and read as 1 when an implementation of
Release 6 of the Architecture in which a 64-bit floating point unit is
implemented.

Signed-off-by: Leon Alrae 
Reviewed-by: Yongbok Kim 
---
 target-mips/translate.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 6f57171..8088781 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -17951,6 +17951,12 @@ void cpu_state_reset(CPUMIPSState *env)
 }
 }
 #endif
+if ((env->insn_flags & ISA_MIPS32R6) &&
+(env->active_fpu.fcr0 & (1 << FCR0_F64))) {
+/* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
+env->CP0_Status |= (1 << CP0St_FR);
+}
+
 compute_hflags(env);
 cs->exception_index = EXCP_NONE;
 }
-- 
2.1.0




[Qemu-devel] [PULL 28/28] target-mips: Remove unused gen_load_ACX, gen_store_ACX and cpu_ACX

2014-10-15 Thread Leon Alrae
From: Peter Maydell 

Remove the functions gen_load_ACX and gen_store_ACX, which appear to have
been unused since they were first introduced many years ago. These functions
were the only places using the cpu_ACX[] array of TCG globals, so remove
that and its accompanying regnames_ACX[] as well.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Signed-off-by: Leon Alrae 
---
 target-mips/translate.c | 20 +---
 1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index c23cb94..446eb8a 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -1104,7 +1104,7 @@ enum {
 /* global register indices */
 static TCGv_ptr cpu_env;
 static TCGv cpu_gpr[32], cpu_PC;
-static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
+static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
 static TCGv cpu_dspctrl, btarget, bcond;
 static TCGv_i32 hflags;
 static TCGv_i32 fpu_fcr0, fpu_fcr31;
@@ -1195,10 +1195,6 @@ static const char * const regnames_LO[] = {
 "LO0", "LO1", "LO2", "LO3",
 };
 
-static const char * const regnames_ACX[] = {
-"ACX0", "ACX1", "ACX2", "ACX3",
-};
-
 static const char * const fregnames[] = {
 "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
 "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
@@ -1241,17 +1237,6 @@ static inline void gen_store_gpr (TCGv t, int reg)
 tcg_gen_mov_tl(cpu_gpr[reg], t);
 }
 
-/* Moves to/from ACX register.  */
-static inline void gen_load_ACX (TCGv t, int reg)
-{
-tcg_gen_mov_tl(t, cpu_ACX[reg]);
-}
-
-static inline void gen_store_ACX (TCGv t, int reg)
-{
-tcg_gen_mov_tl(cpu_ACX[reg], t);
-}
-
 /* Moves to/from shadow registers. */
 static inline void gen_load_srsgpr (int from, int to)
 {
@@ -17716,9 +17701,6 @@ void mips_tcg_init(void)
 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUMIPSState, active_tc.LO[i]),
regnames_LO[i]);
-cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
-offsetof(CPUMIPSState, 
active_tc.ACX[i]),
-regnames_ACX[i]);
 }
 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
  offsetof(CPUMIPSState, 
active_tc.DSPControl),
-- 
2.1.0




[Qemu-devel] [PULL 16/28] target-mips: add new Floating Point instructions

2014-10-15 Thread Leon Alrae
In terms of encoding MIPS32R6 MIN.fmt, MAX.fmt, MINA.fmt, MAXA.fmt replaced
MIPS-3D RECIP1, RECIP2, RSQRT1, RSQRT2 instructions.

In R6 all Floating Point instructions are supposed to be IEEE-2008 compliant
i.e. FIR.HAS2008 always 1. However, QEMU softfloat for MIPS has not been
updated yet.

Signed-off-by: Leon Alrae 
Reviewed-by: Yongbok Kim 
---
 disas/mips.c|  22 +++
 target-mips/helper.h|  20 +++
 target-mips/op_helper.c | 104 
 target-mips/translate.c | 441 +++-
 4 files changed, 543 insertions(+), 44 deletions(-)

diff --git a/disas/mips.c b/disas/mips.c
index 850cb65..fed2e5e 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -1263,6 +1263,28 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"cache",   "k,o(b)",   0x7c25, 0xfc7f, RD_b, 0, 
I32R6},
 {"seleqz",  "d,v,t",0x0035, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
 {"selnez",  "d,v,t",0x0037, 0xfc0007ff, WR_d|RD_s|RD_t,   0, 
I32R6},
+{"maddf.s", "D,S,T",0x4618, 0xffe0003f, WR_D|RD_S|RD_T|FP_S,  0, 
I32R6},
+{"maddf.d", "D,S,T",0x46200018, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,  0, 
I32R6},
+{"msubf.s", "D,S,T",0x4619, 0xffe0003f, WR_D|RD_S|RD_T|FP_S,  0, 
I32R6},
+{"msubf.d", "D,S,T",0x46200019, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,  0, 
I32R6},
+{"max.s",   "D,S,T",0x461e, 0xffe0003f, WR_D|RD_S|RD_T|FP_S,  0, 
I32R6},
+{"max.d",   "D,S,T",0x4620001e, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,  0, 
I32R6},
+{"maxa.s",  "D,S,T",0x461f, 0xffe0003f, WR_D|RD_S|RD_T|FP_S,  0, 
I32R6},
+{"maxa.d",  "D,S,T",0x4620001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,  0, 
I32R6},
+{"rint.s",  "D,S",  0x461a, 0x003f, WR_D|RD_S|FP_S,   0, 
I32R6},
+{"rint.d",  "D,S",  0x4620001a, 0x003f, WR_D|RD_S|FP_D,   0, 
I32R6},
+{"class.s", "D,S",  0x461b, 0x003f, WR_D|RD_S|FP_S,   0, 
I32R6},
+{"class.d", "D,S",  0x4620001b, 0x003f, WR_D|RD_S|FP_D,   0, 
I32R6},
+{"min.s",   "D,S,T",0x461c, 0xffe0003f, WR_D|RD_S|RD_T|FP_S,  0, 
I32R6},
+{"min.d",   "D,S,T",0x4620001c, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,  0, 
I32R6},
+{"mina.s",  "D,S,T",0x461d, 0xffe0003f, WR_D|RD_S|RD_T|FP_S,  0, 
I32R6},
+{"mina.d",  "D,S,T",0x4620001d, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,  0, 
I32R6},
+{"sel.s",   "D,S,T",0x4610, 0xffe0003f, WR_D|RD_S|RD_T|FP_S,  0, 
I32R6},
+{"sel.d",   "D,S,T",0x46200010, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,  0, 
I32R6},
+{"seleqz.s", "D,S,T",   0x4614, 0xffe0003f, WR_D|RD_S|RD_T|FP_S,  0, 
I32R6},
+{"seleqz.d", "D,S,T",   0x46200014, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,  0, 
I32R6},
+{"selnez.s", "D,S,T",   0x4617, 0xffe0003f, WR_D|RD_S|RD_T|FP_S,  0, 
I32R6},
+{"selnez.d", "D,S,T",   0x46200017, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,  0, 
I32R6},
 {"align",   "d,v,t",0x7c000220, 0xfc00073f, WR_d|RD_s|RD_t,   0, 
I32R6},
 {"dalign",  "d,v,t",0x7c000224, 0xfc00063f, WR_d|RD_s|RD_t,   0, 
I64R6},
 {"bitswap", "d,w",  0x7c20, 0xffe007ff, WR_d|RD_t,0, 
I32R6},
diff --git a/target-mips/helper.h b/target-mips/helper.h
index 5511dfc..9020c7b 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -202,6 +202,25 @@ DEF_HELPER_2(float_cvtw_d, i32, env, i64)
 DEF_HELPER_3(float_addr_ps, i64, env, i64, i64)
 DEF_HELPER_3(float_mulr_ps, i64, env, i64, i64)
 
+DEF_HELPER_FLAGS_1(float_class_s, TCG_CALL_NO_RWG_SE, i32, i32)
+DEF_HELPER_FLAGS_1(float_class_d, TCG_CALL_NO_RWG_SE, i64, i64)
+
+#define FOP_PROTO(op) \
+DEF_HELPER_4(float_ ## op ## _s, i32, env, i32, i32, i32) \
+DEF_HELPER_4(float_ ## op ## _d, i64, env, i64, i64, i64)
+FOP_PROTO(maddf)
+FOP_PROTO(msubf)
+#undef FOP_PROTO
+
+#define FOP_PROTO(op)\
+DEF_HELPER_3(float_ ## op ## _s, i32, env, i32, i32) \
+DEF_HELPER_3(float_ ## op ## _d, i64, env, i64, i64)
+FOP_PROTO(max)
+FOP_PROTO(maxa)
+FOP_PROTO(min)
+FOP_PROTO(mina)
+#undef FOP_PROTO
+
 #define FOP_PROTO(op)\
 DEF_HELPER_2(float_ ## op ## l_s, i64, env, i32) \
 DEF_HELPER_2(float_ ## op ## l_d, i64, env, i64) \
@@ -219,6 +238,7 @@ DEF_HELPER_2(float_ ## op ## _d, i64, env, i64)
 FOP_PROTO(sqrt)
 FOP_PROTO(rsqrt)
 FOP_PROTO(recip)
+FOP_PROTO(rint)
 #undef FOP_PROTO
 
 #define FOP_PROTO(op)   \
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index c9841e2..3f449ae 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2809,6 +2809,110 @@ FLOAT_UNOP(abs)
 FLOAT_UNOP(chs)
 #undef FLOAT_UNOP
 
+#define FLOAT_FMADDSUB(name, bits, muladd_arg)  \
+uint ## bits ## _t helper_float_ ## name (CPUMIPSState *env,\
+  uint ## bits ## _t fs,\
+  uint ## bits ## _t ft,\
+  uint ## bits ## _t fd)\
+{

[Qemu-devel] [PULL 17/28] target-mips: add new Floating Point Comparison instructions

2014-10-15 Thread Leon Alrae
From: Yongbok Kim 

Signed-off-by: Yongbok Kim 
Signed-off-by: Leon Alrae 
Reviewed-by: Aurelien Jarno 
---
 disas/mips.c|  44 +++
 target-mips/helper.h|  27 +++
 target-mips/op_helper.c | 111 ++
 target-mips/translate.c | 206 +++-
 4 files changed, 386 insertions(+), 2 deletions(-)

diff --git a/disas/mips.c b/disas/mips.c
index fed2e5e..5ebb5fd 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -1317,6 +1317,50 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"bc1nez",  "T,p",  0x45a0, 0xffe0, CBD|RD_T|FP_S|FP_D,   0, 
I32R6},
 {"bc2eqz",  "E,p",  0x4920, 0xffe0, CBD|RD_C2,0, 
I32R6},
 {"bc2nez",  "E,p",  0x49a0, 0xffe0, CBD|RD_C2,0, 
I32R6},
+{"cmp.af.s",   "D,S,T", 0x4680, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.un.s",   "D,S,T", 0x4681, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.eq.s",   "D,S,T", 0x4682, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.ueq.s",  "D,S,T", 0x4683, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.lt.s",   "D,S,T", 0x4684, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.ult.s",  "D,S,T", 0x4685, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.le.s",   "D,S,T", 0x4686, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.ule.s",  "D,S,T", 0x4687, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.saf.s",  "D,S,T", 0x4688, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.sun.s",  "D,S,T", 0x4689, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.seq.s",  "D,S,T", 0x468a, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.sueq.s", "D,S,T", 0x468b, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.slt.s",  "D,S,T", 0x468c, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.sult.s", "D,S,T", 0x468d, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.sle.s",  "D,S,T", 0x468e, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.sule.s", "D,S,T", 0x468f, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.or.s",   "D,S,T", 0x46800011, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.une.s",  "D,S,T", 0x46800012, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.ne.s",   "D,S,T", 0x46800013, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.sor.s",  "D,S,T", 0x46800019, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.sune.s", "D,S,T", 0x4680001a, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.sne.s",  "D,S,T", 0x4680001b, 0xffe0003f, RD_S|RD_T|WR_D|FP_S,  0, 
I32R6},
+{"cmp.af.d",   "D,S,T", 0x46a0, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.un.d",   "D,S,T", 0x46a1, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.eq.d",   "D,S,T", 0x46a2, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.ueq.d",  "D,S,T", 0x46a3, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.lt.d",   "D,S,T", 0x46a4, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.ult.d",  "D,S,T", 0x46a5, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.le.d",   "D,S,T", 0x46a6, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.ule.d",  "D,S,T", 0x46a7, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.saf.d",  "D,S,T", 0x46a8, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.sun.d",  "D,S,T", 0x46a9, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.seq.d",  "D,S,T", 0x46aa, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.sueq.d", "D,S,T", 0x46ab, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.slt.d",  "D,S,T", 0x46ac, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.sult.d", "D,S,T", 0x46ad, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.sle.d",  "D,S,T", 0x46ae, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.sule.d", "D,S,T", 0x46af, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.or.d",   "D,S,T", 0x46a00011, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.une.d",  "D,S,T", 0x46a00012, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.ne.d",   "D,S,T", 0x46a00013, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.sor.d",  "D,S,T", 0x46a00019, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.sune.d", "D,S,T", 0x46a0001a, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
+{"cmp.sne.d",  "D,S,T", 0x46a0001b, 0xffe0003f, RD_S|RD_T|WR_D|FP_D,  0, 
I32R6},
 {"pref","k,o(b)",   0xcc00, 0xfc00, RD_b,  0,  
I4|I32|G3   },
 {"prefx",   "h,t(b)",  0x4c0f, 0xfc0007ff, RD_b|RD_t,  0,  
I4|I33  },
 {"nop", "", 0x, 0x, 0, 
INSN2_ALIAS,I1  }, /* sll */
diff --git a/target-mips/helper.h b/target-mips/helper.h
index 9020c7b..a127db5 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -304,6 +304,33 @@ FOP_PROTO(le)
 FOP_PROTO(ngt)
 #undef FOP_PROTO
 
+#def

  1   2   3   >