[Qemu-devel] [RFC PATCH v1 2/3] spapr: Remove alignment gap b/n RAM and hotplug regions

2016-06-02 Thread Bharata B Rao
Let the alignment b/n RAM and memory hotplug region be equal to
LMB size (256MB) so that there is no gap b/n RAM and hotplug region.
This new alignment is true for only pseries-2.7 onwards and the older
machine types continue to have the earlier 1GB alignment.

Suggested-by: David Gibson 
Signed-off-by: Bharata B Rao 
---
 hw/ppc/spapr.c | 11 ++-
 include/hw/ppc/spapr.h |  5 ++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 30b9731..623c35f 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1825,7 +1825,7 @@ static void ppc_spapr_init(MachineState *machine)
 }
 
 spapr->hotplug_memory.base = ROUND_UP(machine->ram_size,
-  SPAPR_HOTPLUG_MEM_ALIGN);
+  smc->hotplug_alignment);
 memory_region_init(>hotplug_memory.mr, OBJECT(spapr),
"hotplug-memory", hotplug_mem_size);
 memory_region_add_subregion(sysmem, spapr->hotplug_memory.base,
@@ -2294,6 +2294,7 @@ static void spapr_machine_class_init(ObjectClass *oc, 
void *data)
 mc->cpu_index_to_socket_id = spapr_cpu_index_to_socket_id;
 
 smc->dr_lmb_enabled = true;
+smc->hotplug_alignment = SPAPR_MEMORY_BLOCK_SIZE;
 fwc->get_dev_path = spapr_get_fw_dev_path;
 nc->nmi_monitor_handler = spapr_nmi;
 }
@@ -2369,8 +2370,16 @@ static void 
spapr_machine_2_6_instance_options(MachineState *machine)
 
 static void spapr_machine_2_6_class_options(MachineClass *mc)
 {
+sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
 spapr_machine_2_7_class_options(mc);
 SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_6);
+
+/*
+ * 2.6 and older types supported 1GB alignment gap b/n RAM
+ * and hotplug memory region.
+ */
+smc->hotplug_alignment = G_BYTE;
 }
 
 DEFINE_SPAPR_MACHINE(2_6, "2.6", false);
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 971df3d..b2aeb15 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -37,6 +37,8 @@ struct sPAPRMachineClass {
 /*< public >*/
 bool dr_lmb_enabled;   /* enable dynamic-reconfig/hotplug of LMBs */
 bool use_ohci_by_default;  /* use USB-OHCI instead of XHCI */
+hwaddr hotplug_alignment;  /* controls the alignment b/n RAM and hotplug
+  regions */
 };
 
 /**
@@ -610,9 +612,6 @@ int spapr_rng_populate_dt(void *fdt);
  */
 #define SPAPR_MAX_RAM_SLOTS 32
 
-/* 1GB alignment for hotplug memory region */
-#define SPAPR_HOTPLUG_MEM_ALIGN (1ULL << 30)
-
 /*
  * Number of 32 bit words in each LMB list entry in ibm,dynamic-memory
  * property under ibm,dynamic-reconfiguration-memory node.
-- 
2.1.0




Re: [Qemu-devel] [virtio-comment] [PATCH 5/6 Resend] Vhost-pci RFC: Future Security Enhancement

2016-06-02 Thread Wang, Wei W
On Thu 6/2/2016 5:27 PM, Jan Kiszka wrote:
> On 2016-05-31 10:00, Wang, Wei W wrote:
> > On Mon 5/30/2016 2:24 PM, Jan Kiszka Wrote:
> >> On 2016-05-29 10:11, Wei Wang wrote:
> >>> Signed-off-by: Wei Wang 
> >>> ---
> >>>  FutureWorks | 21 +
> >>>  1 file changed, 21 insertions(+)
> >>>  create mode 100644 FutureWorks
> >>>
> >>> diff --git a/FutureWorks b/FutureWorks new file mode 100644 index
> >>> 000..210edcd
> >>> --- /dev/null
> >>> +++ b/FutureWorks
> >>> @@ -0,0 +1,21 @@
> >>> +The vhost-pci design is currently suitable for a group of VMs who
> >>> +trust each other. To extend it to a more general use case, two
> >>> +security features can be added in the future.
> >>
> >> Sounds a bit like security is just "nice to have" in the foreseen use
> >> cases of this mechanism. Is that really true?
> >
> > Not really. It's usually a tradeoff between performance and security,
> > so I think having security doesn't always mean "Nice" :-)
> 
> I don't disagree. I'm rather wondering if the variant without isolation has 
> valid
> use-cases at all.


I think one of the use examples is Network Function Virtualization. A group of 
Network Function VMs are chained together. AFAIK, compared to isolation,
performance is more important to them.


> > Instead of proposing a compromised solution, we can actually offer two
> independent solutions, performance oriented vhost-pci (let's call it fast 
> vhost-pci)
> and security oriented vhost-pci (say, secure vhost-pci). It's up to the users 
> to
> choose which one to use according to their use cases. So, the secured version 
> of
> vhost-pci can be viewed as another option for users (not a replacement of this
> proposal).
> >
> > Here is a use example:
> > There are two groups of VMs running on the same host machine. The frequent
> inter-VM communication between VMs in Group A can choose the fast vhost-pci
> mechanism. In a special case that a VM from Group A needs to communicate
> with a VM from Group B, they should set up a new NIC each and specify the use
> of the secure vhost-pci.
> > Since the secure vhost-pci is on our future plan, the traditional 
> > vhost-user can
> be an option for that inter-Group communication currently.
> >
> >>> +
> >>> +1 vIOMMU
> >>> +vIOMMU provides the driver VM with the ability to restrict the
> >>> +device VM to transiently access a specified portion of its memory.
> >>> +The vhost-pci design proposed in this RFC can be extended to access
> >>> +the driver VM's memory with vIOMMU. Precisely, the vIOMMU engine in
> >>> +the driver VM configures access permissions (R/W) for the vhost-pci
> >>> +device to access its memory. More details can be found at
> >>> +https://wiki.opnfv.org/display/kvm/Vm2vm+Mst and
> >>> +https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg03993.html
> >>
> >> Do you have performance estimates on this approach already?
> >>
> >> One challenge should be how to let the VMs reuse existing buffer
> >> mappings so that the vIOMMU isn't continuously reprogrammed - which
> >> is likely not very efficient.
> >
> > I think one option here is to reserve a large block of GPA area (like a 
> > memory
> pool). The buffers are allocated from and freed to the pool.
> 
> That's basically communication via shared memory regions (like ivshmem).
> We'll do this for safety and security critical setups where we need to keep 
> the
> hypervisor complexity minimal (we cannot effort a vIOMMU implementation,
> e.g.). Possibly, there is some room for sharing solution details on the guest 
> side
> here.

I think people from redhat have started digging into the guest side vIOMMU. 

> >
> > Another one would be using batching. For example, set up a batch of 32
> buffers (just give the starting guest physical address, and the 32 buffers are
> guest-physically continuous) each time.
> >
> >> The other is how to hand over packets/buffers in a chain of multiple
> >> VMs. Ideally, there is already a hand-over from sender to the first
> >> receiver so that the sender can no longer mess with the packet after the
> receiver started processing it.
> >> However, that will work against efficiency.
> >>
> >> Essentially, it's the old IPC question of remap vs. copy here. The rest is 
> >> "just"
> >> interfaces to exploit this elegantly.
> >
> > There are several ways to do a remapping. The remapping we are using here is
> to have the entire driver VM's memory mapped by the device VM, that is, the
> driver VM's memory is completely shared with the device VM.
> 
> I know - that's what I would call "without isolation".
> 
> >
> > If I understand that old remapping based IPC problem correctly, this kind of
> remapping requires a high degree of coordination between the two parts (i.e.
> the device VM and the driver VM). I think "virtq" is right the coordination
> mechanism here - the device VM grabs and fills a buffer from the available 
> ring
> and puts the filled buffer to the used ring,  so I don't 

[Qemu-devel] [RFC PATCH v1 1/3] spapr: Introduce pseries-2.7 machine type

2016-06-02 Thread Bharata B Rao
Signed-off-by: Bharata B Rao 
---
 hw/ppc/spapr.c | 22 --
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 44e401a..30b9731 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2344,18 +2344,36 @@ static const TypeInfo spapr_machine_info = {
 type_init(spapr_machine_register_##suffix)
 
 /*
+ * pseries-2.7
+ */
+static void spapr_machine_2_7_instance_options(MachineState *machine)
+{
+}
+
+static void spapr_machine_2_7_class_options(MachineClass *mc)
+{
+/* Defaults for the latest behaviour inherited from the base class */
+}
+
+DEFINE_SPAPR_MACHINE(2_7, "2.7", true);
+
+/*
  * pseries-2.6
  */
+#define SPAPR_COMPAT_2_6 \
+HW_COMPAT_2_6
+
 static void spapr_machine_2_6_instance_options(MachineState *machine)
 {
 }
 
 static void spapr_machine_2_6_class_options(MachineClass *mc)
 {
-/* Defaults for the latest behaviour inherited from the base class */
+spapr_machine_2_7_class_options(mc);
+SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_6);
 }
 
-DEFINE_SPAPR_MACHINE(2_6, "2.6", true);
+DEFINE_SPAPR_MACHINE(2_6, "2.6", false);
 
 /*
  * pseries-2.5
-- 
2.1.0




[Qemu-devel] [RFC PATCH v1 0/3] spapr: Work around the memory hotplug failure with DDW

2016-06-02 Thread Bharata B Rao
Memory hotplug can fail when upcoming, yet-to-be-upstreamed, 2.7 feature DDW
is enabled. This happens due to a guest kernel bug which results in DDW code
in QEMU obtaining incorrect value of max possible memory address. This incorrect
max mem value results in incorrect DDW size which later causes hotplug
to fail.

While guest fix has been proposed, this patchset works around the problem
within QEMU. The workaround is described in patch 3/3. In summary this
patchset changes the alignment gap b/n RAM and hotplug region for pseries-2.7
onwards so that memory hotplug works with buggy guests when DDW is present
from 2.7 onwards.

v0: https://lists.nongnu.org/archive/html/qemu-ppc/2016-04/msg00226.html

Bharata B Rao (3):
  spapr: Introduce pseries-2.7 machine type
  spapr: Remove alignment gap b/n RAM and hotplug regions
  spapr: spapr: Work around the memory hotplug failure with DDW

 hw/ppc/spapr.c | 92 +++---
 include/hw/ppc/spapr.h | 10 +++---
 2 files changed, 77 insertions(+), 25 deletions(-)

-- 
2.1.0




[Qemu-devel] [RFC PATCH v1 3/3] spapr: spapr: Work around the memory hotplug failure with DDW

2016-06-02 Thread Bharata B Rao
Memory hotplug can fail for some combinations of RAM and maxmem when
DDW is enabled in the presence of devices like nec-usb-xhci. DDW depends
on maximum addressable memory returned by guest and this value is currently
being calculated wrongly by the guest kernel routine memory_hotplug_max().
While there is an attempt to fix the guest kernel, this patch works
around the problem within QEMU itself.

memory_hotplug_max() routine in the guest kernel arrives at max
addressable memory by multiplying lmb-size with the lmb-count obtained
from ibm,dynamic-memory property. There are two assumptions here:

- All LMBs are part of ibm,dynamic memory: This is not true for PowerKVM
  where only hot-pluggable LMBs are present in this property.
- The memory area comprising of RAM and hotplug region is contiguous: This
  needn't be true always for PowerKVM as there can be gap between
  boot time RAM and hotplug region.

This work around involves having all the LMBs (RMA, rest of the boot time
LMBs and hot-pluggable LMBs) as part of ibm,dynamic-memory so that
guest kernel's calculation of max addressable memory comes out correct
resulting in correct DDW value which prevents memory hotplug failures.
memory@0 is created for RMA, but RMA LMBs are also represented as
"reserved" LMBs in ibm,dynamic-memory. Parts of this are essenitally a
revert of e8f986fc57a664a74b9f685b466506366a15201b.

In addition to this, the alignment of hotplug memory region is reduced from
current 1G to 256M (LMB size in PowerKVM) so that we don't end up with any
gaps between boot time RAM and hotplug region.

Signed-off-by: Bharata B Rao 
---
 hw/ppc/spapr.c | 59 +++---
 include/hw/ppc/spapr.h |  5 +++--
 2 files changed, 45 insertions(+), 19 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 623c35f..3dfbc37 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -569,7 +569,6 @@ static int spapr_populate_memory(sPAPRMachineState *spapr, 
void *fdt)
 }
 if (!mem_start) {
 /* ppc_spapr_init() checks for rma_size <= node0_size already */
-spapr_populate_memory_node(fdt, i, 0, spapr->rma_size);
 mem_start += spapr->rma_size;
 node_size -= spapr->rma_size;
 }
@@ -762,18 +761,13 @@ static int spapr_populate_drconf_memory(sPAPRMachineState 
*spapr, void *fdt)
 int ret, i, offset;
 uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE;
 uint32_t prop_lmb_size[] = {0, cpu_to_be32(lmb_size)};
-uint32_t nr_lmbs = (machine->maxram_size - machine->ram_size)/lmb_size;
+uint32_t nr_rma_lmbs = spapr->rma_size / lmb_size;
+uint32_t nr_lmbs = machine->maxram_size / lmb_size;
+uint32_t nr_assigned_lmbs = machine->ram_size / lmb_size;
 uint32_t *int_buf, *cur_index, buf_len;
 int nr_nodes = nb_numa_nodes ? nb_numa_nodes : 1;
 
 /*
- * Don't create the node if there are no DR LMBs.
- */
-if (!nr_lmbs) {
-return 0;
-}
-
-/*
  * Allocate enough buffer size to fit in ibm,dynamic-memory
  * or ibm,associativity-lookup-arrays
  */
@@ -805,9 +799,15 @@ static int spapr_populate_drconf_memory(sPAPRMachineState 
*spapr, void *fdt)
 for (i = 0; i < nr_lmbs; i++) {
 sPAPRDRConnector *drc;
 sPAPRDRConnectorClass *drck;
-uint64_t addr = i * lmb_size + spapr->hotplug_memory.base;;
+uint64_t addr;
 uint32_t *dynamic_memory = cur_index;
 
+if (i < nr_assigned_lmbs) {
+addr = i * lmb_size;
+} else {
+addr = (i - nr_assigned_lmbs) * lmb_size +
+spapr->hotplug_memory.base;
+}
 drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_LMB,
addr/lmb_size);
 g_assert(drc);
@@ -820,7 +820,11 @@ static int spapr_populate_drconf_memory(sPAPRMachineState 
*spapr, void *fdt)
 dynamic_memory[4] = cpu_to_be32(numa_get_node(addr, NULL));
 if (addr < machine->ram_size ||
 memory_region_present(get_system_memory(), addr)) {
-dynamic_memory[5] = cpu_to_be32(SPAPR_LMB_FLAGS_ASSIGNED);
+if (i < nr_rma_lmbs) {
+dynamic_memory[5] = cpu_to_be32(SPAPR_LMB_FLAGS_RESERVED);
+} else {
+dynamic_memory[5] = cpu_to_be32(SPAPR_LMB_FLAGS_ASSIGNED);
+}
 } else {
 dynamic_memory[5] = cpu_to_be32(0);
 }
@@ -882,6 +886,8 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
 /* Generate ibm,dynamic-reconfiguration-memory node if required */
 if (memory_update && smc->dr_lmb_enabled) {
 _FDT((spapr_populate_drconf_memory(spapr, fdt)));
+} else {
+_FDT((spapr_populate_memory(spapr, fdt)));
 }
 
 /* Pack resulting tree */
@@ -919,10 +925,23 @@ static void spapr_finalize_fdt(sPAPRMachineState *spapr,
 /* open out the base tree into a temp buffer 

Re: [Qemu-devel] [for-2.7 PATCH v3 08/15] spapr: convert boot CPUs into CPU core devices

2016-06-02 Thread David Gibson
On Thu, May 12, 2016 at 09:18:18AM +0530, Bharata B Rao wrote:
> Introduce sPAPRMachineClass.dr_cpu_enabled to indicate support for
> CPU core hotplug. Initialize boot time CPUs as core deivces and prevent
> topologies that result in partially filled cores. Both of these are done
> only if CPU core hotplug is supported.
> 
> Note: An unrelated change in the call to xics_system_init() is done
> in this patch as it makes sense to use the local variable smt introduced
> in this patch instead of kvmppc_smt_threads() call here.
> 
> TODO: We derive sPAPR core type by looking at -cpu . However
> we don't take care of "compat=" feature yet for boot time as well
> as hotplug CPUs.
> 
> Signed-off-by: Bharata B Rao 

This will need some tweaking for the changes I made to earlier
patches, otherwise only a couple of tiny nits.

Reviewed-by: David Gibson 

> ---
>  hw/ppc/spapr.c  | 76 
> +++--
>  hw/ppc/spapr_cpu_core.c | 58 +++
>  include/hw/ppc/spapr.h  |  2 ++
>  include/hw/ppc/spapr_cpu_core.h |  3 ++
>  4 files changed, 129 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 95db047..0f64218 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -65,6 +65,7 @@
>  
>  #include "hw/compat.h"
>  #include "qemu/cutils.h"
> +#include "hw/ppc/spapr_cpu_core.h"
>  
>  #include 
>  
> @@ -1605,6 +1606,10 @@ static void spapr_boot_set(void *opaque, const char 
> *boot_device,
>  machine->boot_order = g_strdup(boot_device);
>  }
>  
> +/*
> + * TODO: Check if some of these can be moved to rtas_start_cpu() where
> + * a few other things required for hotplugged CPUs are being done.
> + */
>  void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu, Error **errp)
>  {
>  CPUPPCState *env = >env;
> @@ -1628,6 +1633,7 @@ void spapr_cpu_init(sPAPRMachineState *spapr, 
> PowerPCCPU *cpu, Error **errp)
>  xics_cpu_setup(spapr->icp, cpu);
>  
>  qemu_register_reset(spapr_cpu_reset, cpu);
> +spapr_cpu_reset(cpu);
>  }
>  
>  /*
> @@ -1711,7 +1717,6 @@ static void ppc_spapr_init(MachineState *machine)
>  const char *kernel_filename = machine->kernel_filename;
>  const char *kernel_cmdline = machine->kernel_cmdline;
>  const char *initrd_filename = machine->initrd_filename;
> -PowerPCCPU *cpu;
>  PCIHostState *phb;
>  int i;
>  MemoryRegion *sysmem = get_system_memory();
> @@ -1725,6 +1730,22 @@ static void ppc_spapr_init(MachineState *machine)
>  long load_limit, fw_size;
>  bool kernel_le = false;
>  char *filename;
> +int smt = kvmppc_smt_threads();
> +int spapr_cores = smp_cpus / smp_threads;
> +int spapr_max_cores = max_cpus / smp_threads;
> +
> +if (smc->dr_cpu_enabled) {
> +if (smp_cpus % smp_threads) {
> +error_report("smp_cpus (%u) must be multiple of threads (%u)",
> + smp_cpus, smp_threads);
> +exit(1);
> +}
> +if (max_cpus % smp_threads) {
> +error_report("max_cpus (%u) must be multiple of threads (%u)",
> + max_cpus, smp_threads);
> +exit(1);
> +}
> +}
>  
>  msi_nonbroken = true;
>  
> @@ -1771,8 +1792,7 @@ static void ppc_spapr_init(MachineState *machine)
>  
>  /* Set up Interrupt Controller before we create the VCPUs */
>  spapr->icp = xics_system_init(machine,
> -  DIV_ROUND_UP(max_cpus * 
> kvmppc_smt_threads(),
> -   smp_threads),
> +  DIV_ROUND_UP(max_cpus * smt, smp_threads),
>XICS_IRQS, _fatal);
>  
>  if (smc->dr_lmb_enabled) {
> @@ -1783,13 +1803,37 @@ static void ppc_spapr_init(MachineState *machine)
>  if (machine->cpu_model == NULL) {
>  machine->cpu_model = kvm_enabled() ? "host" : "POWER7";
>  }
> -for (i = 0; i < smp_cpus; i++) {
> -cpu = cpu_ppc_init(machine->cpu_model);
> -if (cpu == NULL) {
> -error_report("Unable to find PowerPC CPU definition");
> -exit(1);
> +
> +if (smc->dr_cpu_enabled) {
> +spapr->cores = g_new0(Object *, spapr_max_cores);
> +
> +for (i = 0; i < spapr_cores; i++) {
> +int core_dt_id = i * smt;
> +char *type = spapr_get_cpu_core_type(machine->cpu_model);

Probably makes sense to move this lookup outside the loop.

> +Object *core;
> +
> +if (!object_class_by_name(type)) {
> +error_report("Unable to find sPAPR CPU Core definition");
> +exit(1);
> +}
> +
> +core  = object_new(type);
> +g_free(type);
> +object_property_set_int(core, smp_threads, "threads",
> +_fatal);
> +

Re: [Qemu-devel] [for-2.7 PATCH v3 07/15] spapr: Abstract CPU core device and type specific core devices

2016-06-02 Thread David Gibson
On Thu, May 12, 2016 at 09:18:17AM +0530, Bharata B Rao wrote:
> Add sPAPR specific abastract CPU core device that is based on generic
> CPU core device. Use this as base type to create sPAPR CPU specific core
> devices.
> 
> TODO:
> - Add core types for other remaining CPU types
> - Handle CPU model alias correctly
> 
> Signed-off-by: Bharata B Rao 

This is looking pretty cood, but there's some minor changes I'd like
to see.

> ---
>  hw/ppc/Makefile.objs|   1 +
>  hw/ppc/spapr.c  |   3 +-
>  hw/ppc/spapr_cpu_core.c | 168 
> 
>  include/hw/ppc/spapr.h  |   1 +
>  include/hw/ppc/spapr_cpu_core.h |  28 +++
>  5 files changed, 199 insertions(+), 2 deletions(-)
>  create mode 100644 hw/ppc/spapr_cpu_core.c
>  create mode 100644 include/hw/ppc/spapr_cpu_core.h
> 
> diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
> index c1ffc77..5cc6608 100644
> --- a/hw/ppc/Makefile.objs
> +++ b/hw/ppc/Makefile.objs
> @@ -4,6 +4,7 @@ obj-y += ppc.o ppc_booke.o
>  obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o
>  obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
>  obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o
> +obj-$(CONFIG_PSERIES) += spapr_cpu_core.o
>  ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy)
>  obj-y += spapr_pci_vfio.o
>  endif
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index b69995e..95db047 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1605,8 +1605,7 @@ static void spapr_boot_set(void *opaque, const char 
> *boot_device,
>  machine->boot_order = g_strdup(boot_device);
>  }
>  
> -static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
> -   Error **errp)
> +void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu, Error **errp)

I think this function should actually move into spapr_cpu_core.c

>  {
>  CPUPPCState *env = >env;
>  
> diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
> new file mode 100644
> index 000..af63ed9
> --- /dev/null
> +++ b/hw/ppc/spapr_cpu_core.c
> @@ -0,0 +1,168 @@
> +/*
> + * sPAPR CPU core device, acts as container of CPU thread devices.
> + *
> + * Copyright (C) 2016 Bharata B Rao 
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +#include "hw/cpu/core.h"
> +#include "hw/ppc/spapr_cpu_core.h"
> +#include "hw/ppc/spapr.h"
> +#include "hw/boards.h"
> +#include "qapi/error.h"
> +#include 
> +#include "target-ppc/kvm_ppc.h"
> +
> +static void spapr_cpu_core_create_threads(DeviceState *dev, int threads,
> +  Error **errp)

This function could be folded into spapr_cpu_core_realize(), that's
the only caller and they're both fairly short.

> +{
> +int i;
> +Error *local_err = NULL;
> +sPAPRCPUCore *core = SPAPR_CPU_CORE(OBJECT(dev));
> +
> +for (i = 0; i < threads; i++) {
> +char id[32];
> +
> +object_initialize(>threads[i], sizeof(core->threads[i]),
> +  object_class_get_name(core->cpu));

Given we have to go from the class pointer to the class name to
actually use it here, maybe we would be better off storing the name
rather than a class pointer.  Up to you, I'm happy either way.

> +snprintf(id, sizeof(id), "thread[%d]", i);
> +object_property_add_child(OBJECT(core), id, 
> OBJECT(>threads[i]),
> +  _err);
> +if (local_err) {
> +goto err;
> +}
> +}
> +return;
> +
> +err:
> +while (--i) {
> +object_unparent(OBJECT(>threads[i]));

Is this safe if some of the threads haven't been initialized?

> +}
> +error_propagate(errp, local_err);
> +}
> +
> +static int spapr_cpu_core_realize_child(Object *child, void *opaque)
> +{
> +Error **errp = opaque;
> +sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
> +CPUState *cs = CPU(child);
> +PowerPCCPU *cpu = POWERPC_CPU(cs);
> +
> +object_property_set_bool(child, true, "realized", errp);
> +if (*errp) {
> +return 1;
> +}
> +
> +spapr_cpu_init(spapr, cpu, errp);
> +if (*errp) {
> +return 1;
> +}
> +return 0;
> +}
> +
> +static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
> +{
> +sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
> +CPUCore *cc = CPU_CORE(OBJECT(dev));
> +Error *local_err = NULL;
> +
> +sc->threads = g_new0(PowerPCCPU, cc->threads);

This isn't quite safe, because it assume the structure size for all
the threads is that of PowerPCCPU.  That's true now, but cpu thread
subtypes could in theory extend that structure with subtype specific
fields.  I think we need to actually look up the class instance size
here.

> +

Re: [Qemu-devel] [PATCH 4/7] scsi-disk: introduce dma_readv and dma_writev

2016-06-02 Thread Mark Cave-Ayland
On 03/06/16 03:56, xiaoqiang zhao wrote:

> 在 2016年06月02日 03:07, Mark Cave-Ayland 写道:
>> On 23/05/16 13:54, Paolo Bonzini wrote:
>>
>>> >These are replacements for blk_aio_preadv and blk_aio_pwritev that
>>> allow
>>> >customization of the data path.  They reuse the DMA helpers' DMAIOFunc
>>> >callback type, so that the same function can be used in either the
>>> >QEMUSGList or the bounce-buffered case.
>>> >
>>> >This customization will be needed in the next patch to do zero-copy
>>> >SG_IO on scsi-block.
>>> >
>>> >Signed-off-by: Paolo Bonzini
>>> >---
>>> >  hw/scsi/scsi-disk.c | 63
>>> +++--
>>> >  1 file changed, 52 insertions(+), 11 deletions(-)
>>> >
>> Hi Paolo,
>>
>> This patch appears to break qemu-system-sparc booting from CDROM with
>> the following command line:
>>
>> ./qemu-system-sparc -cdrom debian-40r4a-sparc-netinst.iso -boot d
>>
>> Instead of booting straight into SILO, OpenBIOS hangs when trying to
>> read from the CDROM device.
> Paolo:
>   By using git bisect on master branch , I found this patch also break
> qemu-system-arm from booting.
>   command line:
>  qemu-system-arm -M versatilepb -kernel vmlinuz-3.2.0-4-versatile
> -initrd initrd.img-3.2.0-4-versatile -hda
> /home/hitmoon/debian_wheezy_armel_standard.qcow2 -append 'root=/dev/sda1'
> 
>  The booting process stops at mounting the root partition and after
> timeout droped into a initramfs shell. The device '/dev/sda1' is
> presented . I guess it can not read properly from sda1.

I've just sent through a patch which fixes the issue for me - please
test and report back!

Paolo - not sure if it's worth a follow-up patch that renames the
relevant _readv/_writev functions in scsi-disk.c to _preadv/_pwritev to
try and help avoid such confusion in future?


ATB,

Mark.




[Qemu-devel] [PATCH] scsi-disk: fix reads from scsi-disk devices

2016-06-02 Thread Mark Cave-Ayland
Commit fcaafb1001b9c42817714dd3b2aadcfdb997b53d accidentally broke reads from
scsi-disk devices when being updated from its original form to use the new
byte-based block functions. Add the extra missing sector to offset conversion
in order to restore read functionality.

Signed-off-by: Mark Cave-Ayland 
---
 hw/scsi/scsi-disk.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index ace65e0..ab7cf9c 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -347,7 +347,7 @@ static void scsi_do_read(SCSIDiskReq *r, int ret)
 scsi_init_iovec(r, SCSI_DMA_BUF_SIZE);
 block_acct_start(blk_get_stats(s->qdev.conf.blk), >acct,
  r->qiov.size, BLOCK_ACCT_READ);
-r->req.aiocb = sdc->dma_readv(r->sector, >qiov,
+r->req.aiocb = sdc->dma_readv(r->sector << BDRV_SECTOR_BITS, >qiov,
   scsi_read_complete, r, r);
 }
 
-- 
1.7.10.4




Re: [Qemu-devel] [for-2.7 PATCH v3 06/15] cpu: Abstract CPU core type

2016-06-02 Thread David Gibson
On Thu, Jun 02, 2016 at 03:12:09PM -0300, Eduardo Habkost wrote:
> On Thu, Jun 02, 2016 at 01:38:58PM +1000, David Gibson wrote:
> > On Thu, May 12, 2016 at 09:18:16AM +0530, Bharata B Rao wrote:
> > > Add an abstract CPU core type that could be used by machines that want
> > > to define and hotplug CPUs in core granularity.
> > > 
> > > Signed-off-by: Bharata B Rao 
> > > Signed-off-by: Igor Mammedov 
> > >[Integer core property]
> > > Reviewed-by: David Gibson 
> > 
> > Igor, Eduardo,
> > 
> > Do you think we're comfortable enough with this abstract core concept
> > to merge it now?  If so which tree should it go through?
> 
> TBH, I haven't reviewed the concept carefully. I hoped that
> people that spent more time thinking about long-term plans
> (especially Andreas) would help move the discussion forward, but
> Andreas is moving away from QOM CPU.
> 
> I need to review the previous discussions more carefully, but the
> concept looks simple enough to me, and I don't think we should
> hold spapr work because we want a Grand Plan for generic CPU
> abstractions to be finished first. If David, Igor, and the people
> working on spapr are happy with it, I trust their judgement.
> 
> I just wish the interface was better documented, especially the
> meaning of the "core" and "threads" properties. I would prefer to
> have "core-id" as the property name instead of "core" (most of
> the error messages related to it (in patch 08/15) say "core id").

Ok, I've renamed the properties to 'core-id' and 'nr-threads' as I
merged, which I think is clearer.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [for-2.7 PATCH v3 05/15] qdev: hotplug: Introduce HotplugHandler.pre_plug() callback

2016-06-02 Thread David Gibson
On Thu, Jun 02, 2016 at 11:32:13AM +0200, Igor Mammedov wrote:
> On Thu, 2 Jun 2016 11:15:44 +1000
> David Gibson  wrote:
> 
> > On Thu, May 12, 2016 at 09:18:15AM +0530, Bharata B Rao wrote:
> > > From: Igor Mammedov 
> > > 
> > > pre_plug callback is to be called before device.realize() is
> > > executed. This would allow to check/set device's properties from
> > > HotplugHandler.
> > > 
> > > Signed-off-by: Igor Mammedov 
> > > Signed-off-by: Bharata B Rao 
> > > Reviewed-by: David Gibson 
> > 
> > Igor,  do you think we're ready to merge this?
> Yes, I think so.
> 
> > 
> > If so, do you want to take it through your tree, or should I take it
> > through the ppc tree?
> Please take it through your tree, along with the rest patches
> in this series.

Ok, I've made a branch to collate these into, see:
  https://github.com/dgibson/qemu/tree/ppc-cpu-hotplug

For now just patches 5&6 are there (not ppc specific), but I plan to
merge in the rest as I review them.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


[Qemu-devel] [PATCH v5 08/10] block: BdrvDirtyBitmap serialization interface

2016-06-02 Thread Fam Zheng
From: Vladimir Sementsov-Ogievskiy 

Several functions to provide necessary access to BdrvDirtyBitmap for
block-migration.c

Signed-off-by: Vladimir Sementsov-Ogievskiy 
[Add the "finish" parameters. - Fam]
Signed-off-by: Fam Zheng 
Reviewed-by: John Snow 
---
 block/dirty-bitmap.c | 37 +
 include/block/dirty-bitmap.h | 14 ++
 2 files changed, 51 insertions(+)

diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index 39e072a..8113090 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -453,6 +453,43 @@ void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, 
HBitmap *in)
 hbitmap_free(tmp);
 }
 
+uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
+  uint64_t start, uint64_t count)
+{
+return hbitmap_serialization_size(bitmap->bitmap, start, count);
+}
+
+uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
+{
+return hbitmap_serialization_granularity(bitmap->bitmap);
+}
+
+void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
+  uint8_t *buf, uint64_t start,
+  uint64_t count)
+{
+hbitmap_serialize_part(bitmap->bitmap, buf, start, count);
+}
+
+void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
+uint8_t *buf, uint64_t start,
+uint64_t count, bool finish)
+{
+hbitmap_deserialize_part(bitmap->bitmap, buf, start, count, finish);
+}
+
+void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
+  uint64_t start, uint64_t count,
+  bool finish)
+{
+hbitmap_deserialize_zeroes(bitmap->bitmap, start, count, finish);
+}
+
+void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
+{
+hbitmap_deserialize_finish(bitmap->bitmap);
+}
+
 void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
 int nr_sectors)
 {
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
index caa4d82..40a09c0 100644
--- a/include/block/dirty-bitmap.h
+++ b/include/block/dirty-bitmap.h
@@ -55,4 +55,18 @@ void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *hbi, int64_t 
sector_num);
 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
 void bdrv_dirty_bitmap_truncate(BlockDriverState *bs);
 
+uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
+  uint64_t start, uint64_t count);
+uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap);
+void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
+  uint8_t *buf, uint64_t start,
+  uint64_t count);
+void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
+uint8_t *buf, uint64_t start,
+uint64_t count, bool finish);
+void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
+  uint64_t start, uint64_t count,
+  bool finish);
+void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap);
+
 #endif
-- 
2.8.2




[Qemu-devel] [PATCH v5 02/10] HBitmap: Introduce "meta" bitmap to track bit changes

2016-06-02 Thread Fam Zheng
Upon each bit toggle, the corresponding bit in the meta bitmap will be
set.

Signed-off-by: Fam Zheng 
Reviewed-by: John Snow 
---
 block/dirty-bitmap.c   |  2 +-
 include/qemu/hbitmap.h | 17 +
 util/hbitmap.c | 69 +++---
 3 files changed, 72 insertions(+), 16 deletions(-)

diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index ec073ee..628b77c 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -231,7 +231,7 @@ static void 
bdrv_do_release_matching_dirty_bitmap(BlockDriverState *bs,
 BdrvDirtyBitmap *bm, *next;
 QLIST_FOREACH_SAFE(bm, >dirty_bitmaps, list, next) {
 if ((!bitmap || bm == bitmap) && (!only_named || bm->name)) {
-assert(!bitmap->active_iterators);
+assert(!bm->active_iterators);
 assert(!bdrv_dirty_bitmap_frozen(bm));
 QLIST_REMOVE(bm, list);
 hbitmap_free(bm->bitmap);
diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h
index e29188c..f8ed058 100644
--- a/include/qemu/hbitmap.h
+++ b/include/qemu/hbitmap.h
@@ -178,6 +178,23 @@ void hbitmap_iter_init(HBitmapIter *hbi, const HBitmap 
*hb, uint64_t first);
  */
 unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi);
 
+/* hbitmap_create_meta:
+ * Create a "meta" hbitmap to track dirtiness of the bits in this HBitmap.
+ * The caller owns the created bitmap and must call hbitmap_free_meta(hb) to
+ * free it.
+ *
+ * @hb: The HBitmap to operate on.
+ * @chunk_size: How many bits in @hb does one bit in the meta track.
+ */
+HBitmap *hbitmap_create_meta(HBitmap *hb, int chunk_size);
+
+/* hbitmap_free_meta:
+ * Free the meta bitmap of @hb.
+ *
+ * @hb: The HBitmap whose meta bitmap should be freed.
+ */
+void hbitmap_free_meta(HBitmap *hb);
+
 /**
  * hbitmap_iter_next:
  * @hbi: HBitmapIter to operate on.
diff --git a/util/hbitmap.c b/util/hbitmap.c
index b22b87d..13c0df5 100644
--- a/util/hbitmap.c
+++ b/util/hbitmap.c
@@ -79,6 +79,9 @@ struct HBitmap {
  */
 int granularity;
 
+/* A meta dirty bitmap to track the dirtiness of bits in this HBitmap. */
+HBitmap *meta;
+
 /* A number of progressively less coarse bitmaps (i.e. level 0 is the
  * coarsest).  Each bit in level N represents a word in level N+1 that
  * has a set bit, except the last level where each bit represents the
@@ -210,25 +213,27 @@ static uint64_t hb_count_between(HBitmap *hb, uint64_t 
start, uint64_t last)
 }
 
 /* Setting starts at the last layer and propagates up if an element
- * changes from zero to non-zero.
+ * changes.
  */
 static inline bool hb_set_elem(unsigned long *elem, uint64_t start, uint64_t 
last)
 {
 unsigned long mask;
-bool changed;
+unsigned long old;
 
 assert((last >> BITS_PER_LEVEL) == (start >> BITS_PER_LEVEL));
 assert(start <= last);
 
 mask = 2UL << (last & (BITS_PER_LONG - 1));
 mask -= 1UL << (start & (BITS_PER_LONG - 1));
-changed = (*elem == 0);
+old = *elem;
 *elem |= mask;
-return changed;
+return old != *elem;
 }
 
-/* The recursive workhorse (the depth is limited to HBITMAP_LEVELS)... */
-static void hb_set_between(HBitmap *hb, int level, uint64_t start, uint64_t 
last)
+/* The recursive workhorse (the depth is limited to HBITMAP_LEVELS)...
+ * Returns true if at least one bit is changed. */
+static bool hb_set_between(HBitmap *hb, int level, uint64_t start,
+   uint64_t last)
 {
 size_t pos = start >> BITS_PER_LEVEL;
 size_t lastpos = last >> BITS_PER_LEVEL;
@@ -257,22 +262,27 @@ static void hb_set_between(HBitmap *hb, int level, 
uint64_t start, uint64_t last
 if (level > 0 && changed) {
 hb_set_between(hb, level - 1, pos, lastpos);
 }
+return changed;
 }
 
 void hbitmap_set(HBitmap *hb, uint64_t start, uint64_t count)
 {
 /* Compute range in the last layer.  */
+uint64_t first, n;
 uint64_t last = start + count - 1;
 
 trace_hbitmap_set(hb, start, count,
   start >> hb->granularity, last >> hb->granularity);
 
-start >>= hb->granularity;
+first = start >> hb->granularity;
 last >>= hb->granularity;
-count = last - start + 1;
+n = last - first + 1;
 
-hb->count += count - hb_count_between(hb, start, last);
-hb_set_between(hb, HBITMAP_LEVELS - 1, start, last);
+hb->count += n - hb_count_between(hb, first, last);
+if (hb_set_between(hb, HBITMAP_LEVELS - 1, first, last) &&
+hb->meta) {
+hbitmap_set(hb->meta, start, count);
+}
 }
 
 /* Resetting works the other way round: propagate up if the new
@@ -293,8 +303,10 @@ static inline bool hb_reset_elem(unsigned long *elem, 
uint64_t start, uint64_t l
 return blanked;
 }
 
-/* The recursive workhorse (the depth is limited to HBITMAP_LEVELS)... */
-static void hb_reset_between(HBitmap *hb, int level, uint64_t start, uint64_t 
last)
+/* The recursive workhorse (the depth is 

[Qemu-devel] [PATCH v5 10/10] block: More operations for meta dirty bitmap

2016-06-02 Thread Fam Zheng
Callers can create an iterator of meta bitmap with
bdrv_dirty_meta_iter_new(), then use the bdrv_dirty_iter_* operations on
it. Meta iterators are also counted by bitmap->active_iterators.

Also add a couple of functions to retrieve granularity and count.

Signed-off-by: Fam Zheng 
Reviewed-by: Max Reitz 
---
 block/dirty-bitmap.c | 19 +++
 include/block/dirty-bitmap.h |  3 +++
 2 files changed, 22 insertions(+)

diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index 8113090..d94de7b 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -393,6 +393,11 @@ uint32_t bdrv_dirty_bitmap_granularity(BdrvDirtyBitmap 
*bitmap)
 return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->bitmap);
 }
 
+uint32_t bdrv_dirty_bitmap_meta_granularity(BdrvDirtyBitmap *bitmap)
+{
+return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->meta);
+}
+
 BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
  uint64_t first_sector)
 {
@@ -403,6 +408,15 @@ BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap 
*bitmap,
 return iter;
 }
 
+BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap)
+{
+BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
+hbitmap_iter_init(>hbi, bitmap->meta, 0);
+iter->bitmap = bitmap;
+bitmap->active_iterators++;
+return iter;
+}
+
 void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
 {
 if (!iter) {
@@ -514,3 +528,8 @@ int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
 {
 return hbitmap_count(bitmap->bitmap);
 }
+
+int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
+{
+return hbitmap_count(bitmap->meta);
+}
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
index 40a09c0..3cbed02 100644
--- a/include/block/dirty-bitmap.h
+++ b/include/block/dirty-bitmap.h
@@ -30,6 +30,7 @@ void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap);
 BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs);
 uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs);
 uint32_t bdrv_dirty_bitmap_granularity(BdrvDirtyBitmap *bitmap);
+uint32_t bdrv_dirty_bitmap_meta_granularity(BdrvDirtyBitmap *bitmap);
 bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap);
 bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap);
 const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap);
@@ -47,12 +48,14 @@ int bdrv_dirty_bitmap_get_meta(BlockDriverState *bs,
 void bdrv_dirty_bitmap_reset_meta(BlockDriverState *bs,
   BdrvDirtyBitmap *bitmap, int64_t sector,
   int nb_sectors);
+BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap);
 BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
  uint64_t first_sector);
 void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter);
 int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter);
 void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *hbi, int64_t sector_num);
 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
+int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap);
 void bdrv_dirty_bitmap_truncate(BlockDriverState *bs);
 
 uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
-- 
2.8.2




[Qemu-devel] [PATCH v5 05/10] block: Add two dirty bitmap getters

2016-06-02 Thread Fam Zheng
For dirty bitmap users to get the size and the name of a
BdrvDirtyBitmap.

Signed-off-by: Fam Zheng 
Reviewed-by: John Snow 
---
 block/dirty-bitmap.c | 10 ++
 include/block/dirty-bitmap.h |  2 ++
 2 files changed, 12 insertions(+)

diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index 9c53c56..a71c9b7 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -154,6 +154,16 @@ void bdrv_dirty_bitmap_reset_meta(BlockDriverState *bs,
 hbitmap_reset(bitmap->meta, sector, nb_sectors);
 }
 
+int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
+{
+return bitmap->size;
+}
+
+const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap)
+{
+return bitmap->name;
+}
+
 bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
 {
 return bitmap->successor;
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
index 50e0fca..caa4d82 100644
--- a/include/block/dirty-bitmap.h
+++ b/include/block/dirty-bitmap.h
@@ -32,6 +32,8 @@ uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState 
*bs);
 uint32_t bdrv_dirty_bitmap_granularity(BdrvDirtyBitmap *bitmap);
 bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap);
 bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap);
+const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap);
+int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap);
 DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap);
 int bdrv_get_dirty(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
int64_t sector);
-- 
2.8.2




[Qemu-devel] [PATCH v5 07/10] hbitmap: serialization

2016-06-02 Thread Fam Zheng
From: Vladimir Sementsov-Ogievskiy 

Functions to serialize / deserialize(restore) HBitmap. HBitmap should be
saved to linear sequence of bits independently of endianness and bitmap
array element (unsigned long) size. Therefore Little Endian is chosen.

These functions are appropriate for dirty bitmap migration, restoring
the bitmap in several steps is available. To save performance, every
step writes only the last level of the bitmap. All other levels are
restored by hbitmap_deserialize_finish() as a last step of restoring.
So, HBitmap is inconsistent while restoring.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
[Fix left shift operand to 1UL; add "finish" parameter. - Fam]
Signed-off-by: Fam Zheng 
Reviewed-by: Max Reitz 
---
 include/qemu/hbitmap.h |  79 
 util/hbitmap.c | 137 +
 2 files changed, 216 insertions(+)

diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h
index f8ed058..26cac7d 100644
--- a/include/qemu/hbitmap.h
+++ b/include/qemu/hbitmap.h
@@ -146,6 +146,85 @@ void hbitmap_reset_all(HBitmap *hb);
 bool hbitmap_get(const HBitmap *hb, uint64_t item);
 
 /**
+ * hbitmap_serialization_granularity:
+ * @hb: HBitmap to operate on.
+ *
+ * Granularity of serialization chunks, used by other serialization functions.
+ * For every chunk:
+ * 1. Chunk start should be aligned to this granularity.
+ * 2. Chunk size should be aligned too, except for last chunk (for which
+ *  start + count == hb->size)
+ */
+uint64_t hbitmap_serialization_granularity(const HBitmap *hb);
+
+/**
+ * hbitmap_serialization_size:
+ * @hb: HBitmap to operate on.
+ * @start: Starting bit
+ * @count: Number of bits
+ *
+ * Return number of bytes hbitmap_(de)serialize_part needs
+ */
+uint64_t hbitmap_serialization_size(const HBitmap *hb,
+uint64_t start, uint64_t count);
+
+/**
+ * hbitmap_serialize_part
+ * @hb: HBitmap to operate on.
+ * @buf: Buffer to store serialized bitmap.
+ * @start: First bit to store.
+ * @count: Number of bits to store.
+ *
+ * Stores HBitmap data corresponding to given region. The format of saved data
+ * is linear sequence of bits, so it can be used by hbitmap_deserialize_part
+ * independently of endianness and size of HBitmap level array elements
+ */
+void hbitmap_serialize_part(const HBitmap *hb, uint8_t *buf,
+uint64_t start, uint64_t count);
+
+/**
+ * hbitmap_deserialize_part
+ * @hb: HBitmap to operate on.
+ * @buf: Buffer to restore bitmap data from.
+ * @start: First bit to restore.
+ * @count: Number of bits to restore.
+ * @finish: Whether to call hbitmap_deserialize_finish automatically.
+ *
+ * Restores HBitmap data corresponding to given region. The format is the same
+ * as for hbitmap_serialize_part.
+ *
+ * If @finish is false, caller must call hbitmap_serialize_finish before using
+ * the bitmap.
+ */
+void hbitmap_deserialize_part(HBitmap *hb, uint8_t *buf,
+  uint64_t start, uint64_t count,
+  bool finish);
+
+/**
+ * hbitmap_deserialize_zeroes
+ * @hb: HBitmap to operate on.
+ * @start: First bit to restore.
+ * @count: Number of bits to restore.
+ * @finish: Whether to call hbitmap_deserialize_finish automatically.
+ *
+ * Fills the bitmap with zeroes.
+ *
+ * If @finish is false, caller must call hbitmap_serialize_finish before using
+ * the bitmap.
+ */
+void hbitmap_deserialize_zeroes(HBitmap *hb, uint64_t start, uint64_t count,
+bool finish);
+
+/**
+ * hbitmap_deserialize_finish
+ * @hb: HBitmap to operate on.
+ *
+ * Repair HBitmap after calling hbitmap_deserialize_data. Actually, all HBitmap
+ * layers are restored here.
+ */
+void hbitmap_deserialize_finish(HBitmap *hb);
+
+/**
  * hbitmap_free:
  * @hb: HBitmap to operate on.
  *
diff --git a/util/hbitmap.c b/util/hbitmap.c
index 13c0df5..70dc99b 100644
--- a/util/hbitmap.c
+++ b/util/hbitmap.c
@@ -395,6 +395,143 @@ bool hbitmap_get(const HBitmap *hb, uint64_t item)
 return (hb->levels[HBITMAP_LEVELS - 1][pos >> BITS_PER_LEVEL] & bit) != 0;
 }
 
+uint64_t hbitmap_serialization_granularity(const HBitmap *hb)
+{
+/* Require at least 64 bit granularity to be safe on both 64 bit and 32 bit
+ * hosts. */
+return 64 << hb->granularity;
+}
+
+/* Start should be aligned to serialization granularity, chunk size should be
+ * aligned to serialization granularity too, except for last chunk.
+ */
+static void serialization_chunk(const HBitmap *hb,
+uint64_t start, uint64_t count,
+unsigned long **first_el, size_t *el_count)
+{
+uint64_t last = start + count - 1;
+uint64_t gran = hbitmap_serialization_granularity(hb);
+
+assert((start & (gran - 1)) == 0);
+assert((last >> hb->granularity) < hb->size);
+  

[Qemu-devel] [PATCH v5 06/10] block: Assert that bdrv_release_dirty_bitmap succeeded

2016-06-02 Thread Fam Zheng
We use a loop over bs->dirty_bitmaps to make sure the caller is
only releasing a bitmap owned by bs. Let's also assert that in this case
the caller is releasing a bitmap that does exist.

Signed-off-by: Fam Zheng 
---
 block/dirty-bitmap.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index a71c9b7..39e072a 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -305,6 +305,9 @@ static void 
bdrv_do_release_matching_dirty_bitmap(BlockDriverState *bs,
 }
 }
 }
+if (bitmap) {
+abort();
+}
 }
 
 void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
-- 
2.8.2




[Qemu-devel] [PATCH v5 04/10] block: Support meta dirty bitmap

2016-06-02 Thread Fam Zheng
The added group of operations enables tracking of the changed bits in
the dirty bitmap.

Signed-off-by: Fam Zheng 
---
 block/dirty-bitmap.c | 52 
 include/block/dirty-bitmap.h |  9 
 2 files changed, 61 insertions(+)

diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index 628b77c..9c53c56 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -38,6 +38,7 @@
  */
 struct BdrvDirtyBitmap {
 HBitmap *bitmap;/* Dirty sector bitmap implementation */
+HBitmap *meta;  /* Meta dirty bitmap */
 BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */
 char *name; /* Optional non-empty unique ID */
 int64_t size;   /* Size of the bitmap (Number of sectors) */
@@ -103,6 +104,56 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState 
*bs,
 return bitmap;
 }
 
+/* bdrv_create_meta_dirty_bitmap
+ *
+ * Create a meta dirty bitmap that tracks the changes of bits in @bitmap. I.e.
+ * when a dirty status bit in @bitmap is changed (either from reset to set or
+ * the other way around), its respective meta dirty bitmap bit will be marked
+ * dirty as well.
+ *
+ * @bitmap: the block dirty bitmap for which to create a meta dirty bitmap.
+ * @chunk_size: how many bytes of bitmap data does each bit in the meta bitmap
+ * track.
+ */
+void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap,
+   int chunk_size)
+{
+assert(!bitmap->meta);
+bitmap->meta = hbitmap_create_meta(bitmap->bitmap,
+   chunk_size * BITS_PER_BYTE);
+}
+
+void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap)
+{
+assert(bitmap->meta);
+hbitmap_free_meta(bitmap->bitmap);
+bitmap->meta = NULL;
+}
+
+int bdrv_dirty_bitmap_get_meta(BlockDriverState *bs,
+   BdrvDirtyBitmap *bitmap, int64_t sector,
+   int nb_sectors)
+{
+uint64_t i;
+int gran = bdrv_dirty_bitmap_granularity(bitmap) >> BDRV_SECTOR_BITS;
+
+/* To optimize: we can make hbitmap to internally check the range in a
+ * coarse level, or at least do it word by word. */
+for (i = sector; i < sector + nb_sectors; i += gran) {
+if (hbitmap_get(bitmap->meta, i)) {
+return true;
+}
+}
+return false;
+}
+
+void bdrv_dirty_bitmap_reset_meta(BlockDriverState *bs,
+  BdrvDirtyBitmap *bitmap, int64_t sector,
+  int nb_sectors)
+{
+hbitmap_reset(bitmap->meta, sector, nb_sectors);
+}
+
 bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
 {
 return bitmap->successor;
@@ -233,6 +284,7 @@ static void 
bdrv_do_release_matching_dirty_bitmap(BlockDriverState *bs,
 if ((!bitmap || bm == bitmap) && (!only_named || bm->name)) {
 assert(!bm->active_iterators);
 assert(!bdrv_dirty_bitmap_frozen(bm));
+assert(!bm->meta);
 QLIST_REMOVE(bm, list);
 hbitmap_free(bm->bitmap);
 g_free(bm->name);
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
index 2ea601b..50e0fca 100644
--- a/include/block/dirty-bitmap.h
+++ b/include/block/dirty-bitmap.h
@@ -8,6 +8,9 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
   uint32_t granularity,
   const char *name,
   Error **errp);
+void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap,
+   int chunk_size);
+void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap);
 int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
BdrvDirtyBitmap *bitmap,
Error **errp);
@@ -36,6 +39,12 @@ void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
int64_t cur_sector, int nr_sectors);
 void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
  int64_t cur_sector, int nr_sectors);
+int bdrv_dirty_bitmap_get_meta(BlockDriverState *bs,
+   BdrvDirtyBitmap *bitmap, int64_t sector,
+   int nb_sectors);
+void bdrv_dirty_bitmap_reset_meta(BlockDriverState *bs,
+  BdrvDirtyBitmap *bitmap, int64_t sector,
+  int nb_sectors);
 BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
  uint64_t first_sector);
 void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter);
-- 
2.8.2




[Qemu-devel] [PATCH v5 01/10] block: Hide HBitmap in block dirty bitmap interface

2016-06-02 Thread Fam Zheng
HBitmap is an implementation detail of block dirty bitmap that should be hidden
from users. Introduce a BdrvDirtyBitmapIter to encapsulate the underlying
HBitmapIter.

A small difference in the interface is, before, an HBitmapIter is initialized
in place, now the new BdrvDirtyBitmapIter must be dynamically allocated because
the structure definition is in block/dirty-bitmap.c.

Two current users are converted too.

Signed-off-by: Fam Zheng 
---
 block/backup.c   | 14 --
 block/dirty-bitmap.c | 39 +--
 block/mirror.c   | 24 +---
 include/block/dirty-bitmap.h |  7 +--
 include/qemu/typedefs.h  |  1 +
 5 files changed, 60 insertions(+), 25 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index feeb9f8..ac7ca45 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -317,14 +317,14 @@ static int coroutine_fn 
backup_run_incremental(BackupBlockJob *job)
 int64_t end;
 int64_t last_cluster = -1;
 int64_t sectors_per_cluster = cluster_size_sectors(job);
-HBitmapIter hbi;
+BdrvDirtyBitmapIter *dbi;
 
 granularity = bdrv_dirty_bitmap_granularity(job->sync_bitmap);
 clusters_per_iter = MAX((granularity / job->cluster_size), 1);
-bdrv_dirty_iter_init(job->sync_bitmap, );
+dbi = bdrv_dirty_iter_new(job->sync_bitmap, 0);
 
 /* Find the next dirty sector(s) */
-while ((sector = hbitmap_iter_next()) != -1) {
+while ((sector = bdrv_dirty_iter_next(dbi)) != -1) {
 cluster = sector / sectors_per_cluster;
 
 /* Fake progress updates for any clusters we skipped */
@@ -336,7 +336,7 @@ static int coroutine_fn 
backup_run_incremental(BackupBlockJob *job)
 for (end = cluster + clusters_per_iter; cluster < end; cluster++) {
 do {
 if (yield_and_check(job)) {
-return ret;
+goto out;
 }
 ret = backup_do_cow(job, cluster * sectors_per_cluster,
 sectors_per_cluster, _is_read,
@@ -344,7 +344,7 @@ static int coroutine_fn 
backup_run_incremental(BackupBlockJob *job)
 if ((ret < 0) &&
 backup_error_action(job, error_is_read, -ret) ==
 BLOCK_ERROR_ACTION_REPORT) {
-return ret;
+goto out;
 }
 } while (ret < 0);
 }
@@ -352,7 +352,7 @@ static int coroutine_fn 
backup_run_incremental(BackupBlockJob *job)
 /* If the bitmap granularity is smaller than the backup granularity,
  * we need to advance the iterator pointer to the next cluster. */
 if (granularity < job->cluster_size) {
-bdrv_set_dirty_iter(, cluster * sectors_per_cluster);
+bdrv_set_dirty_iter(dbi, cluster * sectors_per_cluster);
 }
 
 last_cluster = cluster - 1;
@@ -364,6 +364,8 @@ static int coroutine_fn 
backup_run_incremental(BackupBlockJob *job)
 job->common.offset += ((end - last_cluster - 1) * job->cluster_size);
 }
 
+out:
+bdrv_dirty_iter_free(dbi);
 return ret;
 }
 
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index 4902ca5..ec073ee 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -42,9 +42,15 @@ struct BdrvDirtyBitmap {
 char *name; /* Optional non-empty unique ID */
 int64_t size;   /* Size of the bitmap (Number of sectors) */
 bool disabled;  /* Bitmap is read-only */
+int active_iterators;   /* How many iterators are active */
 QLIST_ENTRY(BdrvDirtyBitmap) list;
 };
 
+struct BdrvDirtyBitmapIter {
+HBitmapIter hbi;
+BdrvDirtyBitmap *bitmap;
+};
+
 BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name)
 {
 BdrvDirtyBitmap *bm;
@@ -212,6 +218,7 @@ void bdrv_dirty_bitmap_truncate(BlockDriverState *bs)
 
 QLIST_FOREACH(bitmap, >dirty_bitmaps, list) {
 assert(!bdrv_dirty_bitmap_frozen(bitmap));
+assert(!bitmap->active_iterators);
 hbitmap_truncate(bitmap->bitmap, size);
 bitmap->size = size;
 }
@@ -224,6 +231,7 @@ static void 
bdrv_do_release_matching_dirty_bitmap(BlockDriverState *bs,
 BdrvDirtyBitmap *bm, *next;
 QLIST_FOREACH_SAFE(bm, >dirty_bitmaps, list, next) {
 if ((!bitmap || bm == bitmap) && (!only_named || bm->name)) {
+assert(!bitmap->active_iterators);
 assert(!bdrv_dirty_bitmap_frozen(bm));
 QLIST_REMOVE(bm, list);
 hbitmap_free(bm->bitmap);
@@ -320,9 +328,29 @@ uint32_t bdrv_dirty_bitmap_granularity(BdrvDirtyBitmap 
*bitmap)
 return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->bitmap);
 }
 
-void bdrv_dirty_iter_init(BdrvDirtyBitmap *bitmap, HBitmapIter *hbi)
+BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
+ uint64_t 

[Qemu-devel] [PATCH v5 09/10] tests: Add test code for hbitmap serialization

2016-06-02 Thread Fam Zheng
Acked-by: John Snow 
Signed-off-by: Fam Zheng 
---
 tests/test-hbitmap.c | 139 +++
 1 file changed, 139 insertions(+)

diff --git a/tests/test-hbitmap.c b/tests/test-hbitmap.c
index c00c2b5..8f64941 100644
--- a/tests/test-hbitmap.c
+++ b/tests/test-hbitmap.c
@@ -12,6 +12,7 @@
 #include "qemu/osdep.h"
 #include 
 #include "qemu/hbitmap.h"
+#include "qemu/bitmap.h"
 #include "block/block.h"
 
 #define LOG_BITS_PER_LONG  (BITS_PER_LONG == 32 ? 5 : 6)
@@ -738,6 +739,16 @@ static void test_hbitmap_meta_one(TestHBitmapData *data, 
const void *unused)
 }
 }
 
+static void test_hbitmap_serialize_granularity(TestHBitmapData *data,
+   const void *unused)
+{
+int r;
+
+hbitmap_test_init(data, L3 * 2, 3);
+r = hbitmap_serialization_granularity(data->hb);
+g_assert_cmpint(r, ==, BITS_PER_LONG << 3);
+}
+
 static void test_hbitmap_meta_zero(TestHBitmapData *data, const void *unused)
 {
 hbitmap_test_init_meta(data, 0, 0, 1);
@@ -745,6 +756,125 @@ static void test_hbitmap_meta_zero(TestHBitmapData *data, 
const void *unused)
 hbitmap_check_meta(data, 0, 0);
 }
 
+static void hbitmap_test_serialize_range(TestHBitmapData *data,
+ uint8_t *buf, size_t buf_size,
+ uint64_t pos, uint64_t count)
+{
+size_t i;
+
+assert(hbitmap_granularity(data->hb) == 0);
+hbitmap_reset_all(data->hb);
+memset(buf, 0, buf_size);
+if (count) {
+hbitmap_set(data->hb, pos, count);
+}
+hbitmap_serialize_part(data->hb, buf, 0, data->size);
+for (i = 0; i < data->size; i++) {
+int is_set = test_bit(i, (unsigned long *)buf);
+if (i >= pos && i < pos + count) {
+g_assert(is_set);
+} else {
+g_assert(!is_set);
+}
+}
+hbitmap_reset_all(data->hb);
+hbitmap_deserialize_part(data->hb, buf, 0, data->size, true);
+
+for (i = 0; i < data->size; i++) {
+int is_set = hbitmap_get(data->hb, i);
+if (i >= pos && i < pos + count) {
+g_assert(is_set);
+} else {
+g_assert(!is_set);
+}
+}
+}
+
+static void test_hbitmap_serialize_basic(TestHBitmapData *data,
+ const void *unused)
+{
+int i, j;
+size_t buf_size;
+uint8_t *buf;
+uint64_t positions[] = { 0, 1, L1 - 1, L1, L2 - 1, L2, L2 + 1, L3 - 1 };
+int num_positions = sizeof(positions) / sizeof(positions[0]);
+
+hbitmap_test_init(data, L3, 0);
+buf_size = hbitmap_serialization_size(data->hb, 0, data->size);
+buf = g_malloc0(buf_size);
+
+for (i = 0; i < num_positions; i++) {
+for (j = 0; j < num_positions; j++) {
+hbitmap_test_serialize_range(data, buf, buf_size,
+ positions[i],
+ MIN(positions[j], L3 - positions[i]));
+}
+}
+
+g_free(buf);
+}
+
+static void test_hbitmap_serialize_part(TestHBitmapData *data,
+const void *unused)
+{
+int i, j, k;
+size_t buf_size;
+uint8_t *buf;
+uint64_t positions[] = { 0, 1, L1 - 1, L1, L2 - 1, L2, L2 + 1, L3 - 1 };
+int num_positions = sizeof(positions) / sizeof(positions[0]);
+
+hbitmap_test_init(data, L3, 0);
+buf_size = L2;
+buf = g_malloc0(buf_size);
+
+for (i = 0; i < num_positions; i++) {
+hbitmap_set(data->hb, positions[i], 1);
+}
+
+for (i = 0; i < data->size; i += buf_size) {
+hbitmap_serialize_part(data->hb, buf, i, buf_size);
+for (j = 0; j < buf_size; j++) {
+bool should_set = false;
+for (k = 0; k < num_positions; k++) {
+if (positions[k] == j + i) {
+should_set = true;
+break;
+}
+}
+g_assert_cmpint(should_set, ==, test_bit(j, (unsigned long *)buf));
+}
+}
+
+g_free(buf);
+}
+
+static void test_hbitmap_serialize_zeroes(TestHBitmapData *data,
+  const void *unused)
+{
+int i;
+HBitmapIter iter;
+int64_t next;
+uint64_t positions[] = { 0, L1, L2, L3 - L1};
+int num_positions = sizeof(positions) / sizeof(positions[0]);
+
+hbitmap_test_init(data, L3, 0);
+
+for (i = 0; i < num_positions; i++) {
+hbitmap_set(data->hb, positions[i], L1);
+}
+
+for (i = 0; i < num_positions; i++) {
+hbitmap_deserialize_zeroes(data->hb, positions[i], L1, true);
+hbitmap_iter_init(, data->hb, 0);
+next = hbitmap_iter_next();
+if (i == num_positions - 1) {
+g_assert_cmpint(next, ==, -1);
+} else {
+g_assert_cmpint(next, ==, positions[i + 1]);
+}
+}
+}
+
 static void hbitmap_test_add(const char 

[Qemu-devel] [PATCH v5 00/10] Dirty bitmap changes for migration/persistence work

2016-06-02 Thread Fam Zheng
v5: Rebase: first 5 patches from last revision are already merged.

Addressed Max's comments:

01: - "block.c" -> "block/dirty-bitmap.c" in commit message.
- "an BdrvDirtyBitmapIter" -> "an BdrvDirtyBitmapIter" in code comment.
- hbitmap_next => next_dirty as variable name.
- bdrv_dirty_iter_free()/bdrv_dirty_iter_new() pairs =>
  bdrv_set_dirty_iter.

02: Move the assert fix into 01.

04: Truncate the meta bitmap (done by hbitmap_truncate).

06: Add Max's r-b.

07: I left the memcpy vs cpu_to_le32/64w as is to pick up Max's r-b. That
could be improved on top if wanted.

10: Add Max's r-b.

Fam Zheng (8):
  block: Hide HBitmap in block dirty bitmap interface
  HBitmap: Introduce "meta" bitmap to track bit changes
  tests: Add test code for meta bitmap
  block: Support meta dirty bitmap
  block: Add two dirty bitmap getters
  block: Assert that bdrv_release_dirty_bitmap succeeded
  tests: Add test code for hbitmap serialization
  block: More operations for meta dirty bitmap

Vladimir Sementsov-Ogievskiy (2):
  hbitmap: serialization
  block: BdrvDirtyBitmap serialization interface

 block/backup.c   |  14 ++-
 block/dirty-bitmap.c | 160 ++-
 block/mirror.c   |  24 ++--
 include/block/dirty-bitmap.h |  35 +-
 include/qemu/hbitmap.h   |  96 
 include/qemu/typedefs.h  |   1 +
 tests/test-hbitmap.c | 255 +++
 util/hbitmap.c   | 206 +++---
 8 files changed, 751 insertions(+), 40 deletions(-)

-- 
2.8.2




[Qemu-devel] [PATCH v5 03/10] tests: Add test code for meta bitmap

2016-06-02 Thread Fam Zheng
Signed-off-by: Fam Zheng 
Reviewed-by: John Snow 
---
 tests/test-hbitmap.c | 116 +++
 1 file changed, 116 insertions(+)

diff --git a/tests/test-hbitmap.c b/tests/test-hbitmap.c
index abe1427..c00c2b5 100644
--- a/tests/test-hbitmap.c
+++ b/tests/test-hbitmap.c
@@ -12,6 +12,7 @@
 #include "qemu/osdep.h"
 #include 
 #include "qemu/hbitmap.h"
+#include "block/block.h"
 
 #define LOG_BITS_PER_LONG  (BITS_PER_LONG == 32 ? 5 : 6)
 
@@ -21,6 +22,7 @@
 
 typedef struct TestHBitmapData {
 HBitmap   *hb;
+HBitmap   *meta;
 unsigned long *bits;
 size_t size;
 size_t old_size;
@@ -92,6 +94,14 @@ static void hbitmap_test_init(TestHBitmapData *data,
 }
 }
 
+static void hbitmap_test_init_meta(TestHBitmapData *data,
+   uint64_t size, int granularity,
+   int meta_chunk)
+{
+hbitmap_test_init(data, size, granularity);
+data->meta = hbitmap_create_meta(data->hb, meta_chunk);
+}
+
 static inline size_t hbitmap_test_array_size(size_t bits)
 {
 size_t n = (bits + BITS_PER_LONG - 1) / BITS_PER_LONG;
@@ -134,6 +144,9 @@ static void hbitmap_test_teardown(TestHBitmapData *data,
   const void *unused)
 {
 if (data->hb) {
+if (data->meta) {
+hbitmap_free_meta(data->hb);
+}
 hbitmap_free(data->hb);
 data->hb = NULL;
 }
@@ -635,6 +648,103 @@ static void 
test_hbitmap_truncate_shrink_large(TestHBitmapData *data,
 hbitmap_test_truncate(data, size, -diff, 0);
 }
 
+static void hbitmap_check_meta(TestHBitmapData *data,
+   int64_t start, int count)
+{
+int64_t i;
+
+for (i = 0; i < data->size; i++) {
+if (i >= start && i < start + count) {
+g_assert(hbitmap_get(data->meta, i));
+} else {
+g_assert(!hbitmap_get(data->meta, i));
+}
+}
+}
+
+static void hbitmap_test_meta(TestHBitmapData *data,
+  int64_t start, int count,
+  int64_t check_start, int check_count)
+{
+hbitmap_reset_all(data->hb);
+hbitmap_reset_all(data->meta);
+
+/* Test "unset" -> "unset" will not update meta. */
+hbitmap_reset(data->hb, start, count);
+hbitmap_check_meta(data, 0, 0);
+
+/* Test "unset" -> "set" will update meta */
+hbitmap_set(data->hb, start, count);
+hbitmap_check_meta(data, check_start, check_count);
+
+/* Test "set" -> "set" will not update meta */
+hbitmap_reset_all(data->meta);
+hbitmap_set(data->hb, start, count);
+hbitmap_check_meta(data, 0, 0);
+
+/* Test "set" -> "unset" will update meta */
+hbitmap_reset_all(data->meta);
+hbitmap_reset(data->hb, start, count);
+hbitmap_check_meta(data, check_start, check_count);
+}
+
+static void hbitmap_test_meta_do(TestHBitmapData *data, int chunk_size)
+{
+uint64_t size = chunk_size * 100;
+hbitmap_test_init_meta(data, size, 0, chunk_size);
+
+hbitmap_test_meta(data, 0, 1, 0, chunk_size);
+hbitmap_test_meta(data, 0, chunk_size, 0, chunk_size);
+hbitmap_test_meta(data, chunk_size - 1, 1, 0, chunk_size);
+hbitmap_test_meta(data, chunk_size - 1, 2, 0, chunk_size * 2);
+hbitmap_test_meta(data, chunk_size - 1, chunk_size + 1, 0, chunk_size * 2);
+hbitmap_test_meta(data, chunk_size - 1, chunk_size + 2, 0, chunk_size * 3);
+hbitmap_test_meta(data, 7 * chunk_size - 1, chunk_size + 2,
+  6 * chunk_size, chunk_size * 3);
+hbitmap_test_meta(data, size - 1, 1, size - chunk_size, chunk_size);
+hbitmap_test_meta(data, 0, size, 0, size);
+}
+
+static void test_hbitmap_meta_byte(TestHBitmapData *data, const void *unused)
+{
+hbitmap_test_meta_do(data, BITS_PER_BYTE);
+}
+
+static void test_hbitmap_meta_word(TestHBitmapData *data, const void *unused)
+{
+hbitmap_test_meta_do(data, BITS_PER_LONG);
+}
+
+static void test_hbitmap_meta_sector(TestHBitmapData *data, const void *unused)
+{
+hbitmap_test_meta_do(data, BDRV_SECTOR_SIZE * BITS_PER_BYTE);
+}
+
+/**
+ * Create an HBitmap and test set/unset.
+ */
+static void test_hbitmap_meta_one(TestHBitmapData *data, const void *unused)
+{
+int i;
+int64_t offsets[] = {
+0, 1, L1 - 1, L1, L1 + 1, L2 - 1, L2, L2 + 1, L3 - 1, L3, L3 + 1
+};
+
+hbitmap_test_init_meta(data, L3 * 2, 0, 1);
+for (i = 0; i < ARRAY_SIZE(offsets); i++) {
+hbitmap_test_meta(data, offsets[i], 1, offsets[i], 1);
+hbitmap_test_meta(data, offsets[i], L1, offsets[i], L1);
+hbitmap_test_meta(data, offsets[i], L2, offsets[i], L2);
+}
+}
+
+static void test_hbitmap_meta_zero(TestHBitmapData *data, const void *unused)
+{
+hbitmap_test_init_meta(data, 0, 0, 1);
+
+hbitmap_check_meta(data, 0, 0);
+}
+
 static void hbitmap_test_add(const char *testpath,

Re: [Qemu-devel] [QEMU PATCH v2] target-i386: Add Skylake-Client CPU model

2016-06-02 Thread Xiao Guangrong



On 05/23/2016 09:46 PM, Paolo Bonzini wrote:



On 20/05/2016 23:39, Eduardo Habkost wrote:

Introduce Skylake-Client CPU model, which inherits the features
from Broadwell and supports some additional features that are:
MPX, XSAVEC, and XGETBV1.

Signed-off-by: Eduardo Habkost 
Signed-off-by: Xiao Guangrong 
Signed-off-by: Eduardo Habkost 
---
Changes v1 -> v2:
* Remove XSAVES, edited commit message


Reviewed-by: Xiao Guangrong 

I thought this patch has already been upstream yet, but it is not. :(



[Qemu-devel] [Bug 1588591] [NEW] Qemu 2.6 Solaris 8 Sparc telnet terminate itself

2016-06-02 Thread Zhen Ning Lim
Public bug reported:

With Qemu 2.6, Solaris 8 can be installed and run. However, it sometimes
terminate itself with I/O thread spun for 1000 iterations.

qemu-system-sparc -nographic -monitor null -serial 
mon:telnet:0.0.0.0:3000,server -hda ./Sparc8.disk -m 256 -boot c -net 
nic,macaddr=52:54:0:12:34:56 -net tap,ifname=tap0,script=no,downscript=noQEMU 
waiting for connection on: disconnected:telnet:0.0.0.0:3000,server
main-loop: WARNING: I/O thread spun for 1000 iterations

** Affects: qemu
 Importance: Undecided
 Status: New

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

Title:
  Qemu 2.6 Solaris 8 Sparc telnet terminate itself

Status in QEMU:
  New

Bug description:
  With Qemu 2.6, Solaris 8 can be installed and run. However, it
  sometimes terminate itself with I/O thread spun for 1000 iterations.

  qemu-system-sparc -nographic -monitor null -serial 
mon:telnet:0.0.0.0:3000,server -hda ./Sparc8.disk -m 256 -boot c -net 
nic,macaddr=52:54:0:12:34:56 -net tap,ifname=tap0,script=no,downscript=noQEMU 
waiting for connection on: disconnected:telnet:0.0.0.0:3000,server
  main-loop: WARNING: I/O thread spun for 1000 iterations

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



Re: [Qemu-devel] [PATCH v5 1/1] Introduce "xen-load-devices-state"

2016-06-02 Thread Changlong Xie

On 06/03/2016 10:13 AM, Changlong Xie wrote:

On 06/03/2016 09:45 AM, Eric Blake wrote:

On 06/02/2016 07:26 PM, Changlong Xie wrote:


+
+ioc = qio_channel_file_new_path(filename, O_WRONLY | O_CREAT,
0660, errp);


This does not look right, it looks like it's going to open the file
to write to it. You probably want O_RDONLY, also I don't think the
O_CREAT flag is needed. (and without O_WRONLY, mode can be 0 instead of
0660.)



Yes, as you said. We should use 0_RDONLY for open(2), so mode should
be 0.


Huh?  mode doesn't affect the current fd, but DOES affect the next
person to open the file.  If you are truly creating the file, then a
mode of 0 means you won't be able to reopen it without chmod.  And if
you are doing O_RDONLY | O_CREAT, all you will be able to create is an
empty file, which is a pretty boring read.  So drop the O_CREAT, and
then you don't need a mode argument at all.



Yes, i just mean qio_channel_file_new_path(filename, O_RDONLY, 0, errp)


I just notice that, qemu specifies flag 'O_BINARY' to allow system to 
differentiate between a text file and a binary file( I guess so?). For 
backward compatibility, refer to function test_io_channel_file(), i will 
use


qio_channel_file_new_path(filename, O_RDONLY | O_BINARY, 0, errp)

here.


here. Maybe my poor english make you confused :(

Thanks
 -Xie










Re: [Qemu-devel] [PATCH v2 0/2] AVX2 configure fixes

2016-06-02 Thread Li, Liang Z
> Cc: amit.s...@redhat.com
> Subject: [PATCH v2 0/2] AVX2 configure fixes
> 
> From: "Dr. David Alan Gilbert" 
> 
> Hi,
>   This pair of patches fixes a couple of issues that we found during test.
> The first is that the configure test is pessimistic when compiled with -O2, 
> the
> second is that the explicit 4.9 gcc test is a bit coarse; I've removed that 
> test
> but beefed up the ./configure test to actually use the avx2 intrinsics and 
> that
> fails in the same way as the main code, so it works in the same way as the
> explicit check but allows older gcc's to work when -save-temps isn't used.
> 
> Dave
> 
> v2
>   Remove the explicit version check
>   Split the patches
> 
> Dr. David Alan Gilbert (2):
>   Make avx2 configure test work with -O2
>   avx2 configure: Use primitives in test
> 
>  configure | 15 +++
>  util/cutils.c |  8 +---
>  2 files changed, 12 insertions(+), 11 deletions(-)
> 
> --
> 2.7.4

Looks good. Thank!

Reviewed-by: Liang Li 

Liang



Re: [Qemu-devel] [PATCH 4/7] scsi-disk: introduce dma_readv and dma_writev

2016-06-02 Thread xiaoqiang zhao



在 2016年06月02日 03:07, Mark Cave-Ayland 写道:

On 23/05/16 13:54, Paolo Bonzini wrote:


>These are replacements for blk_aio_preadv and blk_aio_pwritev that allow
>customization of the data path.  They reuse the DMA helpers' DMAIOFunc
>callback type, so that the same function can be used in either the
>QEMUSGList or the bounce-buffered case.
>
>This customization will be needed in the next patch to do zero-copy
>SG_IO on scsi-block.
>
>Signed-off-by: Paolo Bonzini
>---
>  hw/scsi/scsi-disk.c | 63 
+++--
>  1 file changed, 52 insertions(+), 11 deletions(-)
>

Hi Paolo,

This patch appears to break qemu-system-sparc booting from CDROM with
the following command line:

./qemu-system-sparc -cdrom debian-40r4a-sparc-netinst.iso -boot d

Instead of booting straight into SILO, OpenBIOS hangs when trying to
read from the CDROM device.

Paolo:
  By using git bisect on master branch , I found this patch also break 
qemu-system-arm from booting.

  command line:
 qemu-system-arm -M versatilepb -kernel vmlinuz-3.2.0-4-versatile 
-initrd initrd.img-3.2.0-4-versatile -hda 
/home/hitmoon/debian_wheezy_armel_standard.qcow2 -append 'root=/dev/sda1'


 The booting process stops at mounting the root partition and after 
timeout droped into a initramfs shell. The device '/dev/sda1' is 
presented . I guess it can not read properly from sda1.







Re: [Qemu-devel] [PATCH v2] raw-posix: Fetch max sectors for host block device

2016-06-02 Thread Fam Zheng
On Thu, 06/02 20:42, Eric Blake wrote:
> On 06/02/2016 08:07 PM, Fam Zheng wrote:
> > This is sometimes a useful value we should count in.
> > 
> > Signed-off-by: Fam Zheng 
> > ---
> >  block/raw-posix.c | 24 
> >  1 file changed, 24 insertions(+)
> > 
> 
> Will conflict with patches I'm about to post to rework BlockLimits to be
> byte-based, rather than a mix of byte- and sector values.  First one in
> gets to watch the other rebase :)

Thanks!  I'm looking forward to a byte based BlockLimits!

Fam



Re: [Qemu-devel] [PATCH v2] raw-posix: Fetch max sectors for host block device

2016-06-02 Thread Eric Blake
On 06/02/2016 08:07 PM, Fam Zheng wrote:
> This is sometimes a useful value we should count in.
> 
> Signed-off-by: Fam Zheng 
> ---
>  block/raw-posix.c | 24 
>  1 file changed, 24 insertions(+)
> 

Will conflict with patches I'm about to post to rework BlockLimits to be
byte-based, rather than a mix of byte- and sector values.  First one in
gets to watch the other rebase :)

Reviewed-by: Eric Blake 

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v4 09/15] block: Support meta dirty bitmap

2016-06-02 Thread Fam Zheng
On Fri, 03/11 16:17, Max Reitz wrote:
> On 08.03.2016 05:45, Fam Zheng wrote:
> > The added group of operations enables tracking of the changed bits in
> > the dirty bitmap.
> > 
> > Signed-off-by: Fam Zheng 
> > ---
> >  block/dirty-bitmap.c | 52 
> > 
> >  include/block/dirty-bitmap.h |  9 
> >  2 files changed, 61 insertions(+)
> 
> Should we truncate the meta bitmaps in bdrv_dirty_bitmap_truncate()?
> 

Yes, adding that. Thanks!

Fam





Re: [Qemu-devel] [PATCH v4 08/15] tests: Add test code for meta bitmap

2016-06-02 Thread Fam Zheng
On Fri, 03/11 15:58, Max Reitz wrote:
> > +/* Test "unset" -> "set" will update meta */
> > +hbitmap_set(data->hb, start, count);
> > +hbitmap_check_meta(data, check_start, check_count);
> > +
> > +/* Test "set" -> "set" will not update meta */
> > +hbitmap_reset_all(data->meta);
> > +hbitmap_set(data->hb, start, count);
> > +hbitmap_check_meta(data, 0, 0);
> 
> Well, but if you'd do an hbitmap_set(data->hb, start, count + 1), then
> it would update meta, right?

Yes.

> 
> I forgot to mention in my reply to patch 7 that the check whether
> anything in the range passed to hbitmap_set() has been changed in order
> to determine whether all of that range should be set in the meta bitmap
> seemed a bit excessive. I don't think this will hurt anyone, but still.

It is. It has been on my list to optimize the unnecessary meta update away but
I haven't done that yet.

Fam

> 
> (So this is not a NACK, just a question.)
> 
> Max
> 



Re: [Qemu-devel] [PATCH v4 00/15] Dirty bitmap changes for migration/persistence work

2016-06-02 Thread Fam Zheng
On Thu, 06/02 18:49, John Snow wrote:
> 
> 
> On 06/02/2016 07:43 AM, Vladimir Sementsov-Ogievskiy wrote:
> > Hi, what are the plans?
> > 
> 
> I'm not sure. Fam, part of this series was merged, wasn't it?
> 
> Do you have outstanding work that you'd like me to take over and push
> through for you?

I will rebase patches 6 - 15, address comments from Max on this revision and
send v5 soon. You are very welcome to take over from there! Thanks a lot!

Fam

> 
> --js
> 
> > On 26.05.2016 03:47, Fam Zheng wrote:
> >> On Wed, 05/25 17:45, Vladimir Sementsov-Ogievskiy wrote:
> >>> Hi!
> >>>
> >>> Are you going to update the series in the near future?
> >> Yes, probably in a couple days.
> >>
> >> Fam
> >>
> >>> On 08.03.2016 07:44, Fam Zheng wrote:
>  v4: Rebase.
>    Add rev-by from John in patches 1-5, 7, 8.
>    Remove BdrvDirtyBitmap typedef from dirty-bitmap.h in patch 4.
>  [Max]
>    Add assertion on bm->meta in patch 9. [John]
> 
>  Two major features are added to block dirty bitmap (and underlying
>  HBitmap) in
>  this series: meta bitmap and serialization, together with all other
>  supportive
>  patches.
> 
>  Both operations are common in dirty bitmap migration and
>  persistence: they need
>  to find whether and which part of the dirty bitmap in question has
>  changed with
>  meta dirty bitmap, and they need to write it to the target with
>  serialization.
> 
> 
>  Fam Zheng (13):
>  backup: Use Bitmap to replace "s->bitmap"
>  block: Include hbitmap.h in block.h
>  typedefs: Add BdrvDirtyBitmap
>  block: Move block dirty bitmap code to separate files
>  block: Remove unused typedef of BlockDriverDirtyHandler
>  block: Hide HBitmap in block dirty bitmap interface
>  HBitmap: Introduce "meta" bitmap to track bit changes
>  tests: Add test code for meta bitmap
>  block: Support meta dirty bitmap
>  block: Add two dirty bitmap getters
>  block: Assert that bdrv_release_dirty_bitmap succeeded
>  tests: Add test code for hbitmap serialization
>  block: More operations for meta dirty bitmap
> 
>  Vladimir Sementsov-Ogievskiy (2):
>  hbitmap: serialization
>  block: BdrvDirtyBitmap serialization interface
> 
> block.c  | 360 -
> block/Makefile.objs  |   2 +-
> block/backup.c   |  25 +-
> block/dirty-bitmap.c | 535
>  +++
> block/mirror.c   |  15 +-
> include/block/block.h|  40 +---
> include/block/dirty-bitmap.h |  75 ++
> include/qemu/hbitmap.h   |  96 
> include/qemu/typedefs.h  |   2 +
> tests/test-hbitmap.c | 255 +
> util/hbitmap.c   | 203 ++--
> 11 files changed, 1177 insertions(+), 431 deletions(-)
> create mode 100644 block/dirty-bitmap.c
> create mode 100644 include/block/dirty-bitmap.h
> 
> >>>
> >>> -- 
> >>> Best regards,
> >>> Vladimir
> >>>
> >>>
> > 
> > 
> 
> -- 
> —js



Re: [Qemu-devel] [PATCH v5 1/1] Introduce "xen-load-devices-state"

2016-06-02 Thread Changlong Xie

On 06/03/2016 09:45 AM, Eric Blake wrote:

On 06/02/2016 07:26 PM, Changlong Xie wrote:


+
+ioc = qio_channel_file_new_path(filename, O_WRONLY | O_CREAT,
0660, errp);


This does not look right, it looks like it's going to open the file
to write to it. You probably want O_RDONLY, also I don't think the
O_CREAT flag is needed. (and without O_WRONLY, mode can be 0 instead of
0660.)



Yes, as you said. We should use 0_RDONLY for open(2), so mode should be 0.


Huh?  mode doesn't affect the current fd, but DOES affect the next
person to open the file.  If you are truly creating the file, then a
mode of 0 means you won't be able to reopen it without chmod.  And if
you are doing O_RDONLY | O_CREAT, all you will be able to create is an
empty file, which is a pretty boring read.  So drop the O_CREAT, and
then you don't need a mode argument at all.



Yes, i just mean qio_channel_file_new_path(filename, O_RDONLY, 0, errp) 
here. Maybe my poor english make you confused :(


Thanks
-Xie





[Qemu-devel] [PATCH v2] raw-posix: Fetch max sectors for host block device

2016-06-02 Thread Fam Zheng
This is sometimes a useful value we should count in.

Signed-off-by: Fam Zheng 
---
 block/raw-posix.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index a4f5a1b..32f9596 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -729,9 +729,33 @@ static void raw_reopen_abort(BDRVReopenState *state)
 state->opaque = NULL;
 }
 
+static int hdev_get_max_transfer_length(int fd)
+{
+#ifdef BLKSECTGET
+int max_sectors = 0;
+if (ioctl(fd, BLKSECTGET, _sectors) == 0) {
+return max_sectors;
+} else {
+return -errno;
+}
+#else
+return -ENOSYS;
+#endif
+}
+
 static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
 {
 BDRVRawState *s = bs->opaque;
+struct stat st;
+
+if (!fstat(s->fd, )) {
+if (S_ISBLK(st.st_mode)) {
+int ret = hdev_get_max_transfer_length(s->fd);
+if (ret >= 0) {
+bs->bl.max_transfer_length = ret;
+}
+}
+}
 
 raw_probe_alignment(bs, s->fd, errp);
 bs->bl.min_mem_alignment = s->buf_align;
-- 
2.8.2




Re: [Qemu-devel] [PATCH v5 1/1] Introduce "xen-load-devices-state"

2016-06-02 Thread Changlong Xie

On 06/02/2016 11:14 PM, Anthony PERARD wrote:

On Thu, Jun 02, 2016 at 06:36:46PM +0800, Changlong Xie wrote:

+void qmp_xen_load_devices_state(const char *filename, Error **errp)
+{
+QEMUFile *f;
+QIOChannelFile *ioc;
+int ret;
+
+/* Guest must be paused before loading the device state; the RAM state
+ * will already have been loaded by xc
+ */
+if (runstate_is_running()) {
+error_setg(errp, "Cannot update device state while vm is running");
+return;
+}
+vm_stop(RUN_STATE_RESTORE_VM);
+
+ioc = qio_channel_file_new_path(filename, O_WRONLY | O_CREAT, 0660, errp);


This does not look right, it looks like it's going to open the file
to write to it. You probably want O_RDONLY, also I don't think the
O_CREAT flag is needed. (and without O_WRONLY, mode can be 0 instead of
0660.)


+if (!ioc) {
+return;
+}
+f = qemu_fopen_channel_output(QIO_CHANNEL(ioc));


I'm not sure, but I guess here you want qemu_fopen_channel_input here.


After go over io channel mechanism, i think you are right here.



Thanks,







Re: [Qemu-devel] [QEMU RFC PATCH v3 1/6] Migration: Defined VMStateDescription struct for spapr_drc

2016-06-02 Thread David Gibson
On Thu, Jun 02, 2016 at 05:28:45PM -0700, Jianjun Duan wrote:
> 
> 
> On 06/01/2016 09:07 PM, David Gibson wrote:
> > On Tue, May 31, 2016 at 11:02:39AM -0700, Jianjun Duan wrote:
> >> To manage hotplug/unplug of dynamic resources such as PCI cards,
> >> memory, and CPU on sPAPR guests, a firmware abstraction known as
> >> a Dynamic Resource Connector (DRC) is used to assign a particular
> >> dynamic resource to the guest, and provide an interface for the
> >> guest to manage configuration/removal of the resource associated
> >> with it.
> >>
> >> To migrate the hotplugged resources in migration, the
> >> associated DRC state need be migrated. To migrate the DRC state,
> >> we defined the VMStateDescription struct for spapr_drc to enable
> >> the transmission of spapr_drc state in migration.
> >>
> >> Not all the elements in the DRC state are migrated. Only those
> >> ones modifiable or needed by guest actions or device add/remove
> >> operation are migrated. From the perspective of device
> >> hotplugging, if we hotplug a device on the source, we need to
> >> "coldplug" it on the target. The states across two hosts for the
> >> same device are not the same. Ideally we want the states be same
> >> after migration so that the device would function as hotplugged
> >> on the target. For example we can unplug it. The minimum DRC
> >> state we need to transfer should cover all the pieces changed by
> >> hotplugging. Out of the elements of the DRC state, isolation_state,
> >> allocation_sate, and configured are involved in the DR state
> >> transition diagram from PAPR+ 2.7, 13.4. configured and signalled
> >> are needed in attaching and detaching devices. indicator_state
> >> provides users with hardware state information. These 6 elements
> >> are migrated.
> >>
> >> detach_cb in the DRC state is a function pointer that cannot be
> >> migrated. We set it right after DRC state is migrated so that
> >> a migrated hot-unplug event could finish its work.
> >>
> >> Signed-off-by: Jianjun Duan 
> > 
> > So, the thing which concerns me about this patch is that it exposes
> > the DRCs as real objects in the migration stream, which will make it
> > difficult to ever remove them in the future.
> > 
> > Particularly for LMBs having full QOM objects for every individual DRC
> > is kind of clunky, and I'd already considered replacing them instead
> > with a QOM interface implementing a whole array of DRCs as part of the
> > "owning" object (machine or PHB).
> > 
> > The internal structure of the VMSD looks ok to me, but the
> > complication is the automatic "addressing" of it as a separate
> > object.  If we could manually take that over, allowing us to direct
> > the same VMSD data at elements in a simpler DRC array later, that
> > would be preferable.
> 
> We can address this concern by setting the unique instance_id for each
> drc. The instance_id can be used to match the drcs from source and
> target.

Ah, yes, that sounds like it should work.  And we already have a DRC
id value we can use for the purpose.

> > 
> > 
> >> ---
> >>  hw/ppc/spapr_drc.c | 61 
> >> ++
> >>  hw/ppc/spapr_pci.c | 22 +
> >>  include/hw/ppc/spapr_drc.h |  9 +++
> >>  3 files changed, 92 insertions(+)
> >>
> >> diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
> >> index 94c875d..1fb5e23 100644
> >> --- a/hw/ppc/spapr_drc.c
> >> +++ b/hw/ppc/spapr_drc.c
> >> @@ -617,6 +617,65 @@ static void spapr_dr_connector_instance_init(Object 
> >> *obj)
> >>  NULL, NULL, NULL, NULL);
> >>  }
> >>  
> >> +static bool spapr_drc_needed(void *opaque)
> >> +{
> >> +sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque;
> >> +sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
> >> +bool rc = false;
> >> +sPAPRDREntitySense value;
> >> +
> >> +drck->entity_sense(drc, );
> >> +/* If no dev is plugged in there is no need to migrate the DRC state 
> >> */
> >> +if (value != SPAPR_DR_ENTITY_SENSE_PRESENT) {
> >> +return false;
> >> +}
> >> +/*
> >> + * If there is dev plugged in, we need to migrate the DRC state when
> >> + * it is different from cold-plugged state
> >> + */
> >> +switch(drc->type) {
> >> +/* for PCI type */
> >> +case SPAPR_DR_CONNECTOR_TYPE_PCI:
> >> +rc = !((drc->isolation_state == 
> >> SPAPR_DR_ISOLATION_STATE_UNISOLATED) &&
> >> +   (drc->allocation_state == 
> >> SPAPR_DR_ALLOCATION_STATE_USABLE) &&
> >> +   drc->configured && drc->signalled && 
> >> !drc->awaiting_release);
> >> +break;
> >> +/* for LMB type */
> >> +case SPAPR_DR_CONNECTOR_TYPE_LMB:
> >> +rc = !((drc->isolation_state == 
> >> SPAPR_DR_ISOLATION_STATE_ISOLATED) &&
> >> +   (drc->allocation_state == 
> >> SPAPR_DR_ALLOCATION_STATE_UNUSABLE) &&
> >> +   drc->configured && drc->signalled && 

Re: [Qemu-devel] [PATCH v5 1/1] Introduce "xen-load-devices-state"

2016-06-02 Thread Eric Blake
On 06/02/2016 07:26 PM, Changlong Xie wrote:

>>> +
>>> +ioc = qio_channel_file_new_path(filename, O_WRONLY | O_CREAT,
>>> 0660, errp);
>>
>> This does not look right, it looks like it's going to open the file
>> to write to it. You probably want O_RDONLY, also I don't think the
>> O_CREAT flag is needed. (and without O_WRONLY, mode can be 0 instead of
>> 0660.)
>>
> 
> Yes, as you said. We should use 0_RDONLY for open(2), so mode should be 0.

Huh?  mode doesn't affect the current fd, but DOES affect the next
person to open the file.  If you are truly creating the file, then a
mode of 0 means you won't be able to reopen it without chmod.  And if
you are doing O_RDONLY | O_CREAT, all you will be able to create is an
empty file, which is a pretty boring read.  So drop the O_CREAT, and
then you don't need a mode argument at all.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH 1/2] raw-posix: Fetch max sectors for host block device from sysfs

2016-06-02 Thread Fam Zheng
On Thu, 06/02 14:54, Kevin Wolf wrote:
> Also a quick search on the internet suggests that the BLKSECTGET ioctl
> is what we're looking for, so hopefully using sysfs is unnecessary
> anyway.

Oops!  Looks like something went terribly wrong with my "quick search", will
post v2. Thanks!

Fam




Re: [Qemu-devel] [PULL 04/16] Makefile: Rules for docker testing

2016-06-02 Thread Fam Zheng
On Thu, 06/02 16:13, Eduardo Habkost wrote:
> On Wed, Jun 01, 2016 at 05:45:12PM +0800, Fam Zheng wrote:
> [...]
> > +
> > +CUR_TIME := $(shell date +%Y-%m-%d-%H.%M.%S.)
> > +# Makes the definition constant after the first expansion
> > +DOCKER_SRC_COPY = $(eval DOCKER_SRC_COPY := 
> > docker-src.$(CUR_TIME))$(DOCKER_SRC_COPY)
> > +
> > +$(DOCKER_SRC_COPY):
> 
> This seems to be confusing make in travis-ci, and I don't
> understand why:
> https://travis-ci.org/ehabkost/qemu/jobs/134820251#L1266

Indeed, but qemu.git master doesn't have that. Wondering why.

I would like to help, but could you fix the "unused variable ‘numvalue’" error
first? It's distracting too much when I try travis with your branch myself.

Fam



Re: [Qemu-devel] [PATCH v5 1/1] Introduce "xen-load-devices-state"

2016-06-02 Thread Changlong Xie

On 06/02/2016 11:14 PM, Anthony PERARD wrote:

On Thu, Jun 02, 2016 at 06:36:46PM +0800, Changlong Xie wrote:

+void qmp_xen_load_devices_state(const char *filename, Error **errp)
+{
+QEMUFile *f;
+QIOChannelFile *ioc;
+int ret;
+
+/* Guest must be paused before loading the device state; the RAM state
+ * will already have been loaded by xc
+ */
+if (runstate_is_running()) {
+error_setg(errp, "Cannot update device state while vm is running");
+return;
+}
+vm_stop(RUN_STATE_RESTORE_VM);
+
+ioc = qio_channel_file_new_path(filename, O_WRONLY | O_CREAT, 0660, errp);


This does not look right, it looks like it's going to open the file
to write to it. You probably want O_RDONLY, also I don't think the
O_CREAT flag is needed. (and without O_WRONLY, mode can be 0 instead of
0660.)



Yes, as you said. We should use 0_RDONLY for open(2), so mode should be 0.

Thanks
-Xie


+if (!ioc) {
+return;
+}
+f = qemu_fopen_channel_output(QIO_CHANNEL(ioc));


I'm not sure, but I guess here you want qemu_fopen_channel_input here.

Thanks,







Re: [Qemu-devel] [PATCH] virtio: move bi-endian target support to a single location

2016-06-02 Thread David Gibson
On Thu, Jun 02, 2016 at 06:04:37PM +0200, Greg Kurz wrote:
> On Wed, 1 Jun 2016 12:33:28 +1000
> David Gibson  wrote:
> 
> > On Tue, May 31, 2016 at 03:15:21PM +0200, Paolo Bonzini wrote:
> > > 
> > > 
> > > On 31/05/2016 15:10, Greg Kurz wrote:  
> > > >>> > > +#if defined(TARGET_PPC64) || defined(TARGET_ARM)
> > > >>> > > +#define LEGACY_VIRTIO_IS_BIENDIAN 1
> > > >>> > > +#endif
> > > >> > 
> > > >> > These will only be correct if something else includes cpu.h.  
> > > >> > Instead of  
> > > > Unless I missed something, the TARGET_* macros come from the generated
> > > > config-target.h header, which is in turn included by qemu/osdep.h and
> > > > thus included by most of the code.  
> > > 
> > > You're right.  Problems _could_ happen if virtio-access.h is included in
> > > a file compiled without -DNEED_CPU_H (i.e. with common-obj-y instead of
> > > obj-y) but include/exec/poison.h should take care of that.
> > >   
> > > >> > defining this, you should add
> > > >> > 
> > > >> > #include "cpu.h"
> > > >> > 
> > > >> > at the top of include/hw/virtio-access.h and leave the definitions in
> > > >> > target-*/cpu.h.
> > > >> >   
> > > > All this bi-endian stuff is really an old-virtio-only thing... it is
> > > > only to be used by virtio_access_is_big_endian(). The fact that it
> > > > broke silently with your cleanup series is yet another proof that
> > > > this workaround is fragile.  
> > > 
> > > It is not fragile actually.  cpu.h doesn't exist in common-obj-y, so the
> > > TARGET_IS_BIENDIAN define can be safely taken from cpu.h.
> > > 
> > > Anyway because of poison.h your solution isn't fragile either, so
> > > 
> > > Reviewed-by: Paolo Bonzini   
> > 
> > Should I take this through my tree?
> > 
> 
> That would be great !

Actually, that was a question for Paolo..


-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [RFC PATCH v0 0/2] Increase max memslots to 512 for PowerPC

2016-06-02 Thread David Gibson
On Thu, Jun 02, 2016 at 07:37:37PM +0530, Bharata B Rao wrote:
> On Thu, Jun 02, 2016 at 09:03:15AM +0200, Thomas Huth wrote:
> > On 02.06.2016 06:39, Bharata B Rao wrote:
> > ...
> > > Agreed. Here is the updated patch:
> > > 
> > > spapr: Increase hotpluggable memory slots to 256
> > > 
> > > From: Bharata B Rao 
> > > 
> > > KVM now supports 512 memslots on PowerPC (earlier it was 32). Allow half
> > > of it (256) to be used as hotpluggable memory slots.
> > > 
> > > Instead of hard coding the max value, use the KVM supplied value if KVM
> > > is enabled. Otherwise resort to the default value of 32.
> > > 
> > > Signed-off-by: Bharata B Rao 
> > > ---
> > >  hw/ppc/spapr.c |   15 +--
> > >  1 file changed, 13 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > > index 44e401a..c82adef 100644
> > > --- a/hw/ppc/spapr.c
> > > +++ b/hw/ppc/spapr.c
> > > @@ -1816,11 +1816,22 @@ static void ppc_spapr_init(MachineState *machine)
> > >  /* initialize hotplug memory address space */
> > >  if (machine->ram_size < machine->maxram_size) {
> > >  ram_addr_t hotplug_mem_size = machine->maxram_size - 
> > > machine->ram_size;
> > > +/*
> > > + * Number of memslots supported by KVM on PowerPC was increased
> > > + * from 32 to 512. Let us limit the number of hotpluggable slots
> > > + * to half of that (256). However ensure that number of slots
> > > + * doesn't drop below 32 on older hosts.
> > > + */
> > 
> > Using "hard-coded" information like "increased to 512" in comments is
> > true for the current state, but this has a risk of being out of date
> > soon. Once we change the memslots in the kernel, this comment is not
> > true anymore and might cause confusion. Better talk about leaving half
> > of the kernel memslots for PCI and other devices, or so.
> 
> Just want to note that even though we are limiting hotpluggable memory
> slots to half of max, it is always possible for other devices to eat
> into the memory hotplug slots, right ?
> 
> David - here is the patch updated with comments as suggested by Thomas.
> If you need a separate post, let me know.

Applied to ppc-for-2.7, thanks.

> 
> spapr: Increase hotpluggable memory slots to 256
> 
> From: Bharata B Rao 
> 
> KVM now supports 512 memslots on PowerPC (earlier it was 32). Allow half
> of it (256) to be used as hotpluggable memory slots.
> 
> Instead of hard coding the max value, use the KVM supplied value if KVM
> is enabled. Otherwise resort to the default value of 32.
> 
> Signed-off-by: Bharata B Rao 
> Reviewed-by: Thomas Huth 
> ---
>  hw/ppc/spapr.c |   14 --
>  1 file changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 44e401a..14cc6ae 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1816,11 +1816,21 @@ static void ppc_spapr_init(MachineState *machine)
>  /* initialize hotplug memory address space */
>  if (machine->ram_size < machine->maxram_size) {
>  ram_addr_t hotplug_mem_size = machine->maxram_size - 
> machine->ram_size;
> +/*
> + * Limit the number of hotpluggable memory slots to half the number
> + * slots that KVM supports, leaving the other half for PCI and other
> + * devices. However ensure that number of slots doesn't drop below 
> 32.
> + */
> +int max_memslots = kvm_enabled() ? kvm_get_max_memslots() / 2 :
> +   SPAPR_MAX_RAM_SLOTS;
>  
> -if (machine->ram_slots > SPAPR_MAX_RAM_SLOTS) {
> +if (max_memslots < SPAPR_MAX_RAM_SLOTS) {
> +max_memslots = SPAPR_MAX_RAM_SLOTS;
> +}
> +if (machine->ram_slots > max_memslots) {
>  error_report("Specified number of memory slots %"
>   PRIu64" exceeds max supported %d",
> - machine->ram_slots, SPAPR_MAX_RAM_SLOTS);
> + machine->ram_slots, max_memslots);
>  exit(1);
>  }
>  
> 

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [RFC v2 PATCH 01/13] Introduce TCGOpcode for memory barrier

2016-06-02 Thread Richard Henderson

On 06/02/2016 02:37 PM, Sergey Fedorov wrote:

On 03/06/16 00:18, Richard Henderson wrote:

On 06/02/2016 01:38 PM, Sergey Fedorov wrote:

On 02/06/16 23:36, Richard Henderson wrote:

On 06/02/2016 09:30 AM, Sergey Fedorov wrote:

I think we need to extend TCG load/store instruction attributes to
provide information about guest ordering requirements and leave
this TCG
operation only for explicit barrier instruction translation.


I do not agree.  I think separate barriers are much cleaner and easier
to manage and reason with.



How are we going to emulate strongly-ordered guests on weakly-ordered
hosts then? I think if every load/store operation must specify which
ordering it implies then this task would be quite simple.


Hum.  That does seem helpful-ish.  But I'm not certain how helpful it
is to complicate the helper functions even further.

What if we have tcg_canonicalize_memop (or some such) split off the
barriers into separate opcodes.  E.g.

MO_BAR_LD_B = 32// prevent earlier loads from crossing current op
MO_BAR_ST_B = 64// prevent earlier stores from crossing current op
MO_BAR_LD_A = 128// prevent later loads from crossing current op
MO_BAR_ST_A = 256// prevent later stores from crossing current op
MO_BAR_LDST_B = MO_BAR_LD_B | MO_BAR_ST_B
MO_BAR_LDST_A = MO_BAR_LD_A | MO_BAR_ST_A
MO_BAR_MASK = MO_BAR_LDST_B | MO_BAR_LDST_A

// Match Sparc MEMBAR as the most flexible host.
TCG_BAR_LD_LD = 1// #LoadLoad barrier
TCG_BAR_ST_LD = 2// #StoreLoad barrier
TCG_BAR_LD_ST = 4// #LoadStore barrier
TCG_BAR_ST_ST = 8// #StoreStore barrier
TCG_BAR_SYNC  = 64// SEQ_CST barrier

where

  tcg_gen_qemu_ld_i32(x, y, i, m | MO_BAR_LD_BEFORE | MO_BAR_ST_AFTER)

emits

  mbTCG_BAR_LD_LD
  qemu_ld_i32x, y, i, m
  mbTCG_BAR_LD_ST

We can then add an optimization pass which folds barriers with no
memory operations in between, so that duplicates are eliminated.


It would give us three TCG operations for each memory operation instead
of one. But then we might like to combine these barrier operations back
with memory operations in each backend. If we propagate memory ordering
semantics up to the backend, it can decide itself what instructions are
best to generate.


A strongly ordered target would generally only set BEFORE bits or AFTER bits, 
but not both (and I suggest we canonicalize on AFTER for all such targets). 
Thus a strongly ordered target would produce only 2 opcodes per memory op.


I supplied both to make it easier to handle a weakly ordered target with 
acquire/release bits.


I would *not* combine the barrier operations back with memory operations in the 
backend.  Only armv8 and ia64 can do that, and given the optimization level at 
which we generate code, I doubt it would really make much difference above 
separate barriers.



So I would just focus on translating only explicit memory barrier
operations for now.


Then why did you bring it up?


r~




[Qemu-devel] [PATCH 8/9] target-avr: adding instruction translation

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/translate-inst.c | 2511 +++
 target-avr/translate.h  |  123 +++
 2 files changed, 2634 insertions(+)
 create mode 100644 target-avr/translate-inst.c
 create mode 100644 target-avr/translate.h

diff --git a/target-avr/translate-inst.c b/target-avr/translate-inst.c
new file mode 100644
index 000..b890cd1
--- /dev/null
+++ b/target-avr/translate-inst.c
@@ -0,0 +1,2511 @@
+/*
+ *  QEMU AVR CPU
+ *
+ *  Copyright (c) 2016 Michael Rolnik
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, see
+ *  
+ */
+
+#include "translate.h"
+#include "translate-inst.h"
+
+/*
+NOTE:   all registers are assumed to hold 8 bit values.
+so all operations done on registers should preseve this property
+*/
+
+/*
+NOTE:   the flags C,H,V,N,V have either 0 or 1 values
+NOTE:   the flag Z has inverse logic, when the value of Zf is 0 the flag 
is assumed to be set, non zero - not set
+*/
+
+void gen_add_CHf(TCGv R, TCGv Rd, TCGv Rr);
+void gen_add_Vf(TCGv R, TCGv Rd, TCGv Rr);
+void gen_sub_CHf(TCGv R, TCGv Rd, TCGv Rr);
+void gen_sub_Vf(TCGv R, TCGv Rd, TCGv Rr);
+void gen_ZNSf(TCGv R);
+void gen_push_ret(CPUAVRState *env, int ret);
+void gen_pop_ret(CPUAVRState *env, TCGv ret);
+void gen_jmp_ez(void);
+void gen_jmp_z(void);
+
+void gen_set_addr(TCGv addr, TCGv H, TCGv M, TCGv l); /*  H:M:L = addr  */
+void gen_set_xaddr(TCGv addr);
+void gen_set_yaddr(TCGv addr);
+void gen_set_zaddr(TCGv addr);
+
+TCGv gen_get_addr(TCGv H, TCGv M, TCGv L);/*  addr = H:M:L*/
+TCGv gen_get_xaddr(void);
+TCGv gen_get_yaddr(void);
+TCGv gen_get_zaddr(void);
+int sex(int Imm, unsigned bits);
+
+void gen_add_CHf(TCGv R, TCGv Rd, TCGv Rr)
+{
+TCGv t1 = tcg_temp_new_i32();
+TCGv t2 = tcg_temp_new_i32();
+TCGv t3 = tcg_temp_new_i32();
+
+tcg_gen_and_tl(t1, Rd, Rr);/*  t1 = Rd & Rr  */
+tcg_gen_not_tl(t2, R); /*  t2 = Rd & ~R  */
+tcg_gen_and_tl(t2, Rd, t2);
+tcg_gen_not_tl(t3, R); /*  t3 = Rr  *~R  */
+tcg_gen_and_tl(t3, Rr, t3);
+tcg_gen_or_tl(t1, t1, t2);/*  t1 = t1 | t2 | t3  */
+tcg_gen_or_tl(t1, t1, t3);
+
+tcg_gen_shri_tl(cpu_Cf, t1, 7); /*  Cf = t1(7)  */
+tcg_gen_shri_tl(cpu_Hf, t1, 3); /*  Hf = t1(3)  */
+tcg_gen_andi_tl(cpu_Hf, cpu_Hf, 1);
+
+tcg_temp_free_i32(t3);
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t1);
+}
+
+void gen_add_Vf(TCGv R, TCGvRd, TCGvRr)
+{
+TCGv t1 = tcg_temp_new_i32();
+TCGv t2 = tcg_temp_new_i32();
+
+tcg_gen_not_tl(t1, Rd);/*  t1 = ~Rd & ~Rr & R  */
+tcg_gen_not_tl(t2, Rr);
+tcg_gen_and_tl(t1, t1, t2);
+tcg_gen_and_tl(t1, t1, R);
+
+tcg_gen_not_tl(t2, R); /*  t2 = Rd & Rr & ~R  */
+tcg_gen_and_tl(t2, t2, Rd);
+tcg_gen_and_tl(t2, t2, Rr);
+
+tcg_gen_or_tl(t1, t1, t2);/*  t1 = Rd & Rr & ~R | ~Rd & ~Rr & R  */
+
+tcg_gen_shri_tl(cpu_Vf, t1, 7); /*  Vf = t1(7)  */
+
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t1);
+}
+
+void gen_sub_CHf(TCGv R, TCGvRd, TCGvRr)
+{
+TCGv t1 = tcg_temp_new_i32();
+TCGv t2 = tcg_temp_new_i32();
+TCGv t3 = tcg_temp_new_i32();
+
+/*  Cf & Hf  */
+tcg_gen_not_tl(t1, Rd);/*  t1 = ~Rd  */
+tcg_gen_and_tl(t2, t1, Rr);/*  t2 = ~Rd & Rr  */
+tcg_gen_or_tl(t3, t1, Rr);/*  t3 = (~Rd | Rr) & R  */
+tcg_gen_and_tl(t3, t3, R);
+tcg_gen_or_tl(t2, t2, t3);/*  t2 = ~Rd & Rr | ~Rd & R | R & Rr  */
+tcg_gen_shri_tl(cpu_Cf, t2, 7); /*  Cf = t2(7)  */
+tcg_gen_shri_tl(cpu_Hf, t2, 3); /*  Hf = t2(3)  */
+tcg_gen_andi_tl(cpu_Hf, cpu_Hf, 1);
+
+tcg_temp_free_i32(t3);
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t1);
+}
+
+void gen_sub_Vf(TCGv R, TCGvRd, TCGvRr)
+{
+TCGv t1 = tcg_temp_new_i32();
+TCGv t2 = tcg_temp_new_i32();
+
+/*  Vf  */
+tcg_gen_and_tl(t1, Rr, R); /*  t1 = Rd & ~Rr & ~R  */
+tcg_gen_not_tl(t1, t1);
+tcg_gen_and_tl(t1, t1, Rd);
+tcg_gen_not_tl(t2, Rd);/*  t2 = ~Rd & Rr & R  */
+tcg_gen_and_tl(t2, t2, Rr);
+tcg_gen_and_tl(t2, t2, R);
+tcg_gen_or_tl(t1, t1, t2);/*  t1 = Rd & ~Rr & ~R | ~Rd & Rr & R  */
+tcg_gen_shri_tl(cpu_Vf, t1, 7); /*  Vf = t1(7)  */
+

[Qemu-devel] [PATCH 9/9] target-avr: updating translate.c to use instructions translation

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/Makefile.objs |   4 +-
 target-avr/translate.c   | 132 ---
 2 files changed, 59 insertions(+), 77 deletions(-)

diff --git a/target-avr/Makefile.objs b/target-avr/Makefile.objs
index c503546..8d06d54 100644
--- a/target-avr/Makefile.objs
+++ b/target-avr/Makefile.objs
@@ -1,3 +1,5 @@
-obj-y   += translate.o cpu.o helper.o
+obj-y   += translate.o helper.o cpu.o translate-inst.o
 obj-y   += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += machine.o
+
+obj-y   += decode.o
diff --git a/target-avr/translate.c b/target-avr/translate.c
index 029cffa..228ee90 100644
--- a/target-avr/translate.c
+++ b/target-avr/translate.c
@@ -18,60 +18,30 @@
  *  
  */
 
-#include "qemu/osdep.h"
-
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "disas/disas.h"
-#include "tcg-op.h"
-#include "exec/cpu_ldst.h"
-
-#include "exec/helper-proto.h"
-#include "exec/helper-gen.h"
-#include "exec/log.h"
-
-typedef struct DisasContext DisasContext;
-typedef struct InstInfo InstInfo;
-
-/*This is the state at translation time.  */
-struct DisasContext {
-struct TranslationBlock*tb;
-
-/*Routine used to access memory */
-int memidx;
-int bstate;
-int singlestep;
-};
-
-enum {
-BS_NONE = 0,/*  Nothing special (none of the below  */
-BS_STOP = 1,/*  We want to stop translation for any reason  */
-BS_BRANCH = 2,/*  A branch condition is reached   */
-BS_EXCP = 3,/*  An exception condition is reached   */
-};
-
-static TCGv_env cpu_env;
-
-static TCGv cpu_pc;
-
-static TCGv cpu_Cf;
-static TCGv cpu_Zf;
-static TCGv cpu_Nf;
-static TCGv cpu_Vf;
-static TCGv cpu_Sf;
-static TCGv cpu_Hf;
-static TCGv cpu_Tf;
-static TCGv cpu_If;
-
-static TCGv cpu_rampD;
-static TCGv cpu_rampX;
-static TCGv cpu_rampY;
-static TCGv cpu_rampZ;
-
-static TCGv cpu_io[64];
-static TCGv cpu_r[32];
-static TCGv cpu_eind;
-static TCGv cpu_sp;
+#include "translate.h"
+
+TCGv_env cpu_env;
+
+TCGv cpu_pc;
+
+TCGv cpu_Cf;
+TCGv cpu_Zf;
+TCGv cpu_Nf;
+TCGv cpu_Vf;
+TCGv cpu_Sf;
+TCGv cpu_Hf;
+TCGv cpu_Tf;
+TCGv cpu_If;
+
+TCGv cpu_rampD;
+TCGv cpu_rampX;
+TCGv cpu_rampY;
+TCGv cpu_rampZ;
+
+TCGv cpu_io[64];
+TCGv cpu_r[32];
+TCGv cpu_eind;
+TCGv cpu_sp;
 
 #include "exec/gen-icount.h"
 #define REG(x)  (cpu_r[x])
@@ -120,24 +90,27 @@ void avr_translate_init(void)
 done_init = 1;
 }
 
-static inline void gen_goto_tb(CPUAVRState *env, DisasContext *ctx, int n, 
target_ulong dest)
+static void decode_opc(AVRCPU *cpu, DisasContext *ctx, InstInfo *inst)
 {
-TranslationBlock   *tb;
+CPUAVRState*env = >env;
 
-tb = ctx->tb;
+inst->opcode = cpu_ldl_code(env, inst->cpc * 2);   /*  pc points to words  
  */
+inst->length = 16;
+inst->translate = NULL;
 
-if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)
-&&  (ctx->singlestep == 0)) {
-tcg_gen_goto_tb(n);
-tcg_gen_movi_i32(cpu_pc, dest);
-tcg_gen_exit_tb((uintptr_t)tb + n);
-} else {
-tcg_gen_movi_i32(cpu_pc, dest);
+/*  the following function looks onto the opcode as a string of bytes   */
+avr_decode(inst->cpc, >length, inst->opcode, >translate);
 
-if (ctx->singlestep) {
-gen_helper_debug(cpu_env);
-}
-tcg_gen_exit_tb(0);
+if (inst->length == 16) {
+inst->npc = inst->cpc + 1;
+/*  get opcode as 16bit value   */
+inst->opcode = inst->opcode & 0x;
+}
+if (inst->length == 32) {
+inst->npc = inst->cpc + 2;
+/*  get opcode as 32bit value   */
+inst->opcode = (inst->opcode << 16)
+ | (inst->opcode >> 16);
 }
 }
 
@@ -171,18 +144,21 @@ void gen_intermediate_code(CPUAVRState *env, struct 
TranslationBlock *tb)
 gen_tb_start(tb);
 
 /*  decode first instruction*/
-cpc = pc_start;
-npc = cpc + 1;
+ctx.inst[0].cpc = pc_start;
+decode_opc(cpu, , [0]);
 do {
-/*  translate current instruction   */
+/*  set curr/next PCs   */
+cpc = ctx.inst[0].cpc;
+npc = ctx.inst[0].npc;
+
+/*  decode next instruction */
+ctx.inst[1].cpc = ctx.inst[0].npc;
+decode_opc(cpu, , [1]);
+
+/*  translate current instruction */
 tcg_gen_insn_start(cpc);
 num_insns++;
 
-/*  just skip to next instruction   */
-cpc++;
-npc++;
-ctx.bstate = BS_NONE;
-
 if (unlikely(cpu_breakpoint_test(cs, cpc * 2, BP_ANY))) {
 tcg_gen_movi_i32(cpu_pc, cpc);
 gen_helper_debug(cpu_env);
@@ -194,6 +170,8 @@ void gen_intermediate_code(CPUAVRState *env, struct 

[Qemu-devel] [PATCH 4/9] target-avr: adding instructions encodings

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/translate-inst.h | 838 
 1 file changed, 838 insertions(+)
 create mode 100644 target-avr/translate-inst.h

diff --git a/target-avr/translate-inst.h b/target-avr/translate-inst.h
new file mode 100644
index 000..0fad30f
--- /dev/null
+++ b/target-avr/translate-inst.h
@@ -0,0 +1,838 @@
+
+#ifndef AVR_TRANSLATE_INST_H_
+#define AVR_TRANSLATE_INST_H_
+
+typedef struct DisasContextDisasContext;
+
+int avr_translate_NOP(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+
+int avr_translate_MOVW(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t MOVW_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t MOVW_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 4);
+}
+
+int avr_translate_MULS(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t MULS_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t MULS_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 4);
+}
+
+int avr_translate_MULSU(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t MULSU_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+static inline uint32_t MULSU_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+int avr_translate_FMUL(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t FMUL_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+static inline uint32_t FMUL_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+int avr_translate_FMULS(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t FMULS_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+static inline uint32_t FMULS_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+int avr_translate_FMULSU(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t FMULSU_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+static inline uint32_t FMULSU_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+int avr_translate_CPC(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t CPC_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t CPC_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t CPC_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_SBC(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t SBC_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t SBC_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t SBC_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_ADD(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t ADD_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t ADD_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t ADD_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_AND(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t AND_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t AND_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t AND_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_EOR(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t EOR_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t EOR_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t EOR_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_OR(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t OR_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t OR_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t OR_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_MOV(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t MOV_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t MOV_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t MOV_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_CPSE(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t CPSE_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t CPSE_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t CPSE_hRr(uint32_t opcode)
+{
+

[Qemu-devel] [PATCH 5/9] target-avr: adding AVR interrupt handling

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/helper.c | 64 -
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/target-avr/helper.c b/target-avr/helper.c
index fbab91d..bb47a87 100644
--- a/target-avr/helper.c
+++ b/target-avr/helper.c
@@ -31,11 +31,73 @@
 
 bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
-return  false;
+CPUClass*cc  = CPU_GET_CLASS(cs);
+AVRCPU  *cpu = AVR_CPU(cs);
+CPUAVRState *env = >env;
+
+boolret = false;
+
+if (interrupt_request & CPU_INTERRUPT_RESET) {
+if (cpu_interrupts_enabled(env)) {
+cs->exception_index = EXCP_RESET;
+cc->do_interrupt(cs);
+
+cs->interrupt_request   &= ~CPU_INTERRUPT_RESET;
+
+ret = true;
+}
+}
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+if (cpu_interrupts_enabled(env) && env->intsrc != 0) {
+int index   = __builtin_ffs(env->intsrc) - 1;
+cs->exception_index = EXCP_INT(index);
+cc->do_interrupt(cs);
+
+env->intsrc &= env->intsrc - 1; /* clear the interrupt 
*/
+cs->interrupt_request   &= ~CPU_INTERRUPT_HARD;
+
+ret = true;
+}
+}
+return ret;
 }
 
 void avr_cpu_do_interrupt(CPUState *cs)
 {
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState*env = >env;
+
+uint32_tret = env->pc;
+int vector;
+int size= avr_feature(env, AVR_FEATURE_JMP_CALL) ? 2 : 1;
+int base= 0;/* TODO: where to get it */
+
+if (cs->exception_index == EXCP_RESET) {
+vector  = 0;
+} else if (env->intsrc != 0) {
+vector  = __builtin_ffs(env->intsrc);
+}
+
+if (avr_feature(env, AVR_FEATURE_3_BYTE_PC)) {
+stb_phys(cs->as, env->sp--, (ret & 0xff));
+stb_phys(cs->as, env->sp--, (ret & 0x00ff00) >>  8);
+stb_phys(cs->as, env->sp--, (ret & 0xff) >> 16);
+
+env->pc = base + vector * size;
+} else if (avr_feature(env, AVR_FEATURE_2_BYTE_PC)) {
+stb_phys(cs->as, env->sp--, (ret & 0xff));
+stb_phys(cs->as, env->sp--, (ret & 0x00ff00) >>  8);
+
+env->pc = base + vector * size;
+} else {
+stb_phys(cs->as, env->sp--, (ret & 0xff));
+
+env->pc = base + vector * size;
+}
+
+env->sregI  = 0;/*  clear Global Interrupt Flag */
+
+cs->exception_index = -1;
 }
 
 int avr_cpu_memory_rw_debug(CPUState *cs, vaddr addr, uint8_t *buf, int len, 
bool is_write)
-- 
2.4.9 (Apple Git-60)




[Qemu-devel] [PATCH 1/9] target-avr: AVR cores support is added. 1. basic CPU structure 2. registers 3. no instructions

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 arch_init.c |   2 +
 configure   |   5 +
 default-configs/avr-softmmu.mak |   1 +
 disas/Makefile.objs |   1 +
 disas/avr.c |  10 ++
 include/disas/bfd.h |   7 +
 include/sysemu/arch_init.h  |   1 +
 target-avr/Makefile.objs|   3 +
 target-avr/cpu-qom.h|  80 +++
 target-avr/cpu.c| 288 
 target-avr/cpu.h| 123 +
 target-avr/gdbstub.c|  99 ++
 target-avr/helper.c |  85 
 target-avr/helper.h |  21 +++
 target-avr/machine.c|  54 
 target-avr/machine.h|  21 +++
 target-avr/translate.c  | 288 
 17 files changed, 1089 insertions(+)
 create mode 100644 default-configs/avr-softmmu.mak
 create mode 100644 disas/avr.c
 create mode 100644 target-avr/Makefile.objs
 create mode 100644 target-avr/cpu-qom.h
 create mode 100644 target-avr/cpu.c
 create mode 100644 target-avr/cpu.h
 create mode 100644 target-avr/gdbstub.c
 create mode 100644 target-avr/helper.c
 create mode 100644 target-avr/helper.h
 create mode 100644 target-avr/machine.c
 create mode 100644 target-avr/machine.h
 create mode 100644 target-avr/translate.c

diff --git a/arch_init.c b/arch_init.c
index fa05973..be6e6de 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -80,6 +80,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_UNICORE32
 #elif defined(TARGET_TRICORE)
 #define QEMU_ARCH QEMU_ARCH_TRICORE
+#elif defined(TARGET_AVR)
+#define QEMU_ARCH QEMU_ARCH_AVR
 #endif
 
 const uint32_t arch_type = QEMU_ARCH;
diff --git a/configure b/configure
index b5aab72..90af399 100755
--- a/configure
+++ b/configure
@@ -5630,6 +5630,8 @@ case "$target_name" in
   x86_64)
 TARGET_BASE_ARCH=i386
   ;;
+  avr)
+  ;;
   alpha)
   ;;
   arm|armeb)
@@ -5826,6 +5828,9 @@ disas_config() {
 
 for i in $ARCH $TARGET_BASE_ARCH ; do
   case "$i" in
+  avr)
+disas_config "AVR"
+  ;;
   alpha)
 disas_config "ALPHA"
   ;;
diff --git a/default-configs/avr-softmmu.mak b/default-configs/avr-softmmu.mak
new file mode 100644
index 000..ca94aad
--- /dev/null
+++ b/default-configs/avr-softmmu.mak
@@ -0,0 +1 @@
+# Default configuration for avr-softmmu
diff --git a/disas/Makefile.objs b/disas/Makefile.objs
index abeba84..218e434 100644
--- a/disas/Makefile.objs
+++ b/disas/Makefile.objs
@@ -21,6 +21,7 @@ common-obj-$(CONFIG_S390_DIS) += s390.o
 common-obj-$(CONFIG_SH4_DIS) += sh4.o
 common-obj-$(CONFIG_SPARC_DIS) += sparc.o
 common-obj-$(CONFIG_LM32_DIS) += lm32.o
+common-obj-$(CONFIG_AVR_DIS) += avr.o
 
 # TODO: As long as the TCG interpreter and its generated code depend
 # on the QEMU target, we cannot compile the disassembler here.
diff --git a/disas/avr.c b/disas/avr.c
new file mode 100644
index 000..f916e72
--- /dev/null
+++ b/disas/avr.c
@@ -0,0 +1,10 @@
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "disas/bfd.h"
+
+int print_insn_avr(bfd_vma addr, disassemble_info *info)
+{
+int length  = 0;;
+/*  TODO*/
+return length;
+}
diff --git a/include/disas/bfd.h b/include/disas/bfd.h
index a112e9c..04e2201 100644
--- a/include/disas/bfd.h
+++ b/include/disas/bfd.h
@@ -213,6 +213,12 @@ enum bfd_architecture
 #define bfd_mach_m32r  0  /* backwards compatibility */
   bfd_arch_mn10200,/* Matsushita MN10200 */
   bfd_arch_mn10300,/* Matsushita MN10300 */
+  bfd_arch_avr,   /* Atmel AVR microcontrollers.  */
+#define bfd_mach_avr1  1
+#define bfd_mach_avr2  2
+#define bfd_mach_avr3  3
+#define bfd_mach_avr4  4
+#define bfd_mach_avr5  5
   bfd_arch_cris,   /* Axis CRIS */
 #define bfd_mach_cris_v0_v10   255
 #define bfd_mach_cris_v32  32
@@ -415,6 +421,7 @@ int print_insn_crisv10  (bfd_vma, 
disassemble_info*);
 int print_insn_microblaze   (bfd_vma, disassemble_info*);
 int print_insn_ia64 (bfd_vma, disassemble_info*);
 int print_insn_lm32 (bfd_vma, disassemble_info*);
+int print_insn_avr  (bfd_vma, disassemble_info*);
 
 #if 0
 /* Fetch the disassembler for a given BFD, if that support is available.  */
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index d690dfa..8c75777 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -23,6 +23,7 @@ enum {
 QEMU_ARCH_UNICORE32 = (1 << 14),
 QEMU_ARCH_MOXIE = (1 << 15),
 QEMU_ARCH_TRICORE = (1 << 16),
+QEMU_ARCH_AVR = (1 << 17),
 };
 
 extern const uint32_t arch_type;
diff --git a/target-avr/Makefile.objs b/target-avr/Makefile.objs
new file mode 100644
index 000..c503546
--- /dev/null
+++ b/target-avr/Makefile.objs
@@ -0,0 +1,3 @@
+obj-y   += translate.o cpu.o helper.o
+obj-y   += gdbstub.o
+obj-$(CONFIG_SOFTMMU) += machine.o
diff 

[Qemu-devel] [PATCH 7/9] target-avr: adding instruction decoder

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/decode.c | 724 
 1 file changed, 724 insertions(+)
 create mode 100644 target-avr/decode.c

diff --git a/target-avr/decode.c b/target-avr/decode.c
new file mode 100644
index 000..b846f1d
--- /dev/null
+++ b/target-avr/decode.c
@@ -0,0 +1,724 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2016 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+
+#include 
+#include "translate.h"
+
+
+uint32_t avr_decode(uint32_t pc, uint32_t *length, uint32_t code, 
translate_function_t *translate)
+{
+uint32_t opcode  = extract32(code, 0, 16);
+switch (opcode & 0xd000) {
+case0x: {
+uint32_t opcode  = extract32(code, 0, 16);
+switch (opcode & 0x2c00) {
+case0x: {
+uint32_t opcode  = extract32(code, 0, 16);
+switch (opcode & 0x0300) {
+case0x: {
+*length = 16;
+*translate = _translate_NOP;
+break;
+}
+case0x0100: {
+*length = 16;
+*translate = _translate_MOVW;
+break;
+}
+case0x0200: {
+*length = 16;
+*translate = _translate_MULS;
+break;
+}
+case0x0300: {
+uint32_t opcode  = extract32(code, 0, 16);
+switch (opcode & 0x0088) {
+case0x: {
+*length = 16;
+*translate = _translate_MULSU;
+break;
+}
+case0x0008: {
+*length = 16;
+*translate = _translate_FMUL;
+break;
+}
+case0x0080: {
+*length = 16;
+*translate = _translate_FMULS;
+break;
+}
+case0x0088: {
+*length = 16;
+*translate = _translate_FMULSU;
+break;
+}
+}
+break;
+}
+}
+break;
+}
+case0x0400: {
+*length = 16;
+*translate = _translate_CPC;
+break;
+}
+case0x0800: {
+*length = 16;
+*translate = _translate_SBC;
+break;
+}
+case0x0c00: {
+*length = 16;
+*translate = _translate_ADD;
+break;
+}
+case0x2000: {
+*length = 16;
+*translate = _translate_AND;
+break;
+}
+case0x2400: {
+*length = 16;
+*translate = _translate_EOR;
+break;
+}
+case0x2800: {
+*length = 16;
+*translate = _translate_OR;
+break;
+}
+case0x2c00: {
+*length = 16;
+*translate = _translate_MOV;
+break;
+}
+}
+break;
+}
+case0x1000: {
+uint32_t opcode  = extract32(code, 0, 16);
+switch (opcode 

[Qemu-devel] [PATCH 3/9] target-avr: adding a sample AVR board

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 hw/Makefile.objs |   1 +
 hw/avr/Makefile.objs |   1 +
 hw/avr/sample-io.c   | 217 +++
 hw/avr/sample.c  | 118 
 4 files changed, 337 insertions(+)
 create mode 100644 hw/avr/Makefile.objs
 create mode 100644 hw/avr/sample-io.c
 create mode 100644 hw/avr/sample.c

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 4a07ed4..262ca15 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -33,6 +33,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += watchdog/
 devices-dirs-$(CONFIG_SOFTMMU) += xen/
 devices-dirs-$(CONFIG_MEM_HOTPLUG) += mem/
 devices-dirs-$(CONFIG_SMBIOS) += smbios/
+devices-dirs-$(CONFIG_SOFTMMU) += avr/
 devices-dirs-y += core/
 common-obj-y += $(devices-dirs-y)
 obj-y += $(devices-dirs-y)
diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
new file mode 100644
index 000..9f6be2f
--- /dev/null
+++ b/hw/avr/Makefile.objs
@@ -0,0 +1 @@
+obj-y   += sample.o sample-io.o
diff --git a/hw/avr/sample-io.c b/hw/avr/sample-io.c
new file mode 100644
index 000..7bf5e48
--- /dev/null
+++ b/hw/avr/sample-io.c
@@ -0,0 +1,217 @@
+/*
+ *  QEMU AVR CPU
+ *
+ *  Copyright (c) 2016 Michael Rolnik
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, see
+ *  
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "include/hw/sysbus.h"
+
+#define TYPE_SAMPLEIO   "SampleIO"
+#define SAMPLEIO(obj)   OBJECT_CHECK(SAMPLEIOState, (obj), TYPE_SAMPLEIO)
+
+#ifndef DEBUG_SAMPLEIO
+#define DEBUG_SAMPLEIO 1
+#endif
+
+#define DPRINTF(fmt, args...) \
+do {  \
+if (DEBUG_SAMPLEIO) { \
+fprintf(stderr, "[%s]%s: " fmt , TYPE_SAMPLEIO, __func__, ##args);\
+} \
+} \
+while (0)
+
+#define AVR_IO_CPU_REGS_SIZE0x0020
+#define AVR_IO_CPU_IO_SIZE  0x0040
+#define AVR_IO_EXTERN_IO_SIZE   0x00a0
+#define AVR_IO_SIZE (AVR_IO_CPU_REGS_SIZE   \
++ AVR_IO_CPU_IO_SIZE\
++ AVR_IO_EXTERN_IO_SIZE)
+
+#define AVR_IO_CPU_REGS_BASE0x
+#define AVR_IO_CPU_IO_BASE  (AVR_IO_CPU_REGS_BASE   \
++ AVR_IO_CPU_REGS_SIZE)
+#define AVR_IO_EXTERN_IO_BASE   (AVR_IO_CPU_IO_BASE \
++ AVR_IO_CPU_IO_SIZE)
+
+
+typedef struct SAMPLEIOState {
+SysBusDeviceparent;
+
+MemoryRegioniomem;
+
+AVRCPU *cpu;
+
+uint8_t io[0x40];
+uint8_t exio[0xa0];
+} SAMPLEIOState;
+
+static uint64_t sample_io_read(void *opaque, hwaddr offset, unsigned size);
+static void sample_io_write(void *opaque, hwaddr offset, uint64_t value, 
unsigned size);
+static int sample_io_init(DeviceState *sbd);
+static void sample_io_class_init(ObjectClass *klass, void *data);
+static void sample_io_register_types(void);
+
+static void write_Rx(CPUAVRState *env, int inst, uint8_t data);
+static uint8_t read_Rx(CPUAVRState *env, int inst);
+
+static const
+MemoryRegionOps sample_io_ops = {
+.read = sample_io_read,
+.write = sample_io_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static
+Propertysample_io_properties[] = {
+DEFINE_PROP_END_OF_LIST(),
+};
+static const
+VMStateDescription  sample_io_vmstate = {
+.name = TYPE_SAMPLEIO,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[])
+{
+VMSTATE_END_OF_LIST()
+}
+};
+
+void write_Rx(CPUAVRState *env, int inst, uint8_t data)
+{
+env->r[inst] = data;
+}
+uint8_t read_Rx(CPUAVRState *env, int inst)
+{
+return  env->r[inst];
+}
+
+static
+void sample_io_reset(DeviceState *dev)
+{
+DPRINTF("\n");
+}
+
+static
+uint64_tsample_io_read(void *opaque, hwaddr offset, unsigned size)
+{
+SAMPLEIOState *s = SAMPLEIO(opaque);
+AVRCPU *cpu = s->cpu;
+CPUAVRState *env = >env;
+uint64_t res = 0;
+
+assert(size == 1);
+
+if (AVR_IO_CPU_REGS_BASE <= offset
+

[Qemu-devel] [PATCH 6/9] target-avr: adding helpers for IN, OUT, SLEEP, WBR & unsupported instructions

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/helper.c | 117 +++-
 target-avr/helper.h |   5 +++
 2 files changed, 111 insertions(+), 11 deletions(-)

diff --git a/target-avr/helper.c b/target-avr/helper.c
index bb47a87..b93589a 100644
--- a/target-avr/helper.c
+++ b/target-avr/helper.c
@@ -31,7 +31,7 @@
 
 bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
-CPUClass*cc  = CPU_GET_CLASS(cs);
+CPUClass*cc = CPU_GET_CLASS(cs);
 AVRCPU  *cpu = AVR_CPU(cs);
 CPUAVRState *env = >env;
 
@@ -49,7 +49,7 @@ bool avr_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 }
 if (interrupt_request & CPU_INTERRUPT_HARD) {
 if (cpu_interrupts_enabled(env) && env->intsrc != 0) {
-int index   = __builtin_ffs(env->intsrc) - 1;
+int index = __builtin_ffs(env->intsrc) - 1;
 cs->exception_index = EXCP_INT(index);
 cc->do_interrupt(cs);
 
@@ -64,18 +64,18 @@ bool avr_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 
 void avr_cpu_do_interrupt(CPUState *cs)
 {
-AVRCPU *cpu = AVR_CPU(cs);
-CPUAVRState*env = >env;
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = >env;
 
-uint32_tret = env->pc;
-int vector;
-int size= avr_feature(env, AVR_FEATURE_JMP_CALL) ? 2 : 1;
-int base= 0;/* TODO: where to get it */
+uint32_t ret = env->pc;
+int vector;
+int size = avr_feature(env, AVR_FEATURE_JMP_CALL) ? 2 : 1;
+int base = 0;/* TODO: where to get it */
 
 if (cs->exception_index == EXCP_RESET) {
-vector  = 0;
+vector = 0;
 } else if (env->intsrc != 0) {
-vector  = __builtin_ffs(env->intsrc);
+vector = __builtin_ffs(env->intsrc);
 }
 
 if (avr_feature(env, AVR_FEATURE_3_BYTE_PC)) {
@@ -95,7 +95,7 @@ void avr_cpu_do_interrupt(CPUState *cs)
 env->pc = base + vector * size;
 }
 
-env->sregI  = 0;/*  clear Global Interrupt Flag */
+env->sregI = 0;/*  clear Global Interrupt Flag */
 
 cs->exception_index = -1;
 }
@@ -136,6 +136,21 @@ void tlb_fill(CPUState *cs, target_ulong vaddr, int 
is_write, int mmu_idx, uintp
 
 tlb_set_page_with_attrs(cs, vaddr, paddr, attrs, prot, mmu_idx, page_size);
 }
+void helper_sleep(CPUAVRState *env)
+{
+CPUState *cs = CPU(avr_env_get_cpu(env));
+
+cs->exception_index = EXCP_HLT;
+cpu_loop_exit(cs);
+}
+void helper_unsupported(CPUAVRState *env)
+{
+CPUState *cs = CPU(avr_env_get_cpu(env));
+
+cs->exception_index = EXCP_DEBUG;
+cpu_dump_state(cs, stderr, fprintf, 0);
+cpu_loop_exit(cs);
+}
 
 void helper_debug(CPUAVRState *env)
 {
@@ -145,3 +160,83 @@ void helper_debug(CPUAVRState *env)
 cpu_loop_exit(cs);
 }
 
+void helper_wdr(CPUAVRState *env)
+{
+CPUState *cs = CPU(avr_env_get_cpu(env));
+
+cs->exception_index = EXCP_DEBUG;
+cpu_loop_exit(cs);
+}
+
+target_ulong helper_inb(CPUAVRState *env, uint32_t port)
+{
+printf("in: io[%02x]\n", port);
+
+switch (port) {
+case0x3b: {
+return  env->rampZ; /*  RAMPZ */
+}
+case0x3d: { /*  SPL */
+return  env->sp & 0x00ff;
+}
+case0x3e: { /*  SPH */
+return  env->sp >> 8;
+}
+case0x3f: { /*  SREG */
+uint8_t sreg;
+sreg =   (env->sregC & 0x01) << 0
+|   (env->sregZ & 0x01) << 1
+|   (env->sregN & 0x01) << 2
+|   (env->sregV & 0x01) << 3
+|   (env->sregS & 0x01) << 4
+|   (env->sregH & 0x01) << 5
+|   (env->sregT & 0x01) << 6
+|   (env->sregI & 0x01) << 7;
+return  sreg;
+}
+}
+return  0;
+}
+
+void helper_outb(CPUAVRState *env, uint32_t port, uint32_t data)
+{
+printf("out:%02x -> io[%02x]\n", data, port);
+
+data&= 0x00ff;
+
+switch (port) {
+case0x04: {
+qemu_irqirq;
+CPUState   *cpu = CPU(avr_env_get_cpu(env));
+irq = qdev_get_gpio_in(DEVICE(cpu), 3);
+qemu_set_irq(irq, 1);
+break;
+}
+case0x3b: {
+env->rampZ = data & 0x01;  /*  RAMPZ */
+break;
+}
+case0x3d: { /*  SPL */
+if (avr_feature(env, AVR_FEATURE_2_BYTE_SP)) {
+env->sp = (env->sp & 0xff00) | (data);
+}
+break;
+}
+case0x3e: {  /*  SPH */
+env->sp = (env->sp & 0x00ff) | (data << 8);
+break;
+}
+case0x3f: { /*  SREG */
+env->sregC = (data >> 0) & 0x01;
+env->sregZ = (data >> 1) & 0x01;
+  

[Qemu-devel] [PATCH 2/9] target-avr: adding AVR CPU features/flavors

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/cpu.c | 311 ++-
 target-avr/cpu.h |  59 +++
 2 files changed, 368 insertions(+), 2 deletions(-)

diff --git a/target-avr/cpu.c b/target-avr/cpu.c
index cfc1aee..97653c5 100644
--- a/target-avr/cpu.c
+++ b/target-avr/cpu.c
@@ -29,7 +29,7 @@ static void avr_cpu_set_pc(CPUState *cs, vaddr value)
 {
 AVRCPU   *cpu = AVR_CPU(cs);
 
-cpu->env.pc = value / 2;/*  internaly PC points to words, not bytes */
+cpu->env.pc = value / 2;/*  internally PC points to words   */
 }
 
 static bool avr_cpu_has_work(CPUState *cs)
@@ -47,7 +47,7 @@ static void avr_cpu_synchronize_from_tb(CPUState *cs, 
TranslationBlock *tb)
 AVRCPU  *cpu = AVR_CPU(cs);
 CPUAVRState *env = >env;
 
-env->pc = tb->pc / 2;
+env->pc = tb->pc / 2;   /*  internally PC points to words   */
 }
 
 static void avr_cpu_reset(CPUState *s)
@@ -55,12 +55,14 @@ static void avr_cpu_reset(CPUState *s)
 AVRCPU *cpu = AVR_CPU(s);
 AVRCPUClass *mcc = AVR_CPU_GET_CLASS(cpu);
 CPUAVRState *env = >env;
+uint32_t features = env->features;
 
 mcc->parent_reset(s);
 
 memset(env, 0, sizeof(CPUAVRState));
 env->pc = 0;
 env->sregI = 1;
+env->features = features;
 
 tlb_flush(s, 1);
 }
@@ -187,6 +189,296 @@ static void avr_cpu_class_init(ObjectClass *oc, void 
*data)
 dc->cannot_destroy_with_object_finalize_yet = true;
 }
 
+static void avr_avr1_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+}
+static void avr_avr2_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env,AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env,AVR_FEATURE_SRAM);
+avr_set_feature(env,AVR_FEATURE_BREAK);
+
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+}
+
+static void avr_avr25_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env,AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env,AVR_FEATURE_SRAM);
+avr_set_feature(env,AVR_FEATURE_BREAK);
+
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env,AVR_FEATURE_LPMX);
+avr_set_feature(env,AVR_FEATURE_MOVW);
+}
+
+static void avr_avr3_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env,AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env,AVR_FEATURE_SRAM);
+avr_set_feature(env,AVR_FEATURE_BREAK);
+
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env,AVR_FEATURE_JMP_CALL);
+}
+
+static void avr_avr31_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env,AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env,AVR_FEATURE_SRAM);
+avr_set_feature(env,AVR_FEATURE_BREAK);
+
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env,AVR_FEATURE_RAMPZ);
+avr_set_feature(env,AVR_FEATURE_ELPM);
+avr_set_feature(env,AVR_FEATURE_JMP_CALL);
+}
+
+static void avr_avr35_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env,AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env,AVR_FEATURE_SRAM);
+avr_set_feature(env,AVR_FEATURE_BREAK);
+
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env,AVR_FEATURE_JMP_CALL);
+avr_set_feature(env,AVR_FEATURE_LPMX);
+avr_set_feature(env,AVR_FEATURE_MOVW);
+}
+
+static void avr_avr4_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env,AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env,AVR_FEATURE_SRAM);
+avr_set_feature(env,AVR_FEATURE_BREAK);
+
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+

[Qemu-devel] AVR cores

2016-06-02 Thread Michael Rolnik
This series of patches adds 8bit AVR cores to QEMU.
All instruction, except BREAK/DES/SPM/SPMX, are implemented. Not fully tested 
yet.
However I was able to execute simple code with functions. e.g fibonacci 
calculation.
This series of patches include a non real, sample board.
No fuses support yet. PC is set to 0 at reset.

the patches include the following
1. just a basic 8bit AVR CPU, without instruction decoding or translation
2. CPU features which allow define the following 8bit AVR cores
 avr1
 avr2 avr25
 avr3 avr31 avr35
 avr4
 avr5 avr51
 avr6
 xmega2 xmega4 xmega5 xmega6 xmega7
3. a difinition of sample machine with SRAM, FLASH and CPU which allows to 
execute simple code
4. encoding for all AVR instructions
5. interrupt handling
6. helpers for IN, OUT, SLEEP, WBR & unsupported instructions
7. a decoder which given an opcode decides what istruction it is
8. translation of AVR instruction into TCG
9. all features together





Re: [Qemu-devel] [PULL V4 00/31] Net patches

2016-06-02 Thread Fam Zheng
On Thu, 06/02 13:05, Eric Blake wrote:
> On 06/02/2016 12:09 PM, Dmitry Fleytman wrote:
> 
> > 
> > The build did not pass because of tracepoint e1000e_rx_rss_ip6 which failed 
> > to compile.
> > 
> > This tracepoint has 11 parameters, when 1 parameter is removed build 
> > succeeds.
> > Could it be that ust backend has a limitation of 10 parameters per event?
> > Should I split this trace into 2 events?
> > 
> > In general, I would like to check compilability of my patches better next 
> > time,
> > is there a way to figure out a full list of configurations to be tested? Is 
> > there a tool for that maybe?
> 
> The brand new docker tests (see commit cbd614870 and above) should make
> it easier to test multiple setups, although I'm not sure if ust is one
> of the docker tests yet.

Yes, thanks for mentioning! And there is a "travis" script that can mimic
travis-ci.org testing (it's a PoC far from perfect for now):

make docker-travis@ubuntu

Next step, I'll take a look at our .travis.yml matrix and make a selection out
of that (maybe by flattening all dimensions onto one base configuration, so it
can become a first class test that completes in a resonable time on a single
average machine that a developer owns).

Fam



Re: [Qemu-devel] [QEMU RFC PATCH v3 1/6] Migration: Defined VMStateDescription struct for spapr_drc

2016-06-02 Thread Jianjun Duan


On 06/01/2016 09:07 PM, David Gibson wrote:
> On Tue, May 31, 2016 at 11:02:39AM -0700, Jianjun Duan wrote:
>> To manage hotplug/unplug of dynamic resources such as PCI cards,
>> memory, and CPU on sPAPR guests, a firmware abstraction known as
>> a Dynamic Resource Connector (DRC) is used to assign a particular
>> dynamic resource to the guest, and provide an interface for the
>> guest to manage configuration/removal of the resource associated
>> with it.
>>
>> To migrate the hotplugged resources in migration, the
>> associated DRC state need be migrated. To migrate the DRC state,
>> we defined the VMStateDescription struct for spapr_drc to enable
>> the transmission of spapr_drc state in migration.
>>
>> Not all the elements in the DRC state are migrated. Only those
>> ones modifiable or needed by guest actions or device add/remove
>> operation are migrated. From the perspective of device
>> hotplugging, if we hotplug a device on the source, we need to
>> "coldplug" it on the target. The states across two hosts for the
>> same device are not the same. Ideally we want the states be same
>> after migration so that the device would function as hotplugged
>> on the target. For example we can unplug it. The minimum DRC
>> state we need to transfer should cover all the pieces changed by
>> hotplugging. Out of the elements of the DRC state, isolation_state,
>> allocation_sate, and configured are involved in the DR state
>> transition diagram from PAPR+ 2.7, 13.4. configured and signalled
>> are needed in attaching and detaching devices. indicator_state
>> provides users with hardware state information. These 6 elements
>> are migrated.
>>
>> detach_cb in the DRC state is a function pointer that cannot be
>> migrated. We set it right after DRC state is migrated so that
>> a migrated hot-unplug event could finish its work.
>>
>> Signed-off-by: Jianjun Duan 
> 
> So, the thing which concerns me about this patch is that it exposes
> the DRCs as real objects in the migration stream, which will make it
> difficult to ever remove them in the future.
> 
> Particularly for LMBs having full QOM objects for every individual DRC
> is kind of clunky, and I'd already considered replacing them instead
> with a QOM interface implementing a whole array of DRCs as part of the
> "owning" object (machine or PHB).
> 
> The internal structure of the VMSD looks ok to me, but the
> complication is the automatic "addressing" of it as a separate
> object.  If we could manually take that over, allowing us to direct
> the same VMSD data at elements in a simpler DRC array later, that
> would be preferable.

We can address this concern by setting the unique instance_id for each
drc. The instance_id can be used to match the drcs from source and target.
> 
> 
>> ---
>>  hw/ppc/spapr_drc.c | 61 
>> ++
>>  hw/ppc/spapr_pci.c | 22 +
>>  include/hw/ppc/spapr_drc.h |  9 +++
>>  3 files changed, 92 insertions(+)
>>
>> diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
>> index 94c875d..1fb5e23 100644
>> --- a/hw/ppc/spapr_drc.c
>> +++ b/hw/ppc/spapr_drc.c
>> @@ -617,6 +617,65 @@ static void spapr_dr_connector_instance_init(Object 
>> *obj)
>>  NULL, NULL, NULL, NULL);
>>  }
>>  
>> +static bool spapr_drc_needed(void *opaque)
>> +{
>> +sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque;
>> +sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
>> +bool rc = false;
>> +sPAPRDREntitySense value;
>> +
>> +drck->entity_sense(drc, );
>> +/* If no dev is plugged in there is no need to migrate the DRC state */
>> +if (value != SPAPR_DR_ENTITY_SENSE_PRESENT) {
>> +return false;
>> +}
>> +/*
>> + * If there is dev plugged in, we need to migrate the DRC state when
>> + * it is different from cold-plugged state
>> + */
>> +switch(drc->type) {
>> +/* for PCI type */
>> +case SPAPR_DR_CONNECTOR_TYPE_PCI:
>> +rc = !((drc->isolation_state == 
>> SPAPR_DR_ISOLATION_STATE_UNISOLATED) &&
>> +   (drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_USABLE) 
>> &&
>> +   drc->configured && drc->signalled && !drc->awaiting_release);
>> +break;
>> +/* for LMB type */
>> +case SPAPR_DR_CONNECTOR_TYPE_LMB:
>> +rc = !((drc->isolation_state == SPAPR_DR_ISOLATION_STATE_ISOLATED) 
>> &&
>> +   (drc->allocation_state == 
>> SPAPR_DR_ALLOCATION_STATE_UNUSABLE) &&
>> +   drc->configured && drc->signalled && !drc->awaiting_release);
>> +break;
>> +default:
>> +;
>> +}
>> +
>> +return rc;
>> +}
>> +
>> +/* detach_cb needs be set since it is not migrated */
>> +static void postmigrate_set_detach_cb(sPAPRDRConnector *drc,
>> +  spapr_drc_detach_cb *detach_cb)
>> +{
>> +drc->detach_cb = detach_cb;
>> +}
>> +
>> +static const 

Re: [Qemu-devel] [PATCH v2 0/8] virtio-blk: multiqueue support

2016-06-02 Thread Stefan Hajnoczi
On Mon, May 30, 2016 at 06:25:58PM -0700, Stefan Hajnoczi wrote:
> v2:
>  * Simplify s->rq live migration [Paolo]
>  * Use more efficient bitmap ops for batch notification [Paolo]
>  * Fix perf regression due to batch notify BH in wrong AioContext [Christian]
> 
> The virtio_blk guest driver has supported multiple virtqueues since Linux 
> 3.17.
> This patch series adds multiple virtqueues to QEMU's virtio-blk emulated
> device.
> 
> Ming Lei sent patches previously but these were not merged.  This series
> implements virtio-blk multiqueue for QEMU from scratch since the codebase has
> changed.  Live migration support for s->rq was also missing from the previous
> series and has been added.
> 
> It's important to note that QEMU's block layer does not support multiqueue 
> yet.
> Therefore virtio-blk device processes all virtqueues in the same AioContext
> (IOThread).  Further work is necessary to take advantage of multiqueue support
> in QEMU's block layer once it becomes available.
> 
> I will post performance results once they are ready.
> 
> Stefan Hajnoczi (8):
>   virtio-blk: use batch notify in non-dataplane case
>   virtio-blk: tell dataplane which vq to notify
>   virtio-blk: associate request with a virtqueue
>   virtio-blk: add VirtIOBlockConf->num_queues
>   virtio-blk: multiqueue batch notify
>   virtio-blk: live migrateion s->rq with multiqueue
>   virtio-blk: dataplane multiqueue support
>   virtio-blk: add num-queues device property
> 
>  hw/block/dataplane/virtio-blk.c |  68 +++--
>  hw/block/dataplane/virtio-blk.h |   2 +-
>  hw/block/virtio-blk.c   | 129 
> +++-
>  include/hw/virtio/virtio-blk.h  |   8 ++-
>  4 files changed, 159 insertions(+), 48 deletions(-)

There is a significant performance regression due to batch notify:

$ ./analyze.py runs/
Name   IOPS   Error
unpatched-d6550e9ed2 19269820.2 ± 1.36%
unpatched-d6550e9ed2-2   19567358.4 ± 2.42%
v2-batch-only-f27ed9a4d9 16252227.2 ± 6.09%
v2-no-dataplane  14560225.4 ± 5.16%
v2-no-dataplane-214622535.6 ± 10.08%
v2-no-dataplane-313960670.8 ± 7.11%

unpatched-d6550e9ed2 is without this patch series.
v2-batch-only-f27ed9a4d9 is with Patch 1 only.  v2-no-dataplane is with
the patch series (dataplane is not enabled in any of these tests).

Next I will compare unpatched dataplane against patched dataplane.  I
want to make sure Patch 1 faithfully moved batch notify from dataplane
code to generic virtio-blk code without affecting performance.

If there is no difference then it means batch notify decreases
performance for some workloads (obviously not the same workload that
Ming Lei was running).

Stefan


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH RFC 0/8] cpus: make "-cpu cpux, features" global properties

2016-06-02 Thread Eduardo Habkost
On Thu, Jun 02, 2016 at 10:44:49PM +0200, David Hildenbrand wrote:
> > Current CLI option -cpu cpux,features serves as template
> > for all created cpus of type: cpux. However QEMU parses
> > "features" every time it creates a cpu instance and applies
> > them to it while doing parsing.
> > 
> > That doesn't work well with -device/device_add infrastructure
> > as it has no idea about cpu specific hooks that's used for
> > parsing "features".
> > In order to make -device/device_add utilize "-cpu features"
> > template convert it into a set of global properties, so that
> > every new CPU created will have them applied automatically.
> > 
> > That also allows to parse features only once, instread of
> > doing it for every CPU instance created.
> 
> While I think this makes sense for most cases, we (s390x) are
> currently working on a mechanism to compare and baseline cpu models via
> a qmp interface, to not have to replicate CPU models in libvirt
> every time we do some changes.
> 
> To do that, we are creating temporary CPUs to handle the model
> parsing. So, with our current prototype, we rely on the mechanism
> to parse properties multiple time, as we are really creating
> different CPUs.

This series only changes the code that exists for parsing the
-cpu option, and nothing else. Is this (the code that parses
-cpu) really what you need to reuse?

If all you need is to parse properties, why can't you reuse the
existing QOM/Device mechanisms to handle properties (the one used
by -device and device_add), instead of the -cpu code?

We need to use less of the infrastructure that exists for the
legacy -cpu option (and use more of the generic QOM/Device
mechanisms), not more of it.


> 
> While we could somehow change our mechanism I don't think this is
> the right thing to do.
> 

If reusing the existing parsing code is something you absolutely
need, we could split the process in two parts: 1) converting the
feature string to a list of property=value pairs; 2) registering
the property=value pairs as global properties. Then you coulde
reuse (1) only. But do you really need to reuse the parser for
the legacy -cpu option in your mechanism?

> We will have to support heterogeneous cpu models (I think arm was one of
> the guys requesting this if I'm not mistaking) and it somehow
> contradicts to the general mechanism of device_add fully specifying
> parameters. These would now be implicit parameters.

The -cpu interface really does contradict the general mechanism
of device_add. This whole series is about translating the
handling of -cpu to a more generic mechanism (-global), to allow
us to deprecate -cpu in the future. Why is that a bad thing?

> 
> Would it be possible to do this for x86 only? Or find another way
> to handle the "create just another ordinary CPU we already have"?

Can you clarify what "create just another ordinary CPU we already
have" mean? If you are talking about creating another CPU using
what's on -cpu, nothing changes. If you are talking about
creating another CPU with different options, I suggest not
reusing the code that was written for -cpu.

-- 
Eduardo



Re: [Qemu-devel] [PATCH 10/10] target-avr: fixing code style

2016-06-02 Thread Peter Maydell
On 2 June 2016 at 21:07, Michael Rolnik  wrote:
> Signed-off-by: Michael Rolnik 
> ---
>  target-avr/cpu-qom.h|  38 +
>  target-avr/cpu.c| 100 
> +---
>  target-avr/cpu.h|  74 
>  target-avr/gdbstub.c|  10 +
>  target-avr/helper.c |  52 ++-
>  target-avr/translate-inst.c |  54 +++-
>  target-avr/translate-inst.h |  20 +
>  target-avr/translate.c  |  27 +++-
>  target-avr/translate.h  |   5 +--
>  9 files changed, 134 insertions(+), 246 deletions(-)

Rather than fixing up code style issues in the preceding
patches, I think you would be better to just fold these changes
into those patches so that the code is right the first time.

PS: it would be good if you could provide a cover letter when
you send out the next round of these patches; that provides
a handy way to deal with the series as a whole (for both
automated tools and people), so we tend to prefer multi-patch
sets to have one.

thanks
-- PMM



Re: [Qemu-devel] [PATCH v4 00/15] Dirty bitmap changes for migration/persistence work

2016-06-02 Thread John Snow


On 06/02/2016 07:43 AM, Vladimir Sementsov-Ogievskiy wrote:
> Hi, what are the plans?
> 

I'm not sure. Fam, part of this series was merged, wasn't it?

Do you have outstanding work that you'd like me to take over and push
through for you?

--js

> On 26.05.2016 03:47, Fam Zheng wrote:
>> On Wed, 05/25 17:45, Vladimir Sementsov-Ogievskiy wrote:
>>> Hi!
>>>
>>> Are you going to update the series in the near future?
>> Yes, probably in a couple days.
>>
>> Fam
>>
>>> On 08.03.2016 07:44, Fam Zheng wrote:
 v4: Rebase.
   Add rev-by from John in patches 1-5, 7, 8.
   Remove BdrvDirtyBitmap typedef from dirty-bitmap.h in patch 4.
 [Max]
   Add assertion on bm->meta in patch 9. [John]

 Two major features are added to block dirty bitmap (and underlying
 HBitmap) in
 this series: meta bitmap and serialization, together with all other
 supportive
 patches.

 Both operations are common in dirty bitmap migration and
 persistence: they need
 to find whether and which part of the dirty bitmap in question has
 changed with
 meta dirty bitmap, and they need to write it to the target with
 serialization.


 Fam Zheng (13):
 backup: Use Bitmap to replace "s->bitmap"
 block: Include hbitmap.h in block.h
 typedefs: Add BdrvDirtyBitmap
 block: Move block dirty bitmap code to separate files
 block: Remove unused typedef of BlockDriverDirtyHandler
 block: Hide HBitmap in block dirty bitmap interface
 HBitmap: Introduce "meta" bitmap to track bit changes
 tests: Add test code for meta bitmap
 block: Support meta dirty bitmap
 block: Add two dirty bitmap getters
 block: Assert that bdrv_release_dirty_bitmap succeeded
 tests: Add test code for hbitmap serialization
 block: More operations for meta dirty bitmap

 Vladimir Sementsov-Ogievskiy (2):
 hbitmap: serialization
 block: BdrvDirtyBitmap serialization interface

block.c  | 360 -
block/Makefile.objs  |   2 +-
block/backup.c   |  25 +-
block/dirty-bitmap.c | 535
 +++
block/mirror.c   |  15 +-
include/block/block.h|  40 +---
include/block/dirty-bitmap.h |  75 ++
include/qemu/hbitmap.h   |  96 
include/qemu/typedefs.h  |   2 +
tests/test-hbitmap.c | 255 +
util/hbitmap.c   | 203 ++--
11 files changed, 1177 insertions(+), 431 deletions(-)
create mode 100644 block/dirty-bitmap.c
create mode 100644 include/block/dirty-bitmap.h

>>>
>>> -- 
>>> Best regards,
>>> Vladimir
>>>
>>>
> 
> 

-- 
—js



Re: [Qemu-devel] [PULL V4 00/31] Net patches

2016-06-02 Thread Peter Maydell
On 2 June 2016 at 19:38, Dmitry Fleytman  wrote:
> From lttng/tracepoint.h:
>
> …
>
> /*
>  * TP_ARGS takes tuples of type, argument separated by a comma.
>  * It can take up to 10 tuples (which means that less than 10 tuples is
>  * fine too).
>  * Each tuple is also separated by a comma.
>  */
>
> …
>
> So this is a ust backend limitation.
>
> Since build is failing, I’m sending a patch that splits this
> tracepoint into 2 events.

I see; thanks for the patch.

(A possible enhancement for the trace code would be to make
going over 10 arguments to a tracepoint be a compile
failure whichever backend was in use, so they're less
likely to slip through.)

thanks
-- PMM



Re: [Qemu-devel] [RFC v2 PATCH 01/13] Introduce TCGOpcode for memory barrier

2016-06-02 Thread Sergey Fedorov
On 03/06/16 00:18, Richard Henderson wrote:
> On 06/02/2016 01:38 PM, Sergey Fedorov wrote:
>> On 02/06/16 23:36, Richard Henderson wrote:
>>> On 06/02/2016 09:30 AM, Sergey Fedorov wrote:
 I think we need to extend TCG load/store instruction attributes to
 provide information about guest ordering requirements and leave
 this TCG
 operation only for explicit barrier instruction translation.
>>>
>>> I do not agree.  I think separate barriers are much cleaner and easier
>>> to manage and reason with.
>>>
>>
>> How are we going to emulate strongly-ordered guests on weakly-ordered
>> hosts then? I think if every load/store operation must specify which
>> ordering it implies then this task would be quite simple.
>
> Hum.  That does seem helpful-ish.  But I'm not certain how helpful it
> is to complicate the helper functions even further.
>
> What if we have tcg_canonicalize_memop (or some such) split off the
> barriers into separate opcodes.  E.g.
>
> MO_BAR_LD_B = 32// prevent earlier loads from crossing current op
> MO_BAR_ST_B = 64// prevent earlier stores from crossing current op
> MO_BAR_LD_A = 128// prevent later loads from crossing current op
> MO_BAR_ST_A = 256// prevent later stores from crossing current op
> MO_BAR_LDST_B = MO_BAR_LD_B | MO_BAR_ST_B
> MO_BAR_LDST_A = MO_BAR_LD_A | MO_BAR_ST_A
> MO_BAR_MASK = MO_BAR_LDST_B | MO_BAR_LDST_A
>
> // Match Sparc MEMBAR as the most flexible host.
> TCG_BAR_LD_LD = 1// #LoadLoad barrier
> TCG_BAR_ST_LD = 2// #StoreLoad barrier
> TCG_BAR_LD_ST = 4// #LoadStore barrier
> TCG_BAR_ST_ST = 8// #StoreStore barrier
> TCG_BAR_SYNC  = 64// SEQ_CST barrier
>
> where
>
>   tcg_gen_qemu_ld_i32(x, y, i, m | MO_BAR_LD_BEFORE | MO_BAR_ST_AFTER)
>
> emits
>
>   mbTCG_BAR_LD_LD
>   qemu_ld_i32x, y, i, m
>   mbTCG_BAR_LD_ST
>
> We can then add an optimization pass which folds barriers with no
> memory operations in between, so that duplicates are eliminated.

It would give us three TCG operations for each memory operation instead
of one. But then we might like to combine these barrier operations back
with memory operations in each backend. If we propagate memory ordering
semantics up to the backend, it can decide itself what instructions are
best to generate.

So I would just focus on translating only explicit memory barrier
operations for now.

Kind regards,
Sergey



Re: [Qemu-devel] [RFC v2 PATCH 01/13] Introduce TCGOpcode for memory barrier

2016-06-02 Thread Richard Henderson

On 06/02/2016 01:38 PM, Sergey Fedorov wrote:

On 02/06/16 23:36, Richard Henderson wrote:

On 06/02/2016 09:30 AM, Sergey Fedorov wrote:

I think we need to extend TCG load/store instruction attributes to
provide information about guest ordering requirements and leave this TCG
operation only for explicit barrier instruction translation.


I do not agree.  I think separate barriers are much cleaner and easier
to manage and reason with.



How are we going to emulate strongly-ordered guests on weakly-ordered
hosts then? I think if every load/store operation must specify which
ordering it implies then this task would be quite simple.


Hum.  That does seem helpful-ish.  But I'm not certain how helpful it is to 
complicate the helper functions even further.


What if we have tcg_canonicalize_memop (or some such) split off the barriers 
into separate opcodes.  E.g.


MO_BAR_LD_B = 32// prevent earlier loads from crossing current op
MO_BAR_ST_B = 64// prevent earlier stores from crossing current op
MO_BAR_LD_A = 128   // prevent later loads from crossing current op
MO_BAR_ST_A = 256   // prevent later stores from crossing current op
MO_BAR_LDST_B = MO_BAR_LD_B | MO_BAR_ST_B
MO_BAR_LDST_A = MO_BAR_LD_A | MO_BAR_ST_A
MO_BAR_MASK = MO_BAR_LDST_B | MO_BAR_LDST_A

// Match Sparc MEMBAR as the most flexible host.
TCG_BAR_LD_LD = 1   // #LoadLoad barrier
TCG_BAR_ST_LD = 2   // #StoreLoad barrier
TCG_BAR_LD_ST = 4   // #LoadStore barrier
TCG_BAR_ST_ST = 8   // #StoreStore barrier
TCG_BAR_SYNC  = 64  // SEQ_CST barrier

where

  tcg_gen_qemu_ld_i32(x, y, i, m | MO_BAR_LD_BEFORE | MO_BAR_ST_AFTER)

emits

  mbTCG_BAR_LD_LD
  qemu_ld_i32   x, y, i, m
  mbTCG_BAR_LD_ST

We can then add an optimization pass which folds barriers with no memory 
operations in between, so that duplicates are eliminated.



r~



Re: [Qemu-devel] [libvirt] [PATCH] target-i386: Remove xlevel & hv-spinlocks option fixups

2016-06-02 Thread Eric Blake
On 06/02/2016 10:55 AM, Eduardo Habkost wrote:
> The "fixup will be removed in future versions" warnings are
> present since QEMU 1.7.0, at least, so users should have fixed
> their scripts and configurations, already.
> 
> In the case of libvirt users, libvirt doesn't use the "xlevel"
> option, and already rejects HyperV spinlock retry count < 0xFFF.
> 
> Signed-off-by: Eduardo Habkost 
> ---
> Igor, feel free to include this in the beginning of your series.
> I believe it will help making the patches simpler.
> ---
>  target-i386/cpu.c | 35 +--
>  1 file changed, 1 insertion(+), 34 deletions(-)
> 

Reviewed-by: Eric Blake 

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH 4/4] 9p: switch back to readdir()

2016-06-02 Thread Eric Blake
On 06/02/2016 02:52 AM, Greg Kurz wrote:
> This patch changes the 9p code to use readdir() again instead of
> readdir_r(), which is deprecated in glibc 2.24.
> 
> All the locking was put in place by a previous patch.
> 
> Signed-off-by: Greg Kurz 
> ---


> +++ b/hw/9pfs/codir.c
> @@ -17,8 +17,7 @@
>  #include "qemu/coroutine.h"
>  #include "coth.h"
>  
> -int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent,
> -  struct dirent **result)
> +int v9fs_co_readdir(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent **dent)
>  {
>  int err;
>  V9fsState *s = pdu->s;
> @@ -28,11 +27,14 @@ int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, 
> struct dirent *dent,
>  }
>  v9fs_co_run_in_worker(
>  {
> -errno = 0;
> -err = s->ops->readdir_r(>ctx, >fs, dent, result);
> -if (!*result && errno) {
> +struct dirent *entry;
> +int old_errno = errno;
> +
> +entry = s->ops->readdir(>ctx, >fs);
> +if (!entry && errno != old_errno) {
>  err = -errno;

Not safe. The only safe way to check errno after readdir() is to assign
it to 0 before readdir().

>  } else {
> +*dent = entry;
>  err = 0;
>  }
>  });


-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [Bug 1588328] Re: Qemu 2.6 Solaris 9 Sparc Segmentation Fault

2016-06-02 Thread Mark Cave-Ayland
That basically looks like it should work. The only time I've seen random
segfaults similar to this is with a corrupted disk, so the first
question to ask is whether you've verified the ISO image you are using?
Unfortunately this isn't an image I currently have access to, but I can
report my Solaris 8 32-bit ISO boots and installs fine with no issues
here. Does it make any difference if you remove the -hda part of the
command line?

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

Title:
  Qemu 2.6 Solaris 9 Sparc Segmentation Fault

Status in QEMU:
  New

Bug description:
  Hi,
  I tried the following command to boot Solaris 9 sparc:
  qemu-system-sparc -nographic -boot d -hda ./Spark9.disk -m 256 -cdrom 
sol-9-905hw-ga-sparc-dvd.iso -serial telnet:0.0.0.0:3000,server 

  It seems there are a few Segmentation Faults, one from the starting of
  the boot. Another at the beginning of the commandline installation.

  Trying 127.0.0.1...
  Connected to localhost.
  Escape character is '^]'.
  Configuration device id QEMU version 1 machine id 32
  Probing SBus slot 0 offset 0
  Probing SBus slot 1 offset 0
  Probing SBus slot 2 offset 0
  Probing SBus slot 3 offset 0
  Probing SBus slot 4 offset 0
  Probing SBus slot 5 offset 0
  Invalid FCode start byte
  CPUs: 1 x FMI,MB86904
  UUID: ----
  Welcome to OpenBIOS v1.1 built on Apr 18 2016 08:19
Type 'help' for detailed information
  Trying cdrom:d...
  Not a bootable ELF image
  Loading a.out image...
  Loaded 7680 bytes
  entry point is 0x4000
  bootpath: 
/iommu@0,1000/sbus@0,10001000/espdma@5,840/esp@5,880/sd@2,0:d

  Jumping to entry point 4000 for type 0005...
  switching to new context:
  SunOS Release 5.9 Version Generic_118558-34 32-bit
  Copyright 1983-2003 Sun Microsystems, Inc.  All rights reserved.
  Use is subject to license terms.
  WARNING: 
/iommu@0,1000/sbus@0,10001000/espdma@5,840/esp@5,880/sd@0,0 (sd0):
Corrupt label; wrong magic number

  Segmentation Fault
  Configuring /dev and /devices
  NOTICE: Couldn't set value (../../sun/io/audio/sada/drv/audiocs/audio_4231.c, 
Line #1759 0x00 0x88)
  audio may not work correctly until it is stopped and restarted
  Segmentation Fault
  Using RPC Bootparams for network configuration information.
  Skipping interface le0
  Searching for configuration file(s)...
  Search complete.

  

  What type of terminal are you using?
   1) ANSI Standard CRT
   2) DEC VT52
   3) DEC VT100
   4) Heathkit 19
   5) Lear Siegler ADM31
   6) PC Console
   7) Sun Command Tool
   8) Sun Workstation
   9) Televideo 910
   10) Televideo 925
   11) Wyse Model 50
   12) X Terminal Emulator (xterms)
   13) CDE Terminal Emulator (dtterm)
   14) Other
  Type the number of your choice and press Return: 3
  syslog service starting.
  savecore: no dump device configured
  Running in command line mode
  /sbin/disk0_install[109]: 143 Segmentation Fault
  /sbin/run_install[130]: 155 Segmentation Fault

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



Re: [Qemu-devel] [PATCH 3/4] 9p: add locking to V9fsDir

2016-06-02 Thread Eric Blake
On 06/02/2016 02:52 AM, Greg Kurz wrote:
> If several threads call concurrently readdir() with the same directory

s/call concurrently/concurrently call/

> stream pointer, it is possible that they all get a pointer to the same
> dirent structure, whose content is overwritten each time readdir() is
> called.
> 
> We must thus serialize accesses to the dirent structure.
> 
> This may be achieved with a mutex like below:
> 
> lock_mutex();
> 
> readdir();
> 
> // work with the dirent
> 
> unlock_mutex();
> 
> This patch adds all the locking, to prepare the switch to readdir().
> 
> Signed-off-by: Greg Kurz 
> ---
>  hw/9pfs/9p.c |   21 +
>  hw/9pfs/9p.h |   16 
>  2 files changed, 37 insertions(+)
> 

Reviewed-by: Eric Blake 

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH] sdl2: skip init without outputs

2016-06-02 Thread Cole Robinson
On 06/01/2016 10:08 AM, Gerd Hoffmann wrote:
> Signed-off-by: Gerd Hoffmann 
> ---
>  ui/sdl2.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/ui/sdl2.c b/ui/sdl2.c
> index 909038f..30d2a3c 100644
> --- a/ui/sdl2.c
> +++ b/ui/sdl2.c
> @@ -794,6 +794,9 @@ void sdl_display_init(DisplayState *ds, int full_screen, 
> int no_frame)
>  }
>  }
>  sdl2_num_outputs = i;
> +if (sdl2_num_outputs == 0) {
> +return;
> +}
>  sdl2_console = g_new0(struct sdl2_console, sdl2_num_outputs);
>  for (i = 0; i < sdl2_num_outputs; i++) {
>  QemuConsole *con = qemu_console_lookup_by_index(i);
> 

Tested-by: Cole Robinson 

Thanks,
Cole



Re: [Qemu-devel] [PATCH RFC 0/8] cpus: make "-cpu cpux, features" global properties

2016-06-02 Thread David Hildenbrand
> Current CLI option -cpu cpux,features serves as template
> for all created cpus of type: cpux. However QEMU parses
> "features" every time it creates a cpu instance and applies
> them to it while doing parsing.
> 
> That doesn't work well with -device/device_add infrastructure
> as it has no idea about cpu specific hooks that's used for
> parsing "features".
> In order to make -device/device_add utilize "-cpu features"
> template convert it into a set of global properties, so that
> every new CPU created will have them applied automatically.
> 
> That also allows to parse features only once, instread of
> doing it for every CPU instance created.

While I think this makes sense for most cases, we (s390x) are
currently working on a mechanism to compare and baseline cpu models via
a qmp interface, to not have to replicate CPU models in libvirt
every time we do some changes.

To do that, we are creating temporary CPUs to handle the model
parsing. So, with our current prototype, we rely on the mechanism
to parse properties multiple time, as we are really creating
different CPUs.

While we could somehow change our mechanism I don't think this is
the right thing to do.

We will have to support heterogeneous cpu models (I think arm was one of
the guys requesting this if I'm not mistaking) and it somehow
contradicts to the general mechanism of device_add fully specifying
parameters. These would now be implicit parameters.

Would it be possible to do this for x86 only? Or find another way
to handle the "create just another ordinary CPU we already have"?

David




Re: [Qemu-devel] [RFC v2 PATCH 01/13] Introduce TCGOpcode for memory barrier

2016-06-02 Thread Sergey Fedorov
On 02/06/16 23:36, Richard Henderson wrote:
> On 06/02/2016 09:30 AM, Sergey Fedorov wrote:
>> I think we need to extend TCG load/store instruction attributes to
>> provide information about guest ordering requirements and leave this TCG
>> operation only for explicit barrier instruction translation.
>
> I do not agree.  I think separate barriers are much cleaner and easier
> to manage and reason with.
>

How are we going to emulate strongly-ordered guests on weakly-ordered
hosts then? I think if every load/store operation must specify which
ordering it implies then this task would be quite simple.

Kind regards,
Sergey



Re: [Qemu-devel] [RFC v2 PATCH 08/13] tcg/s390: Add support for fence

2016-06-02 Thread Richard Henderson

On 06/02/2016 12:31 PM, Sergey Fedorov wrote:

On 31/05/16 21:39, Pranith Kumar wrote:

Cc: Alexander Graf 
Signed-off-by: Richard Henderson 
Signed-off-by: Pranith Kumar 
---
 tcg/s390/tcg-target.inc.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/tcg/s390/tcg-target.inc.c b/tcg/s390/tcg-target.inc.c
index e95b04b..b4f14bc 100644
--- a/tcg/s390/tcg-target.inc.c
+++ b/tcg/s390/tcg-target.inc.c
@@ -341,6 +341,7 @@ static tcg_insn_unit *tb_ret_addr;
 #define FACILITY_EXT_IMM   (1ULL << (63 - 21))
 #define FACILITY_GEN_INST_EXT  (1ULL << (63 - 34))
 #define FACILITY_LOAD_ON_COND   (1ULL << (63 - 45))
+#define FACILITY_FAST_BCR_SER   FACILITY_LOAD_ON_COND

 static uint64_t facilities;

@@ -2157,6 +2158,13 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode 
opc,
 tgen_deposit(s, args[0], args[2], args[3], args[4]);
 break;

+case INDEX_op_mb:
+/* The host memory model is quite strong, we simply need to
+   serialize the instruction stream.  */
+tcg_out_insn(s, RR, BCR,
+facilities & FACILITY_FAST_BCR_SER ? 14 : 15, 0);
+break;
+


Do we? What does that mean?


It's the difference between ACQ_REL and SEQ_CST for s390x.  FWIW.


r~



Re: [Qemu-devel] [RFC v2 PATCH 01/13] Introduce TCGOpcode for memory barrier

2016-06-02 Thread Richard Henderson

On 06/02/2016 09:30 AM, Sergey Fedorov wrote:

I think we need to extend TCG load/store instruction attributes to
provide information about guest ordering requirements and leave this TCG
operation only for explicit barrier instruction translation.


I do not agree.  I think separate barriers are much cleaner and easier to 
manage and reason with.



r~



Re: [Qemu-devel] [RFC v2 PATCH 01/13] Introduce TCGOpcode for memory barrier

2016-06-02 Thread Richard Henderson

On 06/02/2016 11:42 AM, Pranith Kumar wrote:

Yes, I am working on adding flag argument to the TCG MemOp which indicates
this.


Please don't.  I don't think this is the right way to go.


r~



Re: [Qemu-devel] [PATCH RFC 0/2] enable iommu with -device

2016-06-02 Thread Marcel Apfelbaum

On 05/31/2016 04:44 AM, Peter Xu wrote:

On Mon, May 30, 2016 at 05:14:15PM +0300, Marcel Apfelbaum wrote:

On 05/30/2016 04:43 PM, Peter Xu wrote:

On Mon, May 23, 2016 at 05:01:28PM +0300, Marcel Apfelbaum wrote:

This is a proposal on how to create the iommu with
'-device intel-iommu' instead of '-machine,iommu=on'.

The device is part of the machine properties because we wanted
to ensure it is created before any other PCI device.

The alternative is to skip the bus_master_enable_region at
the time the device is created. We can create this region
at machine_done phase. (patch 1)

Then we can enable sysbus devices for PC machines and make all the
init steps inside the iommu realize function. (patch 2)

The series is working, but a lot of issues are not resolved:
   - minimum testing was done
   - the iommu addr should be passed (maybe) in command line rather than 
hard-coded
   - enabling sysbus devices for PC machines is risky, I am not aware yet
 of the side effects of this modification.
   - I am not sure moving the bus_master_enable_region to machine_done
 is with no undesired effects.


I gave it a shot on the patches and it works nicely (of course no
complex configurations, like hot plug).

Could you help introduce what will bring us if we use "-device" rather
than "-M" options?  Benefits I can see is that, we can specify
parameters with specific device, rather than messing them up in
"machine" options. Do we have any other benefits that I may have
missed?


Hi Peter,
Thanks for trying it!

Mainly is about not hard-coding device options (e.g. PCI address for AMD IOMMU),
but also to avoid having devices added as a side-effect of some machine option.
This will bring as closer to a cleaner model of a modular machine.

I plan to post a non-rfc version soon.


I just thought about whether we should support multiple IOMMUs in the
future (never know whether there would be a use case for
that).


This is an interesting scenario, we may find a need for multiple IOMMUs.
I tried it a while ago, but the linux kernel has (had?) a known limitation 
supporting it, see:
https://lkml.org/lkml/2015/11/22/100
Since is categorized as bug, it may be solved and the we can go for it.

 Anyway, looking forward to your non-rfc version. :)

I just posted a new version.
Thanks,
Marcel







Thanks!

-- peterx






Re: [Qemu-devel] [RFC v1 04/12] atomic: introduce atomic_dec_fetch.

2016-06-02 Thread Sergey Fedorov
On 15/04/16 17:23, Alex Bennée wrote:
> Useful for counting down.
>
> Signed-off-by: Alex Bennée 

Reviewed-by: Sergey Fedorov 

> ---
>  include/qemu/atomic.h | 4 
>  1 file changed, 4 insertions(+)
>
> diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
> index 8f1d8d9..5dba7db 100644
> --- a/include/qemu/atomic.h
> +++ b/include/qemu/atomic.h
> @@ -131,6 +131,8 @@
>  #define atomic_fetch_and(ptr, n) __atomic_fetch_and(ptr, n, __ATOMIC_SEQ_CST)
>  #define atomic_fetch_or(ptr, n)  __atomic_fetch_or(ptr, n, __ATOMIC_SEQ_CST)
>  
> +#define atomic_dec_fetch(ptr)  __atomic_sub_fetch(ptr, 1, __ATOMIC_SEQ_CST)
> +
>  /* And even shorter names that return void.  */
>  #define atomic_inc(ptr)((void) __atomic_fetch_add(ptr, 1, 
> __ATOMIC_SEQ_CST))
>  #define atomic_dec(ptr)((void) __atomic_fetch_sub(ptr, 1, 
> __ATOMIC_SEQ_CST))
> @@ -326,6 +328,8 @@
>  #define atomic_fetch_or__sync_fetch_and_or
>  #define atomic_cmpxchg __sync_val_compare_and_swap
>  
> +#define atomic_dec_fetch(ptr)  __sync_sub_and_fetch(ptr, 1)
> +
>  /* And even shorter names that return void.  */
>  #define atomic_inc(ptr)((void) __sync_fetch_and_add(ptr, 1))
>  #define atomic_dec(ptr)((void) __sync_fetch_and_add(ptr, -1))




[Qemu-devel] [PATCH] linux-user: check if NETLINK_ROUTE is available

2016-06-02 Thread Laurent Vivier
Some IFLA_* symbols can be missing in the host linux/if_link.h,
but as they are enums and not "#defines", check in "configure" if
last known  (IFLA_PROTO_DOWN) is available and if not, disable
management of NETLINK_ROUTE protocol.

Signed-off-by: Laurent Vivier 
---
Note:
   This patch must be applied on top of the series:
   [PATCH v2 0/3] linux-user: netlink support

 configure| 15 +++
 linux-user/syscall.c | 18 ++
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/configure b/configure
index b5aab72..294d791 100755
--- a/configure
+++ b/configure
@@ -4526,6 +4526,17 @@ if compile_prog "" "" ; then
 have_fsxattr=yes
 fi
 
+have_rtnetlink=no
+cat > $TMPC << EOF
+#include 
+int main(void) {
+  return IFLA_PROTO_DOWN;
+}
+EOF
+if compile_prog "" "" ; then
+have_rtnetlink=yes
+fi
+
 ##
 # End of CC checks
 # After here, no more $cc or $ld runs
@@ -5461,6 +5472,10 @@ if test "$rdma" = "yes" ; then
   echo "CONFIG_RDMA=y" >> $config_host_mak
 fi
 
+if test "$have_rtnetlink" = "yes" ; then
+  echo "CONFIG_RTNETLINK=y" >> $config_host_mak
+fi
+
 # Hold two types of flag:
 #   CONFIG_THREAD_SETNAME_BYTHREAD  - we've got a way of setting the name on
 # a thread we have a handle to
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index da48ba4..7c88d63 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -104,7 +104,9 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 #include "linux_loop.h"
 #include 
 #include 
+#ifdef CONFIG_RTNETLINK
 #include 
+#endif
 #include 
 #include "uname.h"
 
@@ -1629,6 +1631,7 @@ static abi_long target_to_host_for_each_nlmsg(struct 
nlmsghdr *nlh,
 return 0;
 }
 
+#ifdef CONFIG_RTNETLINK
 static abi_long host_to_target_for_each_rtattr(struct rtattr *rtattr,
size_t len,
abi_long 
(*host_to_target_rtattr)
@@ -2043,6 +2046,7 @@ static abi_long target_to_host_nlmsg_route(struct 
nlmsghdr *nlh, size_t len)
 {
 return target_to_host_for_each_nlmsg(nlh, len, target_to_host_data_route);
 }
+#endif /* CONFIG_RTNETLINK */
 
 static abi_long host_to_target_data_audit(struct nlmsghdr *nlh)
 {
@@ -2794,6 +2798,7 @@ static TargetFdTrans target_packet_trans = {
 .target_to_host_addr = packet_target_to_host_sockaddr,
 };
 
+#ifdef CONFIG_RTNETLINK
 static abi_long netlink_route_target_to_host(void *buf, size_t len)
 {
 return target_to_host_nlmsg_route(buf, len);
@@ -2808,6 +2813,7 @@ static TargetFdTrans target_netlink_route_trans = {
 .target_to_host_data = netlink_route_target_to_host,
 .host_to_target_data = netlink_route_host_to_target,
 };
+#endif /* CONFIG_RTNETLINK */
 
 static abi_long netlink_audit_target_to_host(void *buf, size_t len)
 {
@@ -2835,10 +2841,12 @@ static abi_long do_socket(int domain, int type, int 
protocol)
 return ret;
 }
 
-if (domain == PF_NETLINK &&
-!(protocol == NETLINK_ROUTE ||
-  protocol == NETLINK_KOBJECT_UEVENT ||
-  protocol == NETLINK_AUDIT)) {
+if (domain == PF_NETLINK && !(
+#ifdef CONFIG_RTNETLINK
+ protocol == NETLINK_ROUTE ||
+#endif
+ protocol == NETLINK_KOBJECT_UEVENT ||
+ protocol == NETLINK_AUDIT)) {
 return -EPFNOSUPPORT;
 }
 
@@ -2857,9 +2865,11 @@ static abi_long do_socket(int domain, int type, int 
protocol)
 fd_trans_register(ret, _packet_trans);
 } else if (domain == PF_NETLINK) {
 switch (protocol) {
+#ifdef CONFIG_RTNETLINK
 case NETLINK_ROUTE:
 fd_trans_register(ret, _netlink_route_trans);
 break;
+#endif
 case NETLINK_KOBJECT_UEVENT:
 /* nothing to do: messages are strings */
 break;
-- 
2.5.5




[Qemu-devel] [PATCH v2 3/3] q35: allow dynamic sysbus

2016-06-02 Thread Marcel Apfelbaum
Allow adding sysbus devices with -device on Q35.

At first Q35 will support only intel-iommu to be added this way,
however the command line will support all sysbus devices.

Mark with 'cannot_instantiate_with_device_add_yet' the ones
causing immediate problems (e.g. crashes).

Signed-off-by: Marcel Apfelbaum 
---
 hw/i386/pc_q35.c| 1 +
 hw/pci-bridge/pci_expander_bridge.c | 1 +
 hw/pci-host/piix.c  | 1 +
 hw/pci-host/q35.c   | 1 +
 4 files changed, 4 insertions(+)

diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 04aae89..431eaed 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -281,6 +281,7 @@ static void pc_q35_machine_options(MachineClass *m)
 m->default_machine_opts = "firmware=bios-256k.bin";
 m->default_display = "std";
 m->no_floppy = 1;
+m->has_dynamic_sysbus = true;
 }
 
 static void pc_q35_2_6_machine_options(MachineClass *m)
diff --git a/hw/pci-bridge/pci_expander_bridge.c 
b/hw/pci-bridge/pci_expander_bridge.c
index ba320bd..40518a2 100644
--- a/hw/pci-bridge/pci_expander_bridge.c
+++ b/hw/pci-bridge/pci_expander_bridge.c
@@ -149,6 +149,7 @@ static void pxb_host_class_init(ObjectClass *class, void 
*data)
 PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(class);
 
 dc->fw_name = "pci";
+dc->cannot_instantiate_with_device_add_yet = true;
 sbc->explicit_ofw_unit_address = pxb_host_ofw_unit_address;
 hc->root_bus_path = pxb_host_root_bus_path;
 }
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index df2b0e2..fea7f59 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -865,6 +865,7 @@ static void i440fx_pcihost_class_init(ObjectClass *klass, 
void *data)
 dc->realize = i440fx_pcihost_realize;
 dc->fw_name = "pci";
 dc->props = i440fx_props;
+dc->cannot_instantiate_with_device_add_yet = true;
 }
 
 static const TypeInfo i440fx_pcihost_info = {
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index ea684c7..9d82d30 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -138,6 +138,7 @@ static void q35_host_class_init(ObjectClass *klass, void 
*data)
 hc->root_bus_path = q35_host_root_bus_path;
 dc->realize = q35_host_realize;
 dc->props = mch_props;
+dc->cannot_instantiate_with_device_add_yet = true;
 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
 dc->fw_name = "pci";
 }
-- 
2.4.3




[Qemu-devel] [PATCH 05/10] target-avr: adding AVR interrupt handling

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/helper.c | 64 -
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/target-avr/helper.c b/target-avr/helper.c
index aec37af..ed22b37 100644
--- a/target-avr/helper.c
+++ b/target-avr/helper.c
@@ -33,12 +33,74 @@ boolavr_cpu_exec_interrupt(
 CPUState   *cs,
 int interrupt_request)
 {
-return  false;
+CPUClass*cc  = CPU_GET_CLASS(cs);
+AVRCPU  *cpu = AVR_CPU(cs);
+CPUAVRState *env = >env;
+
+boolret = false;
+
+if (interrupt_request & CPU_INTERRUPT_RESET) {
+if (cpu_interrupts_enabled(env)) {
+cs->exception_index = EXCP_RESET;
+cc->do_interrupt(cs);
+
+cs->interrupt_request   &= ~CPU_INTERRUPT_RESET;
+
+ret = true;
+}
+}
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+if (cpu_interrupts_enabled(env) && env->intsrc != 0) {
+int index   = __builtin_ffs(env->intsrc) - 1;
+cs->exception_index = EXCP_INT(index);
+cc->do_interrupt(cs);
+
+env->intsrc &= env->intsrc - 1; /* clear the interrupt 
*/
+cs->interrupt_request   &= ~CPU_INTERRUPT_HARD;
+
+ret = true;
+}
+}
+return ret;
 }
 
 voidavr_cpu_do_interrupt(
 CPUState   *cs)
 {
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState*env = >env;
+
+uint32_tret = env->pc;
+int vector;
+int size= avr_feature(env, AVR_FEATURE_JMP_CALL) ? 2 : 1;
+int base= 0;/* TODO: where to get it */
+
+if (cs->exception_index == EXCP_RESET) {
+vector  = 0;
+} else if (env->intsrc != 0) {
+vector  = __builtin_ffs(env->intsrc);
+}
+
+if (avr_feature(env, AVR_FEATURE_3_BYTE_PC)) {
+stb_phys(cs->as, env->sp--, (ret & 0xff));
+stb_phys(cs->as, env->sp--, (ret & 0x00ff00) >>  8);
+stb_phys(cs->as, env->sp--, (ret & 0xff) >> 16);
+
+env->pc = base + vector * size;
+} else if (avr_feature(env, AVR_FEATURE_2_BYTE_PC)) {
+stb_phys(cs->as, env->sp--, (ret & 0xff));
+stb_phys(cs->as, env->sp--, (ret & 0x00ff00) >>  8);
+
+env->pc = base + vector * size;
+} else {
+stb_phys(cs->as, env->sp--, (ret & 0xff));
+
+env->pc = base + vector * size;
+}
+
+env->sregI  = 0;/*  clear Global Interrupt Flag */
+
+cs->exception_index = -1;
 }
 
 int avr_cpu_memory_rw_debug(
-- 
2.4.9 (Apple Git-60)




Re: [Qemu-devel] [PATCH] tests: start a /qga/guest-exec test

2016-06-02 Thread Michael Roth
Quoting marcandre.lur...@redhat.com (2016-05-24 08:48:41)
> From: Marc-André Lureau 
> 
> Test a few guest-exec guest agent commands, added in qemu 2.5.
> 
> Signed-off-by: Marc-André Lureau 
> ---
>  tests/test-qga.c | 70 
> 
>  1 file changed, 70 insertions(+)
> 
> diff --git a/tests/test-qga.c b/tests/test-qga.c
> index 72a89de..42c9a89 100644
> --- a/tests/test-qga.c
> +++ b/tests/test-qga.c
> @@ -823,6 +823,75 @@ static void test_qga_fsfreeze_and_thaw(gconstpointer fix)
>  QDECREF(ret);
>  }
> 
> +static void test_qga_guest_exec(gconstpointer fix)
> +{
> +const TestFixture *fixture = fix;
> +QDict *ret, *val, *error;
> +const gchar *class, *desc, *out;
> +gchar *decoded;
> +int64_t pid, now, exitcode;
> +gsize len;
> +bool exited;
> +
> +/* exec 'echo foo bar' */
> +ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
> + " 'path': '/bin/echo', 'arg': [ 'foo', 'bar' ],"

Maybe 'arg': [ '-n', '" test_str "' ]," to make the check below a little
more robust as well, as exercising that arguments are being passed
appropriately (since `echo "foo bar"` and `echo foo bar` are identical
as far as the output.

> + " 'capture-output': true } }");
> +g_assert_nonnull(ret);
> +qmp_assert_no_error(ret);
> +val = qdict_get_qdict(ret, "return");
> +pid = qdict_get_int(val, "pid");
> +g_assert_cmpint(pid, >, 0);
> +QDECREF(ret);
> +
> +/* wait for completion */
> +now = g_get_monotonic_time();
> +do {
> +ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec-status',"
> + " 'arguments': { 'pid': %" PRId64 "  } }", pid);
> +g_assert_nonnull(ret);
> +val = qdict_get_qdict(ret, "return");
> +exited = qdict_get_bool(val, "exited");
> +if (!exited) {
> +QDECREF(ret);
> +}
> +} while (!exited &&
> + g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND);
> +g_assert(exited);
> +
> +/* check stdout */
> +exitcode = qdict_get_int(val, "exitcode");
> +g_assert_cmpint(exitcode, ==, 0);
> +out = qdict_get_str(val, "out-data");
> +decoded = g_base64_decode(out, );
> +g_assert_cmpint(len, ==, 8);
> +g_assert_cmpint(strncmp(decoded, "foo bar\n", 8), ==, 0);
> +g_free(decoded);
> +QDECREF(ret);
> +
> +/* invalid command */
> +ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
> + " 'path': '/bin/invalid-cmd42' } }");

Since there's no shared state between this and the above command I think
I'd rather this be in a separate test function. I know we have somewhat
of a precedence for this with test_qga_blacklist, but there's probably a
number of other checks worth adding that would eventually make this test
function a bit unwieldly.

> +g_assert_nonnull(ret);
> +error = qdict_get_qdict(ret, "error");
> +class = qdict_get_try_str(error, "class");
> +desc = qdict_get_try_str(error, "desc");
> +g_assert_cmpstr(class, ==, "GenericError");
> +g_assert_cmpint(strlen(desc), >, 0);
> +QDECREF(ret);
> +
> +/* invalid pid */
> +ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec-status',"
> + " 'arguments': { 'pid': 0 } }");
> +g_assert_nonnull(ret);
> +error = qdict_get_qdict(ret, "error");

g_assert_nonnull(error)

(qdict_get_try_str doesn't seem to check for null qdict)

> +class = qdict_get_try_str(error, "class");
> +desc = qdict_get_try_str(error, "desc");
> +g_assert_cmpstr(class, ==, "GenericError");
> +g_assert_cmpint(strlen(desc), >, 0);

I might be missing something in the error_setg path, but it doesn't seem
like we can rely on desc not being an empty string. guest-exec-status
doesn't use it in that fashion, but that's an internal detail rather
than something we can reliably test for.

Looks good otherwise.

> +QDECREF(ret);
> +}
> +
>  int main(int argc, char **argv)
>  {
>  TestFixture fix;
> @@ -853,6 +922,7 @@ int main(int argc, char **argv)
> 
>  g_test_add_data_func("/qga/blacklist", NULL, test_qga_blacklist);
>  g_test_add_data_func("/qga/config", NULL, test_qga_config);
> +g_test_add_data_func("/qga/guest-exec", , test_qga_guest_exec);
> 
>  if (g_getenv("QGA_TEST_SIDE_EFFECTING")) {
>  g_test_add_data_func("/qga/fsfreeze-and-thaw", ,
> -- 
> 2.7.4
> 




[Qemu-devel] [PATCH v2 2/3] hw/iommu: enable iommu with -device

2016-06-02 Thread Marcel Apfelbaum
Use the standard '-device iommu' instead of '-machine,iommu=on'
to create the IOMMU device.

Signed-off-by: Marcel Apfelbaum 
---
 hw/core/machine.c | 20 
 hw/i386/intel_iommu.c | 17 +
 hw/pci-host/q35.c | 28 
 qemu-options.hx   |  3 ---
 4 files changed, 17 insertions(+), 51 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index ccdd5fa..8f94301 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -300,20 +300,6 @@ static void machine_set_firmware(Object *obj, const char 
*value, Error **errp)
 ms->firmware = g_strdup(value);
 }
 
-static bool machine_get_iommu(Object *obj, Error **errp)
-{
-MachineState *ms = MACHINE(obj);
-
-return ms->iommu;
-}
-
-static void machine_set_iommu(Object *obj, bool value, Error **errp)
-{
-MachineState *ms = MACHINE(obj);
-
-ms->iommu = value;
-}
-
 static void machine_set_suppress_vmdesc(Object *obj, bool value, Error **errp)
 {
 MachineState *ms = MACHINE(obj);
@@ -493,12 +479,6 @@ static void machine_initfn(Object *obj)
 object_property_set_description(obj, "firmware",
 "Firmware image",
 NULL);
-object_property_add_bool(obj, "iommu",
- machine_get_iommu,
- machine_set_iommu, NULL);
-object_property_set_description(obj, "iommu",
-"Set on/off to enable/disable Intel IOMMU 
(VT-d)",
-NULL);
 object_property_add_bool(obj, "suppress-vmdesc",
  machine_get_suppress_vmdesc,
  machine_set_suppress_vmdesc, NULL);
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 347718f..9af5d6b 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -24,6 +24,8 @@
 #include "exec/address-spaces.h"
 #include "intel_iommu_internal.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/i386/pc.h"
 
 /*#define DEBUG_INTEL_IOMMU*/
 #ifdef DEBUG_INTEL_IOMMU
@@ -2014,8 +2016,20 @@ static void vtd_reset(DeviceState *dev)
 vtd_init(s);
 }
 
+static AddressSpace *vtd_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
+{
+IntelIOMMUState *s = opaque;
+VTDAddressSpace *vtd_as;
+
+assert(0 <= devfn && devfn <= VTD_PCI_DEVFN_MAX);
+
+vtd_as = vtd_find_add_as(s, bus, devfn);
+return _as->as;
+}
+
 static void vtd_realize(DeviceState *dev, Error **errp)
 {
+PCIBus *bus = PC_MACHINE(qdev_get_machine())->bus;
 IntelIOMMUState *s = INTEL_IOMMU_DEVICE(dev);
 
 VTD_DPRINTF(GENERAL, "");
@@ -2029,6 +2043,9 @@ static void vtd_realize(DeviceState *dev, Error **errp)
 s->vtd_as_by_busptr = g_hash_table_new_full(vtd_uint64_hash, 
vtd_uint64_equal,
   g_free, g_free);
 vtd_init(s);
+sysbus_mmio_map(SYS_BUS_DEVICE(s), 0, Q35_HOST_BRIDGE_IOMMU_ADDR);
+bus->iommu_fn = vtd_host_dma_iommu;
+bus->iommu_opaque = dev;
 }
 
 static void vtd_class_init(ObjectClass *klass, void *data)
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 70f897e..ea684c7 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -424,30 +424,6 @@ static void mch_reset(DeviceState *qdev)
 mch_update(mch);
 }
 
-static AddressSpace *q35_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
-{
-IntelIOMMUState *s = opaque;
-VTDAddressSpace *vtd_as;
-
-assert(0 <= devfn && devfn <= VTD_PCI_DEVFN_MAX);
-
-vtd_as = vtd_find_add_as(s, bus, devfn);
-return _as->as;
-}
-
-static void mch_init_dmar(MCHPCIState *mch)
-{
-PCIBus *pci_bus = PCI_BUS(qdev_get_parent_bus(DEVICE(mch)));
-
-mch->iommu = INTEL_IOMMU_DEVICE(qdev_create(NULL, 
TYPE_INTEL_IOMMU_DEVICE));
-object_property_add_child(OBJECT(mch), "intel-iommu",
-  OBJECT(mch->iommu), NULL);
-qdev_init_nofail(DEVICE(mch->iommu));
-sysbus_mmio_map(SYS_BUS_DEVICE(mch->iommu), 0, Q35_HOST_BRIDGE_IOMMU_ADDR);
-
-pci_setup_iommu(pci_bus, q35_host_dma_iommu, mch->iommu);
-}
-
 static void mch_realize(PCIDevice *d, Error **errp)
 {
 int i;
@@ -506,10 +482,6 @@ static void mch_realize(PCIDevice *d, Error **errp)
  mch->pci_address_space, >pam_regions[i+1],
  PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE);
 }
-/* Intel IOMMU (VT-d) */
-if (object_property_get_bool(qdev_get_machine(), "iommu", NULL)) {
-mch_init_dmar(mch);
-}
 }
 
 uint64_t mch_mcfg_base(void)
diff --git a/qemu-options.hx b/qemu-options.hx
index 6106520..2953baf 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -38,7 +38,6 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
 "kvm_shadow_mem=size of KVM shadow MMU\n"
 "dump-guest-core=on|off include guest memory in a core 
dump (default=on)\n"
 "

[Qemu-devel] [PATCH 08/10] target-avr: adding instruction translation

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/translate-inst.c | 2443 +++
 target-avr/translate.h  |  123 +++
 2 files changed, 2566 insertions(+)
 create mode 100644 target-avr/translate-inst.c
 create mode 100644 target-avr/translate.h

diff --git a/target-avr/translate-inst.c b/target-avr/translate-inst.c
new file mode 100644
index 000..fe9d9fc
--- /dev/null
+++ b/target-avr/translate-inst.c
@@ -0,0 +1,2443 @@
+/*
+ *  QEMU AVR CPU
+ *
+ *  Copyright (c) 2016 Michael Rolnik
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, see
+ *  
+ */
+
+#include "translate.h"
+#include "translate-inst.h"
+
+/*
+NOTE:   all registers are assumed to hold 8 bit values.
+so all operations done on registers should preseve this property
+*/
+
+/*
+NOTE:   the flags C,H,V,N,V have either 0 or 1 values
+NOTE:   the flag Z has inverse logic, when the value of Zf is 0 the flag 
is assumed to be set, non zero - not set
+*/
+
+voidgen_add_CHf(TCGv R, TCGv Rd, TCGv Rr);
+voidgen_add_Vf(TCGv R, TCGv Rd, TCGv Rr);
+voidgen_sub_CHf(TCGv R, TCGv Rd, TCGv Rr);
+voidgen_sub_Vf(TCGv R, TCGv Rd, TCGv Rr);
+voidgen_ZNSf(TCGv R);
+voidgen_push_ret(CPUAVRState *env, intret);
+voidgen_pop_ret(CPUAVRState *env, TCGvret);
+voidgen_jmp_ez(void);
+voidgen_jmp_z(void);
+
+voidgen_set_addr(TCGv addr, TCGv H, TCGv M, TCGv l); /*  H:M:L   = addr  */
+voidgen_set_xaddr(TCGv addr);
+voidgen_set_yaddr(TCGv addr);
+voidgen_set_zaddr(TCGv addr);
+
+TCGvgen_get_addr(TCGv H, TCGv M, TCGv L);/*  addr = H:M:L*/
+TCGvgen_get_xaddr(void);
+TCGvgen_get_yaddr(void);
+TCGvgen_get_zaddr(void);
+int sex(int Imm, unsigned bits);
+
+voidgen_add_CHf(TCGv R, TCGv Rd, TCGv Rr)
+{
+TCGvt1  = tcg_temp_new_i32();
+TCGvt2  = tcg_temp_new_i32();
+TCGvt3  = tcg_temp_new_i32();
+
+tcg_gen_and_tl(t1, Rd, Rr);/*  t1  = Rd & Rr  */
+tcg_gen_not_tl(t2, R); /*  t2  = Rd & ~R  */
+tcg_gen_and_tl(t2, Rd, t2);
+tcg_gen_not_tl(t3, R); /*  t3  = Rr  *~R  */
+tcg_gen_and_tl(t3, Rr, t3);
+tcg_gen_or_tl(t1, t1, t2);/*  t1  = t1 | t2 | t3  */
+tcg_gen_or_tl(t1, t1, t3);
+
+tcg_gen_shri_tl(cpu_Cf, t1, 7); /*  Cf  = t1(7)  */
+tcg_gen_shri_tl(cpu_Hf, t1, 3); /*  Hf  = t1(3)  */
+tcg_gen_andi_tl(cpu_Hf, cpu_Hf, 1);
+
+tcg_temp_free_i32(t3);
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t1);
+}
+
+voidgen_add_Vf(TCGvR, TCGvRd, TCGvRr)
+{
+TCGvt1  = tcg_temp_new_i32();
+TCGvt2  = tcg_temp_new_i32();
+
+tcg_gen_not_tl(t1, Rd);/*  t1  = ~Rd & ~Rr & R  */
+tcg_gen_not_tl(t2, Rr);
+tcg_gen_and_tl(t1, t1, t2);
+tcg_gen_and_tl(t1, t1, R);
+
+tcg_gen_not_tl(t2, R); /*  t2  = Rd & Rr & ~R  */
+tcg_gen_and_tl(t2, t2, Rd);
+tcg_gen_and_tl(t2, t2, Rr);
+
+tcg_gen_or_tl(t1, t1, t2);/*  t1  = Rd & Rr & ~R | ~Rd & ~Rr & R  */
+
+tcg_gen_shri_tl(cpu_Vf, t1, 7); /*  Vf  = t1(7)  */
+
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t1);
+}
+
+voidgen_sub_CHf(TCGvR, TCGvRd, TCGvRr)
+{
+TCGvt1  = tcg_temp_new_i32();
+TCGvt2  = tcg_temp_new_i32();
+TCGvt3  = tcg_temp_new_i32();
+
+/*  Cf & Hf  */
+tcg_gen_not_tl(t1, Rd);/*  t1  = ~Rd  */
+tcg_gen_and_tl(t2, t1, Rr);/*  t2  = ~Rd & Rr  */
+tcg_gen_or_tl(t3, t1, Rr);/*  t3  = (~Rd | Rr) & R  */
+tcg_gen_and_tl(t3, t3, R);
+tcg_gen_or_tl(t2, t2, t3);/*  t2  = ~Rd & Rr | ~Rd & R | R & Rr  */
+tcg_gen_shri_tl(cpu_Cf, t2, 7); /*  Cf  = t2(7)  */
+tcg_gen_shri_tl(cpu_Hf, t2, 3); /*  Hf  = t2(3)  */
+tcg_gen_andi_tl(cpu_Hf, cpu_Hf, 1);
+
+tcg_temp_free_i32(t3);
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t1);
+}
+
+voidgen_sub_Vf(TCGvR, TCGvRd, TCGvRr)
+{
+TCGvt1  = tcg_temp_new_i32();
+TCGvt2  = tcg_temp_new_i32();
+
+/*  Vf  */
+tcg_gen_and_tl(t1, Rr, R); /*  t1  = Rd & ~Rr & ~R  */
+tcg_gen_not_tl(t1, t1);
+tcg_gen_and_tl(t1, t1, Rd);
+tcg_gen_not_tl(t2, Rd);/*  t2  = ~Rd & Rr & R  */
+

[Qemu-devel] [PATCH 04/10] target-avr: adding instructions encodings

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/translate-inst.h | 838 
 1 file changed, 838 insertions(+)
 create mode 100644 target-avr/translate-inst.h

diff --git a/target-avr/translate-inst.h b/target-avr/translate-inst.h
new file mode 100644
index 000..6bd180d
--- /dev/null
+++ b/target-avr/translate-inst.h
@@ -0,0 +1,838 @@
+
+#ifndef AVR_TRANSLATE_INST_H_
+#define AVR_TRANSLATE_INST_H_
+
+typedef struct DisasContextDisasContext;
+
+int avr_translate_NOP(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+
+int avr_translate_MOVW(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t MOVW_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t MOVW_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 4);
+}
+
+int avr_translate_MULS(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t MULS_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t MULS_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 4);
+}
+
+int avr_translate_MULSU(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t MULSU_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+static inline uint32_t MULSU_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+int avr_translate_FMUL(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t FMUL_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+static inline uint32_t FMUL_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+int avr_translate_FMULS(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t FMULS_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+static inline uint32_t FMULS_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+int avr_translate_FMULSU(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t FMULSU_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+static inline uint32_t FMULSU_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+int avr_translate_CPC(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t CPC_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t CPC_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t CPC_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_SBC(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t SBC_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t SBC_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t SBC_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_ADD(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t ADD_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t ADD_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t ADD_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_AND(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t AND_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t AND_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t AND_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_EOR(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t EOR_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t EOR_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t EOR_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_OR(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t OR_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t OR_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t OR_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_MOV(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t MOV_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t MOV_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t MOV_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_CPSE(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t CPSE_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t CPSE_Rd(uint32_t opcode)
+{
+return 

[Qemu-devel] [PATCH v2 1/3] hw/pci: delay bus_master_enable_region initialization

2016-06-02 Thread Marcel Apfelbaum
Skip bus_master_enable region creation on PCI device init
in order to be sure the IOMMU device (if present) would
be created in advance. Add this memory region at machine_done time.

Signed-off-by: Marcel Apfelbaum 
---
 hw/pci/pci.c | 46 --
 include/hw/pci/pci_bus.h |  2 ++
 2 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index bb605ef..29dcbcf 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -127,11 +127,44 @@ static void pci_bus_class_init(ObjectClass *klass, void 
*data)
 pbc->numa_node = pcibus_numa_node;
 }
 
+static void pci_init_bus_master(PCIDevice *pci_dev)
+{
+AddressSpace *dma_as = pci_device_iommu_address_space(pci_dev);
+
+memory_region_init_alias(_dev->bus_master_enable_region,
+ OBJECT(pci_dev), "bus master",
+ dma_as->root, 0, 
memory_region_size(dma_as->root));
+memory_region_set_enabled(_dev->bus_master_enable_region, false);
+address_space_init(_dev->bus_master_as,
+   _dev->bus_master_enable_region, pci_dev->name);
+}
+
+static void pcibus_machine_done(Notifier *notifier, void *data)
+{
+PCIBus *bus = container_of(notifier, PCIBus, machine_done);
+int i;
+
+for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
+if (bus->devices[i]) {
+pci_init_bus_master(bus->devices[i]);
+}
+}
+}
+
+static void pcibus_initfn(Object *obj)
+{
+PCIBus *bus = PCI_BUS(obj);
+
+bus->machine_done.notify = pcibus_machine_done;
+qemu_add_machine_init_done_notifier(>machine_done);
+}
+
 static const TypeInfo pci_bus_info = {
 .name = TYPE_PCI_BUS,
 .parent = TYPE_BUS,
 .instance_size = sizeof(PCIBus),
 .class_size = sizeof(PCIBusClass),
+.instance_init = pcibus_initfn,
 .class_init = pci_bus_class_init,
 };
 
@@ -845,7 +878,6 @@ static PCIDevice *do_pci_register_device(PCIDevice 
*pci_dev, PCIBus *bus,
 PCIConfigReadFunc *config_read = pc->config_read;
 PCIConfigWriteFunc *config_write = pc->config_write;
 Error *local_err = NULL;
-AddressSpace *dma_as;
 DeviceState *dev = DEVICE(pci_dev);
 
 pci_dev->bus = bus;
@@ -885,15 +917,9 @@ static PCIDevice *do_pci_register_device(PCIDevice 
*pci_dev, PCIBus *bus,
 }
 
 pci_dev->devfn = devfn;
-dma_as = pci_device_iommu_address_space(pci_dev);
-
-memory_region_init_alias(_dev->bus_master_enable_region,
- OBJECT(pci_dev), "bus master",
- dma_as->root, 0, 
memory_region_size(dma_as->root));
-memory_region_set_enabled(_dev->bus_master_enable_region, false);
-address_space_init(_dev->bus_master_as, 
_dev->bus_master_enable_region,
-   name);
-
+if (qdev_hotplug) {
+pci_init_bus_master(pci_dev);
+}
 pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
 pci_dev->irq_state = 0;
 pci_config_alloc(pci_dev);
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index 403fec6..5484a9b 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -39,6 +39,8 @@ struct PCIBus {
Keep a count of the number of devices with raised IRQs.  */
 int nirq;
 int *irq_count;
+
+Notifier machine_done;
 };
 
 typedef struct PCIBridgeWindows PCIBridgeWindows;
-- 
2.4.3




[Qemu-devel] [PATCH 09/10] target-avr: updating translate.c to use instructions translation

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/Makefile.objs |   4 +-
 target-avr/translate.c   | 148 ++-
 2 files changed, 72 insertions(+), 80 deletions(-)

diff --git a/target-avr/Makefile.objs b/target-avr/Makefile.objs
index c503546..8d06d54 100644
--- a/target-avr/Makefile.objs
+++ b/target-avr/Makefile.objs
@@ -1,3 +1,5 @@
-obj-y   += translate.o cpu.o helper.o
+obj-y   += translate.o helper.o cpu.o translate-inst.o
 obj-y   += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += machine.o
+
+obj-y   += decode.o
diff --git a/target-avr/translate.c b/target-avr/translate.c
index e98aaef..0df0184 100644
--- a/target-avr/translate.c
+++ b/target-avr/translate.c
@@ -18,60 +18,31 @@
  *  
  */
 
-#include "qemu/osdep.h"
-
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "disas/disas.h"
-#include "tcg-op.h"
-#include "exec/cpu_ldst.h"
-
-#include "exec/helper-proto.h"
-#include "exec/helper-gen.h"
-#include "exec/log.h"
-
-typedef struct DisasContext DisasContext;
-typedef struct InstInfo InstInfo;
-
-/*This is the state at translation time.  */
-struct DisasContext {
-struct TranslationBlock*tb;
-
-/*Routine used to access memory */
-int memidx;
-int bstate;
-int singlestep;
-};
-
-enum {
-BS_NONE = 0,/*  Nothing special (none of the below  */
-BS_STOP = 1,/*  We want to stop translation for any reason  */
-BS_BRANCH   = 2,/*  A branch condition is reached   */
-BS_EXCP = 3,/*  An exception condition is reached   */
-};
-
-static TCGv_env cpu_env;
-
-static TCGv cpu_pc;
-
-static TCGv cpu_Cf;
-static TCGv cpu_Zf;
-static TCGv cpu_Nf;
-static TCGv cpu_Vf;
-static TCGv cpu_Sf;
-static TCGv cpu_Hf;
-static TCGv cpu_Tf;
-static TCGv cpu_If;
-
-static TCGv cpu_rampD;
-static TCGv cpu_rampX;
-static TCGv cpu_rampY;
-static TCGv cpu_rampZ;
-
-static TCGv cpu_io[64];
-static TCGv cpu_r[32];
-static TCGv cpu_eind;
-static TCGv cpu_sp;
+#include "translate.h"
+
+
+TCGv_env cpu_env;
+
+TCGv cpu_pc;
+
+TCGv cpu_Cf;
+TCGv cpu_Zf;
+TCGv cpu_Nf;
+TCGv cpu_Vf;
+TCGv cpu_Sf;
+TCGv cpu_Hf;
+TCGv cpu_Tf;
+TCGv cpu_If;
+
+TCGv cpu_rampD;
+TCGv cpu_rampX;
+TCGv cpu_rampY;
+TCGv cpu_rampZ;
+
+TCGv cpu_io[64];
+TCGv cpu_r[32];
+TCGv cpu_eind;
+TCGv cpu_sp;
 
 #include "exec/gen-icount.h"
 #define REG(x)  (cpu_r[x])
@@ -120,30 +91,42 @@ voidavr_translate_init(void)
 done_init = 1;
 }
 
-static inline void  gen_goto_tb(CPUAVRState*env,
-DisasContext   *ctx,
-int n,
-target_ulongdest)
+static void decode_opc(
+AVRCPU *cpu,
+DisasContext   *ctx,
+InstInfo   *inst)
 {
-TranslationBlock   *tb;
+CPUAVRState*env = >env;
 
-tb  = ctx->tb;
+inst->opcode= cpu_ldl_code(env, inst->cpc * 2);   /*  pc points to 
words*/
+inst->length= 16;
+inst->translate = NULL;
 
-if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)
-&&  (ctx->singlestep == 0)) {
-tcg_gen_goto_tb(n);
-tcg_gen_movi_i32(cpu_pc, dest);
-tcg_gen_exit_tb((uintptr_t)tb + n);
-} else {
-tcg_gen_movi_i32(cpu_pc, dest);
+/*  the following function looks onto the opcode as a string of bytes   */
+avr_decode(inst->cpc, >length, inst->opcode, >translate);
 
-if (ctx->singlestep) {
-gen_helper_debug(cpu_env);
-}
-tcg_gen_exit_tb(0);
+if (inst->length == 16) {
+inst->npc= inst->cpc + 1;
+/*  get opcode as 16bit value   */
+inst->opcode = inst->opcode & 0x;
+}
+if (inst->length == 32) {
+inst->npc= inst->cpc + 2;
+/*  get opcode as 32bit value   */
+inst->opcode = (inst->opcode << 16)
+ | (inst->opcode >> 16);
 }
 }
 
+uint32_tget_opcode(
+uint8_t const  *code,
+unsignedbitBase,
+unsignedbitSize)
+{
+return  *(uint16_t *)code;
+}
+
+
 /*generate intermediate code for basic block 'tb'.  */
 voidgen_intermediate_code(
 CPUAVRState*env,
@@ -176,18 +159,21 @@ voidgen_intermediate_code(
 gen_tb_start(tb);
 
 /*  decode first instruction*/
-cpc = pc_start;
-npc = cpc + 1;
+ctx.inst[0].cpc = pc_start;
+decode_opc(cpu, , 

[Qemu-devel] [PATCH 07/10] target-avr: adding instruction decoder

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/decode.c | 724 
 1 file changed, 724 insertions(+)
 create mode 100644 target-avr/decode.c

diff --git a/target-avr/decode.c b/target-avr/decode.c
new file mode 100644
index 000..22e2d36
--- /dev/null
+++ b/target-avr/decode.c
@@ -0,0 +1,724 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2016 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+
+#include 
+#include "translate.h"
+
+
+uint32_tavr_decode(uint32_t pc, uint32_t *length, uint32_t code, 
translate_function_t *translate)
+{
+uint32_topcode  = extract32(code, 0, 16);
+switch (opcode & 0xd000) {
+case0x: {
+uint32_topcode  = extract32(code, 0, 16);
+switch (opcode & 0x2c00) {
+case0x: {
+uint32_topcode  = extract32(code, 0, 16);
+switch (opcode & 0x0300) {
+case0x: {
+*length = 16;
+*translate = 
(translate_function_t)_translate_NOP;
+break;
+}
+case0x0100: {
+*length = 16;
+*translate = 
(translate_function_t)_translate_MOVW;
+break;
+}
+case0x0200: {
+*length = 16;
+*translate = 
(translate_function_t)_translate_MULS;
+break;
+}
+case0x0300: {
+uint32_topcode  = extract32(code, 0, 16);
+switch (opcode & 0x0088) {
+case0x: {
+*length = 16;
+*translate = 
(translate_function_t)_translate_MULSU;
+break;
+}
+case0x0008: {
+*length = 16;
+*translate = 
(translate_function_t)_translate_FMUL;
+break;
+}
+case0x0080: {
+*length = 16;
+*translate = 
(translate_function_t)_translate_FMULS;
+break;
+}
+case0x0088: {
+*length = 16;
+*translate = 
(translate_function_t)_translate_FMULSU;
+break;
+}
+}
+break;
+}
+}
+break;
+}
+case0x0400: {
+*length = 16;
+*translate = (translate_function_t)_translate_CPC;
+break;
+}
+case0x0800: {
+*length = 16;
+*translate = (translate_function_t)_translate_SBC;
+break;
+}
+case0x0c00: {
+*length = 16;
+*translate = (translate_function_t)_translate_ADD;
+break;
+}
+case0x2000: {
+*length = 16;
+*translate = (translate_function_t)_translate_AND;
+break;
+}
+case0x2400: {
+*length = 16;
+*translate = (translate_function_t)_translate_EOR;
+break;
+}
+case0x2800: {
+*length = 16;
+*translate = (translate_function_t)_translate_OR;
+break;
+}
+case   

[Qemu-devel] [PATCH 03/10] target-avr: adding a sample AVR board

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 hw/Makefile.objs |   1 +
 hw/avr/Makefile.objs |   1 +
 hw/avr/sample-io.c   | 246 +++
 hw/avr/sample.c  | 120 +
 4 files changed, 368 insertions(+)
 create mode 100644 hw/avr/Makefile.objs
 create mode 100644 hw/avr/sample-io.c
 create mode 100644 hw/avr/sample.c

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 4a07ed4..262ca15 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -33,6 +33,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += watchdog/
 devices-dirs-$(CONFIG_SOFTMMU) += xen/
 devices-dirs-$(CONFIG_MEM_HOTPLUG) += mem/
 devices-dirs-$(CONFIG_SMBIOS) += smbios/
+devices-dirs-$(CONFIG_SOFTMMU) += avr/
 devices-dirs-y += core/
 common-obj-y += $(devices-dirs-y)
 obj-y += $(devices-dirs-y)
diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
new file mode 100644
index 000..9f6be2f
--- /dev/null
+++ b/hw/avr/Makefile.objs
@@ -0,0 +1 @@
+obj-y   += sample.o sample-io.o
diff --git a/hw/avr/sample-io.c b/hw/avr/sample-io.c
new file mode 100644
index 000..133c72f
--- /dev/null
+++ b/hw/avr/sample-io.c
@@ -0,0 +1,246 @@
+/*
+ *  QEMU AVR CPU
+ *
+ *  Copyright (c) 2016 Michael Rolnik
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, see
+ *  
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "include/hw/sysbus.h"
+
+#define TYPE_SAMPLEIO   "SampleIO"
+#define SAMPLEIO(obj)   OBJECT_CHECK(SAMPLEIOState, (obj), TYPE_SAMPLEIO)
+
+#ifndef DEBUG_SAMPLEIO
+#define DEBUG_SAMPLEIO 1
+#endif
+
+#define DPRINTF(fmt, args...) \
+do {  \
+if (DEBUG_SAMPLEIO) { \
+fprintf(stderr, "[%s]%s: " fmt , TYPE_SAMPLEIO, __func__, ##args);\
+} \
+} \
+while (0)
+
+#define AVR_IO_CPU_REGS_SIZE0x0020
+#define AVR_IO_CPU_IO_SIZE  0x0040
+#define AVR_IO_EXTERN_IO_SIZE   0x00a0
+#define AVR_IO_SIZE (AVR_IO_CPU_REGS_SIZE   \
++ AVR_IO_CPU_IO_SIZE\
++ AVR_IO_EXTERN_IO_SIZE)
+
+#define AVR_IO_CPU_REGS_BASE0x
+#define AVR_IO_CPU_IO_BASE  (AVR_IO_CPU_REGS_BASE   \
++ AVR_IO_CPU_REGS_SIZE)
+#define AVR_IO_EXTERN_IO_BASE   (AVR_IO_CPU_IO_BASE \
++ AVR_IO_CPU_IO_SIZE)
+
+
+typedef struct SAMPLEIOState {
+SysBusDeviceparent;
+
+MemoryRegioniomem;
+
+AVRCPU *cpu;
+
+uint8_t io[0x40];
+uint8_t exio[0xa0];
+} SAMPLEIOState;
+
+static uint64_t sample_io_read(
+void   *opaque,
+hwaddr  offset,
+unsignedsize);
+static void sample_io_write(void   *opaque,
+hwaddr  offset,
+uint64_tvalue,
+unsignedsize);
+static int  sample_io_init(
+DeviceState*sbd);
+static void sample_io_class_init(
+ObjectClass*klass,
+void   *data);
+static void sample_io_register_types(void);
+
+static void write_Rx(
+CPUAVRState*env,
+int inst,
+uint8_t data);
+static uint8_t  read_Rx(
+CPUAVRState*env,
+int inst);
+
+static const
+MemoryRegionOps sample_io_ops = {
+.read   = sample_io_read,
+.write  = sample_io_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static
+Propertysample_io_properties[] = {
+DEFINE_PROP_END_OF_LIST(),
+};
+static const

[Qemu-devel] [PATCH 10/10] target-avr: fixing code style

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/cpu-qom.h|  38 +
 target-avr/cpu.c| 100 +---
 target-avr/cpu.h|  74 
 target-avr/gdbstub.c|  10 +
 target-avr/helper.c |  52 ++-
 target-avr/translate-inst.c |  54 +++-
 target-avr/translate-inst.h |  20 +
 target-avr/translate.c  |  27 +++-
 target-avr/translate.h  |   5 +--
 9 files changed, 134 insertions(+), 246 deletions(-)

diff --git a/target-avr/cpu-qom.h b/target-avr/cpu-qom.h
index 76ca908..bb0fbd7 100644
--- a/target-avr/cpu-qom.h
+++ b/target-avr/cpu-qom.h
@@ -25,9 +25,9 @@
 
 #define TYPE_AVR_CPU"avr"
 
-#define AVR_CPU_CLASS(klass)OBJECT_CLASS_CHECK(AVRCPUClass, (klass), 
TYPE_AVR_CPU)
-#define AVR_CPU(obj)OBJECT_CHECK(AVRCPU, (obj), TYPE_AVR_CPU)
-#define AVR_CPU_GET_CLASS(obj)  OBJECT_GET_CLASS(AVRCPUClass, (obj), 
TYPE_AVR_CPU)
+#define AVR_CPU_CLASS(klass) OBJECT_CLASS_CHECK(AVRCPUClass, (klass), 
TYPE_AVR_CPU)
+#define AVR_CPU(obj) OBJECT_CHECK(AVRCPU, (obj), TYPE_AVR_CPU)
+#define AVR_CPU_GET_CLASS(obj) OBJECT_GET_CLASS(AVRCPUClass, (obj), 
TYPE_AVR_CPU)
 
 /**
 *  AVRCPUClass:
@@ -58,40 +58,24 @@ typedef struct AVRCPU {
 CPUAVRState env;
 } AVRCPU;
 
-static inline AVRCPU   *avr_env_get_cpu(CPUAVRState *env)
+static inline AVRCPU *avr_env_get_cpu(CPUAVRState *env)
 {
 return container_of(env, AVRCPU, env);
 }
 
-#define ENV_GET_CPU(e)  CPU(avr_env_get_cpu(e))
+#define ENV_GET_CPU(e) CPU(avr_env_get_cpu(e))
 #define ENV_OFFSET  offsetof(AVRCPU, env)
 
 #ifndef CONFIG_USER_ONLY
 extern const struct VMStateDescription vmstate_avr_cpu;
 #endif
 
-voidavr_cpu_do_interrupt(
-CPUState   *cpu);
-boolavr_cpu_exec_interrupt(
-CPUState   *cpu,
-int int_req);
-voidavr_cpu_dump_state(
-CPUState   *cs,
-FILE   *f,
-fprintf_functioncpu_fprintf,
-int flags);
+void avr_cpu_do_interrupt(CPUState *cpu);
+bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
+void avr_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, 
int flags);
 
-hwaddr  avr_cpu_get_phys_page_debug(
-CPUState   *cpu,
-vaddr   addr);
-
-int avr_cpu_gdb_read_register(
-CPUState   *cpu,
-uint8_t*buf,
-int reg);
-int avr_cpu_gdb_write_register(
-CPUState   *cpu,
-uint8_t*buf,
-int reg);
+hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+int avr_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
 #endif
diff --git a/target-avr/cpu.c b/target-avr/cpu.c
index 9be0a1d..3c7fa07 100644
--- a/target-avr/cpu.c
+++ b/target-avr/cpu.c
@@ -25,17 +25,14 @@
 #include "migration/vmstate.h"
 #include "machine.h"
 
-static void avr_cpu_set_pc(
-CPUState   *cs,
-vaddr   value)
+static void avr_cpu_set_pc(CPUState *cs, vaddr value)
 {
 AVRCPU   *cpu = AVR_CPU(cs);
 
 cpu->env.pc = value / 2;/*  internally PC points to words   */
 }
 
-static bool avr_cpu_has_work(
-CPUState   *cs)
+static bool avr_cpu_has_work(CPUState *cs)
 {
 AVRCPU  *cpu = AVR_CPU(cs);
 CPUAVRState *env = >env;
@@ -45,9 +42,7 @@ static bool avr_cpu_has_work(
 | CPU_INTERRUPT_RESET))
 &&  cpu_interrupts_enabled(env);
 }
-static void avr_cpu_synchronize_from_tb(
-CPUState   *cs,
-TranslationBlock   *tb)
+static void avr_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
 {
 AVRCPU  *cpu = AVR_CPU(cs);
 CPUAVRState *env = >env;
@@ -55,8 +50,7 @@ static void avr_cpu_synchronize_from_tb(
 env->pc = tb->pc / 2;   /*  internally PC points to words   */
 }
 
-static void avr_cpu_reset(
-CPUState   *s)
+static void avr_cpu_reset(CPUState *s)
 {
 AVRCPU *cpu = AVR_CPU(s);
 AVRCPUClass*mcc = AVR_CPU_GET_CLASS(cpu);
@@ -73,17 +67,13 @@ static void 

[Qemu-devel] [PATCH v2 0/3] enable iommu with -device

2016-06-02 Thread Marcel Apfelbaum
Create the iommu device with '-device intel-iommu' instead of 
'-machine,iommu=on'.

The device is part of the machine properties because we wanted
to ensure it is created before any other PCI device.

The alternative is to skip the bus_master_enable_region at
the time the device is created. We can create this region
at machine_done phase. (patch 1)

Patch 2 moves the init proces into iommu's realize function.

Then we need to enable sysbus devices for PC machines (patch 3).

This creates a new problem since we have now a bunch of
new devices that can be created with -device on Q35:
name "q35-pcihost", bus System
name "sysbus-ohci", bus System, desc "OHCI USB Controller"
name "allwinner-ahci", bus System
name "cfi.pflash01", bus System
name "esp", bus System
name "SUNW,fdtwo", bus System
name "sysbus-ahci", bus System
name "sysbus-fdc", bus System
name "vfio-amd-xgbe", bus System, desc "VFIO AMD XGBE"
name "vfio-calxeda-xgmac", bus System, desc "VFIO Calxeda XGMAC"
name "virtio-mmio", bus System
name "fw_cfg", bus System
name "fw_cfg_io", bus System
name "fw_cfg_mem", bus System
name "generic-sdhci", bus System
name "hpet", bus System
name "i440FX-pcihost", bus System
name "intel-iommu", bus System
name "ioapic", bus System
name "isabus-bridge", bus System
name "kvm-ioapic", bus System
name "kvmclock", bus System
name "kvmvapic", bus System
name "pxb-host", bus System

Took care of the ones creating immediate issues (like crashes) by marking them
as 'cannot_instantiate_with_device_add_yet'. I didn't mark them all because:
  - libvirt will mask them anyway
  - some of them have already a "protection" in place
  - it is possible that some of them can be actually used with -device on other 
platform. 
  - those are not 'interesting' scenarios.
If somebody spots devices in the list that cannot be added with -device on any 
platform
please let me know and I'll mark them.


v1 -> v2:
  - Enable bus_master also on init if the guest OS already booted to enable 
hotplug (Paolo).
  - Add a machine_done notifier to PCIBus instead of adding functionality
for q35 machine_done callback. The main reason is we don't want to replicate
the code for all platforms that support PCI and is also cleaner this way.
  - Added 'cannot_instantiate_with_device_add_yet' to sysbus devices that lead
to crashes if added with -device.
  - Rebased on master

Thanks,
Marcel

Marcel Apfelbaum (2):
  hw/pci: delay bus_master_enable_region initialization
  hw/iommu: enable iommu with -device
  q35: allow dynamic sysbus

 hw/core/machine.c   | 20 
 hw/i386/intel_iommu.c   | 17 ++
 hw/i386/pc_q35.c|  1 +
 hw/pci-bridge/pci_expander_bridge.c |  1 +
 hw/pci-host/piix.c  |  1 +
 hw/pci-host/q35.c   | 29 +--
 hw/pci/pci.c| 46 +
 include/hw/pci/pci_bus.h|  2 ++
 qemu-options.hx |  3 ---
 9 files changed, 59 insertions(+), 61 deletions(-)

-- 
2.4.3




[Qemu-devel] [PATCH 02/10] target-avr: adding AVR CPU features/flavors

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/cpu.c | 326 ++-
 target-avr/cpu.h |  59 ++
 2 files changed, 383 insertions(+), 2 deletions(-)

diff --git a/target-avr/cpu.c b/target-avr/cpu.c
index ff26018..9be0a1d 100644
--- a/target-avr/cpu.c
+++ b/target-avr/cpu.c
@@ -31,7 +31,7 @@ static void avr_cpu_set_pc(
 {
 AVRCPU   *cpu = AVR_CPU(cs);
 
-cpu->env.pc = value / 2;/*  internaly PC points to words, not bytes */
+cpu->env.pc = value / 2;/*  internally PC points to words   */
 }
 
 static bool avr_cpu_has_work(
@@ -52,7 +52,7 @@ static void avr_cpu_synchronize_from_tb(
 AVRCPU  *cpu = AVR_CPU(cs);
 CPUAVRState *env = >env;
 
-env->pc = tb->pc / 2;
+env->pc = tb->pc / 2;   /*  internally PC points to words   */
 }
 
 static void avr_cpu_reset(
@@ -61,12 +61,14 @@ static void avr_cpu_reset(
 AVRCPU *cpu = AVR_CPU(s);
 AVRCPUClass*mcc = AVR_CPU_GET_CLASS(cpu);
 CPUAVRState*env = >env;
+uint32_tfeatures= env->features;
 
 mcc->parent_reset(s);
 
 memset(env, 0, sizeof(CPUAVRState));
 env->pc = 0;
 env->sregI  = 1;
+env->features   = features;
 
 tlb_flush(s, 1);
 }
@@ -206,6 +208,311 @@ static void avr_cpu_class_init(
 = true;
 }
 
+static void avr_avr1_initfn(
+Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState*env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+}
+static void avr_avr2_initfn(
+Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState*env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env,AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env,AVR_FEATURE_SRAM);
+avr_set_feature(env,AVR_FEATURE_BREAK);
+
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+}
+
+static void avr_avr25_initfn(
+Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState*env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env,AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env,AVR_FEATURE_SRAM);
+avr_set_feature(env,AVR_FEATURE_BREAK);
+
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env,AVR_FEATURE_LPMX);
+avr_set_feature(env,AVR_FEATURE_MOVW);
+}
+
+static void avr_avr3_initfn(
+Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState*env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env,AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env,AVR_FEATURE_SRAM);
+avr_set_feature(env,AVR_FEATURE_BREAK);
+
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env,AVR_FEATURE_JMP_CALL);
+}
+
+static void avr_avr31_initfn(
+Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState*env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env,AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env,AVR_FEATURE_SRAM);
+avr_set_feature(env,AVR_FEATURE_BREAK);
+
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env,AVR_FEATURE_RAMPZ);
+avr_set_feature(env,AVR_FEATURE_ELPM);
+avr_set_feature(env,AVR_FEATURE_JMP_CALL);
+}
+
+static void avr_avr35_initfn(
+Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState*env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env,AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env,AVR_FEATURE_SRAM);
+avr_set_feature(env,AVR_FEATURE_BREAK);
+
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env,AVR_FEATURE_JMP_CALL);
+avr_set_feature(env,AVR_FEATURE_LPMX);
+avr_set_feature(env,AVR_FEATURE_MOVW);
+}
+
+static void avr_avr4_initfn(
+Object 

[Qemu-devel] [PATCH 06/10] target-avr: adding helpers for IN, OUT, SLEEP, WBR & unsupported instructions

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/helper.c | 103 
 target-avr/helper.h |   5 +++
 2 files changed, 108 insertions(+)

diff --git a/target-avr/helper.c b/target-avr/helper.c
index ed22b37..450f598 100644
--- a/target-avr/helper.c
+++ b/target-avr/helper.c
@@ -155,6 +155,23 @@ voidtlb_fill(
 
 tlb_set_page_with_attrs(cs, vaddr, paddr, attrs, prot, mmu_idx, page_size);
 }
+voidhelper_sleep(
+CPUAVRState*env)
+{
+CPUState   *cs = CPU(avr_env_get_cpu(env));
+
+cs->exception_index = EXCP_HLT;
+cpu_loop_exit(cs);
+}
+voidhelper_unsupported(
+CPUAVRState*env)
+{
+CPUState   *cs = CPU(avr_env_get_cpu(env));
+
+cs->exception_index = EXCP_DEBUG;
+cpu_dump_state(cs, stderr, fprintf, 0);
+cpu_loop_exit(cs);
+}
 
 voidhelper_debug(
 CPUAVRState*env)
@@ -165,3 +182,89 @@ voidhelper_debug(
 cpu_loop_exit(cs);
 }
 
+voidhelper_wdr(
+CPUAVRState*env)
+{
+CPUState   *cs = CPU(avr_env_get_cpu(env));
+
+cs->exception_index = EXCP_DEBUG;
+cpu_loop_exit(cs);
+}
+
+target_ulonghelper_inb(
+CPUAVRState*env,
+uint32_tport)
+{
+printf("in: io[%02x]\n", port);
+
+switch (port) {
+case0x3b: {
+return  env->rampZ; /*  RAMPZ */
+}
+case0x3d: { /*  SPL */
+return  env->sp & 0x00ff;
+}
+case0x3e: { /*  SPH */
+return  env->sp >> 8;
+}
+case0x3f: { /*  SREG */
+uint8_t sreg;
+sreg=   (env->sregC & 0x01) << 0
+|   (env->sregZ & 0x01) << 1
+|   (env->sregN & 0x01) << 2
+|   (env->sregV & 0x01) << 3
+|   (env->sregS & 0x01) << 4
+|   (env->sregH & 0x01) << 5
+|   (env->sregT & 0x01) << 6
+|   (env->sregI & 0x01) << 7;
+return  sreg;
+}
+}
+return  0;
+}
+
+voidhelper_outb(
+CPUAVRState*env,
+uint32_tport,
+uint32_tdata)
+{
+printf("out:%02x -> io[%02x]\n", data, port);
+
+data&= 0x00ff;
+
+switch (port) {
+case0x04: {
+qemu_irqirq;
+CPUState   *cpu = CPU(avr_env_get_cpu(env));
+irq = qdev_get_gpio_in(DEVICE(cpu), 3);
+qemu_set_irq(irq, 1);
+break;
+}
+case0x3b: {
+env->rampZ  = data & 0x01;  /*  RAMPZ */
+break;
+}
+case0x3d: { /*  SPL */
+if (avr_feature(env, AVR_FEATURE_2_BYTE_SP)) {
+env->sp = (env->sp & 0xff00) | (data);
+}
+break;
+}
+case0x3e: {  /*  SPH */
+env->sp = (env->sp & 0x00ff) | (data << 8);
+break;
+}
+case0x3f: { /*  SREG */
+env->sregC  = (data >> 0) & 0x01;
+env->sregZ  = (data >> 1) & 0x01;
+env->sregN  = (data >> 2) & 0x01;
+env->sregV  = (data >> 3) & 0x01;
+env->sregS  = (data >> 4) & 0x01;
+env->sregH  = (data >> 5) & 0x01;
+env->sregT  = (data >> 6) & 0x01;
+env->sregI  = (data >> 7) & 0x01;
+break;
+}
+}
+}
+
diff --git a/target-avr/helper.h b/target-avr/helper.h
index 017e076..5a08cfd 100644
--- a/target-avr/helper.h
+++ b/target-avr/helper.h
@@ -18,4 +18,9 @@
  * 
  */
 
+DEF_HELPER_1(wdr,   void,   env)
 DEF_HELPER_1(debug, void,   env)
+DEF_HELPER_1(sleep, void,   env)
+DEF_HELPER_1(unsupported,   void,   env)
+DEF_HELPER_3(outb,  void,   env, i32, i32)
+DEF_HELPER_2(inb,   tl, env, i32)
-- 
2.4.9 (Apple Git-60)




[Qemu-devel] [PATCH 05/10] target-avr: adding AVR interrupt handling

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/helper.c | 64 -
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/target-avr/helper.c b/target-avr/helper.c
index aec37af..ed22b37 100644
--- a/target-avr/helper.c
+++ b/target-avr/helper.c
@@ -33,12 +33,74 @@ boolavr_cpu_exec_interrupt(
 CPUState   *cs,
 int interrupt_request)
 {
-return  false;
+CPUClass*cc  = CPU_GET_CLASS(cs);
+AVRCPU  *cpu = AVR_CPU(cs);
+CPUAVRState *env = >env;
+
+boolret = false;
+
+if (interrupt_request & CPU_INTERRUPT_RESET) {
+if (cpu_interrupts_enabled(env)) {
+cs->exception_index = EXCP_RESET;
+cc->do_interrupt(cs);
+
+cs->interrupt_request   &= ~CPU_INTERRUPT_RESET;
+
+ret = true;
+}
+}
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+if (cpu_interrupts_enabled(env) && env->intsrc != 0) {
+int index   = __builtin_ffs(env->intsrc) - 1;
+cs->exception_index = EXCP_INT(index);
+cc->do_interrupt(cs);
+
+env->intsrc &= env->intsrc - 1; /* clear the interrupt 
*/
+cs->interrupt_request   &= ~CPU_INTERRUPT_HARD;
+
+ret = true;
+}
+}
+return ret;
 }
 
 voidavr_cpu_do_interrupt(
 CPUState   *cs)
 {
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState*env = >env;
+
+uint32_tret = env->pc;
+int vector;
+int size= avr_feature(env, AVR_FEATURE_JMP_CALL) ? 2 : 1;
+int base= 0;/* TODO: where to get it */
+
+if (cs->exception_index == EXCP_RESET) {
+vector  = 0;
+} else if (env->intsrc != 0) {
+vector  = __builtin_ffs(env->intsrc);
+}
+
+if (avr_feature(env, AVR_FEATURE_3_BYTE_PC)) {
+stb_phys(cs->as, env->sp--, (ret & 0xff));
+stb_phys(cs->as, env->sp--, (ret & 0x00ff00) >>  8);
+stb_phys(cs->as, env->sp--, (ret & 0xff) >> 16);
+
+env->pc = base + vector * size;
+} else if (avr_feature(env, AVR_FEATURE_2_BYTE_PC)) {
+stb_phys(cs->as, env->sp--, (ret & 0xff));
+stb_phys(cs->as, env->sp--, (ret & 0x00ff00) >>  8);
+
+env->pc = base + vector * size;
+} else {
+stb_phys(cs->as, env->sp--, (ret & 0xff));
+
+env->pc = base + vector * size;
+}
+
+env->sregI  = 0;/*  clear Global Interrupt Flag */
+
+cs->exception_index = -1;
 }
 
 int avr_cpu_memory_rw_debug(
-- 
2.4.9 (Apple Git-60)




Re: [Qemu-devel] [PATCH 2/4] 9p: introduce the V9fsDir type

2016-06-02 Thread Eric Blake
On 06/02/2016 02:52 AM, Greg Kurz wrote:
> If we are to switch back to readdir(), we need a more complex type than
> DIR * to be able to serialize concurrent accesses to the directory stream.
> 
> This patch introduces a placeholder type and fixes all users.
> 
> Signed-off-by: Greg Kurz 
> ---
>  hw/9pfs/9p-handle.c |   18 +-
>  hw/9pfs/9p-local.c  |   18 +-
>  hw/9pfs/9p-proxy.c  |   20 ++--
>  hw/9pfs/9p.c|   12 ++--
>  hw/9pfs/9p.h|6 +-
>  5 files changed, 39 insertions(+), 35 deletions(-)
> 

Reviewed-by: Eric Blake 

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH 01/10] target-avr: AVR cores support is added. 1. basic CPU structure 2. registers 3. no instructions

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 arch_init.c |   2 +
 configure   |   5 +
 default-configs/avr-softmmu.mak |   1 +
 disas/Makefile.objs |   1 +
 disas/avr.c |  10 ++
 include/disas/bfd.h |   7 +
 include/sysemu/arch_init.h  |   1 +
 target-avr/Makefile.objs|   3 +
 target-avr/cpu-qom.h|  97 +
 target-avr/cpu.c| 315 
 target-avr/cpu.h| 152 +++
 target-avr/gdbstub.c| 105 ++
 target-avr/helper.c | 105 ++
 target-avr/helper.h |  21 +++
 target-avr/machine.c|  54 +++
 target-avr/machine.h|  21 +++
 target-avr/translate.c  | 300 ++
 17 files changed, 1200 insertions(+)
 create mode 100644 default-configs/avr-softmmu.mak
 create mode 100644 disas/avr.c
 create mode 100644 target-avr/Makefile.objs
 create mode 100644 target-avr/cpu-qom.h
 create mode 100644 target-avr/cpu.c
 create mode 100644 target-avr/cpu.h
 create mode 100644 target-avr/gdbstub.c
 create mode 100644 target-avr/helper.c
 create mode 100644 target-avr/helper.h
 create mode 100644 target-avr/machine.c
 create mode 100644 target-avr/machine.h
 create mode 100644 target-avr/translate.c

diff --git a/arch_init.c b/arch_init.c
index fa05973..be6e6de 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -80,6 +80,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_UNICORE32
 #elif defined(TARGET_TRICORE)
 #define QEMU_ARCH QEMU_ARCH_TRICORE
+#elif defined(TARGET_AVR)
+#define QEMU_ARCH QEMU_ARCH_AVR
 #endif
 
 const uint32_t arch_type = QEMU_ARCH;
diff --git a/configure b/configure
index b5aab72..90af399 100755
--- a/configure
+++ b/configure
@@ -5630,6 +5630,8 @@ case "$target_name" in
   x86_64)
 TARGET_BASE_ARCH=i386
   ;;
+  avr)
+  ;;
   alpha)
   ;;
   arm|armeb)
@@ -5826,6 +5828,9 @@ disas_config() {
 
 for i in $ARCH $TARGET_BASE_ARCH ; do
   case "$i" in
+  avr)
+disas_config "AVR"
+  ;;
   alpha)
 disas_config "ALPHA"
   ;;
diff --git a/default-configs/avr-softmmu.mak b/default-configs/avr-softmmu.mak
new file mode 100644
index 000..ca94aad
--- /dev/null
+++ b/default-configs/avr-softmmu.mak
@@ -0,0 +1 @@
+# Default configuration for avr-softmmu
diff --git a/disas/Makefile.objs b/disas/Makefile.objs
index abeba84..218e434 100644
--- a/disas/Makefile.objs
+++ b/disas/Makefile.objs
@@ -21,6 +21,7 @@ common-obj-$(CONFIG_S390_DIS) += s390.o
 common-obj-$(CONFIG_SH4_DIS) += sh4.o
 common-obj-$(CONFIG_SPARC_DIS) += sparc.o
 common-obj-$(CONFIG_LM32_DIS) += lm32.o
+common-obj-$(CONFIG_AVR_DIS) += avr.o
 
 # TODO: As long as the TCG interpreter and its generated code depend
 # on the QEMU target, we cannot compile the disassembler here.
diff --git a/disas/avr.c b/disas/avr.c
new file mode 100644
index 000..f916e72
--- /dev/null
+++ b/disas/avr.c
@@ -0,0 +1,10 @@
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "disas/bfd.h"
+
+int print_insn_avr(bfd_vma addr, disassemble_info *info)
+{
+int length  = 0;;
+/*  TODO*/
+return length;
+}
diff --git a/include/disas/bfd.h b/include/disas/bfd.h
index a112e9c..04e2201 100644
--- a/include/disas/bfd.h
+++ b/include/disas/bfd.h
@@ -213,6 +213,12 @@ enum bfd_architecture
 #define bfd_mach_m32r  0  /* backwards compatibility */
   bfd_arch_mn10200,/* Matsushita MN10200 */
   bfd_arch_mn10300,/* Matsushita MN10300 */
+  bfd_arch_avr,   /* Atmel AVR microcontrollers.  */
+#define bfd_mach_avr1  1
+#define bfd_mach_avr2  2
+#define bfd_mach_avr3  3
+#define bfd_mach_avr4  4
+#define bfd_mach_avr5  5
   bfd_arch_cris,   /* Axis CRIS */
 #define bfd_mach_cris_v0_v10   255
 #define bfd_mach_cris_v32  32
@@ -415,6 +421,7 @@ int print_insn_crisv10  (bfd_vma, 
disassemble_info*);
 int print_insn_microblaze   (bfd_vma, disassemble_info*);
 int print_insn_ia64 (bfd_vma, disassemble_info*);
 int print_insn_lm32 (bfd_vma, disassemble_info*);
+int print_insn_avr  (bfd_vma, disassemble_info*);
 
 #if 0
 /* Fetch the disassembler for a given BFD, if that support is available.  */
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index d690dfa..8c75777 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -23,6 +23,7 @@ enum {
 QEMU_ARCH_UNICORE32 = (1 << 14),
 QEMU_ARCH_MOXIE = (1 << 15),
 QEMU_ARCH_TRICORE = (1 << 16),
+QEMU_ARCH_AVR = (1 << 17),
 };
 
 extern const uint32_t arch_type;
diff --git a/target-avr/Makefile.objs b/target-avr/Makefile.objs
new file mode 100644
index 000..c503546
--- /dev/null
+++ b/target-avr/Makefile.objs
@@ -0,0 +1,3 @@
+obj-y   += translate.o cpu.o helper.o
+obj-y   += gdbstub.o
+obj-$(CONFIG_SOFTMMU) += machine.o
diff 

[Qemu-devel] [PATCH 08/10] target-avr: adding instruction translation

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/translate-inst.c | 2443 +++
 target-avr/translate.h  |  123 +++
 2 files changed, 2566 insertions(+)
 create mode 100644 target-avr/translate-inst.c
 create mode 100644 target-avr/translate.h

diff --git a/target-avr/translate-inst.c b/target-avr/translate-inst.c
new file mode 100644
index 000..fe9d9fc
--- /dev/null
+++ b/target-avr/translate-inst.c
@@ -0,0 +1,2443 @@
+/*
+ *  QEMU AVR CPU
+ *
+ *  Copyright (c) 2016 Michael Rolnik
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, see
+ *  
+ */
+
+#include "translate.h"
+#include "translate-inst.h"
+
+/*
+NOTE:   all registers are assumed to hold 8 bit values.
+so all operations done on registers should preseve this property
+*/
+
+/*
+NOTE:   the flags C,H,V,N,V have either 0 or 1 values
+NOTE:   the flag Z has inverse logic, when the value of Zf is 0 the flag 
is assumed to be set, non zero - not set
+*/
+
+voidgen_add_CHf(TCGv R, TCGv Rd, TCGv Rr);
+voidgen_add_Vf(TCGv R, TCGv Rd, TCGv Rr);
+voidgen_sub_CHf(TCGv R, TCGv Rd, TCGv Rr);
+voidgen_sub_Vf(TCGv R, TCGv Rd, TCGv Rr);
+voidgen_ZNSf(TCGv R);
+voidgen_push_ret(CPUAVRState *env, intret);
+voidgen_pop_ret(CPUAVRState *env, TCGvret);
+voidgen_jmp_ez(void);
+voidgen_jmp_z(void);
+
+voidgen_set_addr(TCGv addr, TCGv H, TCGv M, TCGv l); /*  H:M:L   = addr  */
+voidgen_set_xaddr(TCGv addr);
+voidgen_set_yaddr(TCGv addr);
+voidgen_set_zaddr(TCGv addr);
+
+TCGvgen_get_addr(TCGv H, TCGv M, TCGv L);/*  addr = H:M:L*/
+TCGvgen_get_xaddr(void);
+TCGvgen_get_yaddr(void);
+TCGvgen_get_zaddr(void);
+int sex(int Imm, unsigned bits);
+
+voidgen_add_CHf(TCGv R, TCGv Rd, TCGv Rr)
+{
+TCGvt1  = tcg_temp_new_i32();
+TCGvt2  = tcg_temp_new_i32();
+TCGvt3  = tcg_temp_new_i32();
+
+tcg_gen_and_tl(t1, Rd, Rr);/*  t1  = Rd & Rr  */
+tcg_gen_not_tl(t2, R); /*  t2  = Rd & ~R  */
+tcg_gen_and_tl(t2, Rd, t2);
+tcg_gen_not_tl(t3, R); /*  t3  = Rr  *~R  */
+tcg_gen_and_tl(t3, Rr, t3);
+tcg_gen_or_tl(t1, t1, t2);/*  t1  = t1 | t2 | t3  */
+tcg_gen_or_tl(t1, t1, t3);
+
+tcg_gen_shri_tl(cpu_Cf, t1, 7); /*  Cf  = t1(7)  */
+tcg_gen_shri_tl(cpu_Hf, t1, 3); /*  Hf  = t1(3)  */
+tcg_gen_andi_tl(cpu_Hf, cpu_Hf, 1);
+
+tcg_temp_free_i32(t3);
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t1);
+}
+
+voidgen_add_Vf(TCGvR, TCGvRd, TCGvRr)
+{
+TCGvt1  = tcg_temp_new_i32();
+TCGvt2  = tcg_temp_new_i32();
+
+tcg_gen_not_tl(t1, Rd);/*  t1  = ~Rd & ~Rr & R  */
+tcg_gen_not_tl(t2, Rr);
+tcg_gen_and_tl(t1, t1, t2);
+tcg_gen_and_tl(t1, t1, R);
+
+tcg_gen_not_tl(t2, R); /*  t2  = Rd & Rr & ~R  */
+tcg_gen_and_tl(t2, t2, Rd);
+tcg_gen_and_tl(t2, t2, Rr);
+
+tcg_gen_or_tl(t1, t1, t2);/*  t1  = Rd & Rr & ~R | ~Rd & ~Rr & R  */
+
+tcg_gen_shri_tl(cpu_Vf, t1, 7); /*  Vf  = t1(7)  */
+
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t1);
+}
+
+voidgen_sub_CHf(TCGvR, TCGvRd, TCGvRr)
+{
+TCGvt1  = tcg_temp_new_i32();
+TCGvt2  = tcg_temp_new_i32();
+TCGvt3  = tcg_temp_new_i32();
+
+/*  Cf & Hf  */
+tcg_gen_not_tl(t1, Rd);/*  t1  = ~Rd  */
+tcg_gen_and_tl(t2, t1, Rr);/*  t2  = ~Rd & Rr  */
+tcg_gen_or_tl(t3, t1, Rr);/*  t3  = (~Rd | Rr) & R  */
+tcg_gen_and_tl(t3, t3, R);
+tcg_gen_or_tl(t2, t2, t3);/*  t2  = ~Rd & Rr | ~Rd & R | R & Rr  */
+tcg_gen_shri_tl(cpu_Cf, t2, 7); /*  Cf  = t2(7)  */
+tcg_gen_shri_tl(cpu_Hf, t2, 3); /*  Hf  = t2(3)  */
+tcg_gen_andi_tl(cpu_Hf, cpu_Hf, 1);
+
+tcg_temp_free_i32(t3);
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t1);
+}
+
+voidgen_sub_Vf(TCGvR, TCGvRd, TCGvRr)
+{
+TCGvt1  = tcg_temp_new_i32();
+TCGvt2  = tcg_temp_new_i32();
+
+/*  Vf  */
+tcg_gen_and_tl(t1, Rr, R); /*  t1  = Rd & ~Rr & ~R  */
+tcg_gen_not_tl(t1, t1);
+tcg_gen_and_tl(t1, t1, Rd);
+tcg_gen_not_tl(t2, Rd);/*  t2  = ~Rd & Rr & R  */
+

[Qemu-devel] [PATCH 07/10] target-avr: adding instruction decoder

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/decode.c | 724 
 1 file changed, 724 insertions(+)
 create mode 100644 target-avr/decode.c

diff --git a/target-avr/decode.c b/target-avr/decode.c
new file mode 100644
index 000..22e2d36
--- /dev/null
+++ b/target-avr/decode.c
@@ -0,0 +1,724 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2016 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+
+#include 
+#include "translate.h"
+
+
+uint32_tavr_decode(uint32_t pc, uint32_t *length, uint32_t code, 
translate_function_t *translate)
+{
+uint32_topcode  = extract32(code, 0, 16);
+switch (opcode & 0xd000) {
+case0x: {
+uint32_topcode  = extract32(code, 0, 16);
+switch (opcode & 0x2c00) {
+case0x: {
+uint32_topcode  = extract32(code, 0, 16);
+switch (opcode & 0x0300) {
+case0x: {
+*length = 16;
+*translate = 
(translate_function_t)_translate_NOP;
+break;
+}
+case0x0100: {
+*length = 16;
+*translate = 
(translate_function_t)_translate_MOVW;
+break;
+}
+case0x0200: {
+*length = 16;
+*translate = 
(translate_function_t)_translate_MULS;
+break;
+}
+case0x0300: {
+uint32_topcode  = extract32(code, 0, 16);
+switch (opcode & 0x0088) {
+case0x: {
+*length = 16;
+*translate = 
(translate_function_t)_translate_MULSU;
+break;
+}
+case0x0008: {
+*length = 16;
+*translate = 
(translate_function_t)_translate_FMUL;
+break;
+}
+case0x0080: {
+*length = 16;
+*translate = 
(translate_function_t)_translate_FMULS;
+break;
+}
+case0x0088: {
+*length = 16;
+*translate = 
(translate_function_t)_translate_FMULSU;
+break;
+}
+}
+break;
+}
+}
+break;
+}
+case0x0400: {
+*length = 16;
+*translate = (translate_function_t)_translate_CPC;
+break;
+}
+case0x0800: {
+*length = 16;
+*translate = (translate_function_t)_translate_SBC;
+break;
+}
+case0x0c00: {
+*length = 16;
+*translate = (translate_function_t)_translate_ADD;
+break;
+}
+case0x2000: {
+*length = 16;
+*translate = (translate_function_t)_translate_AND;
+break;
+}
+case0x2400: {
+*length = 16;
+*translate = (translate_function_t)_translate_EOR;
+break;
+}
+case0x2800: {
+*length = 16;
+*translate = (translate_function_t)_translate_OR;
+break;
+}
+case   

[Qemu-devel] [PATCH 04/10] target-avr: adding instructions encodings

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/translate-inst.h | 838 
 1 file changed, 838 insertions(+)
 create mode 100644 target-avr/translate-inst.h

diff --git a/target-avr/translate-inst.h b/target-avr/translate-inst.h
new file mode 100644
index 000..6bd180d
--- /dev/null
+++ b/target-avr/translate-inst.h
@@ -0,0 +1,838 @@
+
+#ifndef AVR_TRANSLATE_INST_H_
+#define AVR_TRANSLATE_INST_H_
+
+typedef struct DisasContextDisasContext;
+
+int avr_translate_NOP(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+
+int avr_translate_MOVW(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t MOVW_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t MOVW_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 4);
+}
+
+int avr_translate_MULS(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t MULS_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t MULS_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 4);
+}
+
+int avr_translate_MULSU(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t MULSU_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+static inline uint32_t MULSU_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+int avr_translate_FMUL(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t FMUL_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+static inline uint32_t FMUL_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+int avr_translate_FMULS(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t FMULS_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+static inline uint32_t FMULS_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+int avr_translate_FMULSU(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t FMULSU_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+static inline uint32_t FMULSU_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+int avr_translate_CPC(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t CPC_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t CPC_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t CPC_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_SBC(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t SBC_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t SBC_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t SBC_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_ADD(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t ADD_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t ADD_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t ADD_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_AND(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t AND_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t AND_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t AND_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_EOR(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t EOR_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t EOR_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t EOR_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_OR(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t OR_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t OR_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t OR_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_MOV(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t MOV_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t MOV_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+static inline uint32_t MOV_hRr(uint32_t opcode)
+{
+return extract32(opcode, 9, 1);
+}
+
+int avr_translate_CPSE(CPUAVRState *env, DisasContext* ctx, uint32_t 
opcode);
+static inline uint32_t CPSE_lRr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+static inline uint32_t CPSE_Rd(uint32_t opcode)
+{
+return 

[Qemu-devel] [PATCH 02/10] target-avr: adding AVR CPU features/flavors

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/cpu.c | 326 ++-
 target-avr/cpu.h |  59 ++
 2 files changed, 383 insertions(+), 2 deletions(-)

diff --git a/target-avr/cpu.c b/target-avr/cpu.c
index ff26018..9be0a1d 100644
--- a/target-avr/cpu.c
+++ b/target-avr/cpu.c
@@ -31,7 +31,7 @@ static void avr_cpu_set_pc(
 {
 AVRCPU   *cpu = AVR_CPU(cs);
 
-cpu->env.pc = value / 2;/*  internaly PC points to words, not bytes */
+cpu->env.pc = value / 2;/*  internally PC points to words   */
 }
 
 static bool avr_cpu_has_work(
@@ -52,7 +52,7 @@ static void avr_cpu_synchronize_from_tb(
 AVRCPU  *cpu = AVR_CPU(cs);
 CPUAVRState *env = >env;
 
-env->pc = tb->pc / 2;
+env->pc = tb->pc / 2;   /*  internally PC points to words   */
 }
 
 static void avr_cpu_reset(
@@ -61,12 +61,14 @@ static void avr_cpu_reset(
 AVRCPU *cpu = AVR_CPU(s);
 AVRCPUClass*mcc = AVR_CPU_GET_CLASS(cpu);
 CPUAVRState*env = >env;
+uint32_tfeatures= env->features;
 
 mcc->parent_reset(s);
 
 memset(env, 0, sizeof(CPUAVRState));
 env->pc = 0;
 env->sregI  = 1;
+env->features   = features;
 
 tlb_flush(s, 1);
 }
@@ -206,6 +208,311 @@ static void avr_cpu_class_init(
 = true;
 }
 
+static void avr_avr1_initfn(
+Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState*env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+}
+static void avr_avr2_initfn(
+Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState*env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env,AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env,AVR_FEATURE_SRAM);
+avr_set_feature(env,AVR_FEATURE_BREAK);
+
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+}
+
+static void avr_avr25_initfn(
+Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState*env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env,AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env,AVR_FEATURE_SRAM);
+avr_set_feature(env,AVR_FEATURE_BREAK);
+
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env,AVR_FEATURE_LPMX);
+avr_set_feature(env,AVR_FEATURE_MOVW);
+}
+
+static void avr_avr3_initfn(
+Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState*env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env,AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env,AVR_FEATURE_SRAM);
+avr_set_feature(env,AVR_FEATURE_BREAK);
+
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env,AVR_FEATURE_JMP_CALL);
+}
+
+static void avr_avr31_initfn(
+Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState*env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env,AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env,AVR_FEATURE_SRAM);
+avr_set_feature(env,AVR_FEATURE_BREAK);
+
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env,AVR_FEATURE_RAMPZ);
+avr_set_feature(env,AVR_FEATURE_ELPM);
+avr_set_feature(env,AVR_FEATURE_JMP_CALL);
+}
+
+static void avr_avr35_initfn(
+Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState*env = >env;
+
+avr_set_feature(env,AVR_FEATURE_LPM);
+avr_set_feature(env,AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env,AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env,AVR_FEATURE_SRAM);
+avr_set_feature(env,AVR_FEATURE_BREAK);
+
+avr_set_feature(env,AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env,AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env,AVR_FEATURE_JMP_CALL);
+avr_set_feature(env,AVR_FEATURE_LPMX);
+avr_set_feature(env,AVR_FEATURE_MOVW);
+}
+
+static void avr_avr4_initfn(
+Object 

[Qemu-devel] [PATCH 09/10] target-avr: updating translate.c to use instructions translation

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/Makefile.objs |   4 +-
 target-avr/translate.c   | 148 ++-
 2 files changed, 72 insertions(+), 80 deletions(-)

diff --git a/target-avr/Makefile.objs b/target-avr/Makefile.objs
index c503546..8d06d54 100644
--- a/target-avr/Makefile.objs
+++ b/target-avr/Makefile.objs
@@ -1,3 +1,5 @@
-obj-y   += translate.o cpu.o helper.o
+obj-y   += translate.o helper.o cpu.o translate-inst.o
 obj-y   += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += machine.o
+
+obj-y   += decode.o
diff --git a/target-avr/translate.c b/target-avr/translate.c
index e98aaef..0df0184 100644
--- a/target-avr/translate.c
+++ b/target-avr/translate.c
@@ -18,60 +18,31 @@
  *  
  */
 
-#include "qemu/osdep.h"
-
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "disas/disas.h"
-#include "tcg-op.h"
-#include "exec/cpu_ldst.h"
-
-#include "exec/helper-proto.h"
-#include "exec/helper-gen.h"
-#include "exec/log.h"
-
-typedef struct DisasContext DisasContext;
-typedef struct InstInfo InstInfo;
-
-/*This is the state at translation time.  */
-struct DisasContext {
-struct TranslationBlock*tb;
-
-/*Routine used to access memory */
-int memidx;
-int bstate;
-int singlestep;
-};
-
-enum {
-BS_NONE = 0,/*  Nothing special (none of the below  */
-BS_STOP = 1,/*  We want to stop translation for any reason  */
-BS_BRANCH   = 2,/*  A branch condition is reached   */
-BS_EXCP = 3,/*  An exception condition is reached   */
-};
-
-static TCGv_env cpu_env;
-
-static TCGv cpu_pc;
-
-static TCGv cpu_Cf;
-static TCGv cpu_Zf;
-static TCGv cpu_Nf;
-static TCGv cpu_Vf;
-static TCGv cpu_Sf;
-static TCGv cpu_Hf;
-static TCGv cpu_Tf;
-static TCGv cpu_If;
-
-static TCGv cpu_rampD;
-static TCGv cpu_rampX;
-static TCGv cpu_rampY;
-static TCGv cpu_rampZ;
-
-static TCGv cpu_io[64];
-static TCGv cpu_r[32];
-static TCGv cpu_eind;
-static TCGv cpu_sp;
+#include "translate.h"
+
+
+TCGv_env cpu_env;
+
+TCGv cpu_pc;
+
+TCGv cpu_Cf;
+TCGv cpu_Zf;
+TCGv cpu_Nf;
+TCGv cpu_Vf;
+TCGv cpu_Sf;
+TCGv cpu_Hf;
+TCGv cpu_Tf;
+TCGv cpu_If;
+
+TCGv cpu_rampD;
+TCGv cpu_rampX;
+TCGv cpu_rampY;
+TCGv cpu_rampZ;
+
+TCGv cpu_io[64];
+TCGv cpu_r[32];
+TCGv cpu_eind;
+TCGv cpu_sp;
 
 #include "exec/gen-icount.h"
 #define REG(x)  (cpu_r[x])
@@ -120,30 +91,42 @@ voidavr_translate_init(void)
 done_init = 1;
 }
 
-static inline void  gen_goto_tb(CPUAVRState*env,
-DisasContext   *ctx,
-int n,
-target_ulongdest)
+static void decode_opc(
+AVRCPU *cpu,
+DisasContext   *ctx,
+InstInfo   *inst)
 {
-TranslationBlock   *tb;
+CPUAVRState*env = >env;
 
-tb  = ctx->tb;
+inst->opcode= cpu_ldl_code(env, inst->cpc * 2);   /*  pc points to 
words*/
+inst->length= 16;
+inst->translate = NULL;
 
-if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)
-&&  (ctx->singlestep == 0)) {
-tcg_gen_goto_tb(n);
-tcg_gen_movi_i32(cpu_pc, dest);
-tcg_gen_exit_tb((uintptr_t)tb + n);
-} else {
-tcg_gen_movi_i32(cpu_pc, dest);
+/*  the following function looks onto the opcode as a string of bytes   */
+avr_decode(inst->cpc, >length, inst->opcode, >translate);
 
-if (ctx->singlestep) {
-gen_helper_debug(cpu_env);
-}
-tcg_gen_exit_tb(0);
+if (inst->length == 16) {
+inst->npc= inst->cpc + 1;
+/*  get opcode as 16bit value   */
+inst->opcode = inst->opcode & 0x;
+}
+if (inst->length == 32) {
+inst->npc= inst->cpc + 2;
+/*  get opcode as 32bit value   */
+inst->opcode = (inst->opcode << 16)
+ | (inst->opcode >> 16);
 }
 }
 
+uint32_tget_opcode(
+uint8_t const  *code,
+unsignedbitBase,
+unsignedbitSize)
+{
+return  *(uint16_t *)code;
+}
+
+
 /*generate intermediate code for basic block 'tb'.  */
 voidgen_intermediate_code(
 CPUAVRState*env,
@@ -176,18 +159,21 @@ voidgen_intermediate_code(
 gen_tb_start(tb);
 
 /*  decode first instruction*/
-cpc = pc_start;
-npc = cpc + 1;
+ctx.inst[0].cpc = pc_start;
+decode_opc(cpu, , 

[Qemu-devel] [PATCH 06/10] target-avr: adding helpers for IN, OUT, SLEEP, WBR & unsupported instructions

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 target-avr/helper.c | 103 
 target-avr/helper.h |   5 +++
 2 files changed, 108 insertions(+)

diff --git a/target-avr/helper.c b/target-avr/helper.c
index ed22b37..450f598 100644
--- a/target-avr/helper.c
+++ b/target-avr/helper.c
@@ -155,6 +155,23 @@ voidtlb_fill(
 
 tlb_set_page_with_attrs(cs, vaddr, paddr, attrs, prot, mmu_idx, page_size);
 }
+voidhelper_sleep(
+CPUAVRState*env)
+{
+CPUState   *cs = CPU(avr_env_get_cpu(env));
+
+cs->exception_index = EXCP_HLT;
+cpu_loop_exit(cs);
+}
+voidhelper_unsupported(
+CPUAVRState*env)
+{
+CPUState   *cs = CPU(avr_env_get_cpu(env));
+
+cs->exception_index = EXCP_DEBUG;
+cpu_dump_state(cs, stderr, fprintf, 0);
+cpu_loop_exit(cs);
+}
 
 voidhelper_debug(
 CPUAVRState*env)
@@ -165,3 +182,89 @@ voidhelper_debug(
 cpu_loop_exit(cs);
 }
 
+voidhelper_wdr(
+CPUAVRState*env)
+{
+CPUState   *cs = CPU(avr_env_get_cpu(env));
+
+cs->exception_index = EXCP_DEBUG;
+cpu_loop_exit(cs);
+}
+
+target_ulonghelper_inb(
+CPUAVRState*env,
+uint32_tport)
+{
+printf("in: io[%02x]\n", port);
+
+switch (port) {
+case0x3b: {
+return  env->rampZ; /*  RAMPZ */
+}
+case0x3d: { /*  SPL */
+return  env->sp & 0x00ff;
+}
+case0x3e: { /*  SPH */
+return  env->sp >> 8;
+}
+case0x3f: { /*  SREG */
+uint8_t sreg;
+sreg=   (env->sregC & 0x01) << 0
+|   (env->sregZ & 0x01) << 1
+|   (env->sregN & 0x01) << 2
+|   (env->sregV & 0x01) << 3
+|   (env->sregS & 0x01) << 4
+|   (env->sregH & 0x01) << 5
+|   (env->sregT & 0x01) << 6
+|   (env->sregI & 0x01) << 7;
+return  sreg;
+}
+}
+return  0;
+}
+
+voidhelper_outb(
+CPUAVRState*env,
+uint32_tport,
+uint32_tdata)
+{
+printf("out:%02x -> io[%02x]\n", data, port);
+
+data&= 0x00ff;
+
+switch (port) {
+case0x04: {
+qemu_irqirq;
+CPUState   *cpu = CPU(avr_env_get_cpu(env));
+irq = qdev_get_gpio_in(DEVICE(cpu), 3);
+qemu_set_irq(irq, 1);
+break;
+}
+case0x3b: {
+env->rampZ  = data & 0x01;  /*  RAMPZ */
+break;
+}
+case0x3d: { /*  SPL */
+if (avr_feature(env, AVR_FEATURE_2_BYTE_SP)) {
+env->sp = (env->sp & 0xff00) | (data);
+}
+break;
+}
+case0x3e: {  /*  SPH */
+env->sp = (env->sp & 0x00ff) | (data << 8);
+break;
+}
+case0x3f: { /*  SREG */
+env->sregC  = (data >> 0) & 0x01;
+env->sregZ  = (data >> 1) & 0x01;
+env->sregN  = (data >> 2) & 0x01;
+env->sregV  = (data >> 3) & 0x01;
+env->sregS  = (data >> 4) & 0x01;
+env->sregH  = (data >> 5) & 0x01;
+env->sregT  = (data >> 6) & 0x01;
+env->sregI  = (data >> 7) & 0x01;
+break;
+}
+}
+}
+
diff --git a/target-avr/helper.h b/target-avr/helper.h
index 017e076..5a08cfd 100644
--- a/target-avr/helper.h
+++ b/target-avr/helper.h
@@ -18,4 +18,9 @@
  * 
  */
 
+DEF_HELPER_1(wdr,   void,   env)
 DEF_HELPER_1(debug, void,   env)
+DEF_HELPER_1(sleep, void,   env)
+DEF_HELPER_1(unsupported,   void,   env)
+DEF_HELPER_3(outb,  void,   env, i32, i32)
+DEF_HELPER_2(inb,   tl, env, i32)
-- 
2.4.9 (Apple Git-60)




[Qemu-devel] [PATCH 01/10] target-avr: AVR cores support is added. 1. basic CPU structure 2. registers 3. no instructions

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 arch_init.c |   2 +
 configure   |   5 +
 default-configs/avr-softmmu.mak |   1 +
 disas/Makefile.objs |   1 +
 disas/avr.c |  10 ++
 include/disas/bfd.h |   7 +
 include/sysemu/arch_init.h  |   1 +
 target-avr/Makefile.objs|   3 +
 target-avr/cpu-qom.h|  97 +
 target-avr/cpu.c| 315 
 target-avr/cpu.h| 152 +++
 target-avr/gdbstub.c| 105 ++
 target-avr/helper.c | 105 ++
 target-avr/helper.h |  21 +++
 target-avr/machine.c|  54 +++
 target-avr/machine.h|  21 +++
 target-avr/translate.c  | 300 ++
 17 files changed, 1200 insertions(+)
 create mode 100644 default-configs/avr-softmmu.mak
 create mode 100644 disas/avr.c
 create mode 100644 target-avr/Makefile.objs
 create mode 100644 target-avr/cpu-qom.h
 create mode 100644 target-avr/cpu.c
 create mode 100644 target-avr/cpu.h
 create mode 100644 target-avr/gdbstub.c
 create mode 100644 target-avr/helper.c
 create mode 100644 target-avr/helper.h
 create mode 100644 target-avr/machine.c
 create mode 100644 target-avr/machine.h
 create mode 100644 target-avr/translate.c

diff --git a/arch_init.c b/arch_init.c
index fa05973..be6e6de 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -80,6 +80,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_UNICORE32
 #elif defined(TARGET_TRICORE)
 #define QEMU_ARCH QEMU_ARCH_TRICORE
+#elif defined(TARGET_AVR)
+#define QEMU_ARCH QEMU_ARCH_AVR
 #endif
 
 const uint32_t arch_type = QEMU_ARCH;
diff --git a/configure b/configure
index b5aab72..90af399 100755
--- a/configure
+++ b/configure
@@ -5630,6 +5630,8 @@ case "$target_name" in
   x86_64)
 TARGET_BASE_ARCH=i386
   ;;
+  avr)
+  ;;
   alpha)
   ;;
   arm|armeb)
@@ -5826,6 +5828,9 @@ disas_config() {
 
 for i in $ARCH $TARGET_BASE_ARCH ; do
   case "$i" in
+  avr)
+disas_config "AVR"
+  ;;
   alpha)
 disas_config "ALPHA"
   ;;
diff --git a/default-configs/avr-softmmu.mak b/default-configs/avr-softmmu.mak
new file mode 100644
index 000..ca94aad
--- /dev/null
+++ b/default-configs/avr-softmmu.mak
@@ -0,0 +1 @@
+# Default configuration for avr-softmmu
diff --git a/disas/Makefile.objs b/disas/Makefile.objs
index abeba84..218e434 100644
--- a/disas/Makefile.objs
+++ b/disas/Makefile.objs
@@ -21,6 +21,7 @@ common-obj-$(CONFIG_S390_DIS) += s390.o
 common-obj-$(CONFIG_SH4_DIS) += sh4.o
 common-obj-$(CONFIG_SPARC_DIS) += sparc.o
 common-obj-$(CONFIG_LM32_DIS) += lm32.o
+common-obj-$(CONFIG_AVR_DIS) += avr.o
 
 # TODO: As long as the TCG interpreter and its generated code depend
 # on the QEMU target, we cannot compile the disassembler here.
diff --git a/disas/avr.c b/disas/avr.c
new file mode 100644
index 000..f916e72
--- /dev/null
+++ b/disas/avr.c
@@ -0,0 +1,10 @@
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "disas/bfd.h"
+
+int print_insn_avr(bfd_vma addr, disassemble_info *info)
+{
+int length  = 0;;
+/*  TODO*/
+return length;
+}
diff --git a/include/disas/bfd.h b/include/disas/bfd.h
index a112e9c..04e2201 100644
--- a/include/disas/bfd.h
+++ b/include/disas/bfd.h
@@ -213,6 +213,12 @@ enum bfd_architecture
 #define bfd_mach_m32r  0  /* backwards compatibility */
   bfd_arch_mn10200,/* Matsushita MN10200 */
   bfd_arch_mn10300,/* Matsushita MN10300 */
+  bfd_arch_avr,   /* Atmel AVR microcontrollers.  */
+#define bfd_mach_avr1  1
+#define bfd_mach_avr2  2
+#define bfd_mach_avr3  3
+#define bfd_mach_avr4  4
+#define bfd_mach_avr5  5
   bfd_arch_cris,   /* Axis CRIS */
 #define bfd_mach_cris_v0_v10   255
 #define bfd_mach_cris_v32  32
@@ -415,6 +421,7 @@ int print_insn_crisv10  (bfd_vma, 
disassemble_info*);
 int print_insn_microblaze   (bfd_vma, disassemble_info*);
 int print_insn_ia64 (bfd_vma, disassemble_info*);
 int print_insn_lm32 (bfd_vma, disassemble_info*);
+int print_insn_avr  (bfd_vma, disassemble_info*);
 
 #if 0
 /* Fetch the disassembler for a given BFD, if that support is available.  */
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index d690dfa..8c75777 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -23,6 +23,7 @@ enum {
 QEMU_ARCH_UNICORE32 = (1 << 14),
 QEMU_ARCH_MOXIE = (1 << 15),
 QEMU_ARCH_TRICORE = (1 << 16),
+QEMU_ARCH_AVR = (1 << 17),
 };
 
 extern const uint32_t arch_type;
diff --git a/target-avr/Makefile.objs b/target-avr/Makefile.objs
new file mode 100644
index 000..c503546
--- /dev/null
+++ b/target-avr/Makefile.objs
@@ -0,0 +1,3 @@
+obj-y   += translate.o cpu.o helper.o
+obj-y   += gdbstub.o
+obj-$(CONFIG_SOFTMMU) += machine.o
diff 

[Qemu-devel] [PATCH 03/10] target-avr: adding a sample AVR board

2016-06-02 Thread Michael Rolnik
Signed-off-by: Michael Rolnik 
---
 hw/Makefile.objs |   1 +
 hw/avr/Makefile.objs |   1 +
 hw/avr/sample-io.c   | 246 +++
 hw/avr/sample.c  | 120 +
 4 files changed, 368 insertions(+)
 create mode 100644 hw/avr/Makefile.objs
 create mode 100644 hw/avr/sample-io.c
 create mode 100644 hw/avr/sample.c

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 4a07ed4..262ca15 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -33,6 +33,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += watchdog/
 devices-dirs-$(CONFIG_SOFTMMU) += xen/
 devices-dirs-$(CONFIG_MEM_HOTPLUG) += mem/
 devices-dirs-$(CONFIG_SMBIOS) += smbios/
+devices-dirs-$(CONFIG_SOFTMMU) += avr/
 devices-dirs-y += core/
 common-obj-y += $(devices-dirs-y)
 obj-y += $(devices-dirs-y)
diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
new file mode 100644
index 000..9f6be2f
--- /dev/null
+++ b/hw/avr/Makefile.objs
@@ -0,0 +1 @@
+obj-y   += sample.o sample-io.o
diff --git a/hw/avr/sample-io.c b/hw/avr/sample-io.c
new file mode 100644
index 000..133c72f
--- /dev/null
+++ b/hw/avr/sample-io.c
@@ -0,0 +1,246 @@
+/*
+ *  QEMU AVR CPU
+ *
+ *  Copyright (c) 2016 Michael Rolnik
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, see
+ *  
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "include/hw/sysbus.h"
+
+#define TYPE_SAMPLEIO   "SampleIO"
+#define SAMPLEIO(obj)   OBJECT_CHECK(SAMPLEIOState, (obj), TYPE_SAMPLEIO)
+
+#ifndef DEBUG_SAMPLEIO
+#define DEBUG_SAMPLEIO 1
+#endif
+
+#define DPRINTF(fmt, args...) \
+do {  \
+if (DEBUG_SAMPLEIO) { \
+fprintf(stderr, "[%s]%s: " fmt , TYPE_SAMPLEIO, __func__, ##args);\
+} \
+} \
+while (0)
+
+#define AVR_IO_CPU_REGS_SIZE0x0020
+#define AVR_IO_CPU_IO_SIZE  0x0040
+#define AVR_IO_EXTERN_IO_SIZE   0x00a0
+#define AVR_IO_SIZE (AVR_IO_CPU_REGS_SIZE   \
++ AVR_IO_CPU_IO_SIZE\
++ AVR_IO_EXTERN_IO_SIZE)
+
+#define AVR_IO_CPU_REGS_BASE0x
+#define AVR_IO_CPU_IO_BASE  (AVR_IO_CPU_REGS_BASE   \
++ AVR_IO_CPU_REGS_SIZE)
+#define AVR_IO_EXTERN_IO_BASE   (AVR_IO_CPU_IO_BASE \
++ AVR_IO_CPU_IO_SIZE)
+
+
+typedef struct SAMPLEIOState {
+SysBusDeviceparent;
+
+MemoryRegioniomem;
+
+AVRCPU *cpu;
+
+uint8_t io[0x40];
+uint8_t exio[0xa0];
+} SAMPLEIOState;
+
+static uint64_t sample_io_read(
+void   *opaque,
+hwaddr  offset,
+unsignedsize);
+static void sample_io_write(void   *opaque,
+hwaddr  offset,
+uint64_tvalue,
+unsignedsize);
+static int  sample_io_init(
+DeviceState*sbd);
+static void sample_io_class_init(
+ObjectClass*klass,
+void   *data);
+static void sample_io_register_types(void);
+
+static void write_Rx(
+CPUAVRState*env,
+int inst,
+uint8_t data);
+static uint8_t  read_Rx(
+CPUAVRState*env,
+int inst);
+
+static const
+MemoryRegionOps sample_io_ops = {
+.read   = sample_io_read,
+.write  = sample_io_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static
+Propertysample_io_properties[] = {
+DEFINE_PROP_END_OF_LIST(),
+};
+static const

  1   2   3   4   >