Re: [PATCH v4 2/2] nvme: allow cmb and pmr to be enabled on same device

2020-07-07 Thread Andrzej Jakowski
On 7/6/20 12:15 AM, Klaus Jensen wrote:
> On Jul  2 16:33, Andrzej Jakowski wrote:
>> On 7/2/20 10:51 AM, Klaus Jensen wrote:
>>> On Jul  2 08:07, Andrzej Jakowski wrote:
 On 7/2/20 3:31 AM, Klaus Jensen wrote:
> Aight, an update here. This only happens when QEMU is run with a virtual
> IOMMU. Otherwise, the kernel is happy.
>
> With the vIOMMU, qemu also craps out a bit:
>
> qemu-system-x86_64: vtd_iova_to_slpte: detected slpte permission error 
> (iova=0xfd20, level=0x2, slpte=0x0, write=0)
> qemu-system-x86_64: vtd_iommu_translate: detected translation failure 
> (dev=03:00:00, iova=0xfd20)
>
> So I think we are back in QEMU land for the bug.

 Can you share command line for that?


>>>
>>> qemu-system-x86_64 \
>>>   -nodefaults \
>>>   -display none \
>>>   -device intel-iommu,pt,intremap=on,device-iotlb=on \
>>>   -machine type=q35,accel=kvm,kernel_irqchip=split \
>>>   -cpu host \
>>>   -smp 4 \
>>>   -m 8G \
>>>   -nic user,model=virtio-net-pci,hostfwd=tcp::-:22 \
>>>   -device virtio-rng-pci \
>>>   -drive 
>>> id=boot,file=/home/kbj/work/src/vmctl/state/pmr/boot.qcow2,format=qcow2,if=virtio,discard=on,detect-zeroes=unmap
>>>  \
>>>   -device pcie-root-port,id=pcie_root_port1,chassis=1,slot=0 \
>>>   -device x3130-upstream,id=pcie_upstream1,bus=pcie_root_port1 \
>>>   -device 
>>> xio3130-downstream,id=pcie_downstream1,bus=pcie_upstream1,chassis=1,slot=1 \
>>>   -drive 
>>> id=nvme0n1,file=/home/kbj/work/src/vmctl/state/pmr/nvme0n1.img,format=raw,if=none,discard=on,detect-zeroes=unmap
>>>  \
>>>   -object memory-backend-file,id=pmr,share=on,mem-path=pmr.bin,size=1M \
>>>   -device 
>>> nvme,id=nvme0,serial=deadbeef,bus=pcie_downstream1,drive=nvme0n1,msix_qsize=1,pmrdev=pmr,cmb_size_mb=2
>>>  \
>>>   -pidfile /home/kbj/work/src/vmctl/run/pmr/pidfile \
>>>   -kernel /home/kbj/work/src/kernel/linux/arch/x86_64/boot/bzImage \
>>>   -append root=/dev/vda1 console=ttyS0,115200 audit=0 nokaslr \
>>>   -virtfs 
>>> local,path=/home/kbj/work/src/kernel/linux,security_model=none,readonly,mount_tag=modules
>>>  \
>>>   -serial mon:stdio \
>>>   -trace pci_nvme*
>>>
>>>
>>
>> I focused on reproduction and it looks to me that my patch doesn't 
>> necessarily introduce regression. I run it w/ and w/o patch in both cases
>> getting error while registering. Here is kernel guest log:
>>
>> [   87.606482] nvme nvme0: pci function :00:04.0
>> [   87.635577] dev=95b0a83b bar=2 size=134217728 offset=0
>> [   87.636593] nvme nvme0: failed to register the CMB ret=-95
>> [   87.643262] nvme nvme0: 12/0/0 default/read/poll queues
>>
>> Any thoughts?
>>
> 
> Hmm, that's not what I am seeing.
> 
> With kernel v5.8-rc4, I'm not seeing any issues with CMB with and
> without IOMMU on QEMU master. With your patches, my kernel (v5.8-rc4)
> pukes both with and without iommu.
> 
> BUT! This doesn't mean that your patch is bad, it looks more like an
> issue in the kernel. I still think the BAR configuration looks sane, but
> I am not expert on this.
> 
> To satisify my curiosity I tried mending your patch to put the CMB on
> offset 0 and move the MSI-X vector table and PBA to BAR 0 (like I
> suggested back in the day). That works. With and without IOMMU. So, I
> think it is an issue with the Linux kernel not being too happy about the
> CMB being at an offset. It doesn't directly look like an issue in the
> nvme driver since the issue shows up far lower in the memory subsystem,
> but it would be nice to have the linux nvme gang at least acknowledge
> the issue.
> 

I have managed to reproduce that problem and played with patch to see
when the problem occurs vs not. 
When I put MSIX back to BAR2 (no PMR at all) and CMB left at BAR4 but 
starting at offset 0 I was still able to reproduce issue.
So then I've played with memory region API and interesting observed that
problem occurs when region overlaying is used via:

memory_region_init(>bar4, OBJECT(n), "nvme-bar4",  bar_size);$
$  
if (n->params.cmb_size_mb) {$
memory_region_init_io(>ctrl_mem, OBJECT(n), _cmb_ops, n,$
  "nvme-cmb", NVME_CMBSZ_GETSIZE(n->bar.cmbsz));$
$  
memory_region_add_subregion_overlap(>bar4, cmb_offset, >ctrl_mem, 1);$
}$

on the other hand when cmb memory region is initialized w/o region
overlaying that is:

memory_region_init_io(>ctrl_mem, OBJECT(n), _cmb_ops, n,$
  "nvme-cmb", NVME_CMBSZ_GETSIZE(n->bar.cmbsz));

I get no reproduction.

Also observed qemu complaing about failed translation:
qemu-system-x86_64: vtd_iova_to_slpte: detected slpte permission error 
(iova=0xfe40, level=0x2, slpte=0x0, write=0)
qemu-system-x86_64: vtd_iommu_translate: detected translation failure 
(dev=03:00:00, iova=0xfe40)

Not sure how we want to proceed. Any suggestions?



Re: [PATCH] ppc/pnv: Make PSI device types not user creatable

2020-07-07 Thread David Gibson
On Tue, Jul 07, 2020 at 06:35:57PM +0200, Greg Kurz wrote:
> QEMU aborts with -device pnv-psi-POWER8:
> 
> $ qemu-system-ppc64 -device pnv-psi-POWER8
> qemu-system-ppc64: hw/intc/xics.c:605: ics_realize: Assertion
> `ics->xics' failed.
> Aborted (core dumped)
> 
> The Processor Service Interface Controller is an internal device.
> It should only be instantiated by the chip, which takes care of
> configuring the link required by the ICS object in the case of
> POWER8. It doesn't make sense for a user to specify it on the
> command line.
> 
> Note that the PSI model for POWER8 was added 3 yrs ago but the
> devices weren't available on the command line because of a bug
> that was fixed by recent commit 2f35254aa0 ("pnv/psi: Correct
> the pnv-psi* devices not to be sysbus devices").
> 
> Fixes: 54f59d786c ("ppc/pnv: Add cut down PSI bridge model and hookup 
> external interrupt")
> Reported-by: Thomas Huth 
> Signed-off-by: Greg Kurz 

Applied to ppc-for-5.1.

> ---
>  hw/ppc/pnv_psi.c |1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
> index 75b8ae9703d0..653b41774c34 100644
> --- a/hw/ppc/pnv_psi.c
> +++ b/hw/ppc/pnv_psi.c
> @@ -937,6 +937,7 @@ static void pnv_psi_class_init(ObjectClass *klass, void 
> *data)
>  dc->desc = "PowerNV PSI Controller";
>  device_class_set_props(dc, pnv_psi_properties);
>  dc->reset = pnv_psi_reset;
> +dc->user_creatable = false;
>  }
>  
>  static const TypeInfo pnv_psi_info = {
> 
> 

-- 
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: [PATCH v1 3/3] target/riscv: Regen floating point rounding mode in dynamic mode

2020-07-07 Thread Bin Meng
Hi Alistair,

On Wed, Jul 8, 2020 at 1:33 AM Alistair Francis  wrote:
>
> On Thu, Jul 2, 2020 at 6:25 PM Bin Meng  wrote:
> >
> > On Wed, Jul 1, 2020 at 4:23 AM Alistair Francis
> >  wrote:
> > >
> > > When a guest specificies the the rounding mode should be dynamic 0b111
> > > then we want to re-caclulate the rounding mode on each instruction. The
> > > gen_helper_set_rounding_mode() function will correctly check the
> > > rounding mode and handle a dynamic rounding, we just need to make sure
> > > it's always called if dynamic rounding is selected.
> > >
> > > Fixes: 1885350 ("RISCV dynamic rounding mode is not behaving correctly")
> >
> > I can't find this commit id.
>
> It's a launchpad bug case: https://bugs.launchpad.net/qemu/+bug/1885350
>

My understanding is that the convention used in "Fixes" tag is for
commit id. 1885350 is not a commit id but a QEMU bug report id.

Regards,
Bin



Re: [PULL 40/41] vhost-vdpa: introduce vhost-vdpa backend

2020-07-07 Thread Bruce Rogers
On Fri, 2020-07-03 at 05:05 -0400, Michael S. Tsirkin wrote:
> From: Cindy Lu 
> 
> Currently we have 2 types of vhost backends in QEMU: vhost kernel and
> vhost-user. The above patch provides a generic device for vDPA
> purpose,
> this vDPA device exposes to user space a non-vendor-specific
> configuration
> interface for setting up a vhost HW accelerator, this patch set
> introduces
> a third vhost backend called vhost-vdpa based on the vDPA interface.
> 
> Vhost-vdpa usage:
> 
> qemu-system-x86_64 -cpu host -enable-kvm \
> ..
> -netdev type=vhost-vdpa,vhostdev=/dev/vhost-vdpa-id,id=vhost-
> vdpa0 \
> -device virtio-net-pci,netdev=vhost-vdpa0,page-per-vq=on \
> 
> Signed-off-by: Lingshan zhu 
> Signed-off-by: Tiwei Bie 
> Signed-off-by: Cindy Lu 
> Signed-off-by: Jason Wang 
> Message-Id: <20200701145538.22333-14-l...@redhat.com>
> Reviewed-by: Michael S. Tsirkin 
> Signed-off-by: Michael S. Tsirkin 
> Acked-by: Jason Wang 
> ---
>  configure |  21 ++
>  include/hw/virtio/vhost-backend.h |   4 +-
>  include/hw/virtio/vhost-vdpa.h|  26 ++
>  include/hw/virtio/vhost.h |   7 +
>  hw/net/vhost_net.c|  19 +-
>  hw/net/virtio-net.c   |  19 ++
>  hw/virtio/vhost-backend.c |   6 +
>  hw/virtio/vhost-vdpa.c| 475
> ++
>  docs/interop/index.rst|   1 +
>  docs/interop/vhost-vdpa.rst   |  17 ++
>  hw/virtio/Makefile.objs   |   1 +
>  qemu-options.hx   |  12 +
>  12 files changed, 601 insertions(+), 7 deletions(-)
>  create mode 100644 include/hw/virtio/vhost-vdpa.h
>  create mode 100644 hw/virtio/vhost-vdpa.c
>  create mode 100644 docs/interop/vhost-vdpa.rst
> 
> diff --git a/configure b/configure
> index 4a22dcd563..3db7f20185 100755
> --- a/configure
> +++ b/configure
> @@ -1575,6 +1575,10 @@ for opt do
>;;
>--enable-vhost-user) vhost_user="yes"
>;;
> +  --disable-vhost-vdpa) vhost_vdpa="no"
> +  ;;
> +  --enable-vhost-vdpa) vhost_vdpa="yes"
> +  ;;
>--disable-vhost-kernel) vhost_kernel="no"
>;;
>--enable-vhost-kernel) vhost_kernel="yes"
> @@ -1883,6 +1887,7 @@ disabled with --disable-FEATURE, default is
> enabled if available:
>vhost-cryptovhost-user-crypto backend support
>vhost-kernelvhost kernel backend support
>vhost-user  vhost-user backend support
> +  vhost-vdpa  vhost-vdpa kernel backend support
>spice   spice
>rbd rados block device (rbd)
>libiscsiiscsi support
> @@ -2394,6 +2399,10 @@ test "$vhost_user" = "" && vhost_user=yes
>  if test "$vhost_user" = "yes" && test "$mingw32" = "yes"; then
>error_exit "vhost-user isn't available on win32"
>  fi
> +test "$vhost_vdpa" = "" && vhost_vdpa=$linux
> +if test "$vhost_vdpa" = "yes" && test "$linux" != "yes"; then
> +  error_exit "vhost-vdpa is only available on Linux"
> +fi
>  test "$vhost_kernel" = "" && vhost_kernel=$linux
>  if test "$vhost_kernel" = "yes" && test "$linux" != "yes"; then
>error_exit "vhost-kernel is only available on Linux"
> @@ -2422,6 +2431,11 @@ test "$vhost_user_fs" = "" &&
> vhost_user_fs=$vhost_user
>  if test "$vhost_user_fs" = "yes" && test "$vhost_user" = "no"; then
>error_exit "--enable-vhost-user-fs requires --enable-vhost-user"
>  fi
> +#vhost-vdpa backends
> +test "$vhost_net_vdpa" = "" && vhost_net_vdpa=$vhost_vdpa
> +if test "$vhost_net_vdpa" = "yes" && test "$vhost_vdpa" = "no"; then
> +  error_exit "--enable-vhost-net-vdpa requires --enable-vhost-vdpa"
> +fi
>  
>  # OR the vhost-kernel and vhost-user values for simplicity
>  if test "$vhost_net" = ""; then
> @@ -6936,6 +6950,7 @@ echo "vhost-scsi support $vhost_scsi"
>  echo "vhost-vsock support $vhost_vsock"
>  echo "vhost-user support $vhost_user"
>  echo "vhost-user-fs support $vhost_user_fs"
> +echo "vhost-vdpa support $vhost_vdpa"
>  echo "Trace backends$trace_backends"
>  if have_backend "simple"; then
>  echo "Trace output file $trace_file-"
> @@ -7437,6 +7452,9 @@ fi
>  if test "$vhost_net_user" = "yes" ; then
>echo "CONFIG_VHOST_NET_USER=y" >> $config_host_mak
>  fi
> +if test "$vhost_net_vdpa" = "yes" ; then
> +  echo "CONFIG_VHOST_NET_VDPA=y" >> $config_host_mak
> +fi
>  if test "$vhost_crypto" = "yes" ; then
>echo "CONFIG_VHOST_CRYPTO=y" >> $config_host_mak
>  fi
> @@ -7452,6 +7470,9 @@ fi
>  if test "$vhost_user" = "yes" ; then
>echo "CONFIG_VHOST_USER=y" >> $config_host_mak
>  fi
> +if test "$vhost_vdpa" = "yes" ; then
> +  echo "CONFIG_VHOST_VDPA=y" >> $config_host_mak
> +fi
>  if test "$vhost_user_fs" = "yes" ; then
>echo "CONFIG_VHOST_USER_FS=y" >> $config_host_mak
>  fi
> diff --git a/include/hw/virtio/vhost-backend.h
> b/include/hw/virtio/vhost-backend.h
> index e7cb8d028c..8825bd278f 100644
> --- a/include/hw/virtio/vhost-backend.h
> +++ b/include/hw/virtio/vhost-backend.h
> @@ -17,7 +17,8 @@ typedef enum VhostBackendType {
>  VHOST_BACKEND_TYPE_NONE = 0,
>  

Re: [PATCH] cpu: Add starts_halted() method

2020-07-07 Thread Thiago Jung Bauermann


Hello Eduardo,

Eduardo Habkost  writes:

> On Tue, Jul 07, 2020 at 05:43:33PM -0300, Thiago Jung Bauermann wrote:
>> PowerPC sPAPRs CPUs start in the halted state, but generic QEMU code
>> assumes that CPUs start in the non-halted state. spapr_reset_vcpu()
>> attempts to rectify this by setting CPUState::halted to 1. But that's too
>> late for hotplugged CPUs in a machine configured with 2 or mor threads per
>> core.
>>
>> By then, other parts of QEMU have already caused the vCPU to run in an
>> unitialized state a couple of times. For example, ppc_cpu_reset() calls
>> ppc_tlb_invalidate_all(), which ends up calling async_run_on_cpu(). This
>> kicks the new vCPU while it has CPUState::halted = 0, causing QEMU to issue
>> a KVM_RUN ioctl on the new vCPU before the guest is able to make the
>> start-cpu RTAS call to initialize its register state.
>>
>> This doesn't seem to cause visible issues for regular guests, but on a
>> secure guest running under the Ultravisor it does. The Ultravisor relies on
>> being able to snoop on the start-cpu RTAS call to map vCPUs to guests, and
>> this issue causes it to see a stray vCPU that doesn't belong to any guest.
>>
>> Fix by adding a starts_halted() method to the CPUState class, and making it
>> return 1 if the machine is an sPAPR guest.
>>
>> Signed-off-by: Thiago Jung Bauermann 
> [...]
>> +static uint32_t ppc_cpu_starts_halted(void)
>> +{
>> +SpaprMachineState *spapr =
>> +(SpaprMachineState *) object_dynamic_cast(qdev_get_machine(),
>> +  TYPE_SPAPR_MACHINE);
>
> Wouldn't it be simpler to just implement this as a MachineClass
> boolean field?  e.g.:
>
> Signed-off-by: Eduardo Habkost 

Yes, indeed it would. Thanks for this patch. I just tested and it
also solves the problem (except for the nit mentioned below).

Tested-by: Thiago Jung Bauermann 

Should I submit a proper patch with these changes (with you as the
author)?

> ---
> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index 426ce5f625..ffadc7a17d 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -215,6 +215,7 @@ struct MachineClass {
>  bool nvdimm_supported;
>  bool numa_mem_supported;
>  bool auto_enable_numa;
> +bool cpu_starts_halted;
>  const char *default_ram_id;
>
>  HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
> diff --git a/hw/core/cpu.c b/hw/core/cpu.c
> index 0f23409f1d..08dd504034 100644
> --- a/hw/core/cpu.c
> +++ b/hw/core/cpu.c
> @@ -252,6 +252,7 @@ static void cpu_common_reset(DeviceState *dev)
>  {
>  CPUState *cpu = CPU(dev);
>  CPUClass *cc = CPU_GET_CLASS(cpu);
> +MachineState *machine = object_dynamic_cast(qdev_get_machine(), 
> TYPE_MACHINE);

I had to add a (MachineState *) cast here to get the code to compile.

>
>  if (qemu_loglevel_mask(CPU_LOG_RESET)) {
>  qemu_log("CPU Reset (CPU %d)\n", cpu->cpu_index);
> @@ -259,7 +260,7 @@ static void cpu_common_reset(DeviceState *dev)
>  }
>
>  cpu->interrupt_request = 0;
> -cpu->halted = 0;
> +cpu->halted = machine ? MACHINE_GET_CLASS(machine)->cpu_starts_halted : 
> 0;
>  cpu->mem_io_pc = 0;
>  cpu->icount_extra = 0;
>  atomic_set(>icount_decr_ptr->u32, 0);
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index f6f034d039..d16ec33033 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -4487,6 +4487,7 @@ static void spapr_machine_class_init(ObjectClass *oc, 
> void *data)
>  mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.0");
>  mc->has_hotpluggable_cpus = true;
>  mc->nvdimm_supported = true;
> +mc->cpu_starts_halted = true;
>  smc->resize_hpt_default = SPAPR_RESIZE_HPT_ENABLED;
>  fwc->get_dev_path = spapr_get_fw_dev_path;
>  nc->nmi_monitor_handler = spapr_nmi;
>
>> +
>> +/*
>> + * In sPAPR, all CPUs start halted. CPU0 is unhalted from the machine 
>> level
>> + * reset code and the rest are explicitly started up by the guest using 
>> an
>> + * RTAS call.
>> + */
>> +return spapr != NULL;
>> +}
>> +


--
Thiago Jung Bauermann
IBM Linux Technology Center



Re: [PATCH v3 7/7] Makefile: Ship the generic platform bios images for RISC-V

2020-07-07 Thread Alistair Francis
On Thu, Jul 2, 2020 at 8:20 PM Bin Meng  wrote:
>
> From: Bin Meng 
>
> Update the install blob list to include the generic platform
> fw_dynamic bios images.
>
> Signed-off-by: Bin Meng 

Shouldn't this patch be included in an earlier patch?

Otherwise won't this break `make install` bisection?

Alistair

>
> ---
>
> Changes in v3:
> - change fw_jump to fw_dynamic in the Makefile
>
> Changes in v2:
> - new patch: Makefile: Ship the generic platform bios images for RISC-V
>
>  Makefile | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index b1b8a5a..05e05bb 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -841,8 +841,8 @@ u-boot.e500 u-boot-sam460-20100605.bin \
>  qemu_vga.ndrv \
>  edk2-licenses.txt \
>  hppa-firmware.img \
> -opensbi-riscv32-sifive_u-fw_jump.bin opensbi-riscv32-virt-fw_jump.bin \
> -opensbi-riscv64-sifive_u-fw_jump.bin opensbi-riscv64-virt-fw_jump.bin
> +opensbi-riscv32-generic-fw_dynamic.bin 
> opensbi-riscv32-generic-fw_dynamic.elf \
> +opensbi-riscv64-generic-fw_dynamic.bin opensbi-riscv64-generic-fw_dynamic.elf
>
>
>  DESCS=50-edk2-i386-secure.json 50-edk2-x86_64-secure.json \
> --
> 2.7.4
>
>



Re: [PATCH v3 6/7] gitlab-ci/opensbi: Update GitLab CI to build generic platform

2020-07-07 Thread Alistair Francis
On Thu, Jul 2, 2020 at 8:19 PM Bin Meng  wrote:
>
> From: Bin Meng 
>
> This updates the GitLab CI opensbi job to build opensbi bios images
> for the generic platform.
>
> Signed-off-by: Bin Meng 
> Reviewed-by: Anup Patel 

Reviewed-by: Alistair Francis 

Alistair

>
> ---
>
> Changes in v3:
> - Generate fw_dynamic images in the artifacts
>
> Changes in v2:
> - Include ELF images in the artifacts
>
>  .gitlab-ci.d/opensbi.yml | 28 ++--
>  1 file changed, 10 insertions(+), 18 deletions(-)
>
> diff --git a/.gitlab-ci.d/opensbi.yml b/.gitlab-ci.d/opensbi.yml
> index dd051c0..fd9eed4 100644
> --- a/.gitlab-ci.d/opensbi.yml
> +++ b/.gitlab-ci.d/opensbi.yml
> @@ -34,18 +34,14 @@ build-opensbi:
> when: always
>   artifacts:
> paths: # 'artifacts.zip' will contains the following files:
> -   - pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin
> -   - pc-bios/opensbi-riscv32-virt-fw_jump.bin
> -   - pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin
> -   - pc-bios/opensbi-riscv64-virt-fw_jump.bin
> -   - opensbi32-virt-stdout.log
> -   - opensbi32-virt-stderr.log
> -   - opensbi64-virt-stdout.log
> -   - opensbi64-virt-stderr.log
> -   - opensbi32-sifive_u-stdout.log
> -   - opensbi32-sifive_u-stderr.log
> -   - opensbi64-sifive_u-stdout.log
> -   - opensbi64-sifive_u-stderr.log
> +   - pc-bios/opensbi-riscv32-generic-fw_dynamic.bin
> +   - pc-bios/opensbi-riscv32-generic-fw_dynamic.elf
> +   - pc-bios/opensbi-riscv64-generic-fw_dynamic.bin
> +   - pc-bios/opensbi-riscv64-generic-fw_dynamic.elf
> +   - opensbi32-generic-stdout.log
> +   - opensbi32-generic-stderr.log
> +   - opensbi64-generic-stdout.log
> +   - opensbi64-generic-stderr.log
>   image: $CI_REGISTRY_IMAGE:opensbi-cross-build
>   variables:
> GIT_DEPTH: 3
> @@ -54,10 +50,6 @@ build-opensbi:
>   - export JOBS=$(($(getconf _NPROCESSORS_ONLN) + 1))
>   - echo "=== Using ${JOBS} simultaneous jobs ==="
>   - make -j${JOBS} -C roms/opensbi clean
> - - make -j${JOBS} -C roms opensbi32-virt 2>&1 1>opensbi32-virt-stdout.log | 
> tee -a opensbi32-virt-stderr.log >&2
> + - make -j${JOBS} -C roms opensbi32-generic 2>&1 
> 1>opensbi32-generic-stdout.log | tee -a opensbi32-generic-stderr.log >&2
>   - make -j${JOBS} -C roms/opensbi clean
> - - make -j${JOBS} -C roms opensbi64-virt 2>&1 1>opensbi64-virt-stdout.log | 
> tee -a opensbi64-virt-stderr.log >&2
> - - make -j${JOBS} -C roms/opensbi clean
> - - make -j${JOBS} -C roms opensbi32-sifive_u 2>&1 
> 1>opensbi32-sifive_u-stdout.log | tee -a opensbi32-sifive_u-stderr.log >&2
> - - make -j${JOBS} -C roms/opensbi clean
> - - make -j${JOBS} -C roms opensbi64-sifive_u 2>&1 
> 1>opensbi64-sifive_u-stdout.log | tee -a opensbi64-sifive_u-stderr.log >&2
> + - make -j${JOBS} -C roms opensbi64-generic 2>&1 
> 1>opensbi64-generic-stdout.log | tee -a opensbi64-generic-stderr.log >&2
> --
> 2.7.4
>
>



Re: [PATCH 00/21] target/xtensa: implement double precision FPU

2020-07-07 Thread Max Filippov
On Tue, Jul 7, 2020 at 12:21 PM Alex Bennée  wrote:
> Well it ran some xtensa tests thanks to the docker cross compiler
> support. Do you know what toolchains we need?
>
> Currently we have the following:
>
>   ENV CPU_LIST csp dc232b dc233c
>   ENV TOOLCHAIN_RELEASE 2018.02
>
>   RUN for cpu in $CPU_LIST; do \
>   curl -#SL 
> http://github.com/foss-xtensa/toolchain/releases/download/$TOOLCHAIN_RELEASE/x86_64-$TOOLCHAIN_RELEASE-xtensa-$cpu-elf.tar.gz
>  \

Oh, that's a familiar URL. Let me do the new batch of toolchains and
add FPU2000/DFPU configurations there.
And this is tests/docker/dockerfiles/debian-xtensa-cross.docker, right?
I can add new configurations there as well and add one more patch
to this series.

-- 
Thanks.
-- Max



[PULL 0/3] MIPS + TCG Continuous Benchmarking queue for July 7th, 2020

2020-07-07 Thread Aleksandar Markovic
On Tuesday, July 7, 2020, Paolo Bonzini  wrote:

> I haven't looked at the disassembler code; assuming it comes from an
> upstream code base I don't think we should treat it differently from the
> ARM disassembler (or for that matter the binutils ones) and basically
> handle it as a black box for which we don't really care about the code
> quality or style. It's not security sensitive code, and forking the
> upstream is probably not justified. On the other hand the pull request
> should have explained the provenance of the code (even if only in the
> subject line of the relevant patch).
>
> Regarding the recommendation of a "vacation" after last week's facts,
> QEMU's enforcing of behavior standards so far has been informal, therefore
> my suggestion cannot be anything more than a suggestion, though a strongly
> recommended one. I can also understand the soft freeze pressure. I defer
> to Peter as to whether to merge this pull request or not due to Thomas's
> objections, but I do wish to reinforce that taking some time off to cool
> down can often times be a good idea.
>
>
Sure, I respect the opinion of both Paolo and Thomas. I already reflected
on everything, and will not be an obstacle in any way in qemu community.

There is truly no ulterior motive from my side regarding this pull request
- I was just trying to integrate some code before soft-freeze.

Peter, please discard this pull request, I will send a new one, as soon as
I can, most likely tomorrow, that will fully follow Paolo's and Thomas'
recommendations, no need to worry.

Thanks,
Aleksamdar



> Thanks,
>
> Paolo
>
> Il mar 7 lug 2020, 22:20 Thomas Huth  ha scritto:
>
>> On 07/07/2020 18.40, Aleksandar Markovic wrote:
>> > The following changes since commit 710fb08fd297d7a92163debce1959f
>> ae8f3b6ed7:
>> >
>> >   Merge remote-tracking branch 
>> > 'remotes/huth-gitlab/tags/pull-request-2020-07-06'
>> into staging (2020-07-07 12:41:15 +0100)
>> >
>> > are available in the git repository at:
>> >
>> >   https://github.com/AMarkovic/qemu tags/mips-queue-jul-07-2020
>> >
>> > for you to fetch changes up to fa6e7da119b6da4067e757924e165b
>> c737bb1260:
>> >
>> >   scripts/performance: Add dissect.py script (2020-07-07 18:32:20 +0200)
>> >
>> > 
>> >
>> > MIPS + TCG Continuous Benchmarking queue for July 7th, 2020
>> >
>> >   Highlights:
>> >
>> >  - Fix for a regression in FPU emulation add.s.
>> >  - Add Loongson 2F disassembler.
>> >  - Add a script for a GSoC project.
>> >
>> >   Note:
>> >
>> >  - A checkpatch error and a checkpatch warning are known and
>> >  should be ignored.
>> >
>> > 
>> >
>> > Ahmed Karaman (1):
>> >   scripts/performance: Add dissect.py script
>> >
>> > Alex Richardson (1):
>> >   target/mips: fpu: Fix recent regression in add.s after 1ace099f2a
>> >
>> > Stefan Brankovic (1):
>> >   disas: mips: Add Loongson 2F disassembler
>> >
>> >  configure  |1 +
>> >  disas/loongson2f.h | 2562 +
>> >  include/disas/dis-asm.h|1 +
>> >  include/exec/poison.h  |1 +
>> >  target/mips/cpu.c  |6 +
>> >  target/mips/fpu_helper.c   |2 +-
>> >  MAINTAINERS|1 +
>> >  disas/Makefile.objs|1 +
>> >  disas/loongson2f.cpp   | 8154 ++
>> ++
>>
>> Honestly, no. Peter, please don't merge this pull request.
>>
>> That disassembler source code is really huge, and I think someone should
>> give this a *proper* review first before we include this in our repo. I
>> just had a quick look at it, and I don't think that it is in the right
>> shape already. For example, there are hard-coded magic numbers there,
>> like:
>>
>> bool ADD::disas_output(disassemble_info *info)
>> +{
>> +char alias1[5];
>> +char alias2[5];
>> +char alias3[5];
>> ...
>>
>> and in a completely different function, this hard-coded 5 is used again:
>>
>> +void Instruction32::getAlias(char *buffer, int regNo)
>> +{
>> +switch (regNo) {
>> +case 0:
>> +strncpy(buffer, "zero", 5);
>> +break;
>> +case 1:
>> +strncpy(buffer, "at", 5);
>> ...
>>
>> That definitely needs to be turned into a proper #define or the length
>> needs to be passed as parameter to the function.
>>
>> Also the coding style is weird in a couple of places, and there were
>> checkpatch warnings.
>>
>> Apart from that, Paolo asked you to take a break from MIPS
>> maintainership for a while, Aleksandar. I strongly support that
>> suggestion. Your derogatory behavior during the last weeks, especially
>> in the last one, looked completely unacceptable to me. In my opinion you
>> really need some time to reflect yourself. You, and we all as a
>> community, now cannot continue just like nothing happened.
>>
>>  Thanks,
>>   Thomas
>>
>>


Re: [PATCH 0/6] target/riscv: NaN-boxing for multiple precison

2020-07-07 Thread LIU Zhiwei

Hi Richard,

Ping for other patches in this patch set.

I may not get you ideas. Could you give more information?

Zhiwei

On 2020/7/3 20:33, LIU Zhiwei wrote:



On 2020/7/3 1:37, Richard Henderson wrote:

On 6/26/20 1:59 PM, LIU Zhiwei wrote:
Multiple precison shoule be supported by NaN-boxing. That means, we 
should

flush not valid NaN-boxing input to canonical NaN before effective
calculation and we should NaN-boxing the result after the effective
calculation.

In this patch set, split the implementation to three steps for compute,
sign-injection, and some covert insns, which are check_nanboxed,
effective calculation and gen_nanbox_fpr.

Check_nanboxed checks the inputs and flushes not valid inputs to 
cancical NaN.

Effective calculation is direct calculation on fp32 values.
Gen_nanbox_fpr does the NaN-boxing, writing the 1s to upper 32 bits.
I know I just reviewed a couple of these, but then I got to thinking 
about

patch 3 more closely.

I think it would be better to do all of the nan-boxing work inside of 
the

helpers, including the return values.

Do you mean a helper function just for nan-boxing work?

I don't think so.

The inputs are flushed to canonical NAN only when they are
not legal nan-boxed values.

The result is nan-boxed before writing  to  destination register.

Both of them have some relations to nan-boxing, but they are not the 
same.
Since we must have a helper call for the actual fp arithmetic, we 
might as well
put the rest of the logic in there too.  That way the JIT code is 
smaller.

Yes, we can. But I think it is clearer just let helper do calculation.

 By the way, is there some advantages of  smaller JIT code?
If, for RVF && !RVD, we always maintain the invariant that the values 
are

nanboxed anyway, then we do not even have to check for RVD at runtime.
Do you mean if FMV.X.S and FLW are nan-boxed, then we will not get the 
invalid values?


I don't think so.

First, FMV.X.D can transfer any 64 bits value to float register.
Second, users may set  invalid values  to float register by GDB.

I think it's necessary to do the inputs check and result nan-boxing.


Zhiwei

Thoughts?


r~







Re: [PATCH v3 3/7] roms/Makefile: Build the generic platform for RISC-V OpenSBI firmware

2020-07-07 Thread Alistair Francis
On Thu, Jul 2, 2020 at 8:22 PM Bin Meng  wrote:
>
> From: Bin Meng 
>
> The RISC-V generic platform is a flattened device tree (FDT) based
> platform where all platform specific functionality is provided based
> on FDT passed by previous booting stage. The support was added in
> the upstream OpenSBI v0.8 release recently.
>
> Update our Makefile to build the generic platform instead of building
> virt and sifive_u separately for RISC-V OpenSBI firmware, and change
> to use fw_dynamic type images as well.
>
> Signed-off-by: Bin Meng 
> Reviewed-by: Anup Patel 

Reviewed-by: Alistair Francis 

Alistair

>
> ---
>
> Changes in v3:
> - Change fw_jump to fw_dynamic in the make rules
>
> Changes in v2:
> - Copy the ELF images too in the make rules
>
>  roms/Makefile | 32 ++--
>  1 file changed, 10 insertions(+), 22 deletions(-)
>
> diff --git a/roms/Makefile b/roms/Makefile
> index f9acf39..5d9f15b 100644
> --- a/roms/Makefile
> +++ b/roms/Makefile
> @@ -64,10 +64,8 @@ default help:
> @echo "  u-boot.e500-- update u-boot.e500"
> @echo "  u-boot.sam460  -- update u-boot.sam460"
> @echo "  efi-- update UEFI (edk2) platform firmware"
> -   @echo "  opensbi32-virt -- update OpenSBI for 32-bit virt machine"
> -   @echo "  opensbi64-virt -- update OpenSBI for 64-bit virt machine"
> -   @echo "  opensbi32-sifive_u -- update OpenSBI for 32-bit sifive_u 
> machine"
> -   @echo "  opensbi64-sifive_u -- update OpenSBI for 64-bit sifive_u 
> machine"
> +   @echo "  opensbi32-generic  -- update OpenSBI for 32-bit generic 
> machine"
> +   @echo "  opensbi64-generic  -- update OpenSBI for 64-bit generic 
> machine"
> @echo "  bios-microvm   -- update bios-microvm.bin (qboot)"
> @echo "  clean  -- delete the files generated by the 
> previous" \
>   "build targets"
> @@ -170,29 +168,19 @@ skiboot:
>  efi: edk2-basetools
> $(MAKE) -f Makefile.edk2
>
> -opensbi32-virt:
> +opensbi32-generic:
> $(MAKE) -C opensbi \
> CROSS_COMPILE=$(riscv32_cross_prefix) \
> -   PLATFORM="qemu/virt"
> -   cp opensbi/build/platform/qemu/virt/firmware/fw_jump.bin 
> ../pc-bios/opensbi-riscv32-virt-fw_jump.bin
> +   PLATFORM="generic"
> +   cp opensbi/build/platform/generic/firmware/fw_dynamic.bin 
> ../pc-bios/opensbi-riscv32-generic-fw_dynamic.bin
> +   cp opensbi/build/platform/generic/firmware/fw_dynamic.elf 
> ../pc-bios/opensbi-riscv32-generic-fw_dynamic.elf
>
> -opensbi64-virt:
> +opensbi64-generic:
> $(MAKE) -C opensbi \
> CROSS_COMPILE=$(riscv64_cross_prefix) \
> -   PLATFORM="qemu/virt"
> -   cp opensbi/build/platform/qemu/virt/firmware/fw_jump.bin 
> ../pc-bios/opensbi-riscv64-virt-fw_jump.bin
> -
> -opensbi32-sifive_u:
> -   $(MAKE) -C opensbi \
> -   CROSS_COMPILE=$(riscv32_cross_prefix) \
> -   PLATFORM="sifive/fu540"
> -   cp opensbi/build/platform/sifive/fu540/firmware/fw_jump.bin 
> ../pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin
> -
> -opensbi64-sifive_u:
> -   $(MAKE) -C opensbi \
> -   CROSS_COMPILE=$(riscv64_cross_prefix) \
> -   PLATFORM="sifive/fu540"
> -   cp opensbi/build/platform/sifive/fu540/firmware/fw_jump.bin 
> ../pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin
> +   PLATFORM="generic"
> +   cp opensbi/build/platform/generic/firmware/fw_dynamic.bin 
> ../pc-bios/opensbi-riscv64-generic-fw_dynamic.bin
> +   cp opensbi/build/platform/generic/firmware/fw_dynamic.elf 
> ../pc-bios/opensbi-riscv64-generic-fw_dynamic.elf
>
>  bios-microvm:
> $(MAKE) -C qboot
> --
> 2.7.4
>
>



Re: [PATCH v2 000/100] target/arm: Implement SVE2

2020-07-07 Thread LIU Zhiwei



On 2020/6/18 12:25, Richard Henderson wrote:

I know this patch set is too big, and that there are parts that
can be split out that are prepatory rather that specifically sve2.

It's also not 100% tested.  I have done some amount of testing
vs ArmIE, but because of bugs and missing features therein, that
testing has been somewhat limited.  I understand a new version
of FVP has just been release containing SVE2 support, but I have
not yet tried that.

However, I believe this finally contains all of the instructions
in sve2 and its optional extensions.  Excluding BFloat16, since
that extension is supposed to implement AdvSIMD at the same time.

Hi Richard,

I try to merge this patch set to master branch. As some MTE instructions 
have been merged after this patch set,

it can't be merged now.

Would you mind to rebase it to master branch and send the patch set again?

Best Regards,
Zhiwei


r~


Richard Henderson (81):
   tcg: Save/restore vecop_list around minmax fallback
   qemu/int128: Add int128_lshift
   target/arm: Split out gen_gvec_fn_zz
   target/arm: Split out gen_gvec_fn_zzz, do_zzz_fn
   target/arm: Rearrange {sve,fp}_check_access assert
   target/arm: Merge do_vector2_p into do_mov_p
   target/arm: Clean up 4-operand predicate expansion
   target/arm: Use tcg_gen_gvec_bitsel for trans_SEL_
   target/arm: Split out gen_gvec_ool_zzzp
   target/arm: Merge helper_sve_clr_* and helper_sve_movz_*
   target/arm: Split out gen_gvec_ool_zzp
   target/arm: Split out gen_gvec_ool_zzz
   target/arm: Split out gen_gvec_ool_zz
   target/arm: Add ID_AA64ZFR0 fields and isar_feature_aa64_sve2
   target/arm: Enable SVE2 and some extensions
   target/arm: Implement SVE2 Integer Multiply - Unpredicated
   target/arm: Implement SVE2 integer pairwise add and accumulate long
   target/arm: Implement SVE2 integer unary operations (predicated)
   target/arm: Split out saturating/rounding shifts from neon
   target/arm: Implement SVE2 saturating/rounding bitwise shift left
 (predicated)
   target/arm: Implement SVE2 integer halving add/subtract (predicated)
   target/arm: Implement SVE2 integer pairwise arithmetic
   target/arm: Implement SVE2 saturating add/subtract (predicated)
   target/arm: Implement SVE2 integer add/subtract long
   target/arm: Implement SVE2 integer add/subtract interleaved long
   target/arm: Implement SVE2 integer add/subtract wide
   target/arm: Implement SVE2 integer multiply long
   target/arm: Implement PMULLB and PMULLT
   target/arm: Tidy SVE tszimm shift formats
   target/arm: Implement SVE2 bitwise shift left long
   target/arm: Implement SVE2 bitwise exclusive-or interleaved
   target/arm: Implement SVE2 bitwise permute
   target/arm: Implement SVE2 complex integer add
   target/arm: Implement SVE2 integer absolute difference and accumulate
 long
   target/arm: Implement SVE2 integer add/subtract long with carry
   target/arm: Implement SVE2 bitwise shift right and accumulate
   target/arm: Implement SVE2 bitwise shift and insert
   target/arm: Implement SVE2 integer absolute difference and accumulate
   target/arm: Implement SVE2 saturating extract narrow
   target/arm: Implement SVE2 SHRN, RSHRN
   target/arm: Implement SVE2 SQSHRUN, SQRSHRUN
   target/arm: Implement SVE2 UQSHRN, UQRSHRN
   target/arm: Implement SVE2 SQSHRN, SQRSHRN
   target/arm: Implement SVE2 WHILEGT, WHILEGE, WHILEHI, WHILEHS
   target/arm: Implement SVE2 WHILERW, WHILEWR
   target/arm: Implement SVE2 bitwise ternary operations
   target/arm: Implement SVE2 saturating multiply-add long
   target/arm: Generalize inl_qrdmlah_* helper functions
   target/arm: Implement SVE2 saturating multiply-add high
   target/arm: Implement SVE2 integer multiply-add long
   target/arm: Implement SVE2 complex integer multiply-add
   target/arm: Implement SVE2 XAR
   target/arm: Fix sve_uzp_p vs odd vector lengths
   target/arm: Fix sve_zip_p vs odd vector lengths
   target/arm: Fix sve_punpk_p vs odd vector lengths
   target/arm: Pass separate addend to {U,S}DOT helpers
   target/arm: Pass separate addend to FCMLA helpers
   target/arm: Split out formats for 2 vectors + 1 index
   target/arm: Split out formats for 3 vectors + 1 index
   target/arm: Implement SVE2 integer multiply (indexed)
   target/arm: Use helper_gvec_mul_idx_* for aa64 advsimd
   target/arm: Implement SVE2 integer multiply-add (indexed)
   target/arm: Use helper_gvec_ml{a,s}_idx_* for aa64 advsimd
   target/arm: Implement SVE2 saturating multiply-add high (indexed)
   target/arm: Implement SVE2 saturating multiply-add (indexed)
   target/arm: Implement SVE2 integer multiply long (indexed)
   target/arm: Implement SVE2 saturating multiply (indexed)
   target/arm: Implement SVE2 signed saturating doubling multiply high
   target/arm: Use helper_neon_sq{,r}dmul_* for aa64 advsimd
   target/arm: Implement SVE2 saturating multiply high (indexed)
   target/arm: Implement SVE2 multiply-add long (indexed)
   target/arm: Implement SVE2 complex integer 

[PULL 1/1] Update OpenBIOS images to 75fbb41d built from submodule.

2020-07-07 Thread Mark Cave-Ayland
Signed-off-by: Mark Cave-Ayland 
---
 pc-bios/openbios-ppc | Bin 696912 -> 696912 bytes
 pc-bios/openbios-sparc32 | Bin 382048 -> 382048 bytes
 pc-bios/openbios-sparc64 | Bin 1593408 -> 1593408 bytes
 roms/openbios|   2 +-
 4 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/pc-bios/openbios-ppc b/pc-bios/openbios-ppc
index 
5da9363bff64e21ab61ecf70d571855a3714843f..a07757a987e9ad424067427d23a1a46762952939
 100644
GIT binary patch
delta 44172
zcmce<4_sWu)j!OVy<|aBHwiH$A%+MMVjv-g7^0YDeXBPxlsVx@*CCiE>*_B^B0@LQIZZ(K1u
zG$=^(RJ})$RffM%5X+kLjk6774OU~UDab_mdxLny?2oK6P|}Lo!2#J-;XD#93W~@g
z)@}viST;yO5;NHlY+}haW1Krn8~b^Z=Gm96js0vC;d;P)ZS3h@giE!tr*brpdznnL
z$h1n$(-w?!cEnczrwZXJZLD<~;rR%g5iUY#MF@IN{~b79JlhafBiycywG9KBwXxG5
z*o-eK3v%qaE}PSJuuAjZ?hOhGGHPc{Ij7sU8{aV)tgLE>akIgGx_gIlzGCP)Jy2#m
zkz>d_UHz7Et6}cfgwKZijT<26sNWl7ZmI+^gXVo?O!Gb)t9c6m{iwudDRw3n=am=S
zgM7sMn+4wXZp};3-=gE}%q=U<&9mET1zsz4lF~)j+Z@d;#
z4u9LY#b9SyZyV#3cB0Gb+Kmyc?rr0I!x=XHj`0%qZ*LoS7>q3S9pg)eCQ5o{ZjRu<
z)^HSgQataAYEGcn`4#+xC8?01c844tgzT~t2;T%+cFH$uPws(*LM;gj=~OYyJ{
z59^cguoYMoQtmBy4*a9^?EwiCzw_|PxSR9>)BBc;C-kVZAVCF6RTj|1}QkTONcw-gQBT<}Dl)Jb$@G5;DbeN^4iv@CrVuKswao
zqj;9`sc~5-s+Cd8r^cAjPG7W^qQkyu=cmTFP_r*OLeVr|H1ab<9lmG=MVo!m3Pj!g
zBKk?a<}HdR72|AOnkLooGh`DZpLEU0U+2q@miZ$y@{@h}X(InqC`JJN^?JVhGmAt>
zpMh|hj__HP%y-Sm-{8w{miZVT0Trb9^1EgJz>NI0%S8j--p_^v0+=rOPcMI
zfIokoFF#u5lLY+v$-ewFk1gc~{Nx+}K!I$4G^GO2!
z{1jh)x6CIA`175KWwu-^d-QW-_{t$*glOJ7puV3O0kHsZ^O+S;4QK)M0ESur=f;I@
z8Y~ih#E1sO0@49iKsBHR&;uBjgT+zqEINcT81|oMAmn-uvu4q}g(gVcL3*!w9XTSL
z!DLb*mA;>strlfN$R2)P!|Z=GE?d+s(zb(kVFYNQ-lAmCv9gxG8e_vj(o%<>UB|}0FfLh;1*!_n_%NZ}
zwKr(5=KaFXqDPGz=46QGh^8^COyVt$2J_*pb=0_wuzX3GY+%$Fb0w1Qq;?R8l1M?P
z=KX7e<}I#5eKPNJw6oNRG&|D51wKTQ{5RvOxiuooX1PhJ(d^X}osj
zH#EvQNNAe^|5;yIG@J9Pt{g?1Tyv#I)zAIu06x6b;G2=2rJ9ALb&*~@`W9<}}
zSw96yY;4T9a3l2x^ztOhDQJ_mWVIu=%vR!}xp1r~AkRp7`9;Nc>%F8`W7RBe+_=Qh
z%yPy-tcz7rFvyz5jTZ%vO|x!_MzbLb(i$f4-@>9PsA6dosJ1zPbkHV8S*c@nN$w6C
zRXa|GTW85A@^Y=#GM+cU>LyU_7;7V9;jE8h32bD-7-z^}W)Bh_EQx|TmgPZSJF_GB
zVIOGnxoC4ieyP=#xYJgaSL(Dqfchpz^t{_dp4FCDUbvYLACD1vil(+hZEO~iT?7+g
zD|2q9vK};%Dobnd8kelK=!68KtwhMmL+*=F!=FgcPpjeM+EdRmy~dctHe_RXPjmqK
z0i*sE$S`NW4%YPdjV!8kgxa5b2_)UFaf5BU43bC`S6qpQWzyXOPv?sT$ui
zs`WjC4gM^f>u{Cv9`{BGHuqUHZ}7w@OI3~ehI-bl8W-v_ueY9cBf26|U=kN(Tc}aG
z)qTL#9>ZlF$@^s;08)gx4MUvwz=ItJt)XSQHaV7bc5SE%c6AG%~aACAk
z=x##2g8LZqMbD<`Wmwcd&{?T06~PLZNF}jzD*=n3PD<-w#B(LiOQ1dg
z6lxGyI|B*}z{BmC=p0Dg){O3jL{TDq(s=CxX*@ZbyJy55G%$2KZ}7Z
z>WE@l|1>UKiWUegI<(A~zxP|4aI9biA|7kq2aaa^5Q$+A{usm5q4W{v9O>~uR
zx0T3=L-~Of5l2nATTpiG!P(n
z(xSE$NC{xG1<@$xMoh8j8>pyqbTX(c^Ao6PfLCLM*_?FcVo;P
z*>%)yK&}0EEF1j_
zV>wgL6bqYO&^wasDmzV{uoPhVE1Iz&{j=zBTKw#45jfV;l?Ql!-OT)*UXi~U2-M`S
zq)$iCffRx8?4<*rr#~FNo}th4XWrww2`Z5dkl2*NjV+n*~Y*dYsCa7Kr+_1igMX
z3bfF4J^HX)9I6>K9sD0R~++yf?xJ$X&5XH;}s_<3%Sf1lYS5BSS&|2|HeV%GdwZ6q2Dw14Q}b%QD3L`P
zVk_aTak|QiOA5(~sUZWLD#zOwNoCmBY~=#>+u6#ZInu^}hD?uxJ&80aF*k{EsD_+D
z{ovew;`W%_W^9-8z6YdWJ4~g#wdLR27PD
zaqaLy{W$FEA3R9L{w+$UlcEE_L`v^PU
zYO~v1wnV+u%EMGDG>f-prangs_DGM%yO<+PiCfez8r_Bl+lHkMg`;=}YY$UmHckpE
zv!PapBdAuIUXTqgY!<6+XEEj`*KUVROf_m)vX0Np_9|L@cuv?negL3bS$q+7(e}
zL(nv8^)BNT%mQwZUcnCdX!ZlVT)j?MGNSN2BmOJKiF+g%pfeO_~DYV>Lo4eDY66T1&$mXiYbZo};XC8-*`62C4G`
zc2VGE6sGt%)t#+*eR1Lzah_K#LYr6G7^IWE;c;|2_cI(Kjr={7QO_fY!ZS3J<{9?e
zIm)6H@j__CJ!gWrh9dd626JOA%=8^4Zhg1rb%m3j!W-(B=t$G;C)LSy*eu7d1N9l1
z^*c(8Th19<7GFBBfe+|HRbmDYg1YS0v7mGp_y;rL-u>MTkWYQcy7oDtCi
z-h9xKCYSHfeMzD~Ygown%G|^n9w9jdYCV??*=NZBkIxxp>E|nJ=19J2^pDwD6_VW4
zOCU*2_!3&7_XzbOS*;>8g_Ki=esOhZ%jvc9xxDGrn`8Wzu-Hq`^Js98KtO+lQk
zHY>{w11!s|EL@SSdH18ty_14I=Lfv;xW!e9C8T#NvkIpXXt|P)4dlcvkh0p
z3mh10^@0S>c&;PSUb;)xwvZ+ca7JDdIedI(3fTdi;u4y1=8ZCQq_Qwk*AcHonJpU+
zlv${LA9|8YFd6Y0wk=Y*I5>2gRYths%PBt6;UnF*NV$pw;y915e6u2+*Rz#
zFXG!Q>Y`YX#vnNXR^iuRz;9oPmAksAU!*S%qVy`>!bL)PyzKa5CBnUEnlr`MrP#w%
z7mX6;E~3Ck{$i3PW_((=7NzO=c7J|KKz^p4AMd~_nscx?8~NaDG3>a`!Qu*025Vrp
zeu*;A4bl7Rz))LUDR=-4!9#06ex;sor#eJ_Z$N?n)iCS9k+vc)z_*)Bb8iAk2R
zl-YmeON{a*<}H_nmk5mp^JTkyY3V*ZyDyCzN`kVKRd9NHHFXI#W}~38K`bpwS+xkA
zKr^ja`j=Jkl7v-7SWA>OSXy(;IQiI*RJhoq2>2p*7HSBh_52Q}E#FD{Qqt*Q!Qk
z30>T8k^{$#JekG~dnDqR?r6S{TfICkHmY_w_YtisNeknawwuU{0KOW9I6JshS-w%)
z`+{U@X1UW=mYADYT1I=F>QbLP#U5Q5JX~jSX$kg5)TOa(XsMVHDac`w7b?pZNF{*1
z%5`q9=Bl~0k!2#w-6j}WG(h!WT$j0$NSl|+`pE~NJu#ZA{~f**~t>t*byu6q8
z=Sgn~ml}Ew?xlo#VYtMt^W(a|0Xdl?rwC*ljbx+0z)XB>jZ(|k*6=o6X#Hkp1k>2!
zOhVhC1s667JZyxl5?hvN9jySZYlUzw>=p=^;cR7PrDdFHCONi)m)^+&22_=>jSe`_eDw}WEdX<`ZX+rf>u^UK`*PJV1%_}C*7s5G99
zQjp2au?QS2nSy$j9jh$c*ope|z4wew+TzZ!EUATQHdTvAZF+F87Z_UzRd><`5%
zOBR@c0wY3ByuOmY2>xU&_zGp+9EwlVt5Q*gpP{-qW!ao8VX`F4U2!1X<0pJ^FAh@q)J%QSQEKBOTvzm)yM^zdQqRybe}Wb!Izn8
zTrcPXwxc)boR9rEUfDR8*v8Q0LQ6o{%p4CZOW3t5l}Mkta%kAF~GVgXk=$rVOMjInG=*{
zbLGS<7q4n`KTAu%tk*9X=FWb#aDT}76X=Y>9I4TxqA_~I$VAceN-#@ijF{%DtZYB-
zy^{iGRkWb%TWQ_S`v(ciTpWZAwHOyJh(@D({3|oGRE=nE_%(Lu6B3n$H)M)V
z;_|BEsA|lh=og+AE7PbyAWs_!sS0I`nwkK8;R4IhaabKlk^vx8l4&41Uof0goaX5m
zmn0p~)jYkCrwhN7@WOqDU5$-k;j5KpD_Z<2#)VkRQPky4s2XfgT1+_0TCHrk
zqmsP8ptJ=4!bPcJ
zeV1a(AH2~1FCW2rtucwMLZomFxTOXGKIg9;6Flt$K%u%it^G_-MrtpsOr

[PULL 0/1] qemu-openbios queue 20200707

2020-07-07 Thread Mark Cave-Ayland
The following changes since commit eb2c66b10efd2b914b56b20ae90655914310c925:

  Merge remote-tracking branch 'remotes/maxreitz/tags/pull-block-2020-07-06' 
into staging (2020-07-07 19:47:26 +0100)

are available in the Git repository at:

  git://github.com/mcayland/qemu.git tags/qemu-openbios-20200707

for you to fetch changes up to 1e04092feecfc8caaf314df2670bf9c645a0b122:

  Update OpenBIOS images to 75fbb41d built from submodule. (2020-07-07 21:54:37 
+0100)


qemu-openbios queue


Mark Cave-Ayland (1):
  Update OpenBIOS images to 75fbb41d built from submodule.

 pc-bios/openbios-ppc | Bin 696912 -> 696912 bytes
 pc-bios/openbios-sparc32 | Bin 382048 -> 382048 bytes
 pc-bios/openbios-sparc64 | Bin 1593408 -> 1593408 bytes
 roms/openbios|   2 +-
 4 files changed, 1 insertion(+), 1 deletion(-)



Re: [PULL 0/3] MIPS + TCG Continuous Benchmarking queue for July 7th, 2020

2020-07-07 Thread Paolo Bonzini
I haven't looked at the disassembler code; assuming it comes from an
upstream code base I don't think we should treat it differently from the
ARM disassembler (or for that matter the binutils ones) and basically
handle it as a black box for which we don't really care about the code
quality or style. It's not security sensitive code, and forking the
upstream is probably not justified. On the other hand the pull request
should have explained the provenance of the code (even if only in the
subject line of the relevant patch).

Regarding the recommendation of a "vacation" after last week's facts,
QEMU's enforcing of behavior standards so far has been informal, therefore
my suggestion cannot be anything more than a suggestion, though a strongly
recommended one. I can also understand the soft freeze pressure. I defer to
Peter as to whether to merge this pull request or not due to Thomas's
objections, but I do wish to reinforce that taking some time off to cool
down can often times be a good idea.

Thanks,

Paolo

Il mar 7 lug 2020, 22:20 Thomas Huth  ha scritto:

> On 07/07/2020 18.40, Aleksandar Markovic wrote:
> > The following changes since commit
> 710fb08fd297d7a92163debce1959fae8f3b6ed7:
> >
> >   Merge remote-tracking branch
> 'remotes/huth-gitlab/tags/pull-request-2020-07-06' into staging (2020-07-07
> 12:41:15 +0100)
> >
> > are available in the git repository at:
> >
> >   https://github.com/AMarkovic/qemu tags/mips-queue-jul-07-2020
> >
> > for you to fetch changes up to fa6e7da119b6da4067e757924e165bc737bb1260:
> >
> >   scripts/performance: Add dissect.py script (2020-07-07 18:32:20 +0200)
> >
> > 
> >
> > MIPS + TCG Continuous Benchmarking queue for July 7th, 2020
> >
> >   Highlights:
> >
> >  - Fix for a regression in FPU emulation add.s.
> >  - Add Loongson 2F disassembler.
> >  - Add a script for a GSoC project.
> >
> >   Note:
> >
> >  - A checkpatch error and a checkpatch warning are known and
> >  should be ignored.
> >
> > 
> >
> > Ahmed Karaman (1):
> >   scripts/performance: Add dissect.py script
> >
> > Alex Richardson (1):
> >   target/mips: fpu: Fix recent regression in add.s after 1ace099f2a
> >
> > Stefan Brankovic (1):
> >   disas: mips: Add Loongson 2F disassembler
> >
> >  configure  |1 +
> >  disas/loongson2f.h | 2562 +
> >  include/disas/dis-asm.h|1 +
> >  include/exec/poison.h  |1 +
> >  target/mips/cpu.c  |6 +
> >  target/mips/fpu_helper.c   |2 +-
> >  MAINTAINERS|1 +
> >  disas/Makefile.objs|1 +
> >  disas/loongson2f.cpp   | 8154
> 
>
> Honestly, no. Peter, please don't merge this pull request.
>
> That disassembler source code is really huge, and I think someone should
> give this a *proper* review first before we include this in our repo. I
> just had a quick look at it, and I don't think that it is in the right
> shape already. For example, there are hard-coded magic numbers there, like:
>
> bool ADD::disas_output(disassemble_info *info)
> +{
> +char alias1[5];
> +char alias2[5];
> +char alias3[5];
> ...
>
> and in a completely different function, this hard-coded 5 is used again:
>
> +void Instruction32::getAlias(char *buffer, int regNo)
> +{
> +switch (regNo) {
> +case 0:
> +strncpy(buffer, "zero", 5);
> +break;
> +case 1:
> +strncpy(buffer, "at", 5);
> ...
>
> That definitely needs to be turned into a proper #define or the length
> needs to be passed as parameter to the function.
>
> Also the coding style is weird in a couple of places, and there were
> checkpatch warnings.
>
> Apart from that, Paolo asked you to take a break from MIPS
> maintainership for a while, Aleksandar. I strongly support that
> suggestion. Your derogatory behavior during the last weeks, especially
> in the last one, looked completely unacceptable to me. In my opinion you
> really need some time to reflect yourself. You, and we all as a
> community, now cannot continue just like nothing happened.
>
>  Thanks,
>   Thomas
>
>


[PATCH] cpu: Add starts_halted() method

2020-07-07 Thread Thiago Jung Bauermann
PowerPC sPAPRs CPUs start in the halted state, but generic QEMU code
assumes that CPUs start in the non-halted state. spapr_reset_vcpu()
attempts to rectify this by setting CPUState::halted to 1. But that's too
late for hotplugged CPUs in a machine configured with 2 or mor threads per
core.

By then, other parts of QEMU have already caused the vCPU to run in an
unitialized state a couple of times. For example, ppc_cpu_reset() calls
ppc_tlb_invalidate_all(), which ends up calling async_run_on_cpu(). This
kicks the new vCPU while it has CPUState::halted = 0, causing QEMU to issue
a KVM_RUN ioctl on the new vCPU before the guest is able to make the
start-cpu RTAS call to initialize its register state.

This doesn't seem to cause visible issues for regular guests, but on a
secure guest running under the Ultravisor it does. The Ultravisor relies on
being able to snoop on the start-cpu RTAS call to map vCPUs to guests, and
this issue causes it to see a stray vCPU that doesn't belong to any guest.

Fix by adding a starts_halted() method to the CPUState class, and making it
return 1 if the machine is an sPAPR guest.

Signed-off-by: Thiago Jung Bauermann 
---
 hw/core/cpu.c   |  8 +++-
 hw/ppc/spapr_cpu_core.c |  5 -
 include/hw/core/cpu.h   |  2 ++
 target/ppc/translate_init.inc.c | 16 
 4 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/hw/core/cpu.c b/hw/core/cpu.c
index 0f23409f1d..8f9a3335d5 100644
--- a/hw/core/cpu.c
+++ b/hw/core/cpu.c
@@ -259,7 +259,7 @@ static void cpu_common_reset(DeviceState *dev)
 }
 
 cpu->interrupt_request = 0;
-cpu->halted = 0;
+cpu->halted = cc->starts_halted();
 cpu->mem_io_pc = 0;
 cpu->icount_extra = 0;
 atomic_set(>icount_decr_ptr->u32, 0);
@@ -275,6 +275,11 @@ static void cpu_common_reset(DeviceState *dev)
 }
 }
 
+static uint32_t cpu_common_starts_halted(void)
+{
+return 0;
+}
+
 static bool cpu_common_has_work(CPUState *cs)
 {
 return false;
@@ -428,6 +433,7 @@ static void cpu_class_init(ObjectClass *klass, void *data)
 k->cpu_exec_exit = cpu_common_noop;
 k->cpu_exec_interrupt = cpu_common_exec_interrupt;
 k->adjust_watchpoint_address = cpu_adjust_watchpoint_address;
+k->starts_halted = cpu_common_starts_halted;
 set_bit(DEVICE_CATEGORY_CPU, dc->categories);
 dc->realize = cpu_common_realizefn;
 dc->unrealize = cpu_common_unrealizefn;
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 26ad566f42..d0ad92240c 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -36,11 +36,6 @@ static void spapr_reset_vcpu(PowerPCCPU *cpu)
 
 cpu_reset(cs);
 
-/* All CPUs start halted.  CPU0 is unhalted from the machine level
- * reset code and the rest are explicitly started up by the guest
- * using an RTAS call */
-cs->halted = 1;
-
 env->spr[SPR_HIOR] = 0;
 
 lpcr = env->spr[SPR_LPCR];
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index b3f4b79318..7c9cd67e8d 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -219,6 +219,8 @@ typedef struct CPUClass {
 vaddr (*adjust_watchpoint_address)(CPUState *cpu, vaddr addr, int len);
 void (*tcg_initialize)(void);
 
+uint32_t (*starts_halted)(void);
+
 /* Keep non-pointer data at the end to minimize holes.  */
 int gdb_num_core_regs;
 bool gdb_stop_before_watchpoint;
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 49212bfd90..1dc1ebbdaf 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -36,6 +36,7 @@
 #include "qapi/visitor.h"
 #include "hw/qdev-properties.h"
 #include "hw/ppc/ppc.h"
+#include "hw/ppc/spapr.h"
 #include "mmu-book3s-v3.h"
 #include "sysemu/qtest.h"
 #include "qemu/cutils.h"
@@ -10646,6 +10647,20 @@ static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
 cpu->env.nip = value;
 }
 
+static uint32_t ppc_cpu_starts_halted(void)
+{
+SpaprMachineState *spapr =
+(SpaprMachineState *) object_dynamic_cast(qdev_get_machine(),
+  TYPE_SPAPR_MACHINE);
+
+/*
+ * In sPAPR, all CPUs start halted. CPU0 is unhalted from the machine level
+ * reset code and the rest are explicitly started up by the guest using an
+ * RTAS call.
+ */
+return spapr != NULL;
+}
+
 static bool ppc_cpu_has_work(CPUState *cs)
 {
 PowerPCCPU *cpu = POWERPC_CPU(cs);
@@ -10922,6 +10937,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void 
*data)
 #endif
 
 cc->disas_set_info = ppc_disas_set_info;
+cc->starts_halted = ppc_cpu_starts_halted;
 
 dc->fw_name = "PowerPC,UNKNOWN";
 }



Re: [PATCH 2/4] hw/lm32/milkymist: Comment to remember some IRQs lines are left unwired

2020-07-07 Thread Michael Walle

Am 2020-07-07 18:30, schrieb Peter Maydell:
On Sun, 5 Jul 2020 at 22:10, Philippe Mathieu-Daudé  
wrote:


The 'card is readonly' and 'card inserted' IRQs are not wired.
Add a comment in case someone know where to wire them.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/lm32/milkymist.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index 469e3c4322..117973c967 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -87,6 +87,7 @@ static DeviceState *milkymist_memcard_create(hwaddr 
base)

 dev = qdev_new("milkymist-memcard");
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
+/* FIXME wire 'card is readonly' and 'card inserted' IRQs? */


It's possible that these lines are correctly not wired up
(ie that the hardware does not provide any kind of indication
of the r/o or insertion events). The milkymist mmc device is a
very simple one. AIUI the RTL for the board is on github if
anybody wants to go check.


That is correct, there are not indications nor are there any
interrupts.

-michael



Re: [PATCH v12 1/8] error: New macro ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Markus Armbruster
Vladimir Sementsov-Ogievskiy  writes:

> 07.07.2020 19:50, Markus Armbruster wrote:
>> From: Vladimir Sementsov-Ogievskiy
>>
>> Introduce a new ERRP_AUTO_PROPAGATE macro, to be used at start of
>> functions with an errp OUT parameter.
>>
>> It has three goals:
>>
>> 1. Fix issue with error_fatal and error_prepend/error_append_hint: user
>> can't see this additional information, because exit() happens in
>> error_setg earlier than information is added. [Reported by Greg Kurz]
>>
>> 2. Fix issue with error_abort and error_propagate: when we wrap
>> error_abort by local_err+error_propagate, the resulting coredump will
>> refer to error_propagate and not to the place where error happened.
>> (the macro itself doesn't fix the issue, but it allows us to [3.] drop
>> the local_err+error_propagate pattern, which will definitely fix the
>> issue) [Reported by Kevin Wolf]
>>
>> 3. Drop local_err+error_propagate pattern, which is used to workaround
>> void functions with errp parameter, when caller wants to know resulting
>> status. (Note: actually these functions could be merely updated to
>> return int error code).
>>
>> To achieve these goals, later patches will add invocations
>> of this macro at the start of functions with either use
>> error_prepend/error_append_hint (solving 1) or which use
>> local_err+error_propagate to check errors, switching those
>> functions to use *errp instead (solving 2 and 3).
>>
>> Signed-off-by: Vladimir Sementsov-Ogievskiy
>> Reviewed-by: Paul Durrant
>> Reviewed-by: Greg Kurz
>> Reviewed-by: Eric Blake
>> [Comments merged properly with recent commit "error: Document Error
>> API usage rules", and edited for clarity.  Put ERRP_AUTO_PROPAGATE()
>> before its helpers, and touch up style.  Commit message tweaked.]
>> Signed-off-by: Markus Armbruster
>
> Ok, I see you have mostly rewritten the big comment

Guilty as charged...  I was happy with the contents you provided (and
grateful for it), but our parallel work caused some redundancy.  I went
beyond a minimal merge to get a something that reads as one coherent
text.

> and not only in this patch, so, I go and read the whole comment on top of 
> these series.
>
> =
>
>* Pass an existing error to the caller with the message modified:
>* error_propagate_prepend(errp, err,
>* "Could not frobnicate '%s': ", name);
>* This is more concise than
>* error_propagate(errp, err); // don't do this
>* error_prepend(errp, "Could not frobnicate '%s': ", name);
>* and works even when @errp is _fatal.
>
> - the latter doesn't consider ERRP_AUTO_PROPAGATE: as we know, that 
> ERRP_AUTO_PROPAGATE should be used when we use error_prepend, the latter 
> should look like
>
>
> ERRP_AUTO_PROPAGATE();
> ...
> error_propagate(errp, err); // don't do this
> error_prepend(errp, "Could not frobnicate '%s': ", name);
>
> - and it works even when @errp is _fatal, so the 
> error_propagate_prepend now is just a shortcut, not the only correct way.

I can duplicate the advice from the paragraph preceding it, like this:

 * This is rarely needed.  When @err is a local variable, use of
 * ERRP_GUARD() commonly results in more readable code.
 * Where it is needed, it is more concise than
 * error_propagate(errp, err); // don't do this
 * error_prepend(errp, "Could not frobnicate '%s': ", name);
 * and works even when @errp is _fatal.

> Still, the text is formally correct as is, and may be improved later.
>
> =
>
>* 2. Replace  by errp, and err by *errp.  Delete local variable
>*@err.
>
> - hmm a bit not obvious,, It can be local_err.

Yes, but I trust the reader can make that mental jump.

> It can be (in some rare cases) still needed to handle the error locally, not 
> passing to the caller..

I didn't think of this.

What about

 * To convert a function to use ERRP_GUARD(), assuming the local
 * variable it propagates to @errp is called @err:
 [...]
 * 2. Replace  by errp, and err by *errp.  Delete local variable
 *@err if it s now unused.

Nope, still no good, if we replace like that, @err *will* be unused, and
the locally handled error will leak to the caller.

No time left for wordsmithing; let's improve on top.

> may be just something like "Assume local Error *err variable is used to get 
> errors from called functions and than propagated to caller's errp" before 
> paragraph [2.] will help.
>
>
>*
>* 3. Delete error_propagate(errp, *errp), replace
>*error_propagate_prepend(errp, *errp, ...) by error_prepend(errp, ...),
>*
>* 4. Ensure @errp is valid at return: when you destroy *errp, set
>*errp = NULL.
>
> =
>
>
> May be good to add note about ERRP_AUTO_PROPAGATE() into comment above 
> error_append_hint (and error_(v)prepend)).

Good point.

> =
>
>   /*
>* Make 

Re: [PULL 00/31] Block patches

2020-07-07 Thread Peter Maydell
On Mon, 6 Jul 2020 at 11:04, Max Reitz  wrote:
>
> The following changes since commit eb6490f544388dd24c0d054a96dd304bc7284450:
>
>   Merge remote-tracking branch 
> 'remotes/pmaydell/tags/pull-target-arm-20200703' into staging (2020-07-04 
> 16:08:41 +0100)
>
> are available in the Git repository at:
>
>   https://github.com/XanClic/qemu.git tags/pull-block-2020-07-06
>
> for you to fetch changes up to 365fed5111b06d31c1632af63c7528dfe49d62a2:
>
>   qed: Simplify backing reads (2020-07-06 10:34:14 +0200)
>
> 
> Block patches for 5.1:
> - LUKS keyslot amendment
>   (+ patches to make the iotests pass on non-Linux systems, and to keep
>  the tests passing for qcow v1, and to skip LUKS tests (including
>  qcow2 LUKS) when the built qemu does not support it)
> - Refactoring in the block layer: Drop the basically unnecessary
>   unallocated_blocks_are_zero field from BlockDriverInfo
> - Fix qcow2 preallocation when the image size is not a multiple of the
>   cluster size
> - Fix in block-copy code
>



Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/5.1
for any user-visible changes.

-- PMM



Re: [PATCH 2/2] hw/sd/sdcard: Do not allow invalid SD card sizes

2020-07-07 Thread Niek Linnenbank
Hi Philippe,

Just tried out your patch on latest master, and I noticed I couldn't apply
it without getting this error:

$ git am ~/Downloads/patches/\[PATCH\ 2_2\]\ hw_sd_sdcard\:\ Do\ not\
allow\ invalid\ SD\ card\ sizes\ -\ Philippe\ Mathieu-Daudé\ \<
f4...@amsat.org\>\ -\ 2020-07-07\ 1521.eml
Applying: hw/sd/sdcard: Do not allow invalid SD card sizes
error: patch failed: hw/sd/sd.c:2130
error: hw/sd/sd.c: patch does not apply
Patch failed at 0001 hw/sd/sdcard: Do not allow invalid SD card sizes
Use 'git am --show-current-patch' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

The first patch did go OK. Maybe this one just needs to be rebased, or I
made a mistake.
So I manually copy & pasted the change into hw/sd/sd.c to test it.
It looks like the check works, but my concern is that with this change, we
will be getting this error on 'off-the-shelf' images as well.
For example, the latest Raspbian image size also isn't a power of two:

$ ./arm-softmmu/qemu-system-arm -M raspi2 -sd
~/Downloads/2020-05-27-raspios-buster-lite-armhf.img -nographic
WARNING: Image format was not specified for
'/home/me/Downloads/2020-05-27-raspios-buster-lite-armhf.img' and probing
guessed raw.
 Automatically detecting the format is dangerous for raw images,
write operations on block 0 will be restricted.
 Specify the 'raw' format explicitly to remove the restrictions.
qemu-system-arm: Invalid SD card size: 1.73 GiB (expecting at least 2 GiB)

If we do decide that the change is needed, I would like to propose that we
also give the user some instructions
on how to fix it, maybe some 'dd' command? In my opinion that should also
go in some of the documentation file(s),
possibly also in the one for the OrangePi PC at
docs/system/arm/orangepi.rst (I can also provide a patch for that if you
wish).

Kind regards,

Niek


On Tue, Jul 7, 2020 at 6:11 PM Philippe Mathieu-Daudé 
wrote:

> On 7/7/20 6:06 PM, Peter Maydell wrote:
> > On Tue, 7 Jul 2020 at 17:04, Alistair Francis 
> wrote:
> >>
> >> On Tue, Jul 7, 2020 at 6:22 AM Philippe Mathieu-Daudé 
> wrote:
> >>>
> >>> QEMU allows to create SD card with unrealistic sizes. This could work,
> >>> but some guests (at least Linux) consider sizes that are not a power
> >>> of 2 as a firmware bug and fix the card size to the next power of 2.
> >>>
> >>> Before CVE-2020-13253 fix, this would allow OOB read/write accesses
> >>> past the image size end.
> >>>
> >>> CVE-2020-13253 has been fixed as:
> >>>
> >>> Read command is rejected if BLOCK_LEN_ERROR or ADDRESS_ERROR
> >>> occurred and no data transfer is performed.
> >>>
> >>> Write command is rejected if BLOCK_LEN_ERROR or ADDRESS_ERROR
> >>> occurred and no data transfer is performed.
> >>>
> >>> WP_VIOLATION errors are not modified: the error bit is set, we
> >>> stay in receive-data state, wait for a stop command. All further
> >>> data transfer is ignored. See the check on sd->card_status at the
> >>> beginning of sd_read_data() and sd_write_data().
> >>>
> >>> While this is the correct behavior, in case QEMU create smaller SD
> >>> cards, guests still try to access past the image size end, and QEMU
> >>> considers this is an invalid address, thus "all further data transfer
> >>> is ignored". This is wrong and make the guest looping until
> >>> eventually timeouts.
> >>>
> >>> Fix by not allowing invalid SD card sizes.  Suggesting the expected
> >>> size as a hint:
> >>>
> >>>   $ qemu-system-arm -M orangepi-pc -drive
> file=rootfs.ext2,if=sd,format=raw
> >>>   qemu-system-arm: Invalid SD card size: 60 MiB (expecting at least 64
> MiB)
> >>>
> >>> Signed-off-by: Philippe Mathieu-Daudé 
> >>> ---
> >>>  hw/sd/sd.c | 16 
> >>>  1 file changed, 16 insertions(+)
> >>>
> >>> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> >>> index cb81487e5c..c45106b78e 100644
> >>> --- a/hw/sd/sd.c
> >>> +++ b/hw/sd/sd.c
> >>> @@ -32,6 +32,7 @@
> >>>
> >>>  #include "qemu/osdep.h"
> >>>  #include "qemu/units.h"
> >>> +#include "qemu/cutils.h"
> >>>  #include "hw/irq.h"
> >>>  #include "hw/registerfields.h"
> >>>  #include "sysemu/block-backend.h"
> >>> @@ -2130,11 +2131,26 @@ static void sd_realize(DeviceState *dev, Error
> **errp)
> >>>  }
> >>>
> >>>  if (sd->blk) {
> >>> +int64_t blk_size;
> >>> +
> >>>  if (blk_is_read_only(sd->blk)) {
> >>>  error_setg(errp, "Cannot use read-only drive as SD card");
> >>>  return;
> >>>  }
> >>>
> >>> +blk_size = blk_getlength(sd->blk);
> >>> +if (blk_size > 0 && !is_power_of_2(blk_size)) {
> >>> +int64_t blk_size_aligned = pow2ceil(blk_size);
> >>> +char *blk_size_str = size_to_str(blk_size);
> >>> +char *blk_size_aligned_str =
> size_to_str(blk_size_aligned);
> >>> +
> >>> +   

Re: Failure prints during format or mounting a usb storage device

2020-07-07 Thread Paul Zimmerman
On Tue, Jul 7, 2020 at 12:57 AM Gerd Hoffmann  wrote:

>   Hi,
> >
> > Gerd, do you know the purpose of the 'short_not_ok' parameter to
> > usb_packet_setup()?
>
> Well, some usb host controllers have a flag in the transfer control
> blocks to indicate the host controller should stop processing requests
> in case of a short transfer.
>
> The usb core uses the flag to just to that (i.e. halt the endpoint on
> short transfers).  It is also checked when usb-host pipelines requests
> (requests queued after a short-not-ok packet can't be pipelined because
> we don't know yet whenever we should continue processing the endpoint or
> not).
>
> xhci has no such flag so the flag is never set.
>
> > The simple patch below fixes the reported problem,
> > but I don't know if it could cause some other problems for XHCI.
> > hcd-ehci, hcd-ohci, hcd-uhci all set the parameter conditionally,
> > but hcd-xhci never sets it. I don't understand the purpose of the
> > parameter myself.
> >
> > diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
> > index b330e36fe6..9fb96fdd66 100644
> > --- a/hw/usb/hcd-xhci.c
> > +++ b/hw/usb/hcd-xhci.c
> > @@ -1614,7 +1614,7 @@ static int xhci_setup_packet(XHCITransfer *xfer)
> >  xhci_xfer_create_sgl(xfer, dir == USB_TOKEN_IN); /* Also sets
> int_req */
> >  usb_packet_setup(>packet, dir, ep, xfer->streamid,
> > - xfer->trbs[0].addr, false, xfer->int_req);
> > + xfer->trbs[0].addr, dir == USB_TOKEN_IN,
> xfer->int_req);
>
> I suspect this might lead to queues being halted even though they should
> not.
>
> Why does 7ad3d51ebb8a522ffcad391c4bef281245739dde look at short-not-ok?
>

Because the patch changes dev-storage to terminate the transfer if a
short packet is received, so I figured 'short-not-ok' should affect
that behavior.

I guess instead I could add another flag that only hcd-dwc2 sets. Does
that sound OK to you?

Thanks,
Paul


> take care,
>   Gerd
>
>


Re: [PULL 0/3] MIPS + TCG Continuous Benchmarking queue for July 7th, 2020

2020-07-07 Thread Thomas Huth
On 07/07/2020 18.40, Aleksandar Markovic wrote:
> The following changes since commit 710fb08fd297d7a92163debce1959fae8f3b6ed7:
> 
>   Merge remote-tracking branch 
> 'remotes/huth-gitlab/tags/pull-request-2020-07-06' into staging (2020-07-07 
> 12:41:15 +0100)
> 
> are available in the git repository at:
> 
>   https://github.com/AMarkovic/qemu tags/mips-queue-jul-07-2020
> 
> for you to fetch changes up to fa6e7da119b6da4067e757924e165bc737bb1260:
> 
>   scripts/performance: Add dissect.py script (2020-07-07 18:32:20 +0200)
> 
> 
> 
> MIPS + TCG Continuous Benchmarking queue for July 7th, 2020
> 
>   Highlights:
> 
>  - Fix for a regression in FPU emulation add.s.
>  - Add Loongson 2F disassembler.
>  - Add a script for a GSoC project.
> 
>   Note:
> 
>  - A checkpatch error and a checkpatch warning are known and
>  should be ignored.
> 
> 
> 
> Ahmed Karaman (1):
>   scripts/performance: Add dissect.py script
> 
> Alex Richardson (1):
>   target/mips: fpu: Fix recent regression in add.s after 1ace099f2a
> 
> Stefan Brankovic (1):
>   disas: mips: Add Loongson 2F disassembler
> 
>  configure  |1 +
>  disas/loongson2f.h | 2562 +
>  include/disas/dis-asm.h|1 +
>  include/exec/poison.h  |1 +
>  target/mips/cpu.c  |6 +
>  target/mips/fpu_helper.c   |2 +-
>  MAINTAINERS|1 +
>  disas/Makefile.objs|1 +
>  disas/loongson2f.cpp   | 8154 
> 

Honestly, no. Peter, please don't merge this pull request.

That disassembler source code is really huge, and I think someone should
give this a *proper* review first before we include this in our repo. I
just had a quick look at it, and I don't think that it is in the right
shape already. For example, there are hard-coded magic numbers there, like:

bool ADD::disas_output(disassemble_info *info)
+{
+char alias1[5];
+char alias2[5];
+char alias3[5];
...

and in a completely different function, this hard-coded 5 is used again:

+void Instruction32::getAlias(char *buffer, int regNo)
+{
+switch (regNo) {
+case 0:
+strncpy(buffer, "zero", 5);
+break;
+case 1:
+strncpy(buffer, "at", 5);
...

That definitely needs to be turned into a proper #define or the length
needs to be passed as parameter to the function.

Also the coding style is weird in a couple of places, and there were
checkpatch warnings.

Apart from that, Paolo asked you to take a break from MIPS
maintainership for a while, Aleksandar. I strongly support that
suggestion. Your derogatory behavior during the last weeks, especially
in the last one, looked completely unacceptable to me. In my opinion you
really need some time to reflect yourself. You, and we all as a
community, now cannot continue just like nothing happened.

 Thanks,
  Thomas




[PATCH v3 2/2] tests: tpm: Skip over pcrUpdateCounter byte in result comparison

2020-07-07 Thread Stefan Berger
The TPM 2 code in libtpms was fixed to handle the PCR 'TCB group' according
to the PCClient profile. The change of the PCRs belonging to the 'TCB group'
now affects the pcrUpdateCounter in the TPM2_PCRRead() responses where its
value is now different (typically lower by '1') than what it was before. To
not fail the tests, we skip the comparison of the 14th byte, which
represents the pcrUpdateCounter.

Signed-off-by: Stefan Berger 
---
 tests/qtest/tpm-util.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tests/qtest/tpm-util.c b/tests/qtest/tpm-util.c
index 34efae8f18..58a9593745 100644
--- a/tests/qtest/tpm-util.c
+++ b/tests/qtest/tpm-util.c
@@ -139,7 +139,11 @@ void tpm_util_pcrread(QTestState *s, tx_func *tx,
 
 tx(s, tpm_pcrread, sizeof(tpm_pcrread), buffer, sizeof(buffer));
 
-g_assert_cmpmem(buffer, exp_resp_size, exp_resp, exp_resp_size);
+/* skip pcrUpdateCounter (14th byte) in comparison */
+g_assert(exp_resp_size >= 15);
+g_assert_cmpmem(buffer, 13, exp_resp, 13);
+g_assert_cmpmem([14], exp_resp_size - 14,
+_resp[14], exp_resp_size - 14);
 }
 
 bool tpm_util_swtpm_has_tpm2(void)
-- 
2.24.1




[PATCH v3 0/2] tpm: Some fixes

2020-07-07 Thread Stefan Berger
This series of patches fixes the TPM SPAPR device model so that it reacts
in the same way as the other device models do when the backend device did
not start up properly. It now calls exit(1).

Due to a change in the TPM 2 code, the pcrUpdateCounter (14th byte) in the
TPM2_Pcrread response now returns a different value than before. So it's
better to skip the 14th byte when comparing expected against actual responses.

   Stefan

v2->v3:
  - more elaborate commit messages

v1->v2:
  - simplified skipping of 14th byte in response


Stefan Berger (2):
  tpm: tpm_spapr: Exit on TPM backend failures
  tests: tpm: Skip over pcrUpdateCounter byte in result comparison

 hw/tpm/tpm_spapr.c | 5 -
 tests/qtest/tpm-util.c | 6 +-
 2 files changed, 9 insertions(+), 2 deletions(-)

-- 
2.24.1




[PATCH v3 1/2] tpm: tpm_spapr: Exit on TPM backend failures

2020-07-07 Thread Stefan Berger
Exit on TPM backend failures in the same way as the TPM CRB and TIS device
models do. With this change we now get an error report when the backend
did not start up properly:

error: internal error: qemu unexpectedly closed the monitor:
2020-07-07T12:49:28.333928Z qemu-system-ppc64: tpm-emulator: \
  TPM result for CMD_INIT: 0x101 operation failed

Signed-off-by: Stefan Berger 
---
 hw/tpm/tpm_spapr.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/tpm/tpm_spapr.c b/hw/tpm/tpm_spapr.c
index cb4dfd1e6a..8288ab0a15 100644
--- a/hw/tpm/tpm_spapr.c
+++ b/hw/tpm/tpm_spapr.c
@@ -306,7 +306,10 @@ static void tpm_spapr_reset(SpaprVioDevice *dev)
 TPM_SPAPR_BUFFER_MAX);
 
 tpm_backend_reset(s->be_driver);
-tpm_spapr_do_startup_tpm(s, s->be_buffer_size);
+
+if (tpm_spapr_do_startup_tpm(s, s->be_buffer_size) < 0) {
+exit(1);
+}
 }
 
 static enum TPMVersion tpm_spapr_get_version(TPMIf *ti)
-- 
2.24.1




Re: [PATCH v12 2/8] scripts: Coccinelle script to use ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Markus Armbruster
Eric Blake  writes:

> On 7/7/20 11:50 AM, Markus Armbruster wrote:
>> From: Vladimir Sementsov-Ogievskiy 
>>
>> Script adds ERRP_AUTO_PROPAGATE macro invocation where appropriate and
>> does corresponding changes in code (look for details in
>> include/qapi/error.h)
>>
>> Usage example:
>> spatch --sp-file scripts/coccinelle/auto-propagated-errp.cocci \
>>   --macro-file scripts/cocci-macro-file.h --in-place --no-show-diff \
>>   --max-width 80 FILES...
>>
>> Signed-off-by: Vladimir Sementsov-Ogievskiy 
>> Reviewed-by: Markus Armbruster 
>> Signed-off-by: Markus Armbruster 
>> ---
>>   scripts/coccinelle/auto-propagated-errp.cocci | 337 ++
>>   include/qapi/error.h  |   3 +
>>   MAINTAINERS   |   1 +
>>   3 files changed, 341 insertions(+)
>>   create mode 100644 scripts/coccinelle/auto-propagated-errp.cocci
>
> Needs a tweak if we go with ERRP_GUARD.  But that's easy.
>
>> +
>> +// Convert special case with goto separately.
>> +// I tried merging this into the following rule the obvious way, but
>> +// it made Coccinelle hang on block.c
>> +//
>> +// Note interesting thing: if we don't do it here, and try to fixup
>> +// "out: }" things later after all transformations (the rule will be
>> +// the same, just without error_propagate() call), coccinelle fails to
>> +// match this "out: }".
>
> "out: }" is not valid C; would referring to "out: ; }" fare any better?

We can try for the next batch.

>> +@ disable optional_qualifier@
>> +identifier rule1.fn, rule1.local_err, out;
>> +symbol errp;
>> +@@
>> +
>> + fn(..., Error ** , ...)
>> + {
>> + <...
>> +-goto out;
>> ++return;
>> + ...>
>> +- out:
>> +-error_propagate(errp, local_err);
>> + }
>> +
>> +// Convert most of local_err related stuff.
>> +//
>> +// Note, that we inherit rule1.fn and rule1.local_err names, not
>> +// objects themselves. We may match something not related to the
>> +// pattern matched by rule1. For example, local_err may be defined with
>> +// the same name in different blocks inside one function, and in one
>> +// block follow the propagation pattern and in other block doesn't.
>> +//
>> +// Note also that errp-cleaning functions
>> +//   error_free_errp
>> +//   error_report_errp
>> +//   error_reportf_errp
>> +//   warn_report_errp
>> +//   warn_reportf_errp
>> +// are not yet implemented. They must call corresponding Error* -
>> +// freeing function and then set *errp to NULL, to avoid further
>> +// propagation to original errp (consider ERRP_AUTO_PROPAGATE in use).
>> +// For example, error_free_errp may look like this:
>> +//
>> +//void error_free_errp(Error **errp)
>> +//{
>> +//error_free(*errp);
>> +//*errp = NULL;
>> +//}
>
> I guess we can still decide later if we want these additional
> functions, or if they will even help after the number of places we
> have already improved after applying this script as-is and with
> Markus' cleanups in place.

Yes.

> While I won't call myself a Coccinelle expert, it at least looks sane
> enough that I'm comfortable if you add:
>
> Reviewed-by: Eric Blake 

Thanks!




Re: [PATCH v12 1/8] error: New macro ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Vladimir Sementsov-Ogievskiy

07.07.2020 19:50, Markus Armbruster wrote:

From: Vladimir Sementsov-Ogievskiy

Introduce a new ERRP_AUTO_PROPAGATE macro, to be used at start of
functions with an errp OUT parameter.

It has three goals:

1. Fix issue with error_fatal and error_prepend/error_append_hint: user
can't see this additional information, because exit() happens in
error_setg earlier than information is added. [Reported by Greg Kurz]

2. Fix issue with error_abort and error_propagate: when we wrap
error_abort by local_err+error_propagate, the resulting coredump will
refer to error_propagate and not to the place where error happened.
(the macro itself doesn't fix the issue, but it allows us to [3.] drop
the local_err+error_propagate pattern, which will definitely fix the
issue) [Reported by Kevin Wolf]

3. Drop local_err+error_propagate pattern, which is used to workaround
void functions with errp parameter, when caller wants to know resulting
status. (Note: actually these functions could be merely updated to
return int error code).

To achieve these goals, later patches will add invocations
of this macro at the start of functions with either use
error_prepend/error_append_hint (solving 1) or which use
local_err+error_propagate to check errors, switching those
functions to use *errp instead (solving 2 and 3).

Signed-off-by: Vladimir Sementsov-Ogievskiy
Reviewed-by: Paul Durrant
Reviewed-by: Greg Kurz
Reviewed-by: Eric Blake
[Comments merged properly with recent commit "error: Document Error
API usage rules", and edited for clarity.  Put ERRP_AUTO_PROPAGATE()
before its helpers, and touch up style.  Commit message tweaked.]
Signed-off-by: Markus Armbruster


Ok, I see you have mostly rewritten the big comment and not only in this patch, 
so, I go and read the whole comment on top of these series.

=

   * Pass an existing error to the caller with the message modified:
   * error_propagate_prepend(errp, err,
   * "Could not frobnicate '%s': ", name);
   * This is more concise than
   * error_propagate(errp, err); // don't do this
   * error_prepend(errp, "Could not frobnicate '%s': ", name);
   * and works even when @errp is _fatal.

- the latter doesn't consider ERRP_AUTO_PROPAGATE: as we know, that 
ERRP_AUTO_PROPAGATE should be used when we use error_prepend, the latter should 
look like


ERRP_AUTO_PROPAGATE();
...
error_propagate(errp, err); // don't do this
error_prepend(errp, "Could not frobnicate '%s': ", name);

- and it works even when @errp is _fatal, so the error_propagate_prepend 
now is just a shortcut, not the only correct way.


Still, the text is formally correct as is, and may be improved later.

=

   * 2. Replace  by errp, and err by *errp.  Delete local variable
   *@err.

- hmm a bit not obvious,, It can be local_err. It can be (in some rare cases) 
still needed to handle the error locally, not passing to the caller..

may be just something like "Assume local Error *err variable is used to get errors 
from called functions and than propagated to caller's errp" before paragraph [2.] 
will help.


   *
   * 3. Delete error_propagate(errp, *errp), replace
   *error_propagate_prepend(errp, *errp, ...) by error_prepend(errp, ...),
   *
   * 4. Ensure @errp is valid at return: when you destroy *errp, set
   *errp = NULL.

=


May be good to add note about ERRP_AUTO_PROPAGATE() into comment above 
error_append_hint (and error_(v)prepend)).



=

  /*
   * Make @errp parameter easier to use regardless of argument value

may be s/argument/its/

   *
   * This macro is for use right at the beginning of a function that
   * takes an Error **errp parameter to pass errors to its caller.  The
   * parameter must be named @errp.
   *
   * It must be used when the function dereferences @errp or passes
   * @errp to error_prepend(), error_vprepend(), or error_append_hint().
   * It is safe to use even when it's not needed, but please avoid
   * cluttering the source with useless code.
   *
   * If @errp is NULL or _fatal, rewrite it to point to a local
   * Error variable, which will be automatically propagated to the
   * original @errp on function exit.
   *
   * Note: _abort is not rewritten, because that would move the
   * abort from the place where the error is created to the place where
   * it's propagated.
   */

=


All these are minor, the documentation is good as is, thank you!

--
Best regards,
Vladimir



Re: [PATCH v12 1/8] error: New macro ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Markus Armbruster
Eric Blake  writes:

> On 7/7/20 11:50 AM, Markus Armbruster wrote:
>> From: Vladimir Sementsov-Ogievskiy 
>>
>> Introduce a new ERRP_AUTO_PROPAGATE macro, to be used at start of
>> functions with an errp OUT parameter.
>>
>> It has three goals:
>>
>> 1. Fix issue with error_fatal and error_prepend/error_append_hint: user
>
> the user

Yes.

>> can't see this additional information, because exit() happens in
>> error_setg earlier than information is added. [Reported by Greg Kurz]
>>
>> 2. Fix issue with error_abort and error_propagate: when we wrap
>> error_abort by local_err+error_propagate, the resulting coredump will
>> refer to error_propagate and not to the place where error happened.
>> (the macro itself doesn't fix the issue, but it allows us to [3.] drop
>> the local_err+error_propagate pattern, which will definitely fix the
>> issue) [Reported by Kevin Wolf]
>>
>> 3. Drop local_err+error_propagate pattern, which is used to workaround
>> void functions with errp parameter, when caller wants to know resulting
>> status. (Note: actually these functions could be merely updated to
>> return int error code).
>>
>> To achieve these goals, later patches will add invocations
>> of this macro at the start of functions with either use
>> error_prepend/error_append_hint (solving 1) or which use
>> local_err+error_propagate to check errors, switching those
>> functions to use *errp instead (solving 2 and 3).
>>
>> Signed-off-by: Vladimir Sementsov-Ogievskiy 
>> Reviewed-by: Paul Durrant 
>> Reviewed-by: Greg Kurz 
>> Reviewed-by: Eric Blake 
>> [Comments merged properly with recent commit "error: Document Error
>> API usage rules", and edited for clarity.  Put ERRP_AUTO_PROPAGATE()
>> before its helpers, and touch up style.  Commit message tweaked.]
>> Signed-off-by: Markus Armbruster 
>> ---
>>   include/qapi/error.h | 160 ++-
>>   1 file changed, 141 insertions(+), 19 deletions(-)
>>
>> diff --git a/include/qapi/error.h b/include/qapi/error.h
>> index 3fed49747d..c865a7d2f1 100644
>> --- a/include/qapi/error.h
>> +++ b/include/qapi/error.h
>
>> @@ -128,18 +122,26 @@
>>* handle the error...
>>* }
>>* when it doesn't, say a void function:
>> + * ERRP_AUTO_PROPAGATE();
>> + * foo(arg, errp);
>> + * if (*errp) {
>> + * handle the error...
>> + * }
>> + * More on ERRP_AUTO_PROPAGATE() below.
>> + *
>> + * Code predating ERRP_AUTO_PROPAGATE() still exits, and looks like this:
>
> exists

Fixing...

>>* Error *err = NULL;
>>* foo(arg, );
>>* if (err) {
>>* handle the error...
>> - * error_propagate(errp, err);
>> + * error_propagate(errp, err); // deprecated
>>* }
>> - * Do *not* "optimize" this to
>> + * Avoid in new code.  Do *not* "optimize" it to
>>* foo(arg, errp);
>>* if (*errp) { // WRONG!
>>* handle the error...
>>* }
>> - * because errp may be NULL!
>> + * because errp may be NULL!  Guard with ERRP_AUTO_PROPAGATE().
>
> maybe:
>
> because errp may be NULL without the ERRP_AUTO_PROPAGATE() guard.

Sold.

>>*
>>* But when all you do with the error is pass it on, please use
>>* foo(arg, errp);
>> @@ -158,6 +160,19 @@
>>* handle the error...
>>* }
>>*
>> + * Pass an existing error to the caller:
>
>> + * = Converting to ERRP_AUTO_PROPAGATE() =
>> + *
>> + * To convert a function to use ERRP_AUTO_PROPAGATE():
>> + *
>> + * 0. If the Error ** parameter is not named @errp, rename it to
>> + *@errp.
>> + *
>> + * 1. Add an ERRP_AUTO_PROPAGATE() invocation, by convention right at
>> + *the beginning of the function.  This makes @errp safe to use.
>> + *
>> + * 2. Replace  by errp, and err by *errp.  Delete local variable
>> + *@err.
>> + *
>> + * 3. Delete error_propagate(errp, *errp), replace
>> + *error_propagate_prepend(errp, *errp, ...) by error_prepend(errp, ...),
>> + *
>
> Why a comma here?

Editing accident.

>> + * 4. Ensure @errp is valid at return: when you destroy *errp, set
>> + *errp = NULL.
>> + *
>> + * Example:
>> + *
>> + * bool fn(..., Error **errp)
>> + * {
>> + * Error *err = NULL;
>> + *
>> + * foo(arg, );
>> + * if (err) {
>> + * handle the error...
>> + * error_propagate(errp, err);
>> + * return false;
>> + * }
>> + * ...
>> + * }
>> + *
>> + * becomes
>> + *
>> + * bool fn(..., Error **errp)
>> + * {
>> + * ERRP_AUTO_PROPAGATE();
>> + *
>> + * foo(arg, errp);
>> + * if (*errp) {
>> + * handle the error...
>> + * return false;
>> + * }
>> + * ...
>> + * }
>
> Do we want the example to show the use of error_free and *errp = NULL?

Yes, but we're running out of time, so let's do it in the series that
introduces the usage to the code.

> Otherwise, this is looking good to me.  It will need a 

Re: [PATCH v6 08/10] iotests: Specify explicit backing format where sensible

2020-07-07 Thread Eric Blake

On 7/7/20 11:07 AM, Kevin Wolf wrote:

Am 06.07.2020 um 22:39 hat Eric Blake geschrieben:

There are many existing qcow2 images that specify a backing file but
no format.  This has been the source of CVEs in the past, but has
become more prominent of a problem now that libvirt has switched to
-blockdev.  With older -drive, at least the probing was always done by
qemu (so the only risk of a changed format between successive boots of
a guest was if qemu was upgraded and probed differently).  But with
newer -blockdev, libvirt must specify a format; if libvirt guesses raw
where the image was formatted, this results in data corruption visible
to the guest; conversely, if libvirt guesses qcow2 where qemu was
using raw, this can result in potential security holes, so modern
libvirt instead refuses to use images without explicit backing format.

The change in libvirt to reject images without explicit backing format
has pointed out that a number of tools have been far too reliant on
probing in the past.  It's time to set a better example in our own
iotests of properly setting this parameter.

iotest calls to create, rebase, and convert are all impacted to some
degree.  It's a bit annoying that we are inconsistent on command line
- while all of those accept -o backing_file=...,backing_fmt=..., the
shortcuts are different: create and rebase have -b and -F, while
convert has -B but no -F.  (amend has no shortcuts, but the previous
patch just deprecated the use of amend to change backing chains).

Signed-off-by: Eric Blake 


This breaks at least 024 and 043 for qed because qemu-img info can't
print the backing file format there (qed only saves a flag whether it's
raw or non-raw).


Shoot.  I tend to avoid tests of qed and qcow (because they take so 
long), so while I may have tested them around v1 or v2 of the series, 
all the rebasing has changed the results by now.  Such is life.




We can fix the output filtering during the freeze, though.


Yes indeed, and I'll post such patches soon, now that you've pointed it out.

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [RFC v2 1/1] memory: Delete assertion in memory_region_unregister_iommu_notifier

2020-07-07 Thread Peter Xu
On Tue, Jul 07, 2020 at 04:03:10PM +0800, Jason Wang wrote:
> 
> On 2020/7/3 下午9:03, Peter Xu wrote:
> > On Fri, Jul 03, 2020 at 03:24:19PM +0800, Jason Wang wrote:
> > > On 2020/7/2 下午11:45, Peter Xu wrote:
> > > > On Thu, Jul 02, 2020 at 11:01:54AM +0800, Jason Wang wrote:
> > > > > So I think we agree that a new notifier is needed?
> > > > Good to me, or a new flag should be easier (IOMMU_NOTIFIER_DEV_IOTLB)?
> > > 
> > > That should work but I wonder something as following is better.
> > > 
> > > Instead of introducing new flags, how about carry the type of event in the
> > > notifier then the device (vhost) can choose the message it want to process
> > > like:
> > > 
> > > static vhost_iommu_event(IOMMUNotifier *n, IOMMUTLBEvent *event)
> > > 
> > > {
> > > 
> > > switch (event->type) {
> > > 
> > > case IOMMU_MAP:
> > > case IOMMU_UNMAP:
> > > case IOMMU_DEV_IOTLB_UNMAP:
> > > ...
> > > 
> > > }
> > Looks ok to me, though imo we should still keep the registration 
> > information,
> > so VT-d knows which notifiers is interested in which events.  E.g., we can
> > still do something like vtd_as_has_map_notifier().
> 
> 
> Is this for a better performance?
> 
> I wonder whether it's worth since we can't not have both vhost and vtd to be
> registered into the same as.

/me failed to follow this sentence.. :(

> 
> So it should be functional equivalent to vtd_as_has_notifier().

For example: in vtd_iommu_replay() we'll skip the replay if vhost has
registered the iommu notifier because vtd_as_has_map_notifier() will return
false.  It'll only return true if the device is a vfio-pci device.

Without vtd_as_has_map_notifier(), how could we do that?

-- 
Peter Xu




Re: [PATCH v4 03/45] error: Document Error API usage rules

2020-07-07 Thread Eric Blake

On 7/7/20 2:23 PM, Markus Armbruster wrote:


It helps that you have repeated the same pattern as above.  But that
means if you change the layout, both groupings should have the same
layout.  Maybe:

Intro for a task:
- when the function returns...
- when it doesn't

Also, are there functions that have a return type other than void, but
where the return value is not an indication of error?  If there are,


Yes, there are such functions.


then the "say a void function" clause makes sense (but we should
probably recommend against such functions); if there are not, then
"say a void function" reads awkwardly.  Maybe:

- when it does not, because it is a void function:


What about

   - when it does not, say because it is a void function:


Reasonable.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v4 10/45] qemu-option: Simplify around find_default_by_name()

2020-07-07 Thread Greg Kurz
On Tue,  7 Jul 2020 18:05:38 +0200
Markus Armbruster  wrote:

> Signed-off-by: Markus Armbruster 
> Reviewed-by: Eric Blake 
> Reviewed-by: Vladimir Sementsov-Ogievskiy 
> ---

Reviewed-by: Greg Kurz 

>  util/qemu-option.c | 18 +-
>  1 file changed, 5 insertions(+), 13 deletions(-)
> 
> diff --git a/util/qemu-option.c b/util/qemu-option.c
> index 14e211ddd8..e7b540a21b 100644
> --- a/util/qemu-option.c
> +++ b/util/qemu-option.c
> @@ -277,7 +277,6 @@ static void qemu_opt_del_all(QemuOpts *opts, const char 
> *name)
>  const char *qemu_opt_get(QemuOpts *opts, const char *name)
>  {
>  QemuOpt *opt;
> -const char *def_val;
>  
>  if (opts == NULL) {
>  return NULL;
> @@ -285,12 +284,10 @@ const char *qemu_opt_get(QemuOpts *opts, const char 
> *name)
>  
>  opt = qemu_opt_find(opts, name);
>  if (!opt) {
> -def_val = find_default_by_name(opts, name);
> -if (def_val) {
> -return def_val;
> -}
> +return find_default_by_name(opts, name);
>  }
> -return opt ? opt->str : NULL;
> +
> +return opt->str;
>  }
>  
>  void qemu_opt_iter_init(QemuOptsIter *iter, QemuOpts *opts, const char *name)
> @@ -319,8 +316,7 @@ const char *qemu_opt_iter_next(QemuOptsIter *iter)
>  char *qemu_opt_get_del(QemuOpts *opts, const char *name)
>  {
>  QemuOpt *opt;
> -const char *def_val;
> -char *str = NULL;
> +char *str;
>  
>  if (opts == NULL) {
>  return NULL;
> @@ -328,11 +324,7 @@ char *qemu_opt_get_del(QemuOpts *opts, const char *name)
>  
>  opt = qemu_opt_find(opts, name);
>  if (!opt) {
> -def_val = find_default_by_name(opts, name);
> -if (def_val) {
> -str = g_strdup(def_val);
> -}
> -return str;
> +return g_strdup(find_default_by_name(opts, name));
>  }
>  str = opt->str;
>  opt->str = NULL;




Re: [PATCH v12 7/8] nbd: Use ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Eric Blake

On 7/7/20 11:50 AM, Markus Armbruster wrote:

From: Vladimir Sementsov-Ogievskiy 

If we want to add some info to errp (by error_prepend() or
error_append_hint()), we must use the ERRP_AUTO_PROPAGATE macro.
Otherwise, this info will not be added when errp == _fatal
(the program will exit prior to the error_append_hint() or
error_prepend() call).  Fix such cases.

If we want to check error after errp-function call, we need to
introduce local_err and then propagate it to errp. Instead, use
ERRP_AUTO_PROPAGATE macro, benefits are:
1. No need of explicit error_propagate call
2. No need of explicit local_err variable: use errp directly
3. ERRP_AUTO_PROPAGATE leaves errp as is if it's not NULL or
_fatal, this means that we don't break error_abort
(we'll abort on error_set, not on error_propagate)

This commit is generated by command

 sed -n '/^Network Block Device (NBD)$/,/^$/{s/^F: //p}' \
 MAINTAINERS | \
 xargs git ls-files | grep '\.[hc]$' | \
 xargs spatch \
 --sp-file scripts/coccinelle/auto-propagated-errp.cocci \
 --macro-file scripts/cocci-macro-file.h \
 --in-place --no-show-diff --max-width 80

Reported-by: Kevin Wolf 
Reported-by: Greg Kurz 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Markus Armbruster 
[Commit message tweaked]
Signed-off-by: Markus Armbruster 
---


Reviewed-by: Eric Blake 

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v4 02/45] error: Improve error.h's big comment

2020-07-07 Thread Greg Kurz
On Tue,  7 Jul 2020 18:05:30 +0200
Markus Armbruster  wrote:

> Add headlines to the big comment.
> 
> Explain examples for NULL, _abort and _fatal argument
> better.
> 
> Tweak rationale for error_propagate_prepend().
> 
> Signed-off-by: Markus Armbruster 
> ---

Reviewed-by: Greg Kurz 

>  include/qapi/error.h | 51 +++-
>  1 file changed, 36 insertions(+), 15 deletions(-)
> 
> diff --git a/include/qapi/error.h b/include/qapi/error.h
> index e8960eaad5..6d079c58b7 100644
> --- a/include/qapi/error.h
> +++ b/include/qapi/error.h
> @@ -15,6 +15,8 @@
>  /*
>   * Error reporting system loosely patterned after Glib's GError.
>   *
> + * = Creating errors =
> + *
>   * Create an error:
>   * error_setg(, "situation normal, all fouled up");
>   *
> @@ -27,6 +29,8 @@
>   * error_setg(, "invalid quark\n" // WRONG!
>   *"Valid quarks are up, down, strange, charm, top, bottom.");
>   *
> + * = Reporting and destroying errors =
> + *
>   * Report an error to the current monitor if we have one, else stderr:
>   * error_report_err(err);
>   * This frees the error object.
> @@ -40,6 +44,30 @@
>   * error_free(err);
>   * Note that this loses hints added with error_append_hint().
>   *
> + * Call a function ignoring errors:
> + * foo(arg, NULL);
> + * This is more concise than
> + * Error *err = NULL;
> + * foo(arg, );
> + * error_free(err); // don't do this
> + *
> + * Call a function aborting on errors:
> + * foo(arg, _abort);
> + * This is more concise and fails more nicely than
> + * Error *err = NULL;
> + * foo(arg, );
> + * assert(!err); // don't do this
> + *
> + * Call a function treating errors as fatal:
> + * foo(arg, _fatal);
> + * This is more concise than
> + * Error *err = NULL;
> + * foo(arg, );
> + * if (err) { // don't do this
> + * error_report_err(err);
> + * exit(1);
> + * }
> + *
>   * Handle an error without reporting it (just for completeness):
>   * error_free(err);
>   *
> @@ -47,6 +75,11 @@
>   * reporting it (primarily useful in testsuites):
>   * error_free_or_abort();
>   *
> + * = Passing errors around =
> + *
> + * Errors get passed to the caller through the conventional @errp
> + * parameter.
> + *
>   * Pass an existing error to the caller:
>   * error_propagate(errp, err);
>   * where Error **errp is a parameter, by convention the last one.
> @@ -54,11 +87,10 @@
>   * Pass an existing error to the caller with the message modified:
>   * error_propagate_prepend(errp, err,
>   * "Could not frobnicate '%s': ", name);
> - *
> - * Avoid
> - * error_propagate(errp, err);
> + * This is more concise than
> + * error_propagate(errp, err); // don't do this
>   * error_prepend(errp, "Could not frobnicate '%s': ", name);
> - * because this fails to prepend when @errp is _fatal.
> + * and works even when @errp is _fatal.
>   *
>   * Create a new error and pass it to the caller:
>   * error_setg(errp, "situation normal, all fouled up");
> @@ -70,15 +102,6 @@
>   * handle the error...
>   * }
>   *
> - * Call a function ignoring errors:
> - * foo(arg, NULL);
> - *
> - * Call a function aborting on errors:
> - * foo(arg, _abort);
> - *
> - * Call a function treating errors as fatal:
> - * foo(arg, _fatal);
> - *
>   * Receive an error and pass it on to the caller:
>   * Error *err = NULL;
>   * foo(arg, );
> @@ -86,8 +109,6 @@
>   * handle the error...
>   * error_propagate(errp, err);
>   * }
> - * where Error **errp is a parameter, by convention the last one.
> - *
>   * Do *not* "optimize" this to
>   * foo(arg, errp);
>   * if (*errp) { // WRONG!




Re: [PATCH v12 2/8] scripts: Coccinelle script to use ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Eric Blake

On 7/7/20 11:50 AM, Markus Armbruster wrote:

From: Vladimir Sementsov-Ogievskiy 

Script adds ERRP_AUTO_PROPAGATE macro invocation where appropriate and
does corresponding changes in code (look for details in
include/qapi/error.h)

Usage example:
spatch --sp-file scripts/coccinelle/auto-propagated-errp.cocci \
  --macro-file scripts/cocci-macro-file.h --in-place --no-show-diff \
  --max-width 80 FILES...

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Markus Armbruster 
Signed-off-by: Markus Armbruster 
---
  scripts/coccinelle/auto-propagated-errp.cocci | 337 ++
  include/qapi/error.h  |   3 +
  MAINTAINERS   |   1 +
  3 files changed, 341 insertions(+)
  create mode 100644 scripts/coccinelle/auto-propagated-errp.cocci


Needs a tweak if we go with ERRP_GUARD.  But that's easy.


+
+// Convert special case with goto separately.
+// I tried merging this into the following rule the obvious way, but
+// it made Coccinelle hang on block.c
+//
+// Note interesting thing: if we don't do it here, and try to fixup
+// "out: }" things later after all transformations (the rule will be
+// the same, just without error_propagate() call), coccinelle fails to
+// match this "out: }".


"out: }" is not valid C; would referring to "out: ; }" fare any better?


+@ disable optional_qualifier@
+identifier rule1.fn, rule1.local_err, out;
+symbol errp;
+@@
+
+ fn(..., Error ** , ...)
+ {
+ <...
+-goto out;
++return;
+ ...>
+- out:
+-error_propagate(errp, local_err);
+ }
+
+// Convert most of local_err related stuff.
+//
+// Note, that we inherit rule1.fn and rule1.local_err names, not
+// objects themselves. We may match something not related to the
+// pattern matched by rule1. For example, local_err may be defined with
+// the same name in different blocks inside one function, and in one
+// block follow the propagation pattern and in other block doesn't.
+//
+// Note also that errp-cleaning functions
+//   error_free_errp
+//   error_report_errp
+//   error_reportf_errp
+//   warn_report_errp
+//   warn_reportf_errp
+// are not yet implemented. They must call corresponding Error* -
+// freeing function and then set *errp to NULL, to avoid further
+// propagation to original errp (consider ERRP_AUTO_PROPAGATE in use).
+// For example, error_free_errp may look like this:
+//
+//void error_free_errp(Error **errp)
+//{
+//error_free(*errp);
+//*errp = NULL;
+//}


I guess we can still decide later if we want these additional functions, 
or if they will even help after the number of places we have already 
improved after applying this script as-is and with Markus' cleanups in 
place.


While I won't call myself a Coccinelle expert, it at least looks sane 
enough that I'm comfortable if you add:


Reviewed-by: Eric Blake 

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v4 03/45] error: Document Error API usage rules

2020-07-07 Thread Markus Armbruster
Eric Blake  writes:

> On 7/7/20 11:05 AM, Markus Armbruster wrote:
>> This merely codifies existing practice, with one exception: the rule
>> advising against returning void, where existing practice is mixed.
>>
>> When the Error API was created, we adopted the (unwritten) rule to
>> return void when the function returns no useful value on success,
>> unlike GError, which recommends to return true on success and false on
>> error then.
>>
>
>> Make the rule advising against returning void official by putting it
>> in writing.  This will hopefully reduce confusion.
>>
>> Update the examples accordingly.
>>
>> The remainder of this series will update a substantial amount of code
>> to honor the rule.
>>
>> Signed-off-by: Markus Armbruster 
>> Reviewed-by: Eric Blake 
>> Reviewed-by: Vladimir Sementsov-Ogievskiy 
>> Reviewed-by: Greg Kurz 
>> ---
>
>> @@ -95,14 +122,12 @@
>>* Create a new error and pass it to the caller:
>>* error_setg(errp, "situation normal, all fouled up");
>>*
>> - * Call a function and receive an error from it:
>> - * Error *err = NULL;
>> - * foo(arg, );
>> - * if (err) {
>> + * Call a function, receive an error from it, and pass it to caller
>
> maybe s/to caller/to the caller/

Yes.

>> + * when the function returns a value that indicates failure, say false:
>> + * if (!foo(arg, errp)) {
>>* handle the error...
>>* }
>> - *
>> - * Receive an error and pass it on to the caller:
>> + * when it doesn't, say a void function:
>
> Hmm. It looks like you have a single sentence "Call a function... when
> the function returns", but this line now makes it obvious that you
> have a single prefix: "Call a function, ...and pass it to the caller:"
> with two choices "when the function returns" and "when it doesn't".
> I'm not sure if there is a nicer way to typeset it, adding yet another
> ":" at the end of the line looks odd.  The idea behind the text is
> fine, I'm just trying to paint the bikeshed to see if there is a
> better presentation.
>
>>* Error *err = NULL;
>>* foo(arg, );
>>* if (err) {
>> @@ -120,6 +145,19 @@
>>* foo(arg, errp);
>>* for readability.
>>*
>> + * Receive an error, and handle it locally
>> + * when the function returns a value that indicates failure, say false:
>> + * Error *err = NULL;
>> + * if (!foo(arg, )) {
>> + * handle the error...
>> + * }
>> + * when it doesn't, say a void function:
>
> It helps that you have repeated the same pattern as above.  But that
> means if you change the layout, both groupings should have the same
> layout.  Maybe:
>
> Intro for a task:
> - when the function returns...
> - when it doesn't
>
> Also, are there functions that have a return type other than void, but
> where the return value is not an indication of error?  If there are,

Yes, there are such functions.

> then the "say a void function" clause makes sense (but we should
> probably recommend against such functions); if there are not, then
> "say a void function" reads awkwardly.  Maybe:
>
> - when it does not, because it is a void function:

What about

  - when it does not, say because it is a void function:

>> + * Error *err = NULL;
>> + * foo(arg, );
>> + * if (err) {
>> + * handle the error...
>> + * }
>> + *
>>* Receive and accumulate multiple errors (first one wins):
>>* Error *err = NULL, *local_err = NULL;
>>* foo(arg, );
>>

Thanks!




Re: [PATCH 00/21] target/xtensa: implement double precision FPU

2020-07-07 Thread Alex Bennée


Max Filippov  writes:

> On Tue, Jul 7, 2020 at 4:31 AM Alex Bennée  wrote:
>> I've only looked at the softfloat bits as I'm not familiar with xtensa
>
> Thanks for taking a look!
>
>> at all. However you can have a vague:
>>
>> Tested-by: Alex Bennée 
>>
>> for the series - congratulations you pass your own tests ;-)
>
> Unless you've built toolchains for the newly added cores and
> run the tests on these cores it only means that new tests are
> properly disabled for the cores without FPU/DFPU. I'll
> take it as an independent build test (:

Well it ran some xtensa tests thanks to the docker cross compiler
support. Do you know what toolchains we need?

Currently we have the following:

  ENV CPU_LIST csp dc232b dc233c
  ENV TOOLCHAIN_RELEASE 2018.02

  RUN for cpu in $CPU_LIST; do \
  curl -#SL 
http://github.com/foss-xtensa/toolchain/releases/download/$TOOLCHAIN_RELEASE/x86_64-$TOOLCHAIN_RELEASE-xtensa-$cpu-elf.tar.gz
 \
  | tar -xzC /opt; \
  done

  ENV PATH 
$PATH:/opt/$TOOLCHAIN_RELEASE/xtensa-dc232b-elf/bin:/opt/$TOOLCHAIN_RELEASE/xtensa-dc233c-elf/bin:/opt/$TOOLCHAIN_RELEASE/xtensa-csp-elf/bin

-- 
Alex Bennée



Re: [PATCH v2 01/21] softfloat: make NO_SIGNALING_NANS runtime property

2020-07-07 Thread Alex Bennée


Max Filippov  writes:

> target/xtensa, the only user of NO_SIGNALING_NANS macro has FPU
> implementations with and without the corresponding property. With
> NO_SIGNALING_NANS being a macro they cannot be a part of the same QEMU
> executable.
> Replace macro with new property in float_status to allow cores with
> different FPU implementations coexist.
>
> Cc: Peter Maydell 
> Cc: "Alex Bennée" 
> Signed-off-by: Max Filippov 

Reviewed-by: Alex Bennée 

-- 
Alex Bennée



Re: [PATCH] load_elf: Remove unused address variables from callers

2020-07-07 Thread Max Filippov
On Sun, Jul 5, 2020 at 10:40 AM BALATON Zoltan  wrote:
>
> Several callers of load_elf() pass pointers for lowaddr and highaddr
> parameters which are then not used for anything. This may stem from a
> misunderstanding that load_elf need a value here but in fact it can
> take NULL to ignore these values. Remove such unused variables and
> pass NULL instead from callers that don't need these.
>
> Signed-off-by: BALATON Zoltan 
> ---
[...]
>  hw/xtensa/sim.c|  3 +--
>  hw/xtensa/xtfpga.c |  3 +--

For Xtensa parts:
Acked-by: Max Filippov 

-- 
Thanks.
-- Max



Re: [PATCH v4 1/2] nvme: indicate CMB support through controller capabilities register

2020-07-07 Thread Klaus Jensen
On Jul  7 19:27, Maxim Levitsky wrote:
> On Wed, 2020-07-01 at 14:48 -0700, Andrzej Jakowski wrote:
> > This patch sets CMBS bit in controller capabilities register when user
> > configures NVMe driver with CMB support, so capabilites are correctly
> > reported to guest OS.
> > 
> > Signed-off-by: Andrzej Jakowski 
> > Reviewed-by: Klaus Jensen 
> > ---
> >  hw/block/nvme.c  | 2 +-
> >  include/block/nvme.h | 6 +-
> >  2 files changed, 6 insertions(+), 2 deletions(-)
> > 
> > diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> > index 1aee042d4c..9f11f3e9da 100644
> > --- a/hw/block/nvme.c
> > +++ b/hw/block/nvme.c
> > @@ -1582,6 +1582,7 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice 
> > *pci_dev)
> >  NVME_CAP_SET_TO(n->bar.cap, 0xf);
> >  NVME_CAP_SET_CSS(n->bar.cap, 1);
> >  NVME_CAP_SET_MPSMAX(n->bar.cap, 4);
> > +NVME_CAP_SET_CMBS(n->bar.cap, n->params.cmb_size_mb ? 1 : 0);
> >  
> >  n->bar.vs = 0x00010200;
> >  n->bar.intmc = n->bar.intms = 0;
> > @@ -1591,7 +1592,6 @@ static void nvme_realize(PCIDevice *pci_dev, Error 
> > **errp)
> >  {
> >  NvmeCtrl *n = NVME(pci_dev);
> >  Error *local_err = NULL;
> > -
> >  int i;
> >  
> >  nvme_check_constraints(n, _err);
> > diff --git a/include/block/nvme.h b/include/block/nvme.h
> > index 1720ee1d51..14cf398dfa 100644
> > --- a/include/block/nvme.h
> > +++ b/include/block/nvme.h
> > @@ -35,6 +35,7 @@ enum NvmeCapShift {
> >  CAP_MPSMIN_SHIFT   = 48,
> >  CAP_MPSMAX_SHIFT   = 52,
> >  CAP_PMR_SHIFT  = 56,
> > +CAP_CMB_SHIFT  = 57,
> >  };
> >  
> >  enum NvmeCapMask {
> > @@ -48,6 +49,7 @@ enum NvmeCapMask {
> >  CAP_MPSMIN_MASK= 0xf,
> >  CAP_MPSMAX_MASK= 0xf,
> >  CAP_PMR_MASK   = 0x1,
> > +CAP_CMB_MASK   = 0x1,
> >  };
> >  
> >  #define NVME_CAP_MQES(cap)  (((cap) >> CAP_MQES_SHIFT)   & CAP_MQES_MASK)
> > @@ -78,8 +80,10 @@ enum NvmeCapMask {
> > << 
> > CAP_MPSMIN_SHIFT)
> >  #define NVME_CAP_SET_MPSMAX(cap, val) (cap |= (uint64_t)(val & 
> > CAP_MPSMAX_MASK)\
> >  << 
> > CAP_MPSMAX_SHIFT)
> > -#define NVME_CAP_SET_PMRS(cap, val) (cap |= (uint64_t)(val & CAP_PMR_MASK)\
> > +#define NVME_CAP_SET_PMRS(cap, val)   (cap |= (uint64_t)(val & 
> > CAP_PMR_MASK)   \
> >  << 
> > CAP_PMR_SHIFT)
> > +#define NVME_CAP_SET_CMBS(cap, val)   (cap |= (uint64_t)(val & 
> > CAP_CMB_MASK)   \
> > +   << 
> > CAP_CMB_SHIFT)
> >  
> >  enum NvmeCcShift {
> >  CC_EN_SHIFT = 0,
> 
> 
> I wonder how this could have beeing forgotten. Hmm.
> I see that Linux kernel uses CMBSZ != for that.
> I guess this explains it.
> 
> Reviewed-by: Maxim Levitsky 
> 

It is a v1.4 field. The CMB support was added when NVMe was at v1.2.
And the Linux kernel is also basically adhering to v1.3 wrt. CMB
support. In v1.4 the host actually needs to specifically enable the CMB
- and that is not something the kernel does currently IIRC.



Re: [PATCH v12 1/8] error: New macro ERRP_AUTO_PROPAGATE()

2020-07-07 Thread Eric Blake

On 7/7/20 11:50 AM, Markus Armbruster wrote:

From: Vladimir Sementsov-Ogievskiy 

Introduce a new ERRP_AUTO_PROPAGATE macro, to be used at start of
functions with an errp OUT parameter.

It has three goals:

1. Fix issue with error_fatal and error_prepend/error_append_hint: user


the user


can't see this additional information, because exit() happens in
error_setg earlier than information is added. [Reported by Greg Kurz]

2. Fix issue with error_abort and error_propagate: when we wrap
error_abort by local_err+error_propagate, the resulting coredump will
refer to error_propagate and not to the place where error happened.
(the macro itself doesn't fix the issue, but it allows us to [3.] drop
the local_err+error_propagate pattern, which will definitely fix the
issue) [Reported by Kevin Wolf]

3. Drop local_err+error_propagate pattern, which is used to workaround
void functions with errp parameter, when caller wants to know resulting
status. (Note: actually these functions could be merely updated to
return int error code).

To achieve these goals, later patches will add invocations
of this macro at the start of functions with either use
error_prepend/error_append_hint (solving 1) or which use
local_err+error_propagate to check errors, switching those
functions to use *errp instead (solving 2 and 3).

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Paul Durrant 
Reviewed-by: Greg Kurz 
Reviewed-by: Eric Blake 
[Comments merged properly with recent commit "error: Document Error
API usage rules", and edited for clarity.  Put ERRP_AUTO_PROPAGATE()
before its helpers, and touch up style.  Commit message tweaked.]
Signed-off-by: Markus Armbruster 
---
  include/qapi/error.h | 160 ++-
  1 file changed, 141 insertions(+), 19 deletions(-)

diff --git a/include/qapi/error.h b/include/qapi/error.h
index 3fed49747d..c865a7d2f1 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h



@@ -128,18 +122,26 @@
   * handle the error...
   * }
   * when it doesn't, say a void function:
+ * ERRP_AUTO_PROPAGATE();
+ * foo(arg, errp);
+ * if (*errp) {
+ * handle the error...
+ * }
+ * More on ERRP_AUTO_PROPAGATE() below.
+ *
+ * Code predating ERRP_AUTO_PROPAGATE() still exits, and looks like this:


exists


   * Error *err = NULL;
   * foo(arg, );
   * if (err) {
   * handle the error...
- * error_propagate(errp, err);
+ * error_propagate(errp, err); // deprecated
   * }
- * Do *not* "optimize" this to
+ * Avoid in new code.  Do *not* "optimize" it to
   * foo(arg, errp);
   * if (*errp) { // WRONG!
   * handle the error...
   * }
- * because errp may be NULL!
+ * because errp may be NULL!  Guard with ERRP_AUTO_PROPAGATE().


maybe:

because errp may be NULL without the ERRP_AUTO_PROPAGATE() guard.


   *
   * But when all you do with the error is pass it on, please use
   * foo(arg, errp);
@@ -158,6 +160,19 @@
   * handle the error...
   * }
   *
+ * Pass an existing error to the caller:



+ * = Converting to ERRP_AUTO_PROPAGATE() =
+ *
+ * To convert a function to use ERRP_AUTO_PROPAGATE():
+ *
+ * 0. If the Error ** parameter is not named @errp, rename it to
+ *@errp.
+ *
+ * 1. Add an ERRP_AUTO_PROPAGATE() invocation, by convention right at
+ *the beginning of the function.  This makes @errp safe to use.
+ *
+ * 2. Replace  by errp, and err by *errp.  Delete local variable
+ *@err.
+ *
+ * 3. Delete error_propagate(errp, *errp), replace
+ *error_propagate_prepend(errp, *errp, ...) by error_prepend(errp, ...),
+ *


Why a comma here?


+ * 4. Ensure @errp is valid at return: when you destroy *errp, set
+ *errp = NULL.
+ *
+ * Example:
+ *
+ * bool fn(..., Error **errp)
+ * {
+ * Error *err = NULL;
+ *
+ * foo(arg, );
+ * if (err) {
+ * handle the error...
+ * error_propagate(errp, err);
+ * return false;
+ * }
+ * ...
+ * }
+ *
+ * becomes
+ *
+ * bool fn(..., Error **errp)
+ * {
+ * ERRP_AUTO_PROPAGATE();
+ *
+ * foo(arg, errp);
+ * if (*errp) {
+ * handle the error...
+ * return false;
+ * }
+ * ...
+ * }


Do we want the example to show the use of error_free and *errp = NULL?

Otherwise, this is looking good to me.  It will need a tweak if we go 
with the shorter name ERRP_GUARD, but I like that idea.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




QEMU | Pipeline #164053628 has failed for master | c8eaf81f

2020-07-07 Thread GitLab via


Your pipeline has failed.

Project: QEMU ( https://gitlab.com/qemu-project/qemu )
Branch: master ( https://gitlab.com/qemu-project/qemu/-/commits/master )

Commit: c8eaf81f ( 
https://gitlab.com/qemu-project/qemu/-/commit/c8eaf81fd22638691c5bdcc7d723d31fbb80ff6f
 )
Commit Message: Merge remote-tracking branch 'remotes/mst/tags/...
Commit Author: Peter Maydell ( https://gitlab.com/pm215 )

Pipeline #164053628 ( 
https://gitlab.com/qemu-project/qemu/-/pipelines/164053628 ) triggered by Alex 
Bennée ( https://gitlab.com/stsquad )
had 1 failed build.

Job #627813538 ( https://gitlab.com/qemu-project/qemu/-/jobs/627813538/raw )

Stage: test
Name: build-disabled
Trace: qemu-system-i386: falling back to tcg
Could not access KVM kernel module: No such file or directory
qemu-system-i386: -accel kvm: failed to initialize kvm: No such file or 
directory
qemu-system-i386: falling back to tcg
Could not access KVM kernel module: No such file or directory
qemu-system-i386: -accel kvm: failed to initialize kvm: No such file or 
directory
qemu-system-i386: falling back to tcg
  TESTcheck-qtest-i386: tests/qtest/device-introspect-test
  TESTcheck-qtest-i386: tests/qtest/machine-none-test
  TESTcheck-qtest-i386: tests/qtest/qmp-test
  TESTcheck-qtest-i386: tests/qtest/qmp-cmd-test
  TESTcheck-qtest-i386: tests/qtest/qom-test
  TESTcheck-qtest-i386: tests/qtest/test-hmp
  TESTcheck-qtest-i386: tests/qtest/qos-test
  TESTcheck-qtest-mips64: tests/qtest/endianness-test
  TESTcheck-qtest-mips64: tests/qtest/display-vga-test
  TESTcheck-qtest-mips64: tests/qtest/cdrom-test
  TESTcheck-qtest-mips64: tests/qtest/device-introspect-test
  TESTcheck-qtest-mips64: tests/qtest/machine-none-test
  TESTcheck-qtest-mips64: tests/qtest/qmp-test
  TESTcheck-qtest-mips64: tests/qtest/qmp-cmd-test
  TESTcheck-qtest-mips64: tests/qtest/qom-test
  TESTcheck-qtest-mips64: tests/qtest/test-hmp
  TESTcheck-qtest-mips64: tests/qtest/qos-test
  TESTcheck-qtest-ppc64: tests/qtest/machine-none-test
  TESTcheck-qtest-ppc64: tests/qtest/qmp-test
  TESTcheck-qtest-ppc64: tests/qtest/qmp-cmd-test
  TESTcheck-qtest-ppc64: tests/qtest/qom-test
section_end:1594147912:step_script
ERROR: Job failed: execution took longer than 1h0m0s seconds



-- 
You're receiving this email because of your account on gitlab.com.





Re: [PATCH v12 0/8] error: auto propagated local_err part I

2020-07-07 Thread Eric Blake

On 7/7/20 11:50 AM, Markus Armbruster wrote:

To speed things up, I'm taking the liberty to respin Vladimir's series
with my documentation amendments.

After my documentation work, I'm very much inclined to rename
ERRP_AUTO_PROPAGATE() to ERRP_GUARD().  The fact that it propagates
below the hood is detail.  What matters to its users is that it lets
them use @errp more freely.  Thoughts?


I like it - the shorter name is easier to type.

(The rename is a mechanical change, so if we agree to it, we should do 
it up front to minimize the churn to all the functions where we add use 
of the macro)




Based-on: Message-Id: <20200707160613.848843-1-arm...@redhat.com>

Available from my public repository https://repo.or.cz/qemu/armbru.git
on branch error-auto.

v12: (based on "[PATCH v4 00/45] Less clumsy error checking")
01: Comments merged properly with recent commit "error: Document Error
API usage rules", and edited for clarity.  Put ERRP_AUTO_PROPAGATE()
before its helpers, and touch up style.
01-08: Commit messages tweaked



--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze

2020-07-07 Thread Paolo Bonzini
Il mar 7 lug 2020, 20:42 Peter Maydell  ha
scritto:

> Also it broke my working tree, in the sense that when I
> rolled back to current master incremental-rebuild didn't
> work but instead failed with:
>
> make: *** No rule to make target '/home/ubuntu/qemu/Kconfig', needed
> by 'aarch64-softmmu/config-devices.mak'.  Stop.
>

The latter is unfortunately expected. I am curious about the s390 failure
and especially the x86 link failure which might be a semantic conflict. I
will try to reproduce them locally.

Paolo

>
> thanks
> -- PMM
>
>


Re: [PATCH v12 0/8] error: auto propagated local_err part I

2020-07-07 Thread Vladimir Sementsov-Ogievskiy

07.07.2020 19:50, Markus Armbruster wrote:

To speed things up, I'm taking the liberty to respin Vladimir's series
with my documentation amendments.


Thank you!



After my documentation work, I'm very much inclined to rename
ERRP_AUTO_PROPAGATE() to ERRP_GUARD().  The fact that it propagates
below the hood is detail.  What matters to its users is that it lets
them use @errp more freely.  Thoughts?


No objections, if we are making error-propagation to be internal implementation 
detail, no reason to shout about it in the macro name.


--
Best regards,
Vladimir



[PATCH v4 10/12] hw/ssi: NPCM7xx Flash Interface Unit device model

2020-07-07 Thread Havard Skinnemoen
This implements a device model for the NPCM7xx SPI flash controller.

Direct reads and writes, and user-mode transactions have been tested in
various modes. Protection features are not implemented yet.

All the FIU instances are available in the SoC's address space,
regardless of whether or not they're connected to actual flash chips.

Reviewed-by: Tyrone Ting 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Havard Skinnemoen 
---
 hw/arm/Kconfig   |   1 +
 hw/arm/npcm7xx.c |  57 
 hw/ssi/Makefile.objs |   1 +
 hw/ssi/npcm7xx_fiu.c | 510 +++
 hw/ssi/trace-events  |   9 +
 include/hw/arm/npcm7xx.h |   2 +
 include/hw/ssi/npcm7xx_fiu.h | 100 +++
 7 files changed, 680 insertions(+)
 create mode 100644 hw/ssi/npcm7xx_fiu.c
 create mode 100644 include/hw/ssi/npcm7xx_fiu.h

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index a31d0d282f..8d0ef0593b 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -360,6 +360,7 @@ config NPCM7XX
 select ARM_GIC
 select PL310  # cache controller
 select SERIAL
+select SSI
 select UNIMP
 
 config FSL_IMX25
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 5e6d05642e..0724095b60 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -98,6 +98,37 @@ static const hwaddr npcm7xx_uart_addr[] = {
 0xF0004000,
 };
 
+static const hwaddr npcm7xx_fiu0_flash_addr[] = {
+0x8000,
+0x8800,
+};
+
+static const hwaddr npcm7xx_fiu3_flash_addr[] = {
+0xa000,
+0xa800,
+0xb000,
+0xb800,
+};
+
+static const struct {
+const char *name;
+hwaddr regs_addr;
+int cs_count;
+const hwaddr *flash_addr;
+} npcm7xx_fiu[] = {
+{
+.name = "fiu0",
+.regs_addr = 0xfb00,
+.cs_count = ARRAY_SIZE(npcm7xx_fiu0_flash_addr),
+.flash_addr = npcm7xx_fiu0_flash_addr,
+}, {
+.name = "fiu3",
+.regs_addr = 0xc000,
+.cs_count = ARRAY_SIZE(npcm7xx_fiu3_flash_addr),
+.flash_addr = npcm7xx_fiu3_flash_addr,
+},
+};
+
 void npcm7xx_write_secondary_boot(ARMCPU *cpu, const struct arm_boot_info 
*info)
 {
 /*
@@ -166,6 +197,12 @@ static void npcm7xx_init(Object *obj)
 for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
 object_initialize_child(obj, "tim[*]", >tim[i], TYPE_NPCM7XX_TIMER);
 }
+
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_fiu) != ARRAY_SIZE(s->fiu));
+for (i = 0; i < ARRAY_SIZE(s->fiu); i++) {
+object_initialize_child(obj, npcm7xx_fiu[i].name, >fiu[i],
+TYPE_NPCM7XX_FIU);
+}
 }
 
 static void npcm7xx_realize(DeviceState *dev, Error **errp)
@@ -293,6 +330,26 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
serial_hd(i), DEVICE_LITTLE_ENDIAN);
 }
 
+/* Flash Interface Unit (FIU) */
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_fiu) != ARRAY_SIZE(s->fiu));
+for (i = 0; i < ARRAY_SIZE(s->fiu); i++) {
+SysBusDevice *sbd = SYS_BUS_DEVICE(>fiu[i]);
+int j;
+
+object_property_set_int(OBJECT(sbd), npcm7xx_fiu[i].cs_count,
+"cs-count", _abort);
+sysbus_realize(sbd, );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+
+sysbus_mmio_map(sbd, 0, npcm7xx_fiu[i].regs_addr);
+for (j = 0; j < npcm7xx_fiu[i].cs_count; j++) {
+sysbus_mmio_map(sbd, j + 1, npcm7xx_fiu[i].flash_addr[j]);
+}
+}
+
 /* RAM2 (SRAM) */
 memory_region_init_ram(>sram, OBJECT(dev), "ram2",
NPCM7XX_RAM2_SZ, );
diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
index 07a85f1967..cab48e72c9 100644
--- a/hw/ssi/Makefile.objs
+++ b/hw/ssi/Makefile.objs
@@ -5,6 +5,7 @@ common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
 common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
 common-obj-$(CONFIG_MSF2) += mss-spi.o
+common-obj-$(CONFIG_NPCM7XX) += npcm7xx_fiu.o
 
 common-obj-$(CONFIG_OMAP) += omap_spi.o
 common-obj-$(CONFIG_IMX) += imx_spi.o
diff --git a/hw/ssi/npcm7xx_fiu.c b/hw/ssi/npcm7xx_fiu.c
new file mode 100644
index 00..92ade709e8
--- /dev/null
+++ b/hw/ssi/npcm7xx_fiu.c
@@ -0,0 +1,510 @@
+/*
+ * Nuvoton NPCM7xx Flash Interface Unit (FIU)
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/irq.h"
+#include 

Re: [PATCH] load_elf: Remove unused address variables from callers

2020-07-07 Thread BALATON Zoltan

On Tue, 7 Jul 2020, Alistair Francis wrote:

On Sun, Jul 5, 2020 at 10:41 AM BALATON Zoltan  wrote:

Several callers of load_elf() pass pointers for lowaddr and highaddr
parameters which are then not used for anything. This may stem from a
misunderstanding that load_elf need a value here but in fact it can
take NULL to ignore these values. Remove such unused variables and
pass NULL instead from callers that don't need these.

Signed-off-by: BALATON Zoltan 


Reviewed-by: Alistair Francis 


So this got a few review and acked by but since it touches multiple parts 
who will actually send pull or merge it? I'd like to make sure this won't 
miss the freeze deadline just because everybody thinks this should go in 
via some other maintainer. What's the best way for this? Trivial 
maintainers or Peter should handle such patches?


Regards,
BALATON Zoltan


Alistair


---
 hw/alpha/dp264.c   |  8 
 hw/arm/armv7m.c|  4 +---
 hw/cris/boot.c |  4 ++--
 hw/microblaze/boot.c   |  4 ++--
 hw/mips/fuloong2e.c|  8 
 hw/moxie/moxiesim.c|  4 ++--
 hw/nios2/boot.c|  4 ++--
 hw/ppc/mac_newworld.c  |  6 ++
 hw/ppc/mac_oldworld.c  |  6 ++
 hw/ppc/ppc440_bamboo.c |  9 +++--
 hw/ppc/sam460ex.c  | 12 +---
 hw/ppc/spapr.c | 11 ---
 hw/ppc/virtex_ml507.c  |  4 ++--
 hw/riscv/boot.c|  8 
 hw/xtensa/sim.c|  3 +--
 hw/xtensa/xtfpga.c |  3 +--
 16 files changed, 41 insertions(+), 57 deletions(-)

diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index f7751b18f6..4d24518d1d 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -62,8 +62,8 @@ static void clipper_init(MachineState *machine)
 qemu_irq rtc_irq;
 long size, i;
 char *palcode_filename;
-uint64_t palcode_entry, palcode_low, palcode_high;
-uint64_t kernel_entry, kernel_low, kernel_high;
+uint64_t palcode_entry;
+uint64_t kernel_entry, kernel_low;
 unsigned int smp_cpus = machine->smp.cpus;

 /* Create up to 4 cpus.  */
@@ -113,7 +113,7 @@ static void clipper_init(MachineState *machine)
 exit(1);
 }
 size = load_elf(palcode_filename, NULL, cpu_alpha_superpage_to_phys,
-NULL, _entry, _low, _high, NULL,
+NULL, _entry, NULL, NULL, NULL,
 0, EM_ALPHA, 0, 0);
 if (size < 0) {
 error_report("could not load palcode '%s'", palcode_filename);
@@ -132,7 +132,7 @@ static void clipper_init(MachineState *machine)
 uint64_t param_offset;

 size = load_elf(kernel_filename, NULL, cpu_alpha_superpage_to_phys,
-NULL, _entry, _low, _high, NULL,
+NULL, _entry, _low, NULL, NULL,
 0, EM_ALPHA, 0, 0);
 if (size < 0) {
 error_report("could not load kernel '%s'", kernel_filename);
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 3308211e9c..92f859d760 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -309,7 +309,6 @@ void armv7m_load_kernel(ARMCPU *cpu, const char 
*kernel_filename, int mem_size)
 {
 int image_size;
 uint64_t entry;
-uint64_t lowaddr;
 int big_endian;
 AddressSpace *as;
 int asidx;
@@ -330,12 +329,11 @@ void armv7m_load_kernel(ARMCPU *cpu, const char 
*kernel_filename, int mem_size)

 if (kernel_filename) {
 image_size = load_elf_as(kernel_filename, NULL, NULL, NULL,
- , , NULL,
+ , NULL, NULL,
  NULL, big_endian, EM_ARM, 1, 0, as);
 if (image_size < 0) {
 image_size = load_image_targphys_as(kernel_filename, 0,
 mem_size, as);
-lowaddr = 0;
 }
 if (image_size < 0) {
 error_report("Could not load kernel '%s'", kernel_filename);
diff --git a/hw/cris/boot.c b/hw/cris/boot.c
index b8947bc660..aa8d2756d6 100644
--- a/hw/cris/boot.c
+++ b/hw/cris/boot.c
@@ -67,7 +67,7 @@ static uint64_t translate_kernel_address(void *opaque, 
uint64_t addr)
 void cris_load_image(CRISCPU *cpu, struct cris_load_info *li)
 {
 CPUCRISState *env = >env;
-uint64_t entry, high;
+uint64_t entry;
 int kcmdline_len;
 int image_size;

@@ -76,7 +76,7 @@ void cris_load_image(CRISCPU *cpu, struct cris_load_info *li)
devboard SDK.  */
 image_size = load_elf(li->image_filename, NULL,
   translate_kernel_address, NULL,
-  , NULL, , NULL, 0, EM_CRIS, 0, 0);
+  , NULL, NULL, NULL, 0, EM_CRIS, 0, 0);
 li->entry = entry;
 if (image_size < 0) {
 /* Takes a kimage from the axis devboard SDK.  */
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index 925e3f7c9d..8ad3c27f2c 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -135,7 +135,7 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr 

[PATCH v4 09/12] hw/mem: Stubbed out NPCM7xx Memory Controller model

2020-07-07 Thread Havard Skinnemoen
This just implements the bare minimum to cause the boot block to skip
memory initialization.

Reviewed-by: Tyrone Ting 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Havard Skinnemoen 
---
 hw/arm/npcm7xx.c| 10 +
 hw/mem/Makefile.objs|  1 +
 hw/mem/npcm7xx_mc.c | 84 +
 include/hw/arm/npcm7xx.h|  2 +
 include/hw/mem/npcm7xx_mc.h | 36 
 5 files changed, 133 insertions(+)
 create mode 100644 hw/mem/npcm7xx_mc.c
 create mode 100644 include/hw/mem/npcm7xx_mc.h

diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 71cc141f3c..5e6d05642e 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -46,6 +46,7 @@
 #define NPCM7XX_CPUP_BA (0xF03FE000)
 #define NPCM7XX_GCR_BA  (0xF080)
 #define NPCM7XX_CLK_BA  (0xF0801000)
+#define NPCM7XX_MC_BA   (0xF0824000)
 
 /* Memory blocks at the end of the address space */
 #define NPCM7XX_RAM2_BA (0xFFFD)
@@ -160,6 +161,7 @@ static void npcm7xx_init(Object *obj)
 TYPE_NPCM7XX_KEY_STORAGE);
 object_initialize_child(obj, "otp2", >fuse_array,
 TYPE_NPCM7XX_FUSE_ARRAY);
+object_initialize_child(obj, "mc", >mc, TYPE_NPCM7XX_MC);
 
 for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
 object_initialize_child(obj, "tim[*]", >tim[i], TYPE_NPCM7XX_TIMER);
@@ -255,6 +257,14 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 sysbus_mmio_map(SYS_BUS_DEVICE(>fuse_array), 0, NPCM7XX_OTP2_BA);
 npcm7xx_init_fuses(s);
 
+/* Fake Memory Controller (MC) */
+sysbus_realize(SYS_BUS_DEVICE(>mc), );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>mc), 0, NPCM7XX_MC_BA);
+
 /* Timer Modules (TIM) */
 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_tim_addr) != ARRAY_SIZE(s->tim));
 for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
diff --git a/hw/mem/Makefile.objs b/hw/mem/Makefile.objs
index 56345befd0..9a33ef7b35 100644
--- a/hw/mem/Makefile.objs
+++ b/hw/mem/Makefile.objs
@@ -1,3 +1,4 @@
 common-obj-$(CONFIG_DIMM) += pc-dimm.o
 common-obj-y += memory-device.o
+common-obj-$(CONFIG_NPCM7XX) += npcm7xx_mc.o
 common-obj-$(CONFIG_NVDIMM) += nvdimm.o
diff --git a/hw/mem/npcm7xx_mc.c b/hw/mem/npcm7xx_mc.c
new file mode 100644
index 00..0435d06ab4
--- /dev/null
+++ b/hw/mem/npcm7xx_mc.c
@@ -0,0 +1,84 @@
+/*
+ * Nuvoton NPCM7xx Memory Controller stub
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/mem/npcm7xx_mc.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+
+#define NPCM7XX_MC_REGS_SIZE (4 * KiB)
+
+static uint64_t npcm7xx_mc_read(void *opaque, hwaddr addr, unsigned int size)
+{
+/*
+ * If bits 8..11 @ offset 0 are not zero, the boot block thinks the memory
+ * controller has already been initialized and will skip DDR training.
+ */
+if (addr == 0) {
+return 0x100;
+}
+
+qemu_log_mask(LOG_UNIMP, "%s: mostly unimplemented\n", __func__);
+
+return 0;
+}
+
+static void npcm7xx_mc_write(void *opaque, hwaddr addr, uint64_t v,
+ unsigned int size)
+{
+qemu_log_mask(LOG_UNIMP, "%s: mostly unimplemented\n", __func__);
+}
+
+static const MemoryRegionOps npcm7xx_mc_ops = {
+.read = npcm7xx_mc_read,
+.write = npcm7xx_mc_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 4,
+.max_access_size = 4,
+.unaligned = false,
+},
+};
+
+static void npcm7xx_mc_realize(DeviceState *dev, Error **errp)
+{
+NPCM7xxMCState *s = NPCM7XX_MC(dev);
+
+memory_region_init_io(>mmio, OBJECT(s), _mc_ops, s, "regs",
+  NPCM7XX_MC_REGS_SIZE);
+sysbus_init_mmio(>parent, >mmio);
+}
+
+static void npcm7xx_mc_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->desc = "NPCM7xx Memory Controller stub";
+dc->realize = npcm7xx_mc_realize;
+}
+
+static const TypeInfo npcm7xx_mc_types[] = {
+{
+.name = TYPE_NPCM7XX_MC,
+.parent = TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(NPCM7xxMCState),
+.class_init = npcm7xx_mc_class_init,
+},
+};
+DEFINE_TYPES(npcm7xx_mc_types);
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index 2f2d44aad7..a6c1d4082b 100644
--- a/include/hw/arm/npcm7xx.h

[PATCH v4 12/12] docs/system: Add Nuvoton machine documentation

2020-07-07 Thread Havard Skinnemoen
Reviewed-by: Cédric Le Goater 
Signed-off-by: Havard Skinnemoen 
---
 docs/system/arm/nuvoton.rst | 92 +
 docs/system/target-arm.rst  |  1 +
 2 files changed, 93 insertions(+)
 create mode 100644 docs/system/arm/nuvoton.rst

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
new file mode 100644
index 00..7384662d58
--- /dev/null
+++ b/docs/system/arm/nuvoton.rst
@@ -0,0 +1,92 @@
+Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
+=
+
+The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
+designed to be used as Baseboard Management Controllers (BMCs) in various
+servers. They all feature one or two ARM Cortex A9 CPU cores, as well as an
+assortment of peripherals targeted for either Enterprise or Data Center /
+Hyperscale applications. The former is a superset of the latter, so NPCM750 has
+all the peripherals of NPCM730 and more.
+
+.. _Nuvoton iBMC: https://www.nuvoton.com/products/cloud-computing/ibmc/
+
+The NPCM750 SoC has two Cortex A9 cores and is targeted for the Enterprise
+segment. The following machines are based on this chip :
+
+- ``npcm750-evb``   Nuvoton NPCM750 Evaluation board
+
+The NPCM730 SoC has two Cortex A9 cores and is targeted for Data Center and
+Hyperscale applications. The following machines are based on this chip :
+
+- ``quanta-gsj``Quanta GSJ server BMC
+
+There are also two more SoCs, NPCM710 and NPCM705, which are single-core
+variants of NPCM750 and NPCM730, respectively. These are currently not
+supported by QEMU.
+
+Supported devices
+-
+
+ * SMP (Dual Core Cortex-A9)
+ * Cortex-A9MPCore built-in peripherals: SCU, GIC, Global Timer, Private Timer
+   and Watchdog.
+ * SRAM, ROM and DRAM mappings
+ * System Global Control Registers (GCR)
+ * Clock and reset controller (CLK)
+ * Timer controller (TIM)
+ * Serial ports (16550-based)
+ * DDR4 memory controller (dummy interface indicating memory training is done)
+ * OTP controllers (no protection features)
+ * Flash Interface Unit (FIU; no protection features)
+
+Missing devices
+---
+
+ * GPIO controller
+ * LPC/eSPI host-to-BMC interface, including
+
+   * Keyboard and mouse controller interface (KBCI)
+   * Keyboard Controller Style (KCS) channels
+   * BIOS POST code FIFO
+   * System Wake-up Control (SWC)
+   * Shared memory (SHM)
+   * eSPI slave interface
+
+ * Ethernet controllers (GMAC and EMC)
+ * USB host (USBH)
+ * USB device (USBD)
+ * SMBus controller (SMBF)
+ * Peripheral SPI controller (PSPI)
+ * Analog to Digital Converter (ADC)
+ * SD/MMC host
+ * Random Number Generator (RNG)
+ * PECI interface
+ * Pulse Width Modulation (PWM)
+ * Tachometer
+ * PCI and PCIe root complex and bridges
+ * VDM and MCTP support
+ * Serial I/O expansion
+ * LPC/eSPI host
+ * Coprocessor
+ * Graphics
+ * Video capture
+ * Encoding compression engine
+ * Security features
+
+Boot options
+
+
+The Nuvoton machines can boot from an OpenBMC firmware image, or directly into
+a kernel using the ``-kernel`` option. OpenBMC images for `quanta-gsj` and
+possibly others can be downloaded from the OpenPOWER jenkins :
+
+   https://openpower.xyz/
+
+Booting a full firmware image requires a Boot ROM specified via the ``-bios``
+option to QEMU. The firmware image should be attached as an MTD drive. Example 
:
+
+.. code-block:: bash
+
+  $ qemu-system-arm -machine quanta-gsj -nographic \
+  -bios npcm7xx_bootrom.bin \
+  -drive file=image-bmc,if=mtd,bus=0,unit=0,format=raw
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
index 1bd477a293..38a9daa9b9 100644
--- a/docs/system/target-arm.rst
+++ b/docs/system/target-arm.rst
@@ -84,6 +84,7 @@ undocumented; you can get a complete list by running
arm/aspeed
arm/musicpal
arm/nseries
+   arm/nuvoton
arm/orangepi
arm/palm
arm/xscale
-- 
2.27.0.212.ge8ba1cc988-goog




[PATCH v4 07/12] hw/arm: Load -bios image as a boot ROM for npcm7xx

2020-07-07 Thread Havard Skinnemoen
If a -bios option is specified on the command line, load the image into
the internal ROM memory region, which contains the first instructions
run by the CPU after reset.

A minimal Apache-2.0-licensed boot ROM can be found at

https://github.com/google/vbootrom

It is by no means feature complete, but it is enough to launch the
Nuvoton bootblock[1] from offset 0 in the flash, which in turn will
launch u-boot and finally the Linux kernel.

[1] https://github.com/Nuvoton-Israel/bootblock

Reviewed-by: Tyrone Ting 
Signed-off-by: Havard Skinnemoen 
---
 hw/arm/npcm7xx_boards.c | 26 --
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 205243cde6..de2d2ca786 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -19,8 +19,11 @@
 #include "hw/arm/boot.h"
 #include "hw/arm/npcm7xx.h"
 #include "hw/core/cpu.h"
+#include "hw/loader.h"
 #include "qapi/error.h"
+#include "qemu-common.h"
 #include "qemu/units.h"
+#include "sysemu/sysemu.h"
 
 #define NPCM750_EVB_POWER_ON_STRAPS 0x1ff7
 #define QUANTA_GSJ_POWER_ON_STRAPS 0x1fff
@@ -34,6 +37,25 @@ static struct arm_boot_info npcm7xx_binfo = {
 .board_id   = -1,
 };
 
+static void npcm7xx_load_bootrom(NPCM7xxState *soc)
+{
+if (bios_name) {
+g_autofree char *filename = NULL;
+int ret;
+
+filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+if (!filename) {
+error_report("Could not find ROM image '%s'", bios_name);
+exit(1);
+}
+ret = load_image_mr(filename, >irom);
+if (ret < 0) {
+error_report("Failed to load ROM image '%s'", filename);
+exit(1);
+}
+}
+}
+
 static void npcm7xx_load_kernel(MachineState *machine, NPCM7xxState *soc)
 {
 NPCM7xxClass *sc = NPCM7XX_GET_CLASS(soc);
@@ -66,7 +88,7 @@ static void npcm750_evb_init(MachineState *machine)
 NPCM7xxState *soc;
 
 soc = npcm7xx_create_soc(machine, NPCM750_EVB_POWER_ON_STRAPS);
-
+npcm7xx_load_bootrom(soc);
 npcm7xx_load_kernel(machine, soc);
 }
 
@@ -75,7 +97,7 @@ static void quanta_gsj_init(MachineState *machine)
 NPCM7xxState *soc;
 
 soc = npcm7xx_create_soc(machine, QUANTA_GSJ_POWER_ON_STRAPS);
-
+npcm7xx_load_bootrom(soc);
 npcm7xx_load_kernel(machine, soc);
 }
 
-- 
2.27.0.212.ge8ba1cc988-goog




[PATCH v4 11/12] hw/arm: Wire up BMC boot flash for npcm750-evb and quanta-gsj

2020-07-07 Thread Havard Skinnemoen
This allows these NPCM7xx-based boards to boot from a flash image, e.g.
one built with OpenBMC. For example like this:

IMAGE=${OPENBMC}/build/tmp/deploy/images/gsj/image-bmc
qemu-system-arm -machine quanta-gsj -nographic \
-bios ~/qemu/bootrom/npcm7xx_bootrom.bin \
-drive file=${IMAGE},if=mtd,bus=0,unit=0,format=raw,snapshot=on

Reviewed-by: Tyrone Ting 
Signed-off-by: Havard Skinnemoen 
---
 hw/arm/npcm7xx_boards.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index de2d2ca786..7de73594ed 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -20,6 +20,7 @@
 #include "hw/arm/npcm7xx.h"
 #include "hw/core/cpu.h"
 #include "hw/loader.h"
+#include "hw/qdev-properties.h"
 #include "qapi/error.h"
 #include "qemu-common.h"
 #include "qemu/units.h"
@@ -66,6 +67,21 @@ static void npcm7xx_load_kernel(MachineState *machine, 
NPCM7xxState *soc)
 arm_load_kernel(>cpu[0], machine, _binfo);
 }
 
+static void npcm7xx_connect_flash(NPCM7xxFIUState *fiu, int cs_no,
+  const char *flash_type, DriveInfo *dinfo) {
+DeviceState *flash;
+qemu_irq flash_cs;
+
+flash = qdev_new(flash_type);
+if (dinfo) {
+qdev_prop_set_drive(flash, "drive", blk_by_legacy_dinfo(dinfo));
+}
+qdev_realize_and_unref(flash, BUS(fiu->spi), _fatal);
+
+flash_cs = qdev_get_gpio_in_named(flash, SSI_GPIO_CS, 0);
+sysbus_connect_irq(SYS_BUS_DEVICE(fiu), cs_no, flash_cs);
+}
+
 static NPCM7xxState *npcm7xx_create_soc(MachineState *machine,
 uint32_t hw_straps)
 {
@@ -89,6 +105,7 @@ static void npcm750_evb_init(MachineState *machine)
 
 soc = npcm7xx_create_soc(machine, NPCM750_EVB_POWER_ON_STRAPS);
 npcm7xx_load_bootrom(soc);
+npcm7xx_connect_flash(>fiu[0], 0, "w25q256", drive_get(IF_MTD, 0, 0));
 npcm7xx_load_kernel(machine, soc);
 }
 
@@ -98,6 +115,8 @@ static void quanta_gsj_init(MachineState *machine)
 
 soc = npcm7xx_create_soc(machine, QUANTA_GSJ_POWER_ON_STRAPS);
 npcm7xx_load_bootrom(soc);
+npcm7xx_connect_flash(>fiu[0], 0, "mx25l25635e",
+  drive_get(IF_MTD, 0, 0));
 npcm7xx_load_kernel(machine, soc);
 }
 
-- 
2.27.0.212.ge8ba1cc988-goog




[PATCH v4 05/12] hw/arm: Add NPCM730 and NPCM750 SoC models

2020-07-07 Thread Havard Skinnemoen
The Nuvoton NPCM7xx SoC family are used to implement Baseboard
Management Controllers in servers. While the family includes four SoCs,
this patch implements limited support for two of them: NPCM730 (targeted
for Data Center applications) and NPCM750 (targeted for Enterprise
applications).

This patch includes little more than the bare minimum needed to boot a
Linux kernel built with NPCM7xx support in direct-kernel mode:

  - Two Cortex-A9 CPU cores with built-in periperhals.
  - Global Configuration Registers.
  - Clock Management.
  - 3 Timer Modules with 5 timers each.
  - 4 serial ports.

The chips themselves have a lot more features, some of which will be
added to the model at a later stage.

Reviewed-by: Tyrone Ting 
Reviewed-by: Joel Stanley 
Signed-off-by: Havard Skinnemoen 
---
 hw/arm/Makefile.objs |   1 +
 hw/arm/npcm7xx.c | 328 +++
 include/hw/arm/npcm7xx.h |  81 ++
 3 files changed, 410 insertions(+)
 create mode 100644 hw/arm/npcm7xx.c
 create mode 100644 include/hw/arm/npcm7xx.h

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 534a6a119e..13d163a599 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -41,6 +41,7 @@ obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_STM32F405_SOC) += stm32f405_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zynqmp.o xlnx-zcu102.o
 obj-$(CONFIG_XLNX_VERSAL) += xlnx-versal.o xlnx-versal-virt.o
+obj-$(CONFIG_NPCM7XX) += npcm7xx.o
 obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
 obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
new file mode 100644
index 00..0a9e30f66f
--- /dev/null
+++ b/hw/arm/npcm7xx.c
@@ -0,0 +1,328 @@
+/*
+ * Nuvoton NPCM7xx SoC family.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "exec/address-spaces.h"
+#include "hw/arm/npcm7xx.h"
+#include "hw/char/serial.h"
+#include "hw/loader.h"
+#include "hw/misc/unimp.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qemu/units.h"
+#include "sysemu/sysemu.h"
+
+/* The first half of the address space is reserved for DDR4 DRAM. */
+#define NPCM7XX_DRAM_BA (0x)
+#define NPCM7XX_DRAM_SZ (2 * GiB)
+
+/*
+ * This covers the whole MMIO space. We'll use this to catch any MMIO accesses
+ * that aren't handled by any device.
+ */
+#define NPCM7XX_MMIO_BA (0x8000)
+#define NPCM7XX_MMIO_SZ (0x7FFD)
+
+/* Core system modules. */
+#define NPCM7XX_L2C_BA  (0xF03FC000)
+#define NPCM7XX_CPUP_BA (0xF03FE000)
+#define NPCM7XX_GCR_BA  (0xF080)
+#define NPCM7XX_CLK_BA  (0xF0801000)
+
+/* Memory blocks at the end of the address space */
+#define NPCM7XX_RAM2_BA (0xFFFD)
+#define NPCM7XX_RAM2_SZ (128 * KiB)
+#define NPCM7XX_ROM_BA  (0x)
+#define NPCM7XX_ROM_SZ  (64 * KiB)
+
+/*
+ * Interrupt lines going into the GIC. This does not include internal Cortex-A9
+ * interrupts.
+ */
+enum NPCM7xxInterrupt {
+NPCM7XX_UART0_IRQ   = 2,
+NPCM7XX_UART1_IRQ,
+NPCM7XX_UART2_IRQ,
+NPCM7XX_UART3_IRQ,
+NPCM7XX_TIMER0_IRQ  = 32,   /* Timer Module 0 */
+NPCM7XX_TIMER1_IRQ,
+NPCM7XX_TIMER2_IRQ,
+NPCM7XX_TIMER3_IRQ,
+NPCM7XX_TIMER4_IRQ,
+NPCM7XX_TIMER5_IRQ, /* Timer Module 1 */
+NPCM7XX_TIMER6_IRQ,
+NPCM7XX_TIMER7_IRQ,
+NPCM7XX_TIMER8_IRQ,
+NPCM7XX_TIMER9_IRQ,
+NPCM7XX_TIMER10_IRQ,/* Timer Module 2 */
+NPCM7XX_TIMER11_IRQ,
+NPCM7XX_TIMER12_IRQ,
+NPCM7XX_TIMER13_IRQ,
+NPCM7XX_TIMER14_IRQ,
+};
+
+/* Total number of GIC interrupts, including internal Cortex-A9 interrupts. */
+#define NPCM7XX_NUM_IRQ (160)
+
+/* Register base address for each Timer Module */
+static const hwaddr npcm7xx_tim_addr[] = {
+0xF0008000,
+0xF0009000,
+0xF000A000,
+};
+
+/* Register base address for each 16550 UART */
+static const hwaddr npcm7xx_uart_addr[] = {
+0xF0001000,
+0xF0002000,
+0xF0003000,
+0xF0004000,
+};
+
+void npcm7xx_write_secondary_boot(ARMCPU *cpu, const struct arm_boot_info 
*info)
+{
+/*
+ * The default smpboot stub halts the secondary CPU with a 'wfi'
+ * instruction, but the arch/arm/mach-npcm/platsmp.c in the Linux kernel
+ * does not send an IPI to wake it up, so the second CPU fails to boot. So
+ * we 

[PATCH v4 04/12] hw/timer: Add NPCM7xx Timer device model

2020-07-07 Thread Havard Skinnemoen
The NPCM730 and NPCM750 SoCs have three timer modules each holding five
timers and some shared registers (e.g. interrupt status).

Each timer runs at 25 MHz divided by a prescaler, and counts down from a
configurable initial value to zero. When zero is reached, the interrupt
flag for the timer is set, and the timer is disabled (one-shot mode) or
reloaded from its initial value (periodic mode).

This implementation is sufficient to boot a Linux kernel configured for
NPCM750. Note that the kernel does not seem to actually turn on the
interrupts.

Reviewed-by: Tyrone Ting 
Reviewed-by: Joel Stanley 
Signed-off-by: Havard Skinnemoen 
---
 hw/timer/Makefile.objs   |   1 +
 hw/timer/npcm7xx_timer.c | 468 +++
 hw/timer/trace-events|   5 +
 include/hw/timer/npcm7xx_timer.h |  96 +++
 4 files changed, 570 insertions(+)
 create mode 100644 hw/timer/npcm7xx_timer.c
 create mode 100644 include/hw/timer/npcm7xx_timer.h

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index a39f6ec0c2..84c484dda8 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -14,6 +14,7 @@ common-obj-$(CONFIG_IMX) += imx_epit.o
 common-obj-$(CONFIG_IMX) += imx_gpt.o
 common-obj-$(CONFIG_LM32) += lm32_timer.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o
+common-obj-$(CONFIG_NPCM7XX) += npcm7xx_timer.o
 common-obj-$(CONFIG_NRF51_SOC) += nrf51_timer.o
 
 common-obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
diff --git a/hw/timer/npcm7xx_timer.c b/hw/timer/npcm7xx_timer.c
new file mode 100644
index 00..b0a72aef75
--- /dev/null
+++ b/hw/timer/npcm7xx_timer.c
@@ -0,0 +1,468 @@
+/*
+ * Nuvoton NPCM7xx Timer Controller
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/irq.h"
+#include "hw/timer/npcm7xx_timer.h"
+#include "migration/vmstate.h"
+#include "qemu/bitops.h"
+#include "qemu/error-report.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "qemu/units.h"
+#include "trace.h"
+
+/* Register field definitions. */
+#define NPCM7XX_TCSR_CENBIT(30)
+#define NPCM7XX_TCSR_IE BIT(29)
+#define NPCM7XX_TCSR_PERIODIC   BIT(27)
+#define NPCM7XX_TCSR_CRST   BIT(26)
+#define NPCM7XX_TCSR_CACT   BIT(25)
+#define NPCM7XX_TCSR_RSVD   0x2100
+#define NPCM7XX_TCSR_PRESCALE_START 0
+#define NPCM7XX_TCSR_PRESCALE_LEN   8
+
+/* The reference clock frequency is always 25 MHz. */
+#define NPCM7XX_TIMER_REF_HZ(2500)
+
+/* Return the value by which to divide the reference clock rate. */
+static uint32_t npcm7xx_timer_prescaler(const NPCM7xxTimer *t)
+{
+return extract32(t->tcsr, NPCM7XX_TCSR_PRESCALE_START,
+ NPCM7XX_TCSR_PRESCALE_LEN) + 1;
+}
+
+/* Convert a timer cycle count to a time interval in nanoseconds. */
+static int64_t npcm7xx_timer_count_to_ns(NPCM7xxTimer *t, uint32_t count)
+{
+int64_t ns = count;
+
+ns *= NANOSECONDS_PER_SECOND / NPCM7XX_TIMER_REF_HZ;
+ns *= npcm7xx_timer_prescaler(t);
+
+return ns;
+}
+
+/* Convert a time interval in nanoseconds to a timer cycle count. */
+static uint32_t npcm7xx_timer_ns_to_count(NPCM7xxTimer *t, int64_t ns)
+{
+int64_t count;
+
+count = ns / (NANOSECONDS_PER_SECOND / NPCM7XX_TIMER_REF_HZ);
+count /= npcm7xx_timer_prescaler(t);
+
+return count;
+}
+
+/*
+ * Raise the interrupt line if there's a pending interrupt and interrupts are
+ * enabled for this timer. If not, lower it.
+ */
+static void npcm7xx_timer_check_interrupt(NPCM7xxTimer *t)
+{
+NPCM7xxTimerCtrlState *tc = t->ctrl;
+/* Find the array index of this timer. */
+int index = t - tc->timer;
+
+g_assert(index >= 0 && index < NPCM7XX_TIMERS_PER_CTRL);
+
+if ((t->tcsr & NPCM7XX_TCSR_IE) && (tc->tisr & BIT(index))) {
+qemu_irq_raise(t->irq);
+trace_npcm7xx_timer_irq(DEVICE(tc)->canonical_path, index, 1);
+} else {
+qemu_irq_lower(t->irq);
+trace_npcm7xx_timer_irq(DEVICE(tc)->canonical_path, index, 0);
+}
+}
+
+/* Start or resume the timer. */
+static void npcm7xx_timer_start(NPCM7xxTimer *t)
+{
+int64_t now;
+
+now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+t->expires_ns = now + t->remaining_ns;
+timer_mod(>qtimer, t->expires_ns);
+}
+
+/*
+ * Called when the counter reaches zero. Sets the interrupt flag, and either
+ * restarts or disables the timer.
+ */
+static 

[PATCH v4 06/12] hw/arm: Add two NPCM7xx-based machines

2020-07-07 Thread Havard Skinnemoen
This adds two new machines, both supported by OpenBMC:

  - npcm750-evb: Nuvoton NPCM750 Evaluation Board.
  - quanta-gsj: A board with a NPCM730 chip.

They rely on the NPCM7xx SoC device to do the heavy lifting. They are
almost completely identical at the moment, apart from the SoC type,
which currently only changes the reset contents of one register
(GCR.MDLR), but they might grow apart a bit more as more functionality
is added.

Both machines can boot the Linux kernel into /bin/sh.

Reviewed-by: Tyrone Ting 
Reviewed-by: Joel Stanley 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Havard Skinnemoen 
---
 hw/arm/Makefile.objs |   2 +-
 hw/arm/npcm7xx_boards.c  | 148 +++
 include/hw/arm/npcm7xx.h |  19 +
 3 files changed, 168 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/npcm7xx_boards.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 13d163a599..c333548ce1 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -41,7 +41,7 @@ obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_STM32F405_SOC) += stm32f405_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zynqmp.o xlnx-zcu102.o
 obj-$(CONFIG_XLNX_VERSAL) += xlnx-versal.o xlnx-versal-virt.o
-obj-$(CONFIG_NPCM7XX) += npcm7xx.o
+obj-$(CONFIG_NPCM7XX) += npcm7xx.o npcm7xx_boards.o
 obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
 obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
new file mode 100644
index 00..205243cde6
--- /dev/null
+++ b/hw/arm/npcm7xx_boards.c
@@ -0,0 +1,148 @@
+/*
+ * Machine definitions for boards featuring an NPCM7xx SoC.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/arm/boot.h"
+#include "hw/arm/npcm7xx.h"
+#include "hw/core/cpu.h"
+#include "qapi/error.h"
+#include "qemu/units.h"
+
+#define NPCM750_EVB_POWER_ON_STRAPS 0x1ff7
+#define QUANTA_GSJ_POWER_ON_STRAPS 0x1fff
+
+static struct arm_boot_info npcm7xx_binfo = {
+.loader_start   = NPCM7XX_LOADER_START,
+.smp_loader_start   = NPCM7XX_SMP_LOADER_START,
+.smp_bootreg_addr   = NPCM7XX_SMP_BOOTREG_ADDR,
+.gic_cpu_if_addr= NPCM7XX_GIC_CPU_IF_ADDR,
+.write_secondary_boot = npcm7xx_write_secondary_boot,
+.board_id   = -1,
+};
+
+static void npcm7xx_load_kernel(MachineState *machine, NPCM7xxState *soc)
+{
+NPCM7xxClass *sc = NPCM7XX_GET_CLASS(soc);
+
+npcm7xx_binfo.ram_size = machine->ram_size;
+npcm7xx_binfo.nb_cpus = sc->num_cpus;
+
+arm_load_kernel(>cpu[0], machine, _binfo);
+}
+
+static NPCM7xxState *npcm7xx_create_soc(MachineState *machine,
+uint32_t hw_straps)
+{
+NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_GET_CLASS(machine);
+NPCM7xxState *soc;
+
+soc = NPCM7XX(object_new_with_props(nmc->soc_type, OBJECT(machine), "soc",
+_abort, NULL));
+object_property_set_link(OBJECT(soc), OBJECT(machine->ram), "dram",
+ _abort);
+object_property_set_uint(OBJECT(soc), hw_straps, "power-on-straps",
+ _abort);
+qdev_realize(DEVICE(soc), NULL, _abort);
+
+return soc;
+}
+
+static void npcm750_evb_init(MachineState *machine)
+{
+NPCM7xxState *soc;
+
+soc = npcm7xx_create_soc(machine, NPCM750_EVB_POWER_ON_STRAPS);
+
+npcm7xx_load_kernel(machine, soc);
+}
+
+static void quanta_gsj_init(MachineState *machine)
+{
+NPCM7xxState *soc;
+
+soc = npcm7xx_create_soc(machine, QUANTA_GSJ_POWER_ON_STRAPS);
+
+npcm7xx_load_kernel(machine, soc);
+}
+
+static void npcm7xx_set_soc_type(NPCM7xxMachineClass *nmc, const char *type)
+{
+NPCM7xxClass *sc = NPCM7XX_CLASS(object_class_by_name(type));
+MachineClass *mc = MACHINE_CLASS(nmc);
+
+nmc->soc_type = type;
+mc->default_cpus = mc->min_cpus = mc->max_cpus = sc->num_cpus;
+}
+
+static void npcm7xx_machine_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+
+mc->no_floppy   = 1;
+mc->no_cdrom= 1;
+mc->no_parallel = 1;
+mc->default_ram_id  = "ram";
+}
+
+/*
+ * Schematics:
+ * 
https://github.com/Nuvoton-Israel/nuvoton-info/blob/master/npcm7xx-poleg/evaluation-board/board_deliverables/NPCM750x_EB_ver.A1.1_COMPLETE.pdf
+ */
+static void npcm750_evb_machine_class_init(ObjectClass *oc, void *data)
+{
+

[PATCH v4 01/12] npcm7xx: Add config symbol

2020-07-07 Thread Havard Skinnemoen
Add a config symbol for the NPCM7xx BMC SoC family that subsequent
patches can use in Makefiles.

Reviewed-by: Tyrone Ting 
Acked-by: Joel Stanley 
Signed-off-by: Havard Skinnemoen 
---
 default-configs/arm-softmmu.mak | 1 +
 hw/arm/Kconfig  | 8 
 2 files changed, 9 insertions(+)

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 8fc09a4a51..9a94ebd0be 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -27,6 +27,7 @@ CONFIG_GUMSTIX=y
 CONFIG_SPITZ=y
 CONFIG_TOSA=y
 CONFIG_Z2=y
+CONFIG_NPCM7XX=y
 CONFIG_COLLIE=y
 CONFIG_ASPEED_SOC=y
 CONFIG_NETDUINO2=y
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 4a224a6351..a31d0d282f 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -354,6 +354,14 @@ config XLNX_VERSAL
 select VIRTIO_MMIO
 select UNIMP
 
+config NPCM7XX
+bool
+select A9MPCORE
+select ARM_GIC
+select PL310  # cache controller
+select SERIAL
+select UNIMP
+
 config FSL_IMX25
 bool
 select IMX
-- 
2.27.0.212.ge8ba1cc988-goog




[PATCH v4 03/12] hw/misc: Add NPCM7xx Clock Controller device model

2020-07-07 Thread Havard Skinnemoen
Enough functionality to boot the Linux kernel has been implemented. This
includes:

  - Correct power-on reset values so the various clock rates can be
accurately calculated.
  - Clock enables stick around when written.

In addition, a best effort attempt to implement SECCNT and CNTR25M was
made even though I don't think the kernel needs them.

Reviewed-by: Tyrone Ting 
Reviewed-by: Joel Stanley 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Havard Skinnemoen 
---
 hw/misc/Makefile.objs |   1 +
 hw/misc/npcm7xx_clk.c | 230 ++
 hw/misc/trace-events  |   4 +
 include/hw/misc/npcm7xx_clk.h |  66 ++
 4 files changed, 301 insertions(+)
 create mode 100644 hw/misc/npcm7xx_clk.c
 create mode 100644 include/hw/misc/npcm7xx_clk.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 40a9d1c01e..2e74803005 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -51,6 +51,7 @@ common-obj-$(CONFIG_IMX) += imx_rngc.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 common-obj-$(CONFIG_MAINSTONE) += mst_fpga.o
+common-obj-$(CONFIG_NPCM7XX) += npcm7xx_clk.o
 common-obj-$(CONFIG_NPCM7XX) += npcm7xx_gcr.o
 common-obj-$(CONFIG_OMAP) += omap_clk.o
 common-obj-$(CONFIG_OMAP) += omap_gpmc.o
diff --git a/hw/misc/npcm7xx_clk.c b/hw/misc/npcm7xx_clk.c
new file mode 100644
index 00..9c34b12ea9
--- /dev/null
+++ b/hw/misc/npcm7xx_clk.c
@@ -0,0 +1,230 @@
+/*
+ * Nuvoton NPCM7xx Clock Control Registers.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/misc/npcm7xx_clk.h"
+#include "migration/vmstate.h"
+#include "qemu/error-report.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "qemu/units.h"
+#include "trace.h"
+
+#define PLLCON_LOKI BIT(31)
+#define PLLCON_LOKS BIT(30)
+#define PLLCON_PWDENBIT(12)
+
+/*
+ * These reset values were taken from version 0.91 of the NPCM750R data sheet.
+ *
+ * All are loaded on power-up reset. CLKENx and SWRSTR should also be loaded on
+ * core domain reset, but this reset type is not yet supported by QEMU.
+ */
+static const uint32_t cold_reset_values[NPCM7XX_CLK_NR_REGS] = {
+[NPCM7XX_CLK_CLKEN1]= 0x,
+[NPCM7XX_CLK_CLKSEL]= 0x004a,
+[NPCM7XX_CLK_CLKDIV1]   = 0x5413f855,
+[NPCM7XX_CLK_PLLCON0]   = 0x00222101 | PLLCON_LOKI,
+[NPCM7XX_CLK_PLLCON1]   = 0x00202101 | PLLCON_LOKI,
+[NPCM7XX_CLK_IPSRST1]   = 0x1000,
+[NPCM7XX_CLK_IPSRST2]   = 0x8000,
+[NPCM7XX_CLK_CLKEN2]= 0x,
+[NPCM7XX_CLK_CLKDIV2]   = 0xaa4f8f9f,
+[NPCM7XX_CLK_CLKEN3]= 0x,
+[NPCM7XX_CLK_IPSRST3]   = 0x0300,
+[NPCM7XX_CLK_WD0RCR]= 0x,
+[NPCM7XX_CLK_WD1RCR]= 0x,
+[NPCM7XX_CLK_WD2RCR]= 0x,
+[NPCM7XX_CLK_SWRSTC1]   = 0x0003,
+[NPCM7XX_CLK_PLLCON2]   = 0x00c02105 | PLLCON_LOKI,
+[NPCM7XX_CLK_CORSTC]= 0x0403,
+[NPCM7XX_CLK_PLLCONG]   = 0x01228606 | PLLCON_LOKI,
+[NPCM7XX_CLK_AHBCKFI]   = 0x00c8,
+};
+
+static uint64_t npcm7xx_clk_read(void *opaque, hwaddr offset, unsigned size)
+{
+uint32_t reg = offset / sizeof(uint32_t);
+NPCM7xxCLKState *s = opaque;
+int64_t now_ns;
+uint32_t value = 0;
+
+if (reg >= NPCM7XX_CLK_NR_REGS) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: offset 0x%04x out of range\n",
+  __func__, (unsigned int)offset);
+return 0;
+}
+
+switch (reg) {
+case NPCM7XX_CLK_SWRSTR:
+qemu_log_mask(LOG_GUEST_ERROR, "%s: register @ 0x%04x is write-only\n",
+  __func__, (unsigned int)offset);
+break;
+
+case NPCM7XX_CLK_SECCNT:
+now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+value = (now_ns - s->ref_ns) / NANOSECONDS_PER_SECOND;
+break;
+
+case NPCM7XX_CLK_CNTR25M:
+now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+/*
+ * This register counts 25 MHz cycles, updating every 640 ns. It rolls
+ * over to zero every second.
+ *
+ * The 4 LSBs are always zero: (1e9 / 640) << 4 = 2500.
+ */
+value = (((now_ns - s->ref_ns) / 640) << 4) % 2500;
+break;
+
+default:
+value = s->regs[reg];
+break;
+};
+
+

[PATCH v4 08/12] hw/nvram: NPCM7xx OTP device model

2020-07-07 Thread Havard Skinnemoen
This supports reading and writing OTP fuses and keys. Only fuse reading
has been tested. Protection is not implemented.

Reviewed-by: Avi Fishman 
Signed-off-by: Havard Skinnemoen 
---
 hw/arm/npcm7xx.c   |  32 +++
 hw/nvram/Makefile.objs |   1 +
 hw/nvram/npcm7xx_otp.c | 405 +
 include/hw/arm/npcm7xx.h   |   3 +
 include/hw/nvram/npcm7xx_otp.h |  94 
 5 files changed, 535 insertions(+)
 create mode 100644 hw/nvram/npcm7xx_otp.c
 create mode 100644 include/hw/nvram/npcm7xx_otp.h

diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 0a9e30f66f..71cc141f3c 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -37,6 +37,10 @@
 #define NPCM7XX_MMIO_BA (0x8000)
 #define NPCM7XX_MMIO_SZ (0x7FFD)
 
+/* OTP key storage and fuse strap array */
+#define NPCM7XX_OTP1_BA (0xF0189000)
+#define NPCM7XX_OTP2_BA (0xF018A000)
+
 /* Core system modules. */
 #define NPCM7XX_L2C_BA  (0xF03FC000)
 #define NPCM7XX_CPUP_BA (0xF03FE000)
@@ -123,6 +127,15 @@ void npcm7xx_write_secondary_boot(ARMCPU *cpu, const 
struct arm_boot_info *info)
NPCM7XX_SMP_LOADER_START);
 }
 
+static void npcm7xx_init_fuses(NPCM7xxState *s)
+{
+NPCM7xxClass *nc = NPCM7XX_GET_CLASS(s);
+uint32_t value;
+
+value = tswap32(nc->disabled_modules);
+npcm7xx_otp_array_write(>fuse_array, , 64, sizeof(value));
+}
+
 static qemu_irq npcm7xx_irq(NPCM7xxState *s, int n)
 {
 return qdev_get_gpio_in(DEVICE(>a9mpcore), n);
@@ -143,6 +156,10 @@ static void npcm7xx_init(Object *obj)
 object_property_add_alias(obj, "power-on-straps", OBJECT(>gcr),
   "power-on-straps");
 object_initialize_child(obj, "clk", >clk, TYPE_NPCM7XX_CLK);
+object_initialize_child(obj, "otp1", >key_storage,
+TYPE_NPCM7XX_KEY_STORAGE);
+object_initialize_child(obj, "otp2", >fuse_array,
+TYPE_NPCM7XX_FUSE_ARRAY);
 
 for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
 object_initialize_child(obj, "tim[*]", >tim[i], TYPE_NPCM7XX_TIMER);
@@ -223,6 +240,21 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 }
 sysbus_mmio_map(SYS_BUS_DEVICE(>clk), 0, NPCM7XX_CLK_BA);
 
+/* OTP key storage and fuse strap array */
+sysbus_realize(SYS_BUS_DEVICE(>key_storage), );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>key_storage), 0, NPCM7XX_OTP1_BA);
+sysbus_realize(SYS_BUS_DEVICE(>fuse_array), );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>fuse_array), 0, NPCM7XX_OTP2_BA);
+npcm7xx_init_fuses(s);
+
 /* Timer Modules (TIM) */
 QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_tim_addr) != ARRAY_SIZE(s->tim));
 for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
diff --git a/hw/nvram/Makefile.objs b/hw/nvram/Makefile.objs
index f3ad921382..0270f0bbf7 100644
--- a/hw/nvram/Makefile.objs
+++ b/hw/nvram/Makefile.objs
@@ -4,5 +4,6 @@ common-obj-$(CONFIG_AT24C) += eeprom_at24c.o
 common-obj-y += fw_cfg.o
 common-obj-$(CONFIG_CHRP_NVRAM) += chrp_nvram.o
 common-obj-$(CONFIG_MAC_NVRAM) += mac_nvram.o
+common-obj-$(CONFIG_NPCM7XX) += npcm7xx_otp.o
 common-obj-$(CONFIG_NRF51_SOC) += nrf51_nvm.o
 obj-$(CONFIG_PSERIES) += spapr_nvram.o
diff --git a/hw/nvram/npcm7xx_otp.c b/hw/nvram/npcm7xx_otp.c
new file mode 100644
index 00..18908bc839
--- /dev/null
+++ b/hw/nvram/npcm7xx_otp.c
@@ -0,0 +1,405 @@
+/*
+ * Nuvoton NPCM7xx OTP (Fuse Array) Interface
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/nvram/npcm7xx_otp.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+
+/* Each module has 4 KiB of register space. Only a fraction of it is used. */
+#define NPCM7XX_OTP_REGS_SIZE (4 * KiB)
+
+/* Register field definitions. */
+#define FST_RIEN BIT(2)
+#define FST_RDST BIT(1)
+#define FST_RDY BIT(0)
+#define FST_RO_MASK (FST_RDST | FST_RDY)
+
+#define FADDR_BYTEADDR(rv) extract32((rv), 0, 10)
+#define FADDR_BITPOS(rv) extract32((rv), 10, 3)
+
+#define FDATA_CLEAR 0x0001
+
+#define FCFG_FDIS BIT(31)
+#define FCFG_FCFGLK_MASK 0x00ff
+
+#define FCTL_PROG_CMD1 0x0001
+#define FCTL_PROG_CMD2 0xbf79e5d0
+#define FCTL_READ_CMD 0x0002
+

[PATCH v4 02/12] hw/misc: Add NPCM7xx System Global Control Registers device model

2020-07-07 Thread Havard Skinnemoen
Implement a device model for the System Global Control Registers in the
NPCM730 and NPCM750 BMC SoCs.

This is primarily used to enable SMP boot (the boot ROM spins reading
the SCRPAD register) and DDR memory initialization; other registers are
best effort for now.

The reset values of the MDLR and PWRON registers are determined by the
SoC variant (730 vs 750) and board straps respectively.

Reviewed-by: Joel Stanley 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Havard Skinnemoen 
---
 MAINTAINERS   |   8 ++
 hw/misc/Makefile.objs |   1 +
 hw/misc/npcm7xx_gcr.c | 224 ++
 hw/misc/trace-events  |   4 +
 include/hw/misc/npcm7xx_gcr.h |  77 
 5 files changed, 314 insertions(+)
 create mode 100644 hw/misc/npcm7xx_gcr.c
 create mode 100644 include/hw/misc/npcm7xx_gcr.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 70bceb5088..6e03254da2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -723,6 +723,14 @@ S: Odd Fixes
 F: hw/arm/musicpal.c
 F: docs/system/arm/musicpal.rst
 
+Nuvoton NPCM7xx
+M: Havard Skinnemoen 
+M: Tyrone Ting 
+L: qemu-...@nongnu.org
+S: Supported
+F: hw/*/npcm7xx*
+F: include/hw/*/npcm7xx*
+
 nSeries
 M: Andrzej Zaborowski 
 M: Peter Maydell 
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 5aaca8a039..40a9d1c01e 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -51,6 +51,7 @@ common-obj-$(CONFIG_IMX) += imx_rngc.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 common-obj-$(CONFIG_MAINSTONE) += mst_fpga.o
+common-obj-$(CONFIG_NPCM7XX) += npcm7xx_gcr.o
 common-obj-$(CONFIG_OMAP) += omap_clk.o
 common-obj-$(CONFIG_OMAP) += omap_gpmc.o
 common-obj-$(CONFIG_OMAP) += omap_l4.o
diff --git a/hw/misc/npcm7xx_gcr.c b/hw/misc/npcm7xx_gcr.c
new file mode 100644
index 00..bc2af92b9d
--- /dev/null
+++ b/hw/misc/npcm7xx_gcr.c
@@ -0,0 +1,224 @@
+/*
+ * Nuvoton NPCM7xx System Global Control Registers.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/misc/npcm7xx_gcr.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+
+#include "trace.h"
+
+static const uint32_t cold_reset_values[NPCM7XX_GCR_NR_REGS] = {
+[NPCM7XX_GCR_PDID]  = 0x04A92750,   /* Poleg A1 */
+[NPCM7XX_GCR_MISCPE]= 0x,
+[NPCM7XX_GCR_SPSWC] = 0x0003,
+[NPCM7XX_GCR_INTCR] = 0x035E,
+[NPCM7XX_GCR_HIFCR] = 0x004E,
+[NPCM7XX_GCR_INTCR2]= (1U << 19),   /* DDR initialized */
+[NPCM7XX_GCR_RESSR] = 0x8000,
+[NPCM7XX_GCR_DSCNT] = 0x00c0,
+[NPCM7XX_GCR_DAVCLVLR]  = 0x5A00F3CF,
+[NPCM7XX_GCR_SCRPAD]= 0x0008,
+[NPCM7XX_GCR_USB1PHYCTL]= 0x034730E4,
+[NPCM7XX_GCR_USB2PHYCTL]= 0x034730E4,
+};
+
+static uint64_t npcm7xx_gcr_read(void *opaque, hwaddr offset, unsigned size)
+{
+uint32_t reg = offset / sizeof(uint32_t);
+NPCM7xxGCRState *s = opaque;
+
+if (reg >= NPCM7XX_GCR_NR_REGS) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: offset 0x%04x out of range\n",
+  __func__, (unsigned int)offset);
+return 0;
+}
+
+trace_npcm7xx_gcr_read(offset, s->regs[reg]);
+
+return s->regs[reg];
+}
+
+static void npcm7xx_gcr_write(void *opaque, hwaddr offset,
+  uint64_t v, unsigned size)
+{
+uint32_t reg = offset / sizeof(uint32_t);
+NPCM7xxGCRState *s = opaque;
+uint32_t value = v;
+
+trace_npcm7xx_gcr_write(offset, value);
+
+if (reg >= NPCM7XX_GCR_NR_REGS) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: offset 0x%04x out of range\n",
+  __func__, (unsigned int)offset);
+return;
+}
+
+switch (reg) {
+case NPCM7XX_GCR_PDID:
+case NPCM7XX_GCR_PWRON:
+case NPCM7XX_GCR_INTSR:
+qemu_log_mask(LOG_GUEST_ERROR, "%s: register @ 0x%04x is read-only\n",
+  __func__, (unsigned int)offset);
+return;
+
+case NPCM7XX_GCR_RESSR:
+case NPCM7XX_GCR_CP2BST:
+/* Write 1 to clear */
+value = s->regs[reg] & ~value;
+break;
+
+case NPCM7XX_GCR_RLOCKR1:
+case NPCM7XX_GCR_MDLR:
+/* Write 1 to set */
+value |= s->regs[reg];
+break;
+};
+
+s->regs[reg] = value;
+}
+

Re: [PATCH v4 2/2] net: detect errors from probing vnet hdr flag for TAP devices

2020-07-07 Thread Philippe Mathieu-Daudé
On 7/7/20 8:45 PM, Laurent Vivier wrote:
> From: "Daniel P. Berrange" 
> 
> When QEMU sets up a tap based network device backend, it mostly ignores errors
> reported from various ioctl() calls it makes, assuming the TAP file descriptor
> is valid. This assumption can easily be violated when the user is passing in a
> pre-opened file descriptor. At best, the ioctls may fail with a -EBADF, but if
> the user passes in a bogus FD number that happens to clash with a FD number 
> that
> QEMU has opened internally for another reason, a wide variety of errnos may
> result, as the TUNGETIFF ioctl number may map to a completely different 
> command
> on a different type of file.
> 
> By ignoring all these errors, QEMU sets up a zombie network backend that will
> never pass any data. Even worse, when QEMU shuts down, or that network backend
> is hot-removed, it will close this bogus file descriptor, which could belong 
> to
> another QEMU device backend.
> 
> There's no obvious guaranteed reliable way to detect that a FD genuinely is a
> TAP device, as opposed to a UNIX socket, or pipe, or something else. Checking
> the errno from probing vnet hdr flag though, does catch the big common cases.
> ie calling TUNGETIFF will return EBADF for an invalid FD, and ENOTTY when FD 
> is
> a UNIX socket, or pipe which catches accidental collisions with FDs used for
> stdio, or monitor socket.
> 
> Previously the example below where bogus fd 9 collides with the FD used for 
> the
> chardev saw:
> 
> $ ./x86_64-softmmu/qemu-system-x86_64 -netdev tap,id=hostnet0,fd=9 \
>   -chardev socket,id=charchannel0,path=/tmp/qga,server,nowait \
>   -monitor stdio -vnc :0
> qemu-system-x86_64: -netdev tap,id=hostnet0,fd=9: TUNGETIFF ioctl() failed: 
> Inappropriate ioctl for device
> TUNSETOFFLOAD ioctl() failed: Bad address
> QEMU 2.9.1 monitor - type 'help' for more information
> (qemu) Warning: netdev hostnet0 has no peer
> 
> which gives a running QEMU with a zombie network backend.
> 
> With this change applied we get an error message and QEMU immediately exits
> before carrying on and making a bigger disaster:
> 
> $ ./x86_64-softmmu/qemu-system-x86_64 -netdev tap,id=hostnet0,fd=9 \
>   -chardev socket,id=charchannel0,path=/tmp/qga,server,nowait \
>   -monitor stdio -vnc :0
> qemu-system-x86_64: -netdev tap,id=hostnet0,vhost=on,fd=9: Unable to query 
> TUNGETIFF on FD 9: Inappropriate ioctl for device
> 
> Reported-by: Dr. David Alan Gilbert 
> Signed-off-by: Daniel P. Berrange 
> Tested-by: Dr. David Alan Gilbert 
> Message-id: 20171027085548.3472-1-berra...@redhat.com
> [lv: to simplify, don't check on EINVAL with TUNGETIFF as it exists since 
> v2.6.27]

Reviewed-by: Philippe Mathieu-Daudé 

> Signed-off-by: Laurent Vivier 
> ---
>  net/tap-bsd.c |  2 +-
>  net/tap-linux.c   |  8 +---
>  net/tap-solaris.c |  2 +-
>  net/tap-stub.c|  2 +-
>  net/tap.c | 25 -
>  net/tap_int.h |  2 +-
>  6 files changed, 29 insertions(+), 12 deletions(-)
> 
> diff --git a/net/tap-bsd.c b/net/tap-bsd.c
> index a5c3707f806d..77aaf674b19d 100644
> --- a/net/tap-bsd.c
> +++ b/net/tap-bsd.c
> @@ -211,7 +211,7 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, 
> Error **errp)
>  {
>  }
>  
> -int tap_probe_vnet_hdr(int fd)
> +int tap_probe_vnet_hdr(int fd, Error **errp)
>  {
>  return 0;
>  }
> diff --git a/net/tap-linux.c b/net/tap-linux.c
> index e0dd442ee34f..b0635e9e32ce 100644
> --- a/net/tap-linux.c
> +++ b/net/tap-linux.c
> @@ -147,13 +147,15 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions 
> *tap, Error **errp)
>  }
>  }
>  
> -int tap_probe_vnet_hdr(int fd)
> +int tap_probe_vnet_hdr(int fd, Error **errp)
>  {
>  struct ifreq ifr;
>  
>  if (ioctl(fd, TUNGETIFF, ) != 0) {
> -error_report("TUNGETIFF ioctl() failed: %s", strerror(errno));
> -return 0;
> +/* TUNGETIFF is available since kernel v2.6.27 */
> +error_setg_errno(errp, errno,
> + "Unable to query TUNGETIFF on FD %d", fd);
> +return -1;
>  }
>  
>  return ifr.ifr_flags & IFF_VNET_HDR;
> diff --git a/net/tap-solaris.c b/net/tap-solaris.c
> index 4725d2314eef..ae2ba6828415 100644
> --- a/net/tap-solaris.c
> +++ b/net/tap-solaris.c
> @@ -206,7 +206,7 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, 
> Error **errp)
>  {
>  }
>  
> -int tap_probe_vnet_hdr(int fd)
> +int tap_probe_vnet_hdr(int fd, Error **errp)
>  {
>  return 0;
>  }
> diff --git a/net/tap-stub.c b/net/tap-stub.c
> index a9ab8f829362..de525a2e69d4 100644
> --- a/net/tap-stub.c
> +++ b/net/tap-stub.c
> @@ -37,7 +37,7 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, 
> Error **errp)
>  {
>  }
>  
> -int tap_probe_vnet_hdr(int fd)
> +int tap_probe_vnet_hdr(int fd, Error **errp)
>  {
>  return 0;
>  }
> diff --git a/net/tap.c b/net/tap.c
> index 41a20102fd0b..b37ccae00cd3 100644
> --- a/net/tap.c
> +++ b/net/tap.c
> @@ -597,7 +597,11 @@ int 

[PATCH v4 00/12] Add Nuvoton NPCM730/NPCM750 SoCs and two BMC machines

2020-07-07 Thread Havard Skinnemoen
I also pushed this and the previous two patchsets to my qemu fork on github.
The branches are named npcm7xx-v[1-4].

  https://github.com/hskinnemoen/qemu

This patch series models enough of the Nuvoton NPCM730 and NPCM750 SoCs to boot
an OpenBMC image built for quanta-gsj. This includes device models for:

  - Global Configuration Registers
  - Clock Control
  - Timers
  - Fuses
  - Memory Controller
  - Flash Controller

These modules, along with the existing Cortex A9 CPU cores and built-in
peripherals, are integrated into a NPCM730 or NPCM750 SoC, which in turn form
the foundation for the quanta-gsj and npcm750-evb machines, respectively. The
two SoCs are very similar; the only difference is that NPCM730 is missing some
peripherals that NPCM750 has, and which are not considered essential for
datacenter use (e.g. graphics controllers). For more information, see

https://www.nuvoton.com/products/cloud-computing/ibmc/

Both quanta-gsj and npcm750-evb correspond to real boards supported by OpenBMC.
At the end of the series, qemu can boot an OpenBMC image built for one of these
boards with some minor modifications.

The patches in this series were developed by Google and reviewed by Nuvoton. We
will be maintaining the machine and peripheral support together.

The data sheet for these SoCs is not generally available. Please let me know if
more comments are needed to understand the device behavior.

Changes since v3:

  - License headers are now GPL v2-or-later throughout.
  - Added vmstate throughout (except the memory controller, which doesn't
really have any state worth saving). Successfully booted a gsj image
with two stop/savevm/quit/loadvm cycles along the way.
  - JFFS2 really doesn't like it if I let qemu keep running after savevm,
and then jump back in time with loadvm. I assume this is expected.
  - Fixed an error API violation in npcm7xx_realize, removed pointless error
check after object_property_set_link().
  - Switched the OTP device to use an embedded array instead of a g_malloc0'd
one because I couldn't figure out how to set up vmstate for the latter.

Changes since v2:

  - Simplified the MAINTAINERS entry.
  - Added link to OpenPOWER jenkins for gsj BMC images.
  - Reverted the smpboot change, back to byte swapping.
  - Adapted to upstream API changes:
  - sysbus_init_child_obj -> object_initialize_child
  - object_property_set_bool -> qdev_realize / sysbus_realize
  - ssi_create_slave_no_init -> qdev_new
  - qdev_init_nofail -> qdev_realize_and_unref
  - ssi_auto_connect_slaves removed
  - Moved Boot ROM loading from soc to machine init.
  - Plumbed power-on-straps property from GCR to the machine init code so it
can be properly initialized. Turns out npcm750 memory init doesn't work
without this. npcm730 is fine either way, though I'm not sure why.
  - Reworked the flash init code so it looks more like aspeed (i.e. the flash
device gets added even if there's no drive).

Changes since v1 (requested by reviewers):

  - Clarify the source of CLK reset values.
  - Made smpboot a constant byte array, eliinated byte swapping.
  - NPCM7xxState now stores an array of ARMCPUs, not pointers to ARMCPUs.
  - Clarify why EL3 is disabled.
  - Introduce NPCM7XX_NUM_IRQ constant.
  - Set the number of CPUs according to SoC variant, and disallow command line
overrides (i.e. you can no longer override the number of CPUs with the -smp
parameter). This is trying to follow the spirit of
https://patchwork.kernel.org/patch/11595407/.
  - Switch register operations to DEVICE_LITTLE_ENDIAN throughout.
  - Machine documentation added (new patch).

Changes since v1 to support flash booting:

  - GCR reset value changes to get past memory initialization when booting
from flash (patches 2 and 5):
  - INTCR2 now indicates that the DDR controller is initialized.
  - INTCR3 is initialized according to DDR memory size. A realize()
method was implemented to achieve this.
  - Refactor the machine initialization a bit to make it easier to drop in
machine-specific flash initialization (patch 6).
  - Extend the series with additional patches to enable booting from flash:
  - Boot ROM (through the -bios option).
  - OTP (fuse) controller.
  - Memory Controller stub (just enough to skip memory training).
  - Flash controller.
  - Board-specific flash initialization.

Thanks for reviewing,

Havard

Havard Skinnemoen (12):
  npcm7xx: Add config symbol
  hw/misc: Add NPCM7xx System Global Control Registers device model
  hw/misc: Add NPCM7xx Clock Controller device model
  hw/timer: Add NPCM7xx Timer device model
  hw/arm: Add NPCM730 and NPCM750 SoC models
  hw/arm: Add two NPCM7xx-based machines
  hw/arm: Load -bios image as a boot ROM for npcm7xx
  hw/nvram: NPCM7xx OTP device model
  hw/mem: Stubbed out NPCM7xx Memory Controller model
  hw/ssi: NPCM7xx Flash Interface Unit device model
  hw/arm: Wire up BMC boot 

Re: [PATCH v4 03/45] error: Document Error API usage rules

2020-07-07 Thread Eric Blake

On 7/7/20 11:05 AM, Markus Armbruster wrote:

This merely codifies existing practice, with one exception: the rule
advising against returning void, where existing practice is mixed.

When the Error API was created, we adopted the (unwritten) rule to
return void when the function returns no useful value on success,
unlike GError, which recommends to return true on success and false on
error then.




Make the rule advising against returning void official by putting it
in writing.  This will hopefully reduce confusion.

Update the examples accordingly.

The remainder of this series will update a substantial amount of code
to honor the rule.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Greg Kurz 
---



@@ -95,14 +122,12 @@
   * Create a new error and pass it to the caller:
   * error_setg(errp, "situation normal, all fouled up");
   *
- * Call a function and receive an error from it:
- * Error *err = NULL;
- * foo(arg, );
- * if (err) {
+ * Call a function, receive an error from it, and pass it to caller


maybe s/to caller/to the caller/


+ * when the function returns a value that indicates failure, say false:
+ * if (!foo(arg, errp)) {
   * handle the error...
   * }
- *
- * Receive an error and pass it on to the caller:
+ * when it doesn't, say a void function:


Hmm. It looks like you have a single sentence "Call a function... when 
the function returns", but this line now makes it obvious that you have 
a single prefix: "Call a function, ...and pass it to the caller:"
with two choices "when the function returns" and "when it doesn't".  I'm 
not sure if there is a nicer way to typeset it, adding yet another ":" 
at the end of the line looks odd.  The idea behind the text is fine, I'm 
just trying to paint the bikeshed to see if there is a better presentation.



   * Error *err = NULL;
   * foo(arg, );
   * if (err) {
@@ -120,6 +145,19 @@
   * foo(arg, errp);
   * for readability.
   *
+ * Receive an error, and handle it locally
+ * when the function returns a value that indicates failure, say false:
+ * Error *err = NULL;
+ * if (!foo(arg, )) {
+ * handle the error...
+ * }
+ * when it doesn't, say a void function:


It helps that you have repeated the same pattern as above.  But that 
means if you change the layout, both groupings should have the same 
layout.  Maybe:


Intro for a task:
- when the function returns...
- when it doesn't

Also, are there functions that have a return type other than void, but 
where the return value is not an indication of error?  If there are, 
then the "say a void function" clause makes sense (but we should 
probably recommend against such functions); if there are not, then "say 
a void function" reads awkwardly.  Maybe:


- when it does not, because it is a void function:


+ * Error *err = NULL;
+ * foo(arg, );
+ * if (err) {
+ * handle the error...
+ * }
+ *
   * Receive and accumulate multiple errors (first one wins):
   * Error *err = NULL, *local_err = NULL;
   * foo(arg, );



--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




[PATCH v4 1/2] net: check if the file descriptor is valid before using it

2020-07-07 Thread Laurent Vivier
qemu_set_nonblock() checks that the file descriptor can be used and, if
not, crashes QEMU. An assert() is used for that. The use of assert() is
used to detect programming error and the coredump will allow to debug
the problem.

But in the case of the tap device, this assert() can be triggered by
a misconfiguration by the user. At startup, it's not a real problem, but it
can also happen during the hot-plug of a new device, and here it's a
problem because we can crash a perfectly healthy system.

For instance:
 # ip link add link virbr0 name macvtap0 type macvtap mode bridge
 # ip link set macvtap0 up
 # TAP=/dev/tap$(ip -o link show macvtap0 | cut -d: -f1)
 # qemu-system-x86_64 -machine q35 -device pcie-root-port,id=pcie-root-port-0 
-monitor stdio 9<> $TAP
 (qemu) netdev_add type=tap,id=hostnet0,vhost=on,fd=9
 (qemu) device_add 
driver=virtio-net-pci,netdev=hostnet0,id=net0,bus=pcie-root-port-0
 (qemu) device_del net0
 (qemu) netdev_del hostnet0
 (qemu) netdev_add type=tap,id=hostnet1,vhost=on,fd=9
 qemu-system-x86_64: .../util/oslib-posix.c:247: qemu_set_nonblock: Assertion 
`f != -1' failed.
 Aborted (core dumped)

To avoid that, add a function, qemu_try_set_nonblock(), that allows to report 
the
problem without crashing.

In the same way, we also update the function for vhostfd in net_init_tap_one() 
and
for fd in net_init_socket() (both descriptors are provided by the user and can
be wrong).

Signed-off-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
---
 include/qemu/sockets.h |  1 +
 net/socket.c   |  9 +--
 net/tap.c  | 25 +++---
 util/oslib-posix.c | 26 +--
 util/oslib-win32.c | 57 --
 5 files changed, 79 insertions(+), 39 deletions(-)

diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index 57cd049d6edd..7d1f8135767d 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -18,6 +18,7 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t 
*addrlen);
 int socket_set_cork(int fd, int v);
 int socket_set_nodelay(int fd);
 void qemu_set_block(int fd);
+int qemu_try_set_nonblock(int fd);
 void qemu_set_nonblock(int fd);
 int socket_set_fast_reuse(int fd);
 
diff --git a/net/socket.c b/net/socket.c
index c92354049bca..2d21fddd9cd6 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -725,13 +725,18 @@ int net_init_socket(const Netdev *netdev, const char 
*name,
 }
 
 if (sock->has_fd) {
-int fd;
+int fd, ret;
 
 fd = monitor_fd_param(cur_mon, sock->fd, errp);
 if (fd == -1) {
 return -1;
 }
-qemu_set_nonblock(fd);
+ret = qemu_try_set_nonblock(fd);
+if (ret < 0) {
+error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
+ name, fd);
+return -1;
+}
 if (!net_socket_fd_init(peer, "socket", name, fd, 1, sock->mcast,
 errp)) {
 return -1;
diff --git a/net/tap.c b/net/tap.c
index 6207f61f84ab..41a20102fd0b 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -689,6 +689,8 @@ static void net_init_tap_one(const NetdevTapOptions *tap, 
NetClientState *peer,
 }
 
 if (vhostfdname) {
+int ret;
+
 vhostfd = monitor_fd_param(cur_mon, vhostfdname, );
 if (vhostfd == -1) {
 if (tap->has_vhostforce && tap->vhostforce) {
@@ -698,7 +700,12 @@ static void net_init_tap_one(const NetdevTapOptions *tap, 
NetClientState *peer,
 }
 return;
 }
-qemu_set_nonblock(vhostfd);
+ret = qemu_try_set_nonblock(vhostfd);
+if (ret < 0) {
+error_setg_errno(errp, -ret, "%s: Can't use file descriptor 
%d",
+ name, fd);
+return;
+}
 } else {
 vhostfd = open("/dev/vhost-net", O_RDWR);
 if (vhostfd < 0) {
@@ -766,6 +773,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
 Error *err = NULL;
 const char *vhostfdname;
 char ifname[128];
+int ret = 0;
 
 assert(netdev->type == NET_CLIENT_DRIVER_TAP);
 tap = >u.tap;
@@ -795,7 +803,12 @@ int net_init_tap(const Netdev *netdev, const char *name,
 return -1;
 }
 
-qemu_set_nonblock(fd);
+ret = qemu_try_set_nonblock(fd);
+if (ret < 0) {
+error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
+ name, fd);
+return -1;
+}
 
 vnet_hdr = tap_probe_vnet_hdr(fd);
 
@@ -810,7 +823,6 @@ int net_init_tap(const Netdev *netdev, const char *name,
 char **fds;
 char **vhost_fds;
 int nfds = 0, nvhosts = 0;
-int ret = 0;
 
 if (tap->has_ifname || tap->has_script || tap->has_downscript ||
 tap->has_vnet_hdr || tap->has_helper || tap->has_queues 

[PATCH v4 0/2] net: tap: check file descriptor can be used

2020-07-07 Thread Laurent Vivier
v4: use qemu_try_set_nonblock() with vhostfd in net_init_tap_one(),
and with fd in net_init_socket()

v3: move qemu_fd_is_valid() checking into a new function
qemu_try_set_nonblock(), and use qemu_try_set_nonblock() in
qemu_set_nonblock().

v2: Add patch from Daniel to check the fd can be used

I have updated Daniel's patch not to check for EINVAL on TUNGETIFF
as I think we can avoid this special case because TUNGETIFF
is available since kernel v2.6.27 (October 2008)
Moreover I think the code was wrong as it was checking with -EINVAL and
not EINVAL.

Daniel P. Berrangé (1):
  net: detect errors from probing vnet hdr flag for TAP devices

Laurent Vivier (1):
  net: check if the file descriptor is valid before using it

 include/qemu/sockets.h |  1 +
 net/socket.c   |  9 +--
 net/tap-bsd.c  |  2 +-
 net/tap-linux.c|  8 +++---
 net/tap-solaris.c  |  2 +-
 net/tap-stub.c |  2 +-
 net/tap.c  | 50 +---
 net/tap_int.h  |  2 +-
 util/oslib-posix.c | 26 +--
 util/oslib-win32.c | 57 --
 10 files changed, 108 insertions(+), 51 deletions(-)

-- 
2.26.2





[PATCH v4 2/2] net: detect errors from probing vnet hdr flag for TAP devices

2020-07-07 Thread Laurent Vivier
From: "Daniel P. Berrange" 

When QEMU sets up a tap based network device backend, it mostly ignores errors
reported from various ioctl() calls it makes, assuming the TAP file descriptor
is valid. This assumption can easily be violated when the user is passing in a
pre-opened file descriptor. At best, the ioctls may fail with a -EBADF, but if
the user passes in a bogus FD number that happens to clash with a FD number that
QEMU has opened internally for another reason, a wide variety of errnos may
result, as the TUNGETIFF ioctl number may map to a completely different command
on a different type of file.

By ignoring all these errors, QEMU sets up a zombie network backend that will
never pass any data. Even worse, when QEMU shuts down, or that network backend
is hot-removed, it will close this bogus file descriptor, which could belong to
another QEMU device backend.

There's no obvious guaranteed reliable way to detect that a FD genuinely is a
TAP device, as opposed to a UNIX socket, or pipe, or something else. Checking
the errno from probing vnet hdr flag though, does catch the big common cases.
ie calling TUNGETIFF will return EBADF for an invalid FD, and ENOTTY when FD is
a UNIX socket, or pipe which catches accidental collisions with FDs used for
stdio, or monitor socket.

Previously the example below where bogus fd 9 collides with the FD used for the
chardev saw:

$ ./x86_64-softmmu/qemu-system-x86_64 -netdev tap,id=hostnet0,fd=9 \
  -chardev socket,id=charchannel0,path=/tmp/qga,server,nowait \
  -monitor stdio -vnc :0
qemu-system-x86_64: -netdev tap,id=hostnet0,fd=9: TUNGETIFF ioctl() failed: 
Inappropriate ioctl for device
TUNSETOFFLOAD ioctl() failed: Bad address
QEMU 2.9.1 monitor - type 'help' for more information
(qemu) Warning: netdev hostnet0 has no peer

which gives a running QEMU with a zombie network backend.

With this change applied we get an error message and QEMU immediately exits
before carrying on and making a bigger disaster:

$ ./x86_64-softmmu/qemu-system-x86_64 -netdev tap,id=hostnet0,fd=9 \
  -chardev socket,id=charchannel0,path=/tmp/qga,server,nowait \
  -monitor stdio -vnc :0
qemu-system-x86_64: -netdev tap,id=hostnet0,vhost=on,fd=9: Unable to query 
TUNGETIFF on FD 9: Inappropriate ioctl for device

Reported-by: Dr. David Alan Gilbert 
Signed-off-by: Daniel P. Berrange 
Tested-by: Dr. David Alan Gilbert 
Message-id: 20171027085548.3472-1-berra...@redhat.com
[lv: to simplify, don't check on EINVAL with TUNGETIFF as it exists since 
v2.6.27]
Signed-off-by: Laurent Vivier 
---
 net/tap-bsd.c |  2 +-
 net/tap-linux.c   |  8 +---
 net/tap-solaris.c |  2 +-
 net/tap-stub.c|  2 +-
 net/tap.c | 25 -
 net/tap_int.h |  2 +-
 6 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/net/tap-bsd.c b/net/tap-bsd.c
index a5c3707f806d..77aaf674b19d 100644
--- a/net/tap-bsd.c
+++ b/net/tap-bsd.c
@@ -211,7 +211,7 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, 
Error **errp)
 {
 }
 
-int tap_probe_vnet_hdr(int fd)
+int tap_probe_vnet_hdr(int fd, Error **errp)
 {
 return 0;
 }
diff --git a/net/tap-linux.c b/net/tap-linux.c
index e0dd442ee34f..b0635e9e32ce 100644
--- a/net/tap-linux.c
+++ b/net/tap-linux.c
@@ -147,13 +147,15 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, 
Error **errp)
 }
 }
 
-int tap_probe_vnet_hdr(int fd)
+int tap_probe_vnet_hdr(int fd, Error **errp)
 {
 struct ifreq ifr;
 
 if (ioctl(fd, TUNGETIFF, ) != 0) {
-error_report("TUNGETIFF ioctl() failed: %s", strerror(errno));
-return 0;
+/* TUNGETIFF is available since kernel v2.6.27 */
+error_setg_errno(errp, errno,
+ "Unable to query TUNGETIFF on FD %d", fd);
+return -1;
 }
 
 return ifr.ifr_flags & IFF_VNET_HDR;
diff --git a/net/tap-solaris.c b/net/tap-solaris.c
index 4725d2314eef..ae2ba6828415 100644
--- a/net/tap-solaris.c
+++ b/net/tap-solaris.c
@@ -206,7 +206,7 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, 
Error **errp)
 {
 }
 
-int tap_probe_vnet_hdr(int fd)
+int tap_probe_vnet_hdr(int fd, Error **errp)
 {
 return 0;
 }
diff --git a/net/tap-stub.c b/net/tap-stub.c
index a9ab8f829362..de525a2e69d4 100644
--- a/net/tap-stub.c
+++ b/net/tap-stub.c
@@ -37,7 +37,7 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, 
Error **errp)
 {
 }
 
-int tap_probe_vnet_hdr(int fd)
+int tap_probe_vnet_hdr(int fd, Error **errp)
 {
 return 0;
 }
diff --git a/net/tap.c b/net/tap.c
index 41a20102fd0b..b37ccae00cd3 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -597,7 +597,11 @@ int net_init_bridge(const Netdev *netdev, const char *name,
 }
 
 qemu_set_nonblock(fd);
-vnet_hdr = tap_probe_vnet_hdr(fd);
+vnet_hdr = tap_probe_vnet_hdr(fd, errp);
+if (vnet_hdr < 0) {
+close(fd);
+return -1;
+}
 s = net_tap_fd_init(peer, "bridge", name, fd, vnet_hdr);
 
 snprintf(s->nc.info_str, sizeof(s->nc.info_str), 

Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze

2020-07-07 Thread Peter Maydell
On Tue, 7 Jul 2020 at 19:37, Peter Maydell  wrote:
>
> On Mon, 6 Jul 2020 at 17:48, Paolo Bonzini  wrote:
> >
> > The following changes since commit fc1bff958998910ec8d25db86cd2f53ff125f7ab:
> >
> >   hw/misc/pca9552: Add missing TypeInfo::class_size field (2020-06-29 
> > 21:16:10 +0100)
> >
> > are available in the Git repository at:
> >
> >   git://github.com/bonzini/qemu.git tags/for-upstream
> >
> > for you to fetch changes up to 80270507070ec73ea82741ce24cb7909a9258ea3:
> >
> >   scripts: improve message when TAP based tests fail (2020-07-06 12:14:25 
> > -0400)
> >
> > 
> > * Make checkpatch say 'qemu' instead of 'kernel' (Aleksandar)
> > * Fix PSE guests with emulated NPT (Alexander B. #1)
> > * Fix leak (Alexander B. #2)
> > * HVF fixes (Roman, Cameron)
> > * New Sapphire Rapids CPUID bits (Cathy)
> > * cpus.c and softmmu/ cleanups (Claudio)
> > * TAP driver tweaks (Daniel, Havard)
> > * object-add bugfix and testcases (Eric A.)
> > * Fix Coverity MIN_CONST and MAX_CONST (Eric B.)
> > * SSE fixes (Joseph)
> > * "-msg guest-name" option (Mario)
> > * support for AMD nested live migration (myself)
> > * Small i386 TCG fixes (myself)
> > * improved error reporting for Xen (myself)
> > * fix "-cpu host -overcommit cpu-pm=on" (myself)
> > * Add accel/Kconfig (Philippe)
> > * KVM API cleanup (Philippe)
> > * iscsi sense handling fixes (Yongji)
> > * Misc bugfixes
>
> Hi; various build or test failures (5 total):

Also it broke my working tree, in the sense that when I
rolled back to current master incremental-rebuild didn't
work but instead failed with:

make: *** No rule to make target '/home/ubuntu/qemu/Kconfig', needed
by 'aarch64-softmmu/config-devices.mak'.  Stop.

thanks
-- PMM



Re: [PATCH v4 02/45] error: Improve error.h's big comment

2020-07-07 Thread Eric Blake

On 7/7/20 11:05 AM, Markus Armbruster wrote:

Add headlines to the big comment.

Explain examples for NULL, _abort and _fatal argument
better.

Tweak rationale for error_propagate_prepend().

Signed-off-by: Markus Armbruster 
---
  include/qapi/error.h | 51 +++-
  1 file changed, 36 insertions(+), 15 deletions(-)



Reviewed-by: Eric Blake 

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PULL 00/53] Misc patches for QEMU 5.1 soft freeze

2020-07-07 Thread Peter Maydell
On Mon, 6 Jul 2020 at 17:48, Paolo Bonzini  wrote:
>
> The following changes since commit fc1bff958998910ec8d25db86cd2f53ff125f7ab:
>
>   hw/misc/pca9552: Add missing TypeInfo::class_size field (2020-06-29 
> 21:16:10 +0100)
>
> are available in the Git repository at:
>
>   git://github.com/bonzini/qemu.git tags/for-upstream
>
> for you to fetch changes up to 80270507070ec73ea82741ce24cb7909a9258ea3:
>
>   scripts: improve message when TAP based tests fail (2020-07-06 12:14:25 
> -0400)
>
> 
> * Make checkpatch say 'qemu' instead of 'kernel' (Aleksandar)
> * Fix PSE guests with emulated NPT (Alexander B. #1)
> * Fix leak (Alexander B. #2)
> * HVF fixes (Roman, Cameron)
> * New Sapphire Rapids CPUID bits (Cathy)
> * cpus.c and softmmu/ cleanups (Claudio)
> * TAP driver tweaks (Daniel, Havard)
> * object-add bugfix and testcases (Eric A.)
> * Fix Coverity MIN_CONST and MAX_CONST (Eric B.)
> * SSE fixes (Joseph)
> * "-msg guest-name" option (Mario)
> * support for AMD nested live migration (myself)
> * Small i386 TCG fixes (myself)
> * improved error reporting for Xen (myself)
> * fix "-cpu host -overcommit cpu-pm=on" (myself)
> * Add accel/Kconfig (Philippe)
> * KVM API cleanup (Philippe)
> * iscsi sense handling fixes (Yongji)
> * Misc bugfixes

Hi; various build or test failures (5 total):

1) OSX:

/Users/pm215/src/qemu-for-merges/ui/cocoa.m:1478:9: error: implicit
declaration of function 'cpu_throttle_set' is invalid in C99 [-
Werror,-Wimplicit-function-declaration]
cpu_throttle_set(throttle_pct);
^

2) aarch64 and aarch32 linux:

/home/pm/qemu/target/arm/kvm.c: In function ‘kvm_arch_init’:
/home/pm/qemu/target/arm/kvm.c:248:29: error: passing argument 1 of
‘kvm_check_extension’ makes integer from pointer without a cast
 [-Werror=int-conversion]
  248 | if (kvm_check_extension(s, KVM_CAP_ARM_NISV_TO_USER)) {
  | ^
  | |
  | KVMState * {aka struct KVMState *}
In file included from /home/pm/qemu/target/arm/kvm.c:23:
/home/pm/qemu/include/sysemu/kvm.h:439:38: note: expected ‘unsigned
int’ but argument is of type ‘KVMState *’ {aka ‘struct KVMState
 *’}
  439 | int kvm_check_extension(unsigned int extension);
  | ~^
/home/pm/qemu/target/arm/kvm.c:248:9: error: too many arguments to
function ‘kvm_check_extension’
  248 | if (kvm_check_extension(s, KVM_CAP_ARM_NISV_TO_USER)) {
  | ^~~
In file included from /home/pm/qemu/target/arm/kvm.c:23:
/home/pm/qemu/include/sysemu/kvm.h:439:5: note: declared here
  439 | int kvm_check_extension(unsigned int extension);
  | ^~~
/home/pm/qemu/target/arm/kvm.c:253:59: error: passing argument 1 of
‘kvm_check_extension’ makes integer from pointer without a cast
 [-Werror=int-conversion]
  253 | cap_has_inject_ext_dabt = kvm_check_extension(s,
  |   ^
  |   |
  |
KVMState * {aka struct KVMState *}
In file included from /home/pm/qemu/target/arm/kvm.c:23:
/home/pm/qemu/include/sysemu/kvm.h:439:38: note: expected ‘unsigned
int’ but argument is of type ‘KVMState *’ {aka ‘struct KVMState
 *’}
  439 | int kvm_check_extension(unsigned int extension);
  | ~^
/home/pm/qemu/target/arm/kvm.c:253:39: error: too many arguments to
function ‘kvm_check_extension’
  253 | cap_has_inject_ext_dabt = kvm_check_extension(s,
  |   ^~~
In file included from /home/pm/qemu/target/arm/kvm.c:23:
/home/pm/qemu/include/sysemu/kvm.h:439:5: note: declared here
  439 | int kvm_check_extension(unsigned int extension);
  | ^~~

3) PPC64 had a failure on iotest 030 (though I think this may
be an intermittent in master):

  TESTiotest-qcow2: 030 [fail]
QEMU  --
"/home/pm215/qemu/build/all/tests/qemu-iotests/../../ppc64-softmmu/qemu-system-ppc64"
-nodefaults -display none -accel qtest
QEMU_IMG  -- "/home/pm215/qemu/build/all/tests/qemu-iotests/../../qemu-img"
QEMU_IO   --
"/home/pm215/qemu/build/all/tests/qemu-iotests/../../qemu-io"  --cache
writeback --aio threads -f qcow2
QEMU_NBD  -- "/home/pm215/qemu/build/all/tests/qemu-iotests/../../qemu-nbd"
IMGFMT-- qcow2 (compat=1.1)
IMGPROTO  -- file
PLATFORM  -- Linux/ppc64 gcc1-power7 3.10.0-862.14.4.el7.ppc64
TEST_DIR  -- /home/pm215/qemu/build/all/tests/qemu-iotests/scratch
SOCK_DIR  -- /tmp/tmp.icAW30swbG
SOCKET_SCM_HELPER --
/home/pm215/qemu/build/all/tests/qemu-iotests/socket_scm_helper

--- /home/pm215/qemu/tests/qemu-iotests/030.out 2019-07-15
15:12:04.941863802 +
+++ /home/pm215/qemu/build/all/tests/qemu-iotests/030.out.bad
2020-07-07 18:01:06.975652394 +

Re: [PATCH v4 01/45] error: Fix examples in error.h's big comment

2020-07-07 Thread Eric Blake

On 7/7/20 11:05 AM, Markus Armbruster wrote:

Mark a bad example more clearly.  Fix the error_propagate_prepend()
example.  Add a missing declaration and a second error pileup example.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Greg Kurz 
---
  include/qapi/error.h | 16 ++--
  1 file changed, 14 insertions(+), 2 deletions(-)



I know you kept my R-b because you only trimmed this in relation to v3, 
but I agree that this patch is still looking fine.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




Re: [PATCH v4 04/10] hw/arm/versatilepb: Comment to remember some IRQs lines are left unwired

2020-07-07 Thread Peter Maydell
On Sun, 5 Jul 2020 at 21:46, Philippe Mathieu-Daudé  wrote:
>
> The 'card is readonly' and 'card inserted' IRQs are not wired.
> Add a comment in case someone know where to wire them.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/arm/versatilepb.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
> index e596b8170f..45a13ae2b9 100644
> --- a/hw/arm/versatilepb.c
> +++ b/hw/arm/versatilepb.c
> @@ -310,7 +310,9 @@ static void versatile_init(MachineState *machine, int 
> board_id)
>  qdev_connect_gpio_out(sysctl, 0, qdev_get_gpio_in(dev, 0));
>
>  sysbus_create_varargs("pl181", 0x10005000, sic[22], sic[1], NULL);
> +/* FIXME wire 'card is readonly' and 'card inserted' IRQs? */
>  sysbus_create_varargs("pl181", 0x1000b000, sic[23], sic[2], NULL);
> +/* FIXME wire 'card is readonly' and 'card inserted' IRQs? */

These should be wired up to the SYS_MCI register in the
"system and configuration registers" block:
https://developer.arm.com/documentation/dui0225/d/programmer-s-reference/status-and-system-control-registers/mci-register--sys-mci

Our "realview_sysctl" device implements this (we use it on the
realviewpb). However it only has support for having one MMC
device -- we'd need to extend it to have the GPIO inputs for
the 2nd MMC controller, and make the arm_sysctl_gpio_set()
function handle them to set the right bits. Then we could
wire it up at the board level fairly easily (more simply
than for realview, which also has to wire the same lines up
to a GPIO controller).

If you believe the documentation (which includes a little
circuit diagram in both the versatilepb and realviewpb manuals)
then the versatilepb doesn't have the inverter on the CARDIN
line that the realview does.

thanks
-- PMM



Re: [PULL 0/3] MIPS + TCG Continuous Benchmarking queue for July 7th, 2020

2020-07-07 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/1594140062-23522-1-git-send-email-aleksandar.qemu.de...@gmail.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 1594140062-23522-1-git-send-email-aleksandar.qemu.de...@gmail.com
Subject: [PULL 0/3] MIPS + TCG Continuous Benchmarking queue for July 7th, 2020

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
   710fb08..c8eaf81  master -> master
 - [tag update]  patchew/20200701183949.398134-1-atish.pa...@wdc.com -> 
patchew/20200701183949.398134-1-atish.pa...@wdc.com
 * [new tag] patchew/20200707180836.5435-1-vr_q...@t-online.de -> 
patchew/20200707180836.5435-1-vr_q...@t-online.de
Switched to a new branch 'test'
962f29e scripts/performance: Add dissect.py script
e646d73 disas: mips: Add Loongson 2F disassembler
99e009f target/mips: fpu: Fix recent regression in add.s after 1ace099f2a

=== OUTPUT BEGIN ===
1/3 Checking commit 99e009f3955b (target/mips: fpu: Fix recent regression in 
add.s after 1ace099f2a)
2/3 Checking commit e646d73f8b6e (disas: mips: Add Loongson 2F disassembler)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#60: 
new file mode 100644

ERROR: space prohibited between function name and open parenthesis '('
#10795: FILE: include/disas/dis-asm.h:399:
+int print_insn_loongson2f   (bfd_vma, disassemble_info*);

total: 1 errors, 1 warnings, 10763 lines checked

Patch 2/3 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

3/3 Checking commit 962f29e09a89 (scripts/performance: Add dissect.py script)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#33: 
new file mode 100755

total: 0 errors, 1 warnings, 165 lines checked

Patch 3/3 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/1594140062-23522-1-git-send-email-aleksandar.qemu.de...@gmail.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

[PULL 31/32] target/avr/cpu: Fix $PC displayed address

2020-07-07 Thread Philippe Mathieu-Daudé
$PC is 16-bit wide. Other registers display addresses on a byte
granularity.
To have a coherent ouput, display $PC using byte granularity too.

Reviewed-by: Thomas Huth 
Reviewed-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20200707070021.10031-3-f4...@amsat.org>
---
 target/avr/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index f0f992aa32..f659bc10f5 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -151,7 +151,7 @@ static void avr_cpu_dump_state(CPUState *cs, FILE *f, int 
flags)
 int i;
 
 qemu_fprintf(f, "\n");
-qemu_fprintf(f, "PC:%06x\n", env->pc_w);
+qemu_fprintf(f, "PC:%06x\n", env->pc_w * 2); /* PC points to words */
 qemu_fprintf(f, "SP:  %04x\n", env->sp);
 qemu_fprintf(f, "rampD: %02x\n", env->rampD >> 16);
 qemu_fprintf(f, "rampX: %02x\n", env->rampX >> 16);
-- 
2.21.3




[PULL 29/32] target/avr: Add section into QEMU documentation

2020-07-07 Thread Philippe Mathieu-Daudé
From: Thomas Huth 

The new section explains basic ways of using AVR target in QEMU.

Signed-off-by: Michael Rolnik 
[thuth: Converted doc from texi to Sphinx syntax]
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-31-h...@tuxfamily.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 docs/system/target-avr.rst | 37 +
 docs/system/targets.rst|  1 +
 2 files changed, 38 insertions(+)
 create mode 100644 docs/system/target-avr.rst

diff --git a/docs/system/target-avr.rst b/docs/system/target-avr.rst
new file mode 100644
index 00..dc99afc895
--- /dev/null
+++ b/docs/system/target-avr.rst
@@ -0,0 +1,37 @@
+.. _AVR-System-emulator:
+
+AVR System emulator
+---
+
+Use the executable ``qemu-system-avr`` to emulate a AVR 8 bit based machine.
+These can have one of the following cores: avr1, avr2, avr25, avr3, avr31,
+avr35, avr4, avr5, avr51, avr6, avrtiny, xmega2, xmega3, xmega4, xmega5,
+xmega6 and xmega7.
+
+As for now it supports few Arduino boards for educational and testing purposes.
+These boards use a ATmega controller, which model is limited to USART & 16-bit
+timer devices, enought to run FreeRTOS based applications (like
+https://github.com/seharris/qemu-avr-tests/blob/master/free-rtos/Demo/AVR_ATMega2560_GCC/demo.elf
+).
+
+Following are examples of possible usages, assuming demo.elf is compiled for
+AVR cpu
+
+ - Continuous non interrupted execution:
+   ``qemu-system-avr -machine mega2560 -bios demo.elf``
+
+ - Continuous non interrupted execution with serial output into telnet window:
+   ``qemu-system-avr -machine mega2560 -bios demo.elf -serial
+   tcp::5678,server,nowait -nographic``
+   and then in another shell
+   ``telnet localhost 5678``
+
+ - Debugging wit GDB debugger:
+   ``qemu-system-avr -machine mega2560 -bios demo.elf -s -S``
+   and then in another shell
+   ``avr-gdb demo.elf``
+   and then within GDB shell
+   ``target remote :1234``
+
+ - Print out executed instructions:
+   ``qemu-system-avr -machine mega2560 -bios demo.elf -d in_asm``
diff --git a/docs/system/targets.rst b/docs/system/targets.rst
index 99435a3eba..560783644d 100644
--- a/docs/system/targets.rst
+++ b/docs/system/targets.rst
@@ -19,3 +19,4 @@ Contents:
target-xtensa
target-s390x
target-rx
+   target-avr
-- 
2.21.3




[PULL 30/32] target/avr/cpu: Drop tlb_flush() in avr_cpu_reset()

2020-07-07 Thread Philippe Mathieu-Daudé
Since commit 1f5c00cfdb tlb_flush() is called from cpu_common_reset().

Reviewed-by: Thomas Huth 
Reviewed-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20200707070021.10031-2-f4...@amsat.org>
---
 target/avr/cpu.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index d7ebe4e23b..f0f992aa32 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -78,8 +78,6 @@ static void avr_cpu_reset(DeviceState *ds)
 env->skip = 0;
 
 memset(env->r, 0, sizeof(env->r));
-
-tlb_flush(cs);
 }
 
 static void avr_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
-- 
2.21.3




[PULL 23/32] hw/misc: avr: Add limited support for power reduction device

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

This is a simple device of just one register, and whenever this
register is written to it calls qemu_set_irq function for each
of 8 bits/IRQs. It is used to implement AVR Power Reduction.

[AM: Remove word 'Atmel' from filenames and all elements of code]
Suggested-by: Aleksandar Markovic 
Signed-off-by: Michael Rolnik 
Signed-off-by: Philippe Mathieu-Daudé 
[rth: Squash include fix and file rename from f4bug]
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Reviewed-by: Alex Bennée 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-22-h...@tuxfamily.org>
---
 include/hw/misc/avr_power.h |  46 +++
 hw/misc/avr_power.c | 113 
 MAINTAINERS |   2 +
 hw/misc/Kconfig |   3 +
 hw/misc/Makefile.objs   |   2 +
 hw/misc/trace-events|   4 ++
 6 files changed, 170 insertions(+)
 create mode 100644 include/hw/misc/avr_power.h
 create mode 100644 hw/misc/avr_power.c

diff --git a/include/hw/misc/avr_power.h b/include/hw/misc/avr_power.h
new file mode 100644
index 00..e08e44f629
--- /dev/null
+++ b/include/hw/misc/avr_power.h
@@ -0,0 +1,46 @@
+/*
+ * AVR Power Reduction Management
+ *
+ * Copyright (c) 2019-2020 Michael Rolnik
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_MISC_AVR_POWER_H
+#define HW_MISC_AVR_POWER_H
+
+#include "hw/sysbus.h"
+#include "hw/hw.h"
+
+
+#define TYPE_AVR_MASK "avr-power"
+#define AVR_MASK(obj) OBJECT_CHECK(AVRMaskState, (obj), TYPE_AVR_MASK)
+
+typedef struct {
+/*  */
+SysBusDevice parent_obj;
+
+/*  */
+MemoryRegion iomem;
+
+uint8_t val;
+qemu_irq irq[8];
+} AVRMaskState;
+
+#endif /* HW_MISC_AVR_POWER_H */
diff --git a/hw/misc/avr_power.c b/hw/misc/avr_power.c
new file mode 100644
index 00..a5412f2cfe
--- /dev/null
+++ b/hw/misc/avr_power.c
@@ -0,0 +1,113 @@
+/*
+ * AVR Power Reduction Management
+ *
+ * Copyright (c) 2019-2020 Michael Rolnik
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/misc/avr_power.h"
+#include "qemu/log.h"
+#include "hw/qdev-properties.h"
+#include "hw/irq.h"
+#include "trace.h"
+
+static void avr_mask_reset(DeviceState *dev)
+{
+AVRMaskState *s = AVR_MASK(dev);
+
+s->val = 0x00;
+
+for (int i = 0; i < 8; i++) {
+qemu_set_irq(s->irq[i], 0);
+}
+}
+
+static uint64_t avr_mask_read(void *opaque, hwaddr offset, unsigned size)
+{
+assert(size == 1);
+assert(offset == 0);
+AVRMaskState *s = opaque;
+
+trace_avr_power_read(s->val);
+
+return (uint64_t)s->val;
+}
+
+static void avr_mask_write(void *opaque, hwaddr offset,
+   uint64_t val64, unsigned size)
+{
+assert(size == 1);
+assert(offset == 0);
+AVRMaskState *s = opaque;
+uint8_t val8 = val64;
+
+

[PULL 32/32] target/avr/disas: Fix store instructions display order

2020-07-07 Thread Philippe Mathieu-Daudé
While LOAD instructions use the target register as first
argument, STORE instructions use it as second argument:

  LD Rd, X// Rd <- (X)

  ST Y, Rd// (Y) <- Rr

Reported-by: Joaquin de Andres 
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20200707070021.10031-4-f4...@amsat.org>
---
 target/avr/disas.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/target/avr/disas.c b/target/avr/disas.c
index 8c11509ce8..70d65ea4b2 100644
--- a/target/avr/disas.c
+++ b/target/avr/disas.c
@@ -196,16 +196,16 @@ INSN(LDZ2,   "r%d, Z+", a->rd)
 INSN(LDZ3,   "r%d, -Z", a->rd)
 INSN(LDDY,   "r%d, Y+%d", a->rd, a->imm)
 INSN(LDDZ,   "r%d, Z+%d", a->rd, a->imm)
-INSN(STS,"r%d, %d", a->rd, a->imm)
-INSN(STX1,   "r%d, X", a->rr)
-INSN(STX2,   "r%d, X+", a->rr)
-INSN(STX3,   "r%d, -X", a->rr)
-INSN(STY2,   "r%d, Y+", a->rd)
-INSN(STY3,   "r%d, -Y", a->rd)
-INSN(STZ2,   "r%d, Z+", a->rd)
-INSN(STZ3,   "r%d, -Z", a->rd)
-INSN(STDY,   "r%d, Y+%d", a->rd, a->imm)
-INSN(STDZ,   "r%d, Z+%d", a->rd, a->imm)
+INSN(STS,"%d, r%d", a->imm, a->rd)
+INSN(STX1,   "X, r%d", a->rr)
+INSN(STX2,   "X+, r%d", a->rr)
+INSN(STX3,   "-X, r%d", a->rr)
+INSN(STY2,   "Y+, r%d", a->rd)
+INSN(STY3,   "-Y, r%d", a->rd)
+INSN(STZ2,   "Z+, r%d", a->rd)
+INSN(STZ3,   "-Z, r%d", a->rd)
+INSN(STDY,   "Y+%d, r%d", a->imm, a->rd)
+INSN(STDZ,   "Z+%d, r%d", a->imm, a->rd)
 INSN(LPM1,   "")
 INSN(LPM2,   "r%d, Z", a->rd)
 INSN(LPMX,   "r%d, Z+", a->rd)
-- 
2.21.3




[PULL 27/32] tests/boot-serial: Test some Arduino boards (AVR based)

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

Print out 'T' through serial port.

The Arduino Duemilanove is based on a AVR5 CPU, while the
Arduino MEGA2560 on a AVR6 CPU.

Signed-off-by: Michael Rolnik 
Signed-off-by: Philippe Mathieu-Daudé 
[rth: Squash Arduino adjustments from f4bug]
Tested-by: Richard Henderson 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Acked-by: Thomas Huth 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-29-h...@tuxfamily.org>
---
 tests/qtest/boot-serial-test.c | 11 +++
 tests/qtest/Makefile.include   |  2 ++
 2 files changed, 13 insertions(+)

diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
index 85a3614286..bfe7624dc6 100644
--- a/tests/qtest/boot-serial-test.c
+++ b/tests/qtest/boot-serial-test.c
@@ -17,6 +17,15 @@
 #include "libqtest.h"
 #include "libqos/libqos-spapr.h"
 
+static const uint8_t bios_avr[] = {
+0x88, 0xe0, /* ldi r24, 0x08   */
+0x80, 0x93, 0xc1, 0x00, /* sts 0x00C1, r24 ; Enable tx */
+0x86, 0xe0, /* ldi r24, 0x06   */
+0x80, 0x93, 0xc2, 0x00, /* sts 0x00C2, r24 ; Set the data bits to 8 */
+0x84, 0xe5, /* ldi r24, 0x54   */
+0x80, 0x93, 0xc6, 0x00, /* sts 0x00C6, r24 ; Output 'T' */
+};
+
 static const uint8_t kernel_mcf5208[] = {
 0x41, 0xf9, 0xfc, 0x06, 0x00, 0x00, /* lea 0xfc06,%a0 */
 0x10, 0x3c, 0x00, 0x54, /* move.b #'T',%d0 */
@@ -104,6 +113,8 @@ typedef struct testdef {
 
 static testdef_t tests[] = {
 { "alpha", "clipper", "", "PCI:" },
+{ "avr", "arduino-duemilanove", "", "T", sizeof(bios_avr), NULL, bios_avr 
},
+{ "avr", "arduino-mega-2560-v3", "", "T", sizeof(bios_avr), NULL, 
bios_avr},
 { "ppc", "ppce500", "", "U-Boot" },
 { "ppc", "40p", "-vga none -boot d", "Trying cd:," },
 { "ppc", "g3beige", "", "PowerPC,750" },
diff --git a/tests/qtest/Makefile.include b/tests/qtest/Makefile.include
index 98af2c2d93..994ac47399 100644
--- a/tests/qtest/Makefile.include
+++ b/tests/qtest/Makefile.include
@@ -66,6 +66,8 @@ check-qtest-i386-y += numa-test
 
 check-qtest-x86_64-y += $(check-qtest-i386-y)
 
+check-qtest-avr-y += boot-serial-test
+
 check-qtest-alpha-y += boot-serial-test
 check-qtest-alpha-$(CONFIG_VGA) += display-vga-test
 
-- 
2.21.3




[PULL 25/32] hw/avr: Add some ATmega microcontrollers

2020-07-07 Thread Philippe Mathieu-Daudé
Add some AVR microcontrollers from the ATmega family:

  - middle range: ATmega168 and ATmega328
  - high range: ATmega1280 and ATmega2560

For product comparison:
  https://www.microchip.com/wwwproducts/ProductCompare/ATmega168P/ATmega328P
  https://www.microchip.com/wwwproducts/ProductCompare/ATmega1280/ATmega2560

Datasheets:
  
http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf
  
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf

[AM: Remove word 'Atmel' from filenames and all elements of code]
Suggested-by: Aleksandar Markovic 
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
[thuth: Rebased to master, fixed object_initialize_child() calls etc.]
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-25-h...@tuxfamily.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/avr/atmega.h  |  48 +
 hw/avr/atmega.c  | 458 +++
 hw/avr/Kconfig   |   5 +
 hw/avr/Makefile.objs |   1 +
 4 files changed, 512 insertions(+)
 create mode 100644 hw/avr/atmega.h
 create mode 100644 hw/avr/atmega.c
 create mode 100644 hw/avr/Kconfig

diff --git a/hw/avr/atmega.h b/hw/avr/atmega.h
new file mode 100644
index 00..0928cb0ce6
--- /dev/null
+++ b/hw/avr/atmega.h
@@ -0,0 +1,48 @@
+/*
+ * QEMU ATmega MCU
+ *
+ * Copyright (c) 2019-2020 Philippe Mathieu-Daudé
+ *
+ * This work is licensed under the terms of the GNU GPLv2 or later.
+ * See the COPYING file in the top-level directory.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_AVR_ATMEGA_H
+#define HW_AVR_ATMEGA_H
+
+#include "hw/char/avr_usart.h"
+#include "hw/timer/avr_timer16.h"
+#include "hw/misc/avr_power.h"
+#include "target/avr/cpu.h"
+
+#define TYPE_ATMEGA_MCU "ATmega"
+#define TYPE_ATMEGA168_MCU  "ATmega168"
+#define TYPE_ATMEGA328_MCU  "ATmega328"
+#define TYPE_ATMEGA1280_MCU "ATmega1280"
+#define TYPE_ATMEGA2560_MCU "ATmega2560"
+
+#define ATMEGA_MCU(obj) OBJECT_CHECK(AtmegaMcuState, (obj), TYPE_ATMEGA_MCU)
+
+#define POWER_MAX 2
+#define USART_MAX 4
+#define TIMER_MAX 6
+#define GPIO_MAX 12
+
+typedef struct AtmegaMcuState {
+/*< private >*/
+SysBusDevice parent_obj;
+/*< public >*/
+
+AVRCPU cpu;
+MemoryRegion flash;
+MemoryRegion eeprom;
+MemoryRegion sram;
+DeviceState *io;
+AVRMaskState pwr[POWER_MAX];
+AVRUsartState usart[USART_MAX];
+AVRTimer16State timer[TIMER_MAX];
+uint64_t xtal_freq_hz;
+} AtmegaMcuState;
+
+#endif /* HW_AVR_ATMEGA_H */
diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c
new file mode 100644
index 00..49ec8047f9
--- /dev/null
+++ b/hw/avr/atmega.c
@@ -0,0 +1,458 @@
+/*
+ * QEMU ATmega MCU
+ *
+ * Copyright (c) 2019-2020 Philippe Mathieu-Daudé
+ *
+ * This work is licensed under the terms of the GNU GPLv2 or later.
+ * See the COPYING file in the top-level directory.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "exec/memory.h"
+#include "exec/address-spaces.h"
+#include "sysemu/sysemu.h"
+#include "hw/qdev-properties.h"
+#include "hw/sysbus.h"
+#include "hw/boards.h" /* FIXME memory_region_allocate_system_memory for sram 
*/
+#include "hw/misc/unimp.h"
+#include "atmega.h"
+
+enum AtmegaPeripheral {
+POWER0, POWER1,
+GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF,
+GPIOG, GPIOH, GPIOI, GPIOJ, GPIOK, GPIOL,
+USART0, USART1, USART2, USART3,
+TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, TIMER5,
+PERIFMAX
+};
+
+#define GPIO(n) (n + GPIOA)
+#define USART(n)(n + USART0)
+#define TIMER(n)(n + TIMER0)
+#define POWER(n)(n + POWER0)
+
+typedef struct {
+uint16_t addr;
+enum AtmegaPeripheral power_index;
+uint8_t power_bit;
+/* timer specific */
+uint16_t intmask_addr;
+uint16_t intflag_addr;
+bool is_timer16;
+} peripheral_cfg;
+
+typedef struct AtmegaMcuClass {
+/*< private >*/
+SysBusDeviceClass parent_class;
+/*< public >*/
+const char *uc_name;
+const char *cpu_type;
+size_t flash_size;
+size_t eeprom_size;
+size_t sram_size;
+size_t io_size;
+size_t gpio_count;
+size_t adc_count;
+const uint8_t *irq;
+const peripheral_cfg *dev;
+} AtmegaMcuClass;
+
+#define ATMEGA_MCU_CLASS(klass) \
+OBJECT_CLASS_CHECK(AtmegaMcuClass, (klass), TYPE_ATMEGA_MCU)
+#define ATMEGA_MCU_GET_CLASS(obj) \
+OBJECT_GET_CLASS(AtmegaMcuClass, (obj), TYPE_ATMEGA_MCU)
+
+static const peripheral_cfg dev168_328[PERIFMAX] = {
+[USART0]= {  0xc0, POWER0, 1 },
+[TIMER2]= {  0xb0, POWER0, 6, 0x70, 0x37, false },
+[TIMER1]= {  0x80, POWER0, 3, 0x6f, 0x36, true },
+[POWER0]= {  0x64 },
+[TIMER0]= {  0x44, POWER0, 5, 0x6e, 0x35, false },
+[GPIOD] = {  

[PULL 21/32] hw/char: avr: Add limited support for USART peripheral

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

These were designed to facilitate testing but should provide enough
function to be useful in other contexts.  Only a subset of the functions
of each peripheral is implemented, mainly due to the lack of a standard
way to handle electrical connections (like GPIO pins).

[AM: Remove word 'Atmel' from filenames and all elements of code]
Suggested-by: Aleksandar Markovic 
Signed-off-by: Michael Rolnik 
Signed-off-by: Sarah Harris 
Signed-off-by: Philippe Mathieu-Daudé 
[rth: Squash I/O size fix and file rename from f4bug]
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-20-h...@tuxfamily.org>
---
 include/hw/char/avr_usart.h |  93 +++
 hw/char/avr_usart.c | 320 
 MAINTAINERS |   2 +
 hw/char/Kconfig |   3 +
 hw/char/Makefile.objs   |   1 +
 5 files changed, 419 insertions(+)
 create mode 100644 include/hw/char/avr_usart.h
 create mode 100644 hw/char/avr_usart.c

diff --git a/include/hw/char/avr_usart.h b/include/hw/char/avr_usart.h
new file mode 100644
index 00..5739aaf26f
--- /dev/null
+++ b/include/hw/char/avr_usart.h
@@ -0,0 +1,93 @@
+/*
+ * AVR USART
+ *
+ * Copyright (c) 2018 University of Kent
+ * Author: Sarah Harris
+ *
+ * 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
+ * 
+ */
+
+#ifndef HW_CHAR_AVR_USART_H
+#define HW_CHAR_AVR_USART_H
+
+#include "hw/sysbus.h"
+#include "chardev/char-fe.h"
+#include "hw/hw.h"
+
+/* Offsets of registers. */
+#define USART_DR   0x06
+#define USART_CSRA  0x00
+#define USART_CSRB  0x01
+#define USART_CSRC  0x02
+#define USART_BRRH 0x05
+#define USART_BRRL 0x04
+
+/* Relevant bits in regiters. */
+#define USART_CSRA_RXC(1 << 7)
+#define USART_CSRA_TXC(1 << 6)
+#define USART_CSRA_DRE(1 << 5)
+#define USART_CSRA_MPCM   (1 << 0)
+
+#define USART_CSRB_RXCIE  (1 << 7)
+#define USART_CSRB_TXCIE  (1 << 6)
+#define USART_CSRB_DREIE  (1 << 5)
+#define USART_CSRB_RXEN   (1 << 4)
+#define USART_CSRB_TXEN   (1 << 3)
+#define USART_CSRB_CSZ2   (1 << 2)
+#define USART_CSRB_RXB8   (1 << 1)
+#define USART_CSRB_TXB8   (1 << 0)
+
+#define USART_CSRC_MSEL1  (1 << 7)
+#define USART_CSRC_MSEL0  (1 << 6)
+#define USART_CSRC_PM1(1 << 5)
+#define USART_CSRC_PM0(1 << 4)
+#define USART_CSRC_CSZ1   (1 << 2)
+#define USART_CSRC_CSZ0   (1 << 1)
+
+#define TYPE_AVR_USART "avr-usart"
+#define AVR_USART(obj) \
+OBJECT_CHECK(AVRUsartState, (obj), TYPE_AVR_USART)
+
+typedef struct {
+/*  */
+SysBusDevice parent_obj;
+
+/*  */
+MemoryRegion mmio;
+
+CharBackend chr;
+
+bool enabled;
+
+uint8_t data;
+bool data_valid;
+uint8_t char_mask;
+/* Control and Status Registers */
+uint8_t csra;
+uint8_t csrb;
+uint8_t csrc;
+/* Baud Rate Registers (low/high byte) */
+uint8_t brrh;
+uint8_t brrl;
+
+/* Receive Complete */
+qemu_irq rxc_irq;
+/* Transmit Complete */
+qemu_irq txc_irq;
+/* Data Register Empty */
+qemu_irq dre_irq;
+} AVRUsartState;
+
+#endif /* HW_CHAR_AVR_USART_H */
diff --git a/hw/char/avr_usart.c b/hw/char/avr_usart.c
new file mode 100644
index 00..fbe2a112b7
--- /dev/null
+++ b/hw/char/avr_usart.c
@@ -0,0 +1,320 @@
+/*
+ * AVR USART
+ *
+ * Copyright (c) 2018 University of Kent
+ * Author: Sarah Harris
+ *
+ * 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 "hw/char/avr_usart.h"
+#include "qemu/log.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+
+static int avr_usart_can_receive(void *opaque)
+{
+AVRUsartState *usart = opaque;
+
+

[PULL 24/32] hw/avr: Add support for loading ELF/raw binaries

2020-07-07 Thread Philippe Mathieu-Daudé
Add avr_load_firmware() function to load firmware in ELF or
raw binary format.

[AM: Corrected the type of the variable containing e_flags]
[AM: Moved definition of e_flags conversion function to boot.c]
Suggested-by: Aleksandar Markovic 
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Aleksandar Markovic 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-24-h...@tuxfamily.org>
[PMD: Replace load_image_targphys() by load_image_mr()]
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/avr/boot.h|  33 +
 include/elf.h|   4 ++
 hw/avr/boot.c| 115 +++
 MAINTAINERS  |   1 +
 hw/avr/Makefile.objs |   1 +
 5 files changed, 154 insertions(+)
 create mode 100644 hw/avr/boot.h
 create mode 100644 hw/avr/boot.c
 create mode 100644 hw/avr/Makefile.objs

diff --git a/hw/avr/boot.h b/hw/avr/boot.h
new file mode 100644
index 00..684d553322
--- /dev/null
+++ b/hw/avr/boot.h
@@ -0,0 +1,33 @@
+/*
+ * AVR loader helpers
+ *
+ * Copyright (c) 2019-2020 Philippe Mathieu-Daudé
+ *
+ * This work is licensed under the terms of the GNU GPLv2 or later.
+ * See the COPYING file in the top-level directory.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_AVR_BOOT_H
+#define HW_AVR_BOOT_H
+
+#include "hw/boards.h"
+#include "cpu.h"
+
+/**
+ * avr_load_firmware:   load an image into a memory region
+ *
+ * @cpu:Handle a AVR CPU object
+ * @ms: A MachineState
+ * @mr: Memory Region to load into
+ * @firmware:   Path to the firmware file (raw binary or ELF format)
+ *
+ * Load a firmware supplied by the machine or by the user  with the
+ * '-bios' command line option, and put it in target memory.
+ *
+ * Returns: true on success, false on error.
+ */
+bool avr_load_firmware(AVRCPU *cpu, MachineState *ms,
+   MemoryRegion *mr, const char *firmware);
+
+#endif
diff --git a/include/elf.h b/include/elf.h
index 8fbfe60e09..5b06b55f28 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -160,6 +160,8 @@ typedef struct mips_elf_abiflags_v0 {
 
 #define EM_CRIS 76  /* Axis Communications 32-bit embedded 
processor */
 
+#define EM_AVR  83  /* AVR 8-bit microcontroller */
+
 #define EM_V85087  /* NEC v850 */
 
 #define EM_H8_300H  47  /* Hitachi H8/300H */
@@ -202,6 +204,8 @@ typedef struct mips_elf_abiflags_v0 {
 #define EM_MOXIE   223 /* Moxie processor family */
 #define EM_MOXIE_OLD   0xFEED
 
+#define EF_AVR_MACH 0x7F   /* Mask for AVR e_flags to get core type */
+
 /* This is the info that is needed to parse the dynamic section of the file */
 #define DT_NULL0
 #define DT_NEEDED  1
diff --git a/hw/avr/boot.c b/hw/avr/boot.c
new file mode 100644
index 00..6fbcde4061
--- /dev/null
+++ b/hw/avr/boot.c
@@ -0,0 +1,115 @@
+/*
+ * AVR loader helpers
+ *
+ * Copyright (c) 2019-2020 Philippe Mathieu-Daudé
+ *
+ * This work is licensed under the terms of the GNU GPLv2 or later.
+ * See the COPYING file in the top-level directory.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/loader.h"
+#include "elf.h"
+#include "boot.h"
+#include "qemu/error-report.h"
+
+static const char *avr_elf_e_flags_to_cpu_type(uint32_t flags)
+{
+switch (flags & EF_AVR_MACH) {
+case bfd_mach_avr1:
+return AVR_CPU_TYPE_NAME("avr1");
+case bfd_mach_avr2:
+return AVR_CPU_TYPE_NAME("avr2");
+case bfd_mach_avr25:
+return AVR_CPU_TYPE_NAME("avr25");
+case bfd_mach_avr3:
+return AVR_CPU_TYPE_NAME("avr3");
+case bfd_mach_avr31:
+return AVR_CPU_TYPE_NAME("avr31");
+case bfd_mach_avr35:
+return AVR_CPU_TYPE_NAME("avr35");
+case bfd_mach_avr4:
+return AVR_CPU_TYPE_NAME("avr4");
+case bfd_mach_avr5:
+return AVR_CPU_TYPE_NAME("avr5");
+case bfd_mach_avr51:
+return AVR_CPU_TYPE_NAME("avr51");
+case bfd_mach_avr6:
+return AVR_CPU_TYPE_NAME("avr6");
+case bfd_mach_avrtiny:
+return AVR_CPU_TYPE_NAME("avrtiny");
+case bfd_mach_avrxmega2:
+return AVR_CPU_TYPE_NAME("xmega2");
+case bfd_mach_avrxmega3:
+return AVR_CPU_TYPE_NAME("xmega3");
+case bfd_mach_avrxmega4:
+return AVR_CPU_TYPE_NAME("xmega4");
+case bfd_mach_avrxmega5:
+return AVR_CPU_TYPE_NAME("xmega5");
+case bfd_mach_avrxmega6:
+return AVR_CPU_TYPE_NAME("xmega6");
+case bfd_mach_avrxmega7:
+return AVR_CPU_TYPE_NAME("xmega7");
+default:
+return NULL;
+}
+}
+
+bool avr_load_firmware(AVRCPU *cpu, MachineState *ms,
+   MemoryRegion *program_mr, const char *firmware)
+{
+const char *filename;
+int bytes_loaded;
+uint64_t entry;
+uint32_t e_flags;
+
+filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, firmware);
+if 

[PULL 15/32] target/avr: Add instruction translation - MCU Control Instructions

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

This includes:
- BREAK
- NOP
- SLEEP
- WDR

Signed-off-by: Michael Rolnik 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-16-h...@tuxfamily.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/avr/insn.decode |  8 ++
 target/avr/translate.c | 65 ++
 2 files changed, 73 insertions(+)

diff --git a/target/avr/insn.decode b/target/avr/insn.decode
index 7bb6ce7495..482c23ad0c 100644
--- a/target/avr/insn.decode
+++ b/target/avr/insn.decode
@@ -177,3 +177,11 @@ BST  101 rd:5 0 bit:3
 BLD  100 rd:5 0 bit:3
 BSET1001 0100 0 bit:3 1000
 BCLR1001 0100 1 bit:3 1000
+
+#
+# MCU Control Instructions
+#
+BREAK   1001 0101 1001 1000
+NOP    
+SLEEP   1001 0101 1000 1000
+WDR 1001 0101 1010 1000
diff --git a/target/avr/translate.c b/target/avr/translate.c
index 884fbb6081..ee7811995a 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -2740,3 +2740,68 @@ static bool trans_BCLR(DisasContext *ctx, arg_BCLR *a)
 
 return true;
 }
+
+/*
+ * MCU Control Instructions
+ */
+
+/*
+ *  The BREAK instruction is used by the On-chip Debug system, and is
+ *  normally not used in the application software. When the BREAK instruction 
is
+ *  executed, the AVR CPU is set in the Stopped Mode. This gives the On-chip
+ *  Debugger access to internal resources.  If any Lock bits are set, or either
+ *  the JTAGEN or OCDEN Fuses are unprogrammed, the CPU will treat the BREAK
+ *  instruction as a NOP and will not enter the Stopped mode.  This instruction
+ *  is not available in all devices. Refer to the device specific instruction
+ *  set summary.
+ */
+static bool trans_BREAK(DisasContext *ctx, arg_BREAK *a)
+{
+if (!avr_have_feature(ctx, AVR_FEATURE_BREAK)) {
+return true;
+}
+
+#ifdef BREAKPOINT_ON_BREAK
+tcg_gen_movi_tl(cpu_pc, ctx->npc - 1);
+gen_helper_debug(cpu_env);
+ctx->bstate = DISAS_EXIT;
+#else
+/* NOP */
+#endif
+
+return true;
+}
+
+/*
+ *  This instruction performs a single cycle No Operation.
+ */
+static bool trans_NOP(DisasContext *ctx, arg_NOP *a)
+{
+
+/* NOP */
+
+return true;
+}
+
+/*
+ *  This instruction sets the circuit in sleep mode defined by the MCU
+ *  Control Register.
+ */
+static bool trans_SLEEP(DisasContext *ctx, arg_SLEEP *a)
+{
+gen_helper_sleep(cpu_env);
+ctx->bstate = DISAS_NORETURN;
+return true;
+}
+
+/*
+ *  This instruction resets the Watchdog Timer. This instruction must be
+ *  executed within a limited time given by the WD prescaler. See the Watchdog
+ *  Timer hardware specification.
+ */
+static bool trans_WDR(DisasContext *ctx, arg_WDR *a)
+{
+gen_helper_wdr(cpu_env);
+
+return true;
+}
-- 
2.21.3




[PULL 26/32] hw/avr: Add limited support for some Arduino boards

2020-07-07 Thread Philippe Mathieu-Daudé
Arduino boards are build with AVR chipsets. Add some of these
boards:

  - Arduino Duemilanove
  - Arduino Uno
  - Arduino Mega

For more information:
  https://www.arduino.cc/en/Main/Products
  https://store.arduino.cc/arduino-genuino/most-popular

[AM: Remove word 'Atmel' from filenames and all elements of code]
Suggested-by: Aleksandar Markovic 
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Reviewed-by: Igor Mammedov 
Reviewed-by: Joaquin de Andres 
[thuth: sysbus_init_child_obj() ==> object_initialize_child()]
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-26-h...@tuxfamily.org>
---
 default-configs/avr-softmmu.mak |   4 +
 hw/avr/arduino.c| 149 
 MAINTAINERS |   6 ++
 hw/Kconfig  |   1 +
 hw/avr/Kconfig  |   4 +
 hw/avr/Makefile.objs|   1 +
 6 files changed, 165 insertions(+)
 create mode 100644 hw/avr/arduino.c

diff --git a/default-configs/avr-softmmu.mak b/default-configs/avr-softmmu.mak
index ca94aad4e1..80218add98 100644
--- a/default-configs/avr-softmmu.mak
+++ b/default-configs/avr-softmmu.mak
@@ -1 +1,5 @@
 # Default configuration for avr-softmmu
+
+# Boards:
+#
+CONFIG_ARDUINO=y
diff --git a/hw/avr/arduino.c b/hw/avr/arduino.c
new file mode 100644
index 00..aeaf2afb82
--- /dev/null
+++ b/hw/avr/arduino.c
@@ -0,0 +1,149 @@
+/*
+ * QEMU Arduino boards
+ *
+ * Copyright (c) 2019-2020 Philippe Mathieu-Daudé
+ *
+ * This work is licensed under the terms of the GNU GPLv2 or later.
+ * See the COPYING file in the top-level directory.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/* TODO: Implement the use of EXTRAM */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/boards.h"
+#include "atmega.h"
+#include "boot.h"
+
+typedef struct ArduinoMachineState {
+/*< private >*/
+MachineState parent_obj;
+/*< public >*/
+AtmegaMcuState mcu;
+} ArduinoMachineState;
+
+typedef struct ArduinoMachineClass {
+/*< private >*/
+MachineClass parent_class;
+/*< public >*/
+const char *mcu_type;
+uint64_t xtal_hz;
+} ArduinoMachineClass;
+
+#define TYPE_ARDUINO_MACHINE \
+MACHINE_TYPE_NAME("arduino")
+#define ARDUINO_MACHINE(obj) \
+OBJECT_CHECK(ArduinoMachineState, (obj), TYPE_ARDUINO_MACHINE)
+#define ARDUINO_MACHINE_CLASS(klass) \
+OBJECT_CLASS_CHECK(ArduinoMachineClass, (klass), TYPE_ARDUINO_MACHINE)
+#define ARDUINO_MACHINE_GET_CLASS(obj) \
+OBJECT_GET_CLASS(ArduinoMachineClass, (obj), TYPE_ARDUINO_MACHINE)
+
+static void arduino_machine_init(MachineState *machine)
+{
+ArduinoMachineClass *amc = ARDUINO_MACHINE_GET_CLASS(machine);
+ArduinoMachineState *ams = ARDUINO_MACHINE(machine);
+
+object_initialize_child(OBJECT(machine), "mcu", >mcu, amc->mcu_type);
+object_property_set_uint(OBJECT(>mcu), amc->xtal_hz,
+ "xtal-frequency-hz", _abort);
+sysbus_realize(SYS_BUS_DEVICE(>mcu), _abort);
+
+if (machine->firmware) {
+if (!avr_load_firmware(>mcu.cpu, machine,
+   >mcu.flash, machine->firmware)) {
+exit(1);
+}
+}
+}
+
+static void arduino_machine_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+
+mc->init = arduino_machine_init;
+mc->default_cpus = 1;
+mc->min_cpus = mc->default_cpus;
+mc->max_cpus = mc->default_cpus;
+mc->no_floppy = 1;
+mc->no_cdrom = 1;
+mc->no_parallel = 1;
+}
+
+static void arduino_duemilanove_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
+
+/* https://www.arduino.cc/en/Main/ArduinoBoardDuemilanove */
+mc->desc= "Arduino Duemilanove (ATmega168)",
+mc->alias   = "2009";
+amc->mcu_type   = TYPE_ATMEGA168_MCU;
+amc->xtal_hz= 16 * 1000 * 1000;
+};
+
+static void arduino_uno_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
+
+/* https://store.arduino.cc/arduino-uno-rev3 */
+mc->desc= "Arduino UNO (ATmega328P)";
+mc->alias   = "uno";
+amc->mcu_type   = TYPE_ATMEGA328_MCU;
+amc->xtal_hz= 16 * 1000 * 1000;
+};
+
+static void arduino_mega_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
+
+/* https://www.arduino.cc/en/Main/ArduinoBoardMega */
+mc->desc= "Arduino Mega (ATmega1280)";
+mc->alias   = "mega";
+amc->mcu_type   = TYPE_ATMEGA1280_MCU;
+amc->xtal_hz= 16 * 1000 * 1000;
+};
+
+static void arduino_mega2560_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+ArduinoMachineClass *amc = 

[PULL 13/32] target/avr: Add instruction translation - Data Transfer Instructions

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

This includes:
- MOV, MOVW
- LDI, LDS LDX LDY LDZ
- LDDY, LDDZ
- STS, STX STY STZ
- STDY, STDZ
- LPM, LPMX
- ELPM, ELPMX
- SPM, SPMX
- IN, OUT
- PUSH, POP
- XCH
- LAS, LAC LAT

Signed-off-by: Michael Rolnik 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-14-h...@tuxfamily.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/avr/insn.decode |  56 +++
 target/avr/translate.c | 990 +
 2 files changed, 1046 insertions(+)

diff --git a/target/avr/insn.decode b/target/avr/insn.decode
index 851eddedc7..279ddfbc0c 100644
--- a/target/avr/insn.decode
+++ b/target/avr/insn.decode
@@ -107,3 +107,59 @@ SBIC1001 1001 reg:5 bit:3
 SBIS1001 1011 reg:5 bit:3
 BRBS 00 ... ... @op_bit_imm
 BRBC 01 ... ... @op_bit_imm
+
+#
+# Data Transfer Instructions
+#
+
+%rd_d   4:4 !function=to_regs_00_30_by_two
+%rr_d   0:4 !function=to_regs_00_30_by_two
+
+@io_rd_imm   . .. . _imm rd=%rd imm=%io_imm
+@ldst_d .. . . .. . rd:5  . ... _imm imm=%ldst_d_imm
+
+# The 16-bit immediate is completely in the next word.
+# Fields cannot be defined with no bits, so we cannot play
+# the same trick and append to a zero-bit value.
+# Defer reading the immediate until trans_{LDS,STS}.
+@ldst_s  ... rd:5   imm=0
+
+MOV 0010 11 . . @op_rd_rr
+MOVW 0001   _rr  rd=%rd_d rr=%rr_d
+LDI 1110    @op_rd_imm8
+LDS 1001 000 .  @ldst_s
+LDX11001 000 rd:5 1100
+LDX21001 000 rd:5 1101
+LDX31001 000 rd:5 1110
+LDY21001 000 rd:5 1001
+LDY31001 000 rd:5 1010
+LDZ21001 000 rd:5 0001
+LDZ31001 000 rd:5 0010
+LDDY10 . 0 .. 0 . 1 ... @ldst_d
+LDDZ10 . 0 .. 0 . 0 ... @ldst_d
+STS 1001 001 .  @ldst_s
+STX11001 001 rr:5 1100
+STX21001 001 rr:5 1101
+STX31001 001 rr:5 1110
+STY21001 001 rd:5 1001
+STY31001 001 rd:5 1010
+STZ21001 001 rd:5 0001
+STZ31001 001 rd:5 0010
+STDY10 . 0 .. 1 . 1 ... @ldst_d
+STDZ10 . 0 .. 1 . 0 ... @ldst_d
+LPM11001 0101 1100 1000
+LPM21001 000 rd:5 0100
+LPMX1001 000 rd:5 0101
+ELPM1   1001 0101 1101 1000
+ELPM2   1001 000 rd:5 0110
+ELPMX   1001 000 rd:5 0111
+SPM 1001 0101 1110 1000
+SPMX1001 0101  1000
+IN  1011 0 .. . @io_rd_imm
+OUT 1011 1 .. . @io_rd_imm
+PUSH1001 001 rd:5 
+POP 1001 000 rd:5 
+XCH 1001 001 rd:5 0100
+LAC 1001 001 rd:5 0110
+LAS 1001 001 rd:5 0101
+LAT 1001 001 rd:5 0111
diff --git a/target/avr/translate.c b/target/avr/translate.c
index 5581264045..fce8b5af9a 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -143,6 +143,10 @@ static int to_regs_24_30_by_two(DisasContext *ctx, int 
indx)
 return 24 + (indx % 4) * 2;
 }
 
+static int to_regs_00_30_by_two(DisasContext *ctx, int indx)
+{
+return (indx % 16) * 2;
+}
 
 static uint16_t next_word(DisasContext *ctx)
 {
@@ -1503,3 +1507,989 @@ static bool trans_BRBS(DisasContext *ctx, arg_BRBS *a)
 ctx->bstate = DISAS_CHAIN;
 return true;
 }
+
+/*
+ * Data Transfer Instructions
+ */
+
+/*
+ *  in the gen_set_addr & gen_get_addr functions
+ *  H assumed to be in 0x00ff format
+ *  M assumed to be in 0x00ff format
+ *  L assumed to be in 0x00ff format
+ */
+static void gen_set_addr(TCGv addr, TCGv H, TCGv M, TCGv L)
+{
+
+tcg_gen_andi_tl(L, addr, 0x00ff);
+
+tcg_gen_andi_tl(M, addr, 0xff00);
+tcg_gen_shri_tl(M, M, 8);
+
+tcg_gen_andi_tl(H, addr, 0x00ff);
+}
+
+static void gen_set_xaddr(TCGv addr)
+{
+gen_set_addr(addr, cpu_rampX, cpu_r[27], cpu_r[26]);
+}
+
+static void gen_set_yaddr(TCGv addr)
+{
+gen_set_addr(addr, cpu_rampY, cpu_r[29], cpu_r[28]);
+}
+
+static void gen_set_zaddr(TCGv addr)
+{
+gen_set_addr(addr, cpu_rampZ, cpu_r[31], cpu_r[30]);
+}
+
+static TCGv gen_get_addr(TCGv H, TCGv M, TCGv L)
+{
+TCGv addr = tcg_temp_new_i32();
+
+tcg_gen_deposit_tl(addr, M, H, 8, 8);
+tcg_gen_deposit_tl(addr, L, addr, 8, 16);
+
+return addr;
+}
+
+static TCGv gen_get_xaddr(void)
+{
+return gen_get_addr(cpu_rampX, cpu_r[27], cpu_r[26]);
+}
+
+static TCGv gen_get_yaddr(void)
+{
+return 

[PULL 19/32] target/avr: Register AVR support with the rest of QEMU

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

Add AVR related definitions into QEMU, make AVR support buildable.

[AM: Remove word 'Atmel' from filenames and all elements of code]
Suggested-by: Aleksandar Markovic 
Signed-off-by: Michael Rolnik 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-23-h...@tuxfamily.org>
[PMD: Fixed @avr tag in qapi/machine.json]
Signed-off-by: Philippe Mathieu-Daudé 
---
 configure   |  7 +++
 default-configs/avr-softmmu.mak |  1 +
 qapi/machine.json   |  3 ++-
 include/disas/dis-asm.h | 19 ++
 include/sysemu/arch_init.h  |  1 +
 arch_init.c |  2 ++
 MAINTAINERS |  9 +
 target/avr/Makefile.objs| 34 +
 8 files changed, 75 insertions(+), 1 deletion(-)
 create mode 100644 default-configs/avr-softmmu.mak
 create mode 100644 target/avr/Makefile.objs

diff --git a/configure b/configure
index c220ab4d80..11f7353e2f 100755
--- a/configure
+++ b/configure
@@ -8115,6 +8115,10 @@ case "$target_name" in
 mttcg="yes"
 gdb_xml_files="aarch64-core.xml aarch64-fpu.xml arm-core.xml arm-vfp.xml 
arm-vfp3.xml arm-neon.xml arm-m-profile.xml"
   ;;
+  avr)
+gdb_xml_files="avr-cpu.xml"
+target_compiler=$cross_cc_avr
+  ;;
   cris)
   ;;
   hppa)
@@ -8359,6 +8363,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   disas_config "ARM_A64"
 fi
   ;;
+  avr)
+disas_config "AVR"
+  ;;
   cris)
 disas_config "CRIS"
   ;;
diff --git a/default-configs/avr-softmmu.mak b/default-configs/avr-softmmu.mak
new file mode 100644
index 00..ca94aad4e1
--- /dev/null
+++ b/default-configs/avr-softmmu.mak
@@ -0,0 +1 @@
+# Default configuration for avr-softmmu
diff --git a/qapi/machine.json b/qapi/machine.json
index ff7b5032e3..f59144023c 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -17,6 +17,7 @@
 # being.
 #
 # @rx: since 5.0
+# @avr: since 5.1
 #
 # Notes: The resulting QMP strings can be appended to the "qemu-system-"
 #prefix to produce the corresponding QEMU executable name. This
@@ -25,7 +26,7 @@
 # Since: 3.0
 ##
 { 'enum' : 'SysEmuTarget',
-  'data' : [ 'aarch64', 'alpha', 'arm', 'cris', 'hppa', 'i386', 'lm32',
+  'data' : [ 'aarch64', 'alpha', 'arm', 'avr', 'cris', 'hppa', 'i386', 'lm32',
  'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64',
  'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc',
  'ppc64', 'riscv32', 'riscv64', 'rx', 's390x', 'sh4',
diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index c5f9fa08ab..9856bf7921 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -211,6 +211,25 @@ enum bfd_architecture
 #define bfd_mach_m32r  0  /* backwards compatibility */
   bfd_arch_mn10200,/* Matsushita MN10200 */
   bfd_arch_mn10300,/* Matsushita MN10300 */
+  bfd_arch_avr,/* AVR microcontrollers */
+#define bfd_mach_avr1   1
+#define bfd_mach_avr2   2
+#define bfd_mach_avr25  25
+#define bfd_mach_avr3   3
+#define bfd_mach_avr31  31
+#define bfd_mach_avr35  35
+#define bfd_mach_avr4   4
+#define bfd_mach_avr5   5
+#define bfd_mach_avr51  51
+#define bfd_mach_avr6   6
+#define bfd_mach_avrtiny100
+#define bfd_mach_avrxmega1  101
+#define bfd_mach_avrxmega2  102
+#define bfd_mach_avrxmega3  103
+#define bfd_mach_avrxmega4  104
+#define bfd_mach_avrxmega5  105
+#define bfd_mach_avrxmega6  106
+#define bfd_mach_avrxmega7  107
   bfd_arch_cris,   /* Axis CRIS */
 #define bfd_mach_cris_v0_v10   255
 #define bfd_mach_cris_v32  32
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 71a7a285ee..54f069d491 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -25,6 +25,7 @@ enum {
 QEMU_ARCH_HPPA = (1 << 18),
 QEMU_ARCH_RISCV = (1 << 19),
 QEMU_ARCH_RX = (1 << 20),
+QEMU_ARCH_AVR = (1 << 21),
 
 QEMU_ARCH_NONE = (1 << 31),
 };
diff --git a/arch_init.c b/arch_init.c
index 8afea4748b..7fd5c09b2b 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -90,6 +90,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_UNICORE32
 #elif defined(TARGET_XTENSA)
 #define QEMU_ARCH QEMU_ARCH_XTENSA
+#elif defined(TARGET_AVR)
+#define QEMU_ARCH QEMU_ARCH_AVR
 #endif
 
 const uint32_t arch_type = QEMU_ARCH;
diff --git a/MAINTAINERS b/MAINTAINERS
index d439aa41b6..3e6651ecc3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -975,6 +975,15 @@ F: include/hw/*/nrf51*.h
 F: include/hw/*/microbit*.h
 F: tests/qtest/microbit-test.c
 
+AVR Machines
+-
+
+AVR MCUs
+M: Michael Rolnik 
+R: Sarah Harris 
+S: Maintained
+F: default-configs/avr-softmmu.mak
+
 CRIS Machines
 -
 Axis Dev88
diff --git a/target/avr/Makefile.objs b/target/avr/Makefile.objs
new file mode 100644
index 

[PULL 22/32] hw/timer: avr: Add limited support for 16-bit timer peripheral

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

These were designed to facilitate testing but should provide enough
function to be useful in other contexts.  Only a subset of the functions
of each peripheral is implemented, mainly due to the lack of a standard
way to handle electrical connections (like GPIO pins).

[AM: Remove word 'Atmel' from filenames and all elements of code]
Suggested-by: Aleksandar Markovic 
Signed-off-by: Sarah Harris 
Signed-off-by: Ed Robbins 
Signed-off-by: Philippe Mathieu-Daudé 
[rth: Squash info mtree fixes and a file rename from f4bug]
Signed-off-by: Richard Henderson 
[PMD: Use qemu_log_mask(LOG_UNIMP), replace goto by return]
Signed-off-by: Aleksandar Markovic 
Reviewed-by: Alex Bennée 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-21-h...@tuxfamily.org>
[PMD: Check cpu-frequency-hz property in realize()]
Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/timer/avr_timer16.h |  94 +
 hw/timer/avr_timer16.c | 621 +
 MAINTAINERS|   2 +
 hw/timer/Kconfig   |   3 +
 hw/timer/Makefile.objs |   2 +
 hw/timer/trace-events  |  12 +
 6 files changed, 734 insertions(+)
 create mode 100644 include/hw/timer/avr_timer16.h
 create mode 100644 hw/timer/avr_timer16.c

diff --git a/include/hw/timer/avr_timer16.h b/include/hw/timer/avr_timer16.h
new file mode 100644
index 00..982019d242
--- /dev/null
+++ b/include/hw/timer/avr_timer16.h
@@ -0,0 +1,94 @@
+/*
+ * AVR 16-bit timer
+ *
+ * Copyright (c) 2018 University of Kent
+ * Author: Ed Robbins
+ *
+ * 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
+ * 
+ */
+
+/*
+ * Driver for 16 bit timers on 8 bit AVR devices.
+ * Note:
+ * On ATmega640/V-1280/V-1281/V-2560/V-2561/V timers 1, 3, 4 and 5 are 16 bit
+ */
+
+#ifndef HW_TIMER_AVR_TIMER16_H
+#define HW_TIMER_AVR_TIMER16_H
+
+#include "hw/sysbus.h"
+#include "qemu/timer.h"
+#include "hw/hw.h"
+
+enum NextInterrupt {
+OVERFLOW,
+COMPA,
+COMPB,
+COMPC,
+CAPT
+};
+
+#define TYPE_AVR_TIMER16 "avr-timer16"
+#define AVR_TIMER16(obj) \
+OBJECT_CHECK(AVRTimer16State, (obj), TYPE_AVR_TIMER16)
+
+typedef struct AVRTimer16State {
+/*  */
+SysBusDevice parent_obj;
+
+/*  */
+MemoryRegion iomem;
+MemoryRegion imsk_iomem;
+MemoryRegion ifr_iomem;
+QEMUTimer *timer;
+qemu_irq capt_irq;
+qemu_irq compa_irq;
+qemu_irq compb_irq;
+qemu_irq compc_irq;
+qemu_irq ovf_irq;
+
+bool enabled;
+
+/* registers */
+uint8_t cra;
+uint8_t crb;
+uint8_t crc;
+uint8_t cntl;
+uint8_t cnth;
+uint8_t icrl;
+uint8_t icrh;
+uint8_t ocral;
+uint8_t ocrah;
+uint8_t ocrbl;
+uint8_t ocrbh;
+uint8_t ocrcl;
+uint8_t ocrch;
+/*
+ * Reads and writes to CNT and ICR utilise a bizarre temporary
+ * register, which we emulate
+ */
+uint8_t rtmp;
+uint8_t imsk;
+uint8_t ifr;
+
+uint8_t id;
+uint64_t cpu_freq_hz;
+uint64_t freq_hz;
+uint64_t period_ns;
+uint64_t reset_time_ns;
+enum NextInterrupt next_interrupt;
+} AVRTimer16State;
+
+#endif /* HW_TIMER_AVR_TIMER16_H */
diff --git a/hw/timer/avr_timer16.c b/hw/timer/avr_timer16.c
new file mode 100644
index 00..c48555da52
--- /dev/null
+++ b/hw/timer/avr_timer16.c
@@ -0,0 +1,621 @@
+/*
+ * AVR 16-bit timer
+ *
+ * Copyright (c) 2018 University of Kent
+ * Author: Ed Robbins
+ *
+ * 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
+ * 
+ */
+
+/*
+ * Driver for 16 bit timers on 8 bit AVR devices.
+ * Note:
+ * ATmega640/V-1280/V-1281/V-2560/V-2561/V timers 1, 3, 4 and 5 are 16 bit
+ */
+
+/*
+ * XXX TODO: Power Reduction Register support
+ *   

[PULL 14/32] target/avr: Add instruction translation - Bit and Bit-test Instructions

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

This includes:
- LSR, ROR
- ASR
- SWAP
- SBI, CBI
- BST, BLD
- BSET, BCLR

Signed-off-by: Michael Rolnik 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-15-h...@tuxfamily.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/avr/insn.decode |  14 +++
 target/avr/translate.c | 247 +
 2 files changed, 261 insertions(+)

diff --git a/target/avr/insn.decode b/target/avr/insn.decode
index 279ddfbc0c..7bb6ce7495 100644
--- a/target/avr/insn.decode
+++ b/target/avr/insn.decode
@@ -163,3 +163,17 @@ XCH 1001 001 rd:5 0100
 LAC 1001 001 rd:5 0110
 LAS 1001 001 rd:5 0101
 LAT 1001 001 rd:5 0111
+
+#
+# Bit and Bit-test Instructions
+#
+LSR 1001 010 rd:5 0110
+ROR 1001 010 rd:5 0111
+ASR 1001 010 rd:5 0101
+SWAP1001 010 rd:5 0010
+SBI 1001 1010 reg:5 bit:3
+CBI 1001 1000 reg:5 bit:3
+BST  101 rd:5 0 bit:3
+BLD  100 rd:5 0 bit:3
+BSET1001 0100 0 bit:3 1000
+BCLR1001 0100 1 bit:3 1000
diff --git a/target/avr/translate.c b/target/avr/translate.c
index fce8b5af9a..884fbb6081 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -2493,3 +2493,250 @@ static bool trans_LAT(DisasContext *ctx, arg_LAT *a)
 
 return true;
 }
+
+/*
+ * Bit and Bit-test Instructions
+ */
+static void gen_rshift_ZNVSf(TCGv R)
+{
+tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, R, 0); /* Zf = R == 0 */
+tcg_gen_shri_tl(cpu_Nf, R, 7); /* Nf = R(7) */
+tcg_gen_xor_tl(cpu_Vf, cpu_Nf, cpu_Cf);
+tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf = Nf ^ Vf */
+}
+
+/*
+ *  Shifts all bits in Rd one place to the right. Bit 7 is cleared. Bit 0 is
+ *  loaded into the C Flag of the SREG. This operation effectively divides an
+ *  unsigned value by two. The C Flag can be used to round the result.
+ */
+static bool trans_LSR(DisasContext *ctx, arg_LSR *a)
+{
+TCGv Rd = cpu_r[a->rd];
+
+tcg_gen_andi_tl(cpu_Cf, Rd, 1);
+tcg_gen_shri_tl(Rd, Rd, 1);
+
+/* update status register */
+tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_Zf, Rd, 0); /* Zf = Rd == 0 */
+tcg_gen_movi_tl(cpu_Nf, 0);
+tcg_gen_mov_tl(cpu_Vf, cpu_Cf);
+tcg_gen_mov_tl(cpu_Sf, cpu_Vf);
+
+return true;
+}
+
+/*
+ *  Shifts all bits in Rd one place to the right. The C Flag is shifted into
+ *  bit 7 of Rd. Bit 0 is shifted into the C Flag.  This operation, combined
+ *  with ASR, effectively divides multi-byte signed values by two. Combined 
with
+ *  LSR it effectively divides multi-byte unsigned values by two. The Carry 
Flag
+ *  can be used to round the result.
+ */
+static bool trans_ROR(DisasContext *ctx, arg_ROR *a)
+{
+TCGv Rd = cpu_r[a->rd];
+TCGv t0 = tcg_temp_new_i32();
+
+tcg_gen_shli_tl(t0, cpu_Cf, 7);
+
+/* update status register */
+tcg_gen_andi_tl(cpu_Cf, Rd, 1);
+
+/* update output register */
+tcg_gen_shri_tl(Rd, Rd, 1);
+tcg_gen_or_tl(Rd, Rd, t0);
+
+/* update status register */
+gen_rshift_ZNVSf(Rd);
+
+tcg_temp_free_i32(t0);
+
+return true;
+}
+
+/*
+ *  Shifts all bits in Rd one place to the right. Bit 7 is held constant. Bit 0
+ *  is loaded into the C Flag of the SREG. This operation effectively divides a
+ *  signed value by two without changing its sign. The Carry Flag can be used 
to
+ *  round the result.
+ */
+static bool trans_ASR(DisasContext *ctx, arg_ASR *a)
+{
+TCGv Rd = cpu_r[a->rd];
+TCGv t0 = tcg_temp_new_i32();
+
+/* update status register */
+tcg_gen_andi_tl(cpu_Cf, Rd, 1); /* Cf = Rd(0) */
+
+/* update output register */
+tcg_gen_andi_tl(t0, Rd, 0x80); /* Rd = (Rd & 0x80) | (Rd >> 1) */
+tcg_gen_shri_tl(Rd, Rd, 1);
+tcg_gen_or_tl(Rd, Rd, t0);
+
+/* update status register */
+gen_rshift_ZNVSf(Rd);
+
+tcg_temp_free_i32(t0);
+
+return true;
+}
+
+/*
+ *  Swaps high and low nibbles in a register.
+ */
+static bool trans_SWAP(DisasContext *ctx, arg_SWAP *a)
+{
+TCGv Rd = cpu_r[a->rd];
+TCGv t0 = tcg_temp_new_i32();
+TCGv t1 = tcg_temp_new_i32();
+
+tcg_gen_andi_tl(t0, Rd, 0x0f);
+tcg_gen_shli_tl(t0, t0, 4);
+tcg_gen_andi_tl(t1, Rd, 0xf0);
+tcg_gen_shri_tl(t1, t1, 4);
+tcg_gen_or_tl(Rd, t0, t1);
+
+tcg_temp_free_i32(t1);
+tcg_temp_free_i32(t0);
+
+return true;
+}
+
+/*
+ *  Sets a specified bit in an I/O Register. This instruction operates on
+ *  the lower 32 I/O Registers -- addresses 0-31.
+ */
+static bool trans_SBI(DisasContext *ctx, arg_SBI *a)
+{
+TCGv data = tcg_temp_new_i32();
+TCGv port = tcg_const_i32(a->reg);
+
+gen_helper_inb(data, cpu_env, port);
+tcg_gen_ori_tl(data, data, 1 << a->bit);
+gen_helper_outb(cpu_env, port, data);
+
+

[PULL 18/32] target/avr: Add support for disassembling via option '-d in_asm'

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

Provide function disassembles executed instruction when '-d in_asm' is
provided.

Example:

$ qemu-system-avr -bios free-rtos/Demo/AVR_ATMega2560_GCC/demo.elf -d in_asm
...
IN:
0x014a:  CALL  0x3808

IN: main
0x3808:  CALL  0x4b4

IN: vParTestInitialise
0x04b4:  LDI   r24, 255
0x04b6:  STS   r24, 0
0x04b8:  MULS  r16, r20
0x04ba:  OUT   $1, r24
0x04bc:  LDS   r24, 0
0x04be:  MULS  r16, r20
0x04c0:  OUT   $2, r24
0x04c2:  RET
...

Suggested-by: Richard Henderson 
Suggested-by: Philippe Mathieu-Daudé 
Suggested-by: Aleksandar Markovic 
Signed-off-by: Michael Rolnik 
[rth: Fix spacing and const mnemonic arrays]
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-19-h...@tuxfamily.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/avr/cpu.h   |   1 +
 target/avr/cpu.c   |   2 +-
 target/avr/disas.c | 246 +
 target/avr/translate.c |  12 ++
 4 files changed, 260 insertions(+), 1 deletion(-)
 create mode 100644 target/avr/disas.c

diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index f229ff78c0..ae95585cdc 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -161,6 +161,7 @@ bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
 hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int avr_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+int avr_print_insn(bfd_vma addr, disassemble_info *info);
 
 static inline int avr_feature(CPUAVRState *env, AVRFeature feature)
 {
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index 7178e86f69..d7ebe4e23b 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -85,7 +85,7 @@ static void avr_cpu_reset(DeviceState *ds)
 static void avr_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
 {
 info->mach = bfd_arch_avr;
-info->print_insn = NULL;
+info->print_insn = avr_print_insn;
 }
 
 static void avr_cpu_realizefn(DeviceState *dev, Error **errp)
diff --git a/target/avr/disas.c b/target/avr/disas.c
new file mode 100644
index 00..8c11509ce8
--- /dev/null
+++ b/target/avr/disas.c
@@ -0,0 +1,246 @@
+/*
+ * AVR disassembler
+ *
+ * Copyright (c) 2019-2020 Richard Henderson 
+ * Copyright (c) 2019-2020 Michael Rolnik 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+
+typedef struct {
+disassemble_info *info;
+uint16_t next_word;
+bool next_word_used;
+} DisasContext;
+
+static int to_regs_16_31_by_one(DisasContext *ctx, int indx)
+{
+return 16 + (indx % 16);
+}
+
+static int to_regs_16_23_by_one(DisasContext *ctx, int indx)
+{
+return 16 + (indx % 8);
+}
+
+static int to_regs_24_30_by_two(DisasContext *ctx, int indx)
+{
+return 24 + (indx % 4) * 2;
+}
+
+static int to_regs_00_30_by_two(DisasContext *ctx, int indx)
+{
+return (indx % 16) * 2;
+}
+
+static uint16_t next_word(DisasContext *ctx)
+{
+ctx->next_word_used = true;
+return ctx->next_word;
+}
+
+static int append_16(DisasContext *ctx, int x)
+{
+return x << 16 | next_word(ctx);
+}
+
+
+/* Include the auto-generated decoder.  */
+static bool decode_insn(DisasContext *ctx, uint16_t insn);
+#include "decode_insn.inc.c"
+
+#define output(mnemonic, format, ...) \
+(pctx->info->fprintf_func(pctx->info->stream, "%-9s " format, \
+mnemonic, ##__VA_ARGS__))
+
+int avr_print_insn(bfd_vma addr, disassemble_info *info)
+{
+DisasContext ctx;
+DisasContext *pctx = 
+bfd_byte buffer[4];
+uint16_t insn;
+int status;
+
+ctx.info = info;
+
+status = info->read_memory_func(addr, buffer, 4, info);
+if (status != 0) {
+info->memory_error_func(status, addr, info);
+return -1;
+}
+insn = bfd_getl16(buffer);
+ctx.next_word = bfd_getl16(buffer + 2);
+ctx.next_word_used = false;
+
+if (!decode_insn(, insn)) {
+output(".db", "0x%02x, 0x%02x", buffer[0], buffer[1]);
+}
+
+return ctx.next_word_used ? 4 : 2;
+}
+
+
+#define INSN(opcode, format, ...) 

[PULL 28/32] tests/acceptance: Test the Arduino MEGA2560 board

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

The test is based on
https://github.com/seharris/qemu-avr-tests/tree/master/free-rtos/Demo
demo which. If working correctly, prints 'ABCDEFGHIJKLMNOPQRSTUVWX' out.
it also demostrates that timer and IRQ are working

As the path name demonstrates, the FreeRTOS tests target a
board based on a ATMega2560 MCU. We have one, the Arduino
MEGA2560.

Complementary documentation:

https://feilipu.me/2012/01/15/ethermega-arduino-mega-2560-and-freertos/
https://feilipu.me/2015/11/24/arduino_freertos/ (see 'Compatibility')

Signed-off-by: Michael Rolnik 
Signed-off-by: Philippe Mathieu-Daudé 
[rth: Squash multiple avocado fixups from f4bug]
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Tested-by: Richard Henderson 
Tested-by: Philippe Mathieu-Daudé 
Acked-by: Thomas Huth 
Reviewed-by: Philippe Mathieu-Daudé 
---
 MAINTAINERS  |  1 +
 tests/acceptance/machine_avr6.py | 50 
 2 files changed, 51 insertions(+)
 create mode 100644 tests/acceptance/machine_avr6.py

diff --git a/MAINTAINERS b/MAINTAINERS
index eba91ae406..f684f6d37c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -173,6 +173,7 @@ R: Sarah Harris 
 S: Maintained
 F: gdb-xml/avr-cpu.xml
 F: target/avr/
+F: tests/acceptance/machine_avr6.py
 
 CRIS TCG CPUs
 M: Edgar E. Iglesias 
diff --git a/tests/acceptance/machine_avr6.py b/tests/acceptance/machine_avr6.py
new file mode 100644
index 00..6baf4e9c7f
--- /dev/null
+++ b/tests/acceptance/machine_avr6.py
@@ -0,0 +1,50 @@
+#
+# QEMU AVR acceptance tests
+#
+# Copyright (c) 2019-2020 Michael Rolnik 
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+
+import time
+
+from avocado_qemu import Test
+
+class AVR6Machine(Test):
+timeout = 5
+
+def test_freertos(self):
+"""
+:avocado: tags=arch:avr
+:avocado: tags=machine:arduino-mega-2560-v3
+"""
+"""
+
https://github.com/seharris/qemu-avr-tests/raw/master/free-rtos/Demo/AVR_ATMega2560_GCC/demo.elf
+constantly prints out 
'ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX'
+"""
+rom_url = ('https://github.com/seharris/qemu-avr-tests'
+   '/raw/36c3e67b8755dcf/free-rtos/Demo'
+   '/AVR_ATMega2560_GCC/demo.elf')
+rom_hash = '7eb521f511ca8f2622e0a3c5e8dd686efbb911d4'
+rom_path = self.fetch_asset(rom_url, asset_hash=rom_hash)
+
+self.vm.add_args('-bios', rom_path)
+self.vm.add_args('-nographic')
+self.vm.launch()
+
+time.sleep(2)
+self.vm.shutdown()
+
+self.assertIn('ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX',
+self.vm.get_log())
-- 
2.21.3




[PULL 11/32] target/avr: Add instruction translation - Arithmetic and Logic Instructions

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

This includes:
- ADD, ADC, ADIW
- SBIW, SUB, SUBI, SBC, SBCI
- AND, ANDI
- OR, ORI, EOR
- COM, NEG
- INC, DEC
- MUL, MULS, MULSU
- FMUL, FMULS, FMULSU
- DES

Signed-off-by: Michael Rolnik 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-12-h...@tuxfamily.org>
[PMD: Added qemu_log_mask(LOG_UNIMP) in trans_DES()]
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/avr/insn.decode |  76 
 target/avr/translate.c | 820 +
 2 files changed, 896 insertions(+)
 create mode 100644 target/avr/insn.decode

diff --git a/target/avr/insn.decode b/target/avr/insn.decode
new file mode 100644
index 00..94351ca787
--- /dev/null
+++ b/target/avr/insn.decode
@@ -0,0 +1,76 @@
+#
+# AVR instruction decode definitions.
+#
+# Copyright (c) 2019-2020 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 .
+#
+
+#
+#   regs_16_31_by_one = [16 .. 31]
+#   regs_16_23_by_one = [16 .. 23]
+#   regs_24_30_by_two = [24, 26, 28, 30]
+#   regs_00_30_by_two = [0, 2, 4, 6, 8, .. 30]
+
+%rd 4:5
+%rr 9:1 0:4
+
+%rd_a   4:4 !function=to_regs_16_31_by_one
+%rd_b   4:3 !function=to_regs_16_23_by_one
+%rd_c   4:2 !function=to_regs_24_30_by_two
+%rr_a   0:4 !function=to_regs_16_31_by_one
+%rr_b   0:3 !function=to_regs_16_23_by_one
+
+%imm6   6:2 0:4
+%imm8   8:4 0:4
+
+%io_imm 9:2 0:4
+%ldst_d_imm 13:1 10:2 0:3
+
+
+_rr  rd rr
+_imm rd imm
+
+@op_rd_rr    .. . . _rr  rd=%rd rr=%rr
+@op_rd_imm6   .. .. _imm rd=%rd_c imm=%imm6
+@op_rd_imm8     _imm rd=%rd_a imm=%imm8
+@fmul     . ... . ...   _rr  rd=%rd_b rr=%rr_b
+
+#
+# Arithmetic Instructions
+#
+ADD  11 . . @op_rd_rr
+ADC 0001 11 . . @op_rd_rr
+ADIW1001 0110 .. .. @op_rd_imm6
+SUB 0001 10 . . @op_rd_rr
+SUBI0101    @op_rd_imm8
+SBC  10 . . @op_rd_rr
+SBCI0100    @op_rd_imm8
+SBIW1001 0111 .. .. @op_rd_imm6
+AND 0010 00 . . @op_rd_rr
+ANDI0111    @op_rd_imm8
+OR  0010 10 . . @op_rd_rr
+ORI 0110    @op_rd_imm8
+EOR 0010 01 . . @op_rd_rr
+COM 1001 010 rd:5 
+NEG 1001 010 rd:5 0001
+INC 1001 010 rd:5 0011
+DEC 1001 010 rd:5 1010
+MUL 1001 11 . . @op_rd_rr
+MULS 0010   _rr  rd=%rd_a rr=%rr_a
+MULSU    0011 0 ... 0 ...   @fmul
+FMUL 0011 0 ... 1 ...   @fmul
+FMULS    0011 1 ... 0 ...   @fmul
+FMULSU   0011 1 ... 1 ...   @fmul
+DES 1001 0100 imm:4 1011
diff --git a/target/avr/translate.c b/target/avr/translate.c
index f802e6b29c..fae9ed742d 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -128,6 +128,22 @@ struct DisasContext {
 bool free_skip_var0;
 };
 
+static int to_regs_16_31_by_one(DisasContext *ctx, int indx)
+{
+return 16 + (indx % 16);
+}
+
+static int to_regs_16_23_by_one(DisasContext *ctx, int indx)
+{
+return 16 + (indx % 8);
+}
+
+static int to_regs_24_30_by_two(DisasContext *ctx, int indx)
+{
+return 24 + (indx % 4) * 2;
+}
+
+
 static bool avr_have_feature(DisasContext *ctx, int feature)
 {
 if (!avr_feature(ctx->env, feature)) {
@@ -140,3 +156,807 @@ static bool avr_have_feature(DisasContext *ctx, int 
feature)
 
 static bool decode_insn(DisasContext *ctx, uint16_t insn);
 #include "decode_insn.inc.c"
+
+/*
+ * Arithmetic Instructions
+ */
+
+/*
+ * Utility functions for updating status registers:
+ *
+ *   - gen_add_CHf()
+ *   - gen_add_Vf()
+ *   - gen_sub_CHf()
+ *   - gen_sub_Vf()
+ *   - gen_NSf()
+ *   

[PULL 09/32] target/avr: Add instruction helpers

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

Add helpers for instructions that need to interact with QEMU. Also,
add stubs for unimplemented instructions. Instructions SPM and WDR
are left unimplemented because they require emulation of complex
peripherals. The implementation of instruction SLEEP is very limited
due to the lack of peripherals to generate wake interrupts. Memory
access instructions are implemented here because some address ranges
actually refer to CPU registers.

Signed-off-by: Michael Rolnik 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-10-h...@tuxfamily.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/avr/helper.h |  29 +++
 target/avr/helper.c | 203 
 2 files changed, 232 insertions(+)
 create mode 100644 target/avr/helper.h

diff --git a/target/avr/helper.h b/target/avr/helper.h
new file mode 100644
index 00..8e1ae7fda0
--- /dev/null
+++ b/target/avr/helper.h
@@ -0,0 +1,29 @@
+/*
+ * QEMU AVR CPU helpers
+ *
+ * Copyright (c) 2016-2020 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
+ * 
+ */
+
+DEF_HELPER_1(wdr, void, env)
+DEF_HELPER_1(debug, void, env)
+DEF_HELPER_1(break, 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)
+DEF_HELPER_3(fullwr, void, env, i32, i32)
+DEF_HELPER_2(fullrd, tl, env, i32)
diff --git a/target/avr/helper.c b/target/avr/helper.c
index 66ab648218..753384b2e7 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -137,3 +137,206 @@ bool avr_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 
 return true;
 }
+
+/*
+ *  helpers
+ */
+
+void helper_sleep(CPUAVRState *env)
+{
+CPUState *cs = env_cpu(env);
+
+cs->exception_index = EXCP_HLT;
+cpu_loop_exit(cs);
+}
+
+void helper_unsupported(CPUAVRState *env)
+{
+CPUState *cs = env_cpu(env);
+
+/*
+ *  I count not find what happens on the real platform, so
+ *  it's EXCP_DEBUG for meanwhile
+ */
+cs->exception_index = EXCP_DEBUG;
+if (qemu_loglevel_mask(LOG_UNIMP)) {
+qemu_log("UNSUPPORTED\n");
+cpu_dump_state(cs, stderr, 0);
+}
+cpu_loop_exit(cs);
+}
+
+void helper_debug(CPUAVRState *env)
+{
+CPUState *cs = env_cpu(env);
+
+cs->exception_index = EXCP_DEBUG;
+cpu_loop_exit(cs);
+}
+
+void helper_break(CPUAVRState *env)
+{
+CPUState *cs = env_cpu(env);
+
+cs->exception_index = EXCP_DEBUG;
+cpu_loop_exit(cs);
+}
+
+void helper_wdr(CPUAVRState *env)
+{
+CPUState *cs = env_cpu(env);
+
+/* WD is not implemented yet, placeholder */
+cs->exception_index = EXCP_DEBUG;
+cpu_loop_exit(cs);
+}
+
+/*
+ * This function implements IN instruction
+ *
+ * It does the following
+ * a.  if an IO register belongs to CPU, its value is read and returned
+ * b.  otherwise io address is translated to mem address and physical memory
+ * is read.
+ * c.  it caches the value for sake of SBI, SBIC, SBIS & CBI implementation
+ *
+ */
+target_ulong helper_inb(CPUAVRState *env, uint32_t port)
+{
+target_ulong data = 0;
+
+switch (port) {
+case 0x38: /* RAMPD */
+data = 0xff & (env->rampD >> 16);
+break;
+case 0x39: /* RAMPX */
+data = 0xff & (env->rampX >> 16);
+break;
+case 0x3a: /* RAMPY */
+data = 0xff & (env->rampY >> 16);
+break;
+case 0x3b: /* RAMPZ */
+data = 0xff & (env->rampZ >> 16);
+break;
+case 0x3c: /* EIND */
+data = 0xff & (env->eind >> 16);
+break;
+case 0x3d: /* SPL */
+data = env->sp & 0x00ff;
+break;
+case 0x3e: /* SPH */
+data = env->sp >> 8;
+break;
+case 0x3f: /* SREG */
+data = cpu_get_sreg(env);
+break;
+default:
+/* not a special register, pass to normal memory access */
+cpu_physical_memory_read(OFFSET_IO_REGISTERS + port, , 1);
+}
+
+return data;
+}
+
+/*
+ *  This function implements OUT instruction
+ *
+ *  It does the following
+ *  a.  if an IO register belongs to CPU, its value is written into the 
register
+ *  b.  otherwise io address is translated to 

[PULL 16/32] target/avr: Add instruction translation - CPU main translation function

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

Add the core of translation mechanism.

Co-developed-by: Richard Henderson 
Co-developed-by: Michael Rolnik 
Signed-off-by: Michael Rolnik 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-17-h...@tuxfamily.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/avr/translate.c | 213 +
 1 file changed, 213 insertions(+)

diff --git a/target/avr/translate.c b/target/avr/translate.c
index ee7811995a..7ad3dec031 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -2805,3 +2805,216 @@ static bool trans_WDR(DisasContext *ctx, arg_WDR *a)
 
 return true;
 }
+
+/*
+ *  Core translation mechanism functions:
+ *
+ *- translate()
+ *- canonicalize_skip()
+ *- gen_intermediate_code()
+ *- restore_state_to_opc()
+ *
+ */
+static void translate(DisasContext *ctx)
+{
+uint32_t opcode = next_word(ctx);
+
+if (!decode_insn(ctx, opcode)) {
+gen_helper_unsupported(cpu_env);
+ctx->bstate = DISAS_NORETURN;
+}
+}
+
+/* Standardize the cpu_skip condition to NE.  */
+static bool canonicalize_skip(DisasContext *ctx)
+{
+switch (ctx->skip_cond) {
+case TCG_COND_NEVER:
+/* Normal case: cpu_skip is known to be false.  */
+return false;
+
+case TCG_COND_ALWAYS:
+/*
+ * Breakpoint case: cpu_skip is known to be true, via TB_FLAGS_SKIP.
+ * The breakpoint is on the instruction being skipped, at the start
+ * of the TranslationBlock.  No need to update.
+ */
+return false;
+
+case TCG_COND_NE:
+if (ctx->skip_var1 == NULL) {
+tcg_gen_mov_tl(cpu_skip, ctx->skip_var0);
+} else {
+tcg_gen_xor_tl(cpu_skip, ctx->skip_var0, ctx->skip_var1);
+ctx->skip_var1 = NULL;
+}
+break;
+
+default:
+/* Convert to a NE condition vs 0. */
+if (ctx->skip_var1 == NULL) {
+tcg_gen_setcondi_tl(ctx->skip_cond, cpu_skip, ctx->skip_var0, 0);
+} else {
+tcg_gen_setcond_tl(ctx->skip_cond, cpu_skip,
+   ctx->skip_var0, ctx->skip_var1);
+ctx->skip_var1 = NULL;
+}
+ctx->skip_cond = TCG_COND_NE;
+break;
+}
+if (ctx->free_skip_var0) {
+tcg_temp_free(ctx->skip_var0);
+ctx->free_skip_var0 = false;
+}
+ctx->skip_var0 = cpu_skip;
+return true;
+}
+
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
+{
+CPUAVRState *env = cs->env_ptr;
+DisasContext ctx = {
+.tb = tb,
+.cs = cs,
+.env = env,
+.memidx = 0,
+.bstate = DISAS_NEXT,
+.skip_cond = TCG_COND_NEVER,
+.singlestep = cs->singlestep_enabled,
+};
+target_ulong pc_start = tb->pc / 2;
+int num_insns = 0;
+
+if (tb->flags & TB_FLAGS_FULL_ACCESS) {
+/*
+ * This flag is set by ST/LD instruction we will regenerate it ONLY
+ * with mem/cpu memory access instead of mem access
+ */
+max_insns = 1;
+}
+if (ctx.singlestep) {
+max_insns = 1;
+}
+
+gen_tb_start(tb);
+
+ctx.npc = pc_start;
+if (tb->flags & TB_FLAGS_SKIP) {
+ctx.skip_cond = TCG_COND_ALWAYS;
+ctx.skip_var0 = cpu_skip;
+}
+
+do {
+TCGLabel *skip_label = NULL;
+
+/* translate current instruction */
+tcg_gen_insn_start(ctx.npc);
+num_insns++;
+
+/*
+ * this is due to some strange GDB behavior
+ * let's assume main has address 0x100
+ * b main   - sets breakpoint at address 0x0100 (code)
+ * b *0x100 - sets breakpoint at address 0x00800100 (data)
+ */
+if (unlikely(!ctx.singlestep &&
+(cpu_breakpoint_test(cs, OFFSET_CODE + ctx.npc * 2, BP_ANY) ||
+ cpu_breakpoint_test(cs, OFFSET_DATA + ctx.npc * 2, BP_ANY 
{
+canonicalize_skip();
+tcg_gen_movi_tl(cpu_pc, ctx.npc);
+gen_helper_debug(cpu_env);
+goto done_generating;
+}
+
+/* Conditionally skip the next instruction, if indicated.  */
+if (ctx.skip_cond != TCG_COND_NEVER) {
+skip_label = gen_new_label();
+if (ctx.skip_var0 == cpu_skip) {
+/*
+ * Copy cpu_skip so that we may zero it before the branch.
+ * This ensures that cpu_skip is non-zero after the label
+ * if and only if the skipped insn itself sets a skip.
+ */
+ctx.free_skip_var0 = true;
+ctx.skip_var0 = tcg_temp_new();
+tcg_gen_mov_tl(ctx.skip_var0, cpu_skip);
+tcg_gen_movi_tl(cpu_skip, 0);
+}
+if (ctx.skip_var1 == 

[PULL 20/32] tests/machine-none: Add AVR support

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

Add a single code line that will automatically provide
'machine none' test.

Signed-off-by: Michael Rolnik 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
Reviewed-by: Thomas Huth 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-28-h...@tuxfamily.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/qtest/machine-none-test.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/qtest/machine-none-test.c b/tests/qtest/machine-none-test.c
index 8b7abea8af..57107f1aec 100644
--- a/tests/qtest/machine-none-test.c
+++ b/tests/qtest/machine-none-test.c
@@ -27,6 +27,7 @@ static struct arch2cpu cpus_map[] = {
 /* tested targets list */
 { "arm", "cortex-a15" },
 { "aarch64", "cortex-a57" },
+{ "avr", "avr6-avr-cpu" },
 { "x86_64", "qemu64,apic-id=0" },
 { "i386", "qemu32,apic-id=0" },
 { "alpha", "ev67" },
-- 
2.21.3




[PULL 10/32] target/avr: Add instruction translation - Register definitions

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

Start implementation of instructions by adding register definitions.

Signed-off-by: Michael Rolnik 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-11-h...@tuxfamily.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/avr/translate.c | 142 +
 1 file changed, 142 insertions(+)
 create mode 100644 target/avr/translate.c

diff --git a/target/avr/translate.c b/target/avr/translate.c
new file mode 100644
index 00..f802e6b29c
--- /dev/null
+++ b/target/avr/translate.c
@@ -0,0 +1,142 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2019-2020 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 "qemu/qemu-print.h"
+#include "tcg/tcg.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "tcg/tcg-op.h"
+#include "exec/cpu_ldst.h"
+#include "exec/helper-proto.h"
+#include "exec/helper-gen.h"
+#include "exec/log.h"
+#include "exec/translator.h"
+#include "exec/gen-icount.h"
+
+/*
+ *  Define if you want a BREAK instruction translated to a breakpoint
+ *  Active debugging connection is assumed
+ *  This is for
+ *  https://github.com/seharris/qemu-avr-tests/tree/master/instruction-tests
+ *  tests
+ */
+#undef BREAKPOINT_ON_BREAK
+
+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_r[NUMBER_OF_CPU_REGISTERS];
+static TCGv cpu_eind;
+static TCGv cpu_sp;
+
+static TCGv cpu_skip;
+
+static const char reg_names[NUMBER_OF_CPU_REGISTERS][8] = {
+"r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
+"r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
+"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+};
+#define REG(x) (cpu_r[x])
+
+enum {
+DISAS_EXIT   = DISAS_TARGET_0,  /* We want return to the cpu main loop.  */
+DISAS_LOOKUP = DISAS_TARGET_1,  /* We have a variable condition exit.  */
+DISAS_CHAIN  = DISAS_TARGET_2,  /* We have a single condition exit.  */
+};
+
+typedef struct DisasContext DisasContext;
+
+/* This is the state at translation time. */
+struct DisasContext {
+TranslationBlock *tb;
+
+CPUAVRState *env;
+CPUState *cs;
+
+target_long npc;
+uint32_t opcode;
+
+/* Routine used to access memory */
+int memidx;
+int bstate;
+int singlestep;
+
+/*
+ * some AVR instructions can make the following instruction to be skipped
+ * Let's name those instructions
+ * A   - instruction that can skip the next one
+ * B   - instruction that can be skipped. this depends on execution of 
A
+ * there are two scenarios
+ * 1. A and B belong to the same translation block
+ * 2. A is the last instruction in the translation block and B is the last
+ *
+ * following variables are used to simplify the skipping logic, they are
+ * used in the following manner (sketch)
+ *
+ * TCGLabel *skip_label = NULL;
+ * if (ctx.skip_cond != TCG_COND_NEVER) {
+ * skip_label = gen_new_label();
+ * tcg_gen_brcond_tl(skip_cond, skip_var0, skip_var1, skip_label);
+ * }
+ *
+ * if (free_skip_var0) {
+ * tcg_temp_free(skip_var0);
+ * free_skip_var0 = false;
+ * }
+ *
+ * translate();
+ *
+ * if (skip_label) {
+ * gen_set_label(skip_label);
+ * }
+ */
+TCGv skip_var0;
+TCGv skip_var1;
+TCGCond skip_cond;
+bool free_skip_var0;
+};
+
+static bool avr_have_feature(DisasContext *ctx, int feature)
+{
+if (!avr_feature(ctx->env, feature)) {
+gen_helper_unsupported(cpu_env);
+ctx->bstate = DISAS_NORETURN;
+return false;
+}
+return true;
+}
+
+static bool decode_insn(DisasContext *ctx, uint16_t insn);
+#include "decode_insn.inc.c"
-- 
2.21.3




[PULL 07/32] target/avr: Introduce enumeration AVRFeature

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

This patch introduces enumeration "AVRFeature" that will be
used for defining various AVR core types.

[AM: Split a larger AVR introduction patch into logical units]
Suggested-by: Aleksandar Markovic 
Co-developed-by: Michael Rolnik 
Co-developed-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Signed-off-by: Sarah Harris 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Acked-by: Igor Mammedov 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-8-h...@tuxfamily.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/avr/cpu.h | 46 ++
 1 file changed, 46 insertions(+)

diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index 6f231d096c..f229ff78c0 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -72,6 +72,42 @@
  */
 #define OFFSET_IO_REGISTERS (OFFSET_DATA + NUMBER_OF_CPU_REGISTERS)
 
+typedef enum AVRFeature {
+AVR_FEATURE_SRAM,
+
+AVR_FEATURE_1_BYTE_PC,
+AVR_FEATURE_2_BYTE_PC,
+AVR_FEATURE_3_BYTE_PC,
+
+AVR_FEATURE_1_BYTE_SP,
+AVR_FEATURE_2_BYTE_SP,
+
+AVR_FEATURE_BREAK,
+AVR_FEATURE_DES,
+AVR_FEATURE_RMW, /* Read Modify Write - XCH LAC LAS LAT */
+
+AVR_FEATURE_EIJMP_EICALL,
+AVR_FEATURE_IJMP_ICALL,
+AVR_FEATURE_JMP_CALL,
+
+AVR_FEATURE_ADIW_SBIW,
+
+AVR_FEATURE_SPM,
+AVR_FEATURE_SPMX,
+
+AVR_FEATURE_ELPMX,
+AVR_FEATURE_ELPM,
+AVR_FEATURE_LPMX,
+AVR_FEATURE_LPM,
+
+AVR_FEATURE_MOVW,
+AVR_FEATURE_MUL,
+AVR_FEATURE_RAMPD,
+AVR_FEATURE_RAMPX,
+AVR_FEATURE_RAMPY,
+AVR_FEATURE_RAMPZ,
+} AVRFeature;
+
 typedef struct CPUAVRState CPUAVRState;
 
 struct CPUAVRState {
@@ -126,6 +162,16 @@ hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr 
addr);
 int avr_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
+static inline int avr_feature(CPUAVRState *env, AVRFeature feature)
+{
+return (env->features & (1U << feature)) != 0;
+}
+
+static inline void set_avr_feature(CPUAVRState *env, int feature)
+{
+env->features |= (1U << feature);
+}
+
 #define cpu_list avr_cpu_list
 #define cpu_signal_handler cpu_avr_signal_handler
 #define cpu_mmu_index avr_cpu_mmu_index
-- 
2.21.3




[PULL 08/32] target/avr: Add definitions of AVR core types

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

AVR core types are:

  - avr5
  - avr51
  - avr6

Each core type covers multiple AVR MCUs, mentioned in the comments
before definition of particular AVR core type (part of this patch).

AVR core type defines shared features that are valid for all AVR
MCUs belonging in that type.

[AM: Split a larger AVR introduction patch into logical units]
Suggested-by: Aleksandar Markovic 
Co-developed-by: Michael Rolnik 
Co-developed-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Signed-off-by: Sarah Harris 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Acked-by: Igor Mammedov 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-9-h...@tuxfamily.org>
[PMD: Only include reviewed cores: avr5/avr51/avr6]
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/avr/cpu.c | 152 +++
 1 file changed, 152 insertions(+)

diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index ac496b8f03..7178e86f69 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -215,3 +215,155 @@ static void avr_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->gdb_num_core_regs = 35;
 cc->gdb_core_xml_file = "avr-cpu.xml";
 }
+
+/*
+ * Setting features of AVR core type avr5
+ * --
+ *
+ * This type of AVR core is present in the following AVR MCUs:
+ *
+ * ata5702m322, ata5782, ata5790, ata5790n, ata5791, ata5795, ata5831, 
ata6613c,
+ * ata6614q, ata8210, ata8510, atmega16, atmega16a, atmega161, atmega162,
+ * atmega163, atmega164a, atmega164p, atmega164pa, atmega165, atmega165a,
+ * atmega165p, atmega165pa, atmega168, atmega168a, atmega168p, atmega168pa,
+ * atmega168pb, atmega169, atmega169a, atmega169p, atmega169pa, atmega16hvb,
+ * atmega16hvbrevb, atmega16m1, atmega16u4, atmega32a, atmega32, atmega323,
+ * atmega324a, atmega324p, atmega324pa, atmega325, atmega325a, atmega325p,
+ * atmega325pa, atmega3250, atmega3250a, atmega3250p, atmega3250pa, atmega328,
+ * atmega328p, atmega328pb, atmega329, atmega329a, atmega329p, atmega329pa,
+ * atmega3290, atmega3290a, atmega3290p, atmega3290pa, atmega32c1, atmega32m1,
+ * atmega32u4, atmega32u6, atmega406, atmega64, atmega64a, atmega640, 
atmega644,
+ * atmega644a, atmega644p, atmega644pa, atmega645, atmega645a, atmega645p,
+ * atmega6450, atmega6450a, atmega6450p, atmega649, atmega649a, atmega649p,
+ * atmega6490, atmega16hva, atmega16hva2, atmega32hvb, atmega6490a, 
atmega6490p,
+ * atmega64c1, atmega64m1, atmega64hve, atmega64hve2, atmega64rfr2,
+ * atmega644rfr2, atmega32hvbrevb, at90can32, at90can64, at90pwm161, 
at90pwm216,
+ * at90pwm316, at90scr100, at90usb646, at90usb647, at94k, m3000
+ */
+static void avr_avr5_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+set_avr_feature(env, AVR_FEATURE_LPM);
+set_avr_feature(env, AVR_FEATURE_IJMP_ICALL);
+set_avr_feature(env, AVR_FEATURE_ADIW_SBIW);
+set_avr_feature(env, AVR_FEATURE_SRAM);
+set_avr_feature(env, AVR_FEATURE_BREAK);
+
+set_avr_feature(env, AVR_FEATURE_2_BYTE_PC);
+set_avr_feature(env, AVR_FEATURE_2_BYTE_SP);
+set_avr_feature(env, AVR_FEATURE_JMP_CALL);
+set_avr_feature(env, AVR_FEATURE_LPMX);
+set_avr_feature(env, AVR_FEATURE_MOVW);
+set_avr_feature(env, AVR_FEATURE_MUL);
+}
+
+/*
+ * Setting features of AVR core type avr51
+ * --
+ *
+ * This type of AVR core is present in the following AVR MCUs:
+ *
+ * atmega128, atmega128a, atmega1280, atmega1281, atmega1284, atmega1284p,
+ * atmega128rfa1, atmega128rfr2, atmega1284rfr2, at90can128, at90usb1286,
+ * at90usb1287
+ */
+static void avr_avr51_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+set_avr_feature(env, AVR_FEATURE_LPM);
+set_avr_feature(env, AVR_FEATURE_IJMP_ICALL);
+set_avr_feature(env, AVR_FEATURE_ADIW_SBIW);
+set_avr_feature(env, AVR_FEATURE_SRAM);
+set_avr_feature(env, AVR_FEATURE_BREAK);
+
+set_avr_feature(env, AVR_FEATURE_2_BYTE_PC);
+set_avr_feature(env, AVR_FEATURE_2_BYTE_SP);
+set_avr_feature(env, AVR_FEATURE_RAMPZ);
+set_avr_feature(env, AVR_FEATURE_ELPMX);
+set_avr_feature(env, AVR_FEATURE_ELPM);
+set_avr_feature(env, AVR_FEATURE_JMP_CALL);
+set_avr_feature(env, AVR_FEATURE_LPMX);
+set_avr_feature(env, AVR_FEATURE_MOVW);
+set_avr_feature(env, AVR_FEATURE_MUL);
+}
+
+/*
+ * Setting features of AVR core type avr6
+ * --
+ *
+ * This type of AVR core is present in the following AVR MCUs:
+ *
+ * atmega2560, atmega2561, atmega256rfr2, atmega2564rfr2
+ */
+static void avr_avr6_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+set_avr_feature(env, AVR_FEATURE_LPM);
+set_avr_feature(env, AVR_FEATURE_IJMP_ICALL);
+set_avr_feature(env, AVR_FEATURE_ADIW_SBIW);
+set_avr_feature(env, AVR_FEATURE_SRAM);
+

[PULL 17/32] target/avr: Initialize TCG register variables

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

Initialize TCG register variables.

Co-developed-by: Richard Henderson 
Co-developed-by: Michael Rolnik 
Signed-off-by: Michael Rolnik 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-18-h...@tuxfamily.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/avr/translate.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/target/avr/translate.c b/target/avr/translate.c
index 7ad3dec031..3d8a77e5ae 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -128,6 +128,35 @@ struct DisasContext {
 bool free_skip_var0;
 };
 
+void avr_cpu_tcg_init(void)
+{
+int i;
+
+#define AVR_REG_OFFS(x) offsetof(CPUAVRState, x)
+cpu_pc = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(pc_w), "pc");
+cpu_Cf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregC), "Cf");
+cpu_Zf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregZ), "Zf");
+cpu_Nf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregN), "Nf");
+cpu_Vf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregV), "Vf");
+cpu_Sf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregS), "Sf");
+cpu_Hf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregH), "Hf");
+cpu_Tf = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregT), "Tf");
+cpu_If = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sregI), "If");
+cpu_rampD = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampD), "rampD");
+cpu_rampX = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampX), "rampX");
+cpu_rampY = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampY), "rampY");
+cpu_rampZ = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(rampZ), "rampZ");
+cpu_eind = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(eind), "eind");
+cpu_sp = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(sp), "sp");
+cpu_skip = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(skip), "skip");
+
+for (i = 0; i < NUMBER_OF_CPU_REGISTERS; i++) {
+cpu_r[i] = tcg_global_mem_new_i32(cpu_env, AVR_REG_OFFS(r[i]),
+  reg_names[i]);
+}
+#undef AVR_REG_OFFS
+}
+
 static int to_regs_16_31_by_one(DisasContext *ctx, int indx)
 {
 return 16 + (indx % 16);
-- 
2.21.3




[PULL 12/32] target/avr: Add instruction translation - Branch Instructions

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

This includes:
- RJMP, IJMP, EIJMP, JMP
- RCALL, ICALL, EICALL, CALL
- RET, RETI
- CPSE, CP, CPC, CPI
- SBRC, SBRS, SBIC, SBIS
- BRBC, BRBS

Signed-off-by: Michael Rolnik 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Aleksandar Markovic 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-13-h...@tuxfamily.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/avr/insn.decode |  33 +++
 target/avr/translate.c | 543 +
 2 files changed, 576 insertions(+)

diff --git a/target/avr/insn.decode b/target/avr/insn.decode
index 94351ca787..851eddedc7 100644
--- a/target/avr/insn.decode
+++ b/target/avr/insn.decode
@@ -74,3 +74,36 @@ FMUL 0011 0 ... 1 ...   @fmul
 FMULS    0011 1 ... 0 ...   @fmul
 FMULSU   0011 1 ... 1 ...   @fmul
 DES 1001 0100 imm:4 1011
+
+#
+# Branch Instructions
+#
+
+# The 22-bit immediate is partially in the opcode word,
+# and partially in the next.  Use append_16 to build the
+# complete 22-bit value.
+%imm_call   4:5 0:1 !function=append_16
+
+@op_bit   . bit:3 
+@op_bit_imm  .. imm:s7 bit:3
+
+RJMP1100 imm:s12
+IJMP1001 0100  1001
+EIJMP   1001 0100 0001 1001
+JMP 1001 010 . 110 .imm=%imm_call
+RCALL   1101 imm:s12
+ICALL   1001 0101  1001
+EICALL  1001 0101 0001 1001
+CALL1001 010 . 111 .imm=%imm_call
+RET 1001 0101  1000
+RETI1001 0101 0001 1000
+CPSE0001 00 . . @op_rd_rr
+CP  0001 01 . . @op_rd_rr
+CPC  01 . . @op_rd_rr
+CPI 0011    @op_rd_imm8
+SBRC 110 rr:5 0 bit:3
+SBRS 111 rr:5 0 bit:3
+SBIC1001 1001 reg:5 bit:3
+SBIS1001 1011 reg:5 bit:3
+BRBS 00 ... ... @op_bit_imm
+BRBC 01 ... ... @op_bit_imm
diff --git a/target/avr/translate.c b/target/avr/translate.c
index fae9ed742d..5581264045 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -144,6 +144,16 @@ static int to_regs_24_30_by_two(DisasContext *ctx, int 
indx)
 }
 
 
+static uint16_t next_word(DisasContext *ctx)
+{
+return cpu_lduw_code(ctx->env, ctx->npc++ * 2);
+}
+
+static int append_16(DisasContext *ctx, int x)
+{
+return x << 16 | next_word(ctx);
+}
+
 static bool avr_have_feature(DisasContext *ctx, int feature)
 {
 if (!avr_feature(ctx->env, feature)) {
@@ -960,3 +970,536 @@ static bool trans_DES(DisasContext *ctx, arg_DES *a)
 
 return true;
 }
+
+/*
+ * Branch Instructions
+ */
+static void gen_jmp_ez(DisasContext *ctx)
+{
+tcg_gen_deposit_tl(cpu_pc, cpu_r[30], cpu_r[31], 8, 8);
+tcg_gen_or_tl(cpu_pc, cpu_pc, cpu_eind);
+ctx->bstate = DISAS_LOOKUP;
+}
+
+static void gen_jmp_z(DisasContext *ctx)
+{
+tcg_gen_deposit_tl(cpu_pc, cpu_r[30], cpu_r[31], 8, 8);
+ctx->bstate = DISAS_LOOKUP;
+}
+
+static void gen_push_ret(DisasContext *ctx, int ret)
+{
+if (avr_feature(ctx->env, AVR_FEATURE_1_BYTE_PC)) {
+
+TCGv t0 = tcg_const_i32((ret & 0xff));
+
+tcg_gen_qemu_st_tl(t0, cpu_sp, MMU_DATA_IDX, MO_UB);
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
+
+tcg_temp_free_i32(t0);
+} else if (avr_feature(ctx->env, AVR_FEATURE_2_BYTE_PC)) {
+
+TCGv t0 = tcg_const_i32((ret & 0x00));
+
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
+tcg_gen_qemu_st_tl(t0, cpu_sp, MMU_DATA_IDX, MO_BEUW);
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
+
+tcg_temp_free_i32(t0);
+
+} else if (avr_feature(ctx->env, AVR_FEATURE_3_BYTE_PC)) {
+
+TCGv lo = tcg_const_i32((ret & 0xff));
+TCGv hi = tcg_const_i32((ret & 0x00) >> 8);
+
+tcg_gen_qemu_st_tl(lo, cpu_sp, MMU_DATA_IDX, MO_UB);
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 2);
+tcg_gen_qemu_st_tl(hi, cpu_sp, MMU_DATA_IDX, MO_BEUW);
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
+
+tcg_temp_free_i32(lo);
+tcg_temp_free_i32(hi);
+}
+}
+
+static void gen_pop_ret(DisasContext *ctx, TCGv ret)
+{
+if (avr_feature(ctx->env, AVR_FEATURE_1_BYTE_PC)) {
+tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
+tcg_gen_qemu_ld_tl(ret, cpu_sp, MMU_DATA_IDX, MO_UB);
+} else if (avr_feature(ctx->env, AVR_FEATURE_2_BYTE_PC)) {
+tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
+tcg_gen_qemu_ld_tl(ret, cpu_sp, MMU_DATA_IDX, MO_BEUW);
+tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
+} else if (avr_feature(ctx->env, AVR_FEATURE_3_BYTE_PC)) {
+TCGv lo = tcg_temp_new_i32();
+TCGv hi = tcg_temp_new_i32();
+
+tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
+tcg_gen_qemu_ld_tl(hi, cpu_sp, 

[PULL 06/32] target/avr: CPU class: Add GDB support

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

This includes GDB hooks for reading from wnd wrtiting to AVR
registers, and xml register definition file as well.

[AM: Split a larger AVR introduction patch into logical units]
Suggested-by: Aleksandar Markovic 
Co-developed-by: Michael Rolnik 
Co-developed-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Signed-off-by: Sarah Harris 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Acked-by: Igor Mammedov 
Tested-by: Philippe Mathieu-Daudé 
[thuth: Fixed avr_cpu_gdb_read_register() parameter]
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-7-h...@tuxfamily.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/avr/cpu.h |  2 ++
 target/avr/cpu.c |  4 +++
 target/avr/gdbstub.c | 84 
 MAINTAINERS  |  1 +
 gdb-xml/avr-cpu.xml  | 49 ++
 5 files changed, 140 insertions(+)
 create mode 100644 target/avr/gdbstub.c
 create mode 100644 gdb-xml/avr-cpu.xml

diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index 59b89a3a71..6f231d096c 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -123,6 +123,8 @@ extern const struct VMStateDescription vms_avr_cpu;
 void avr_cpu_do_interrupt(CPUState *cpu);
 bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
 hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+int avr_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
+int avr_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
 #define cpu_list avr_cpu_list
 #define cpu_signal_handler cpu_avr_signal_handler
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index f4b2d6f55c..ac496b8f03 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -210,4 +210,8 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
 cc->disas_set_info = avr_cpu_disas_set_info;
 cc->tcg_initialize = avr_cpu_tcg_init;
 cc->synchronize_from_tb = avr_cpu_synchronize_from_tb;
+cc->gdb_read_register = avr_cpu_gdb_read_register;
+cc->gdb_write_register = avr_cpu_gdb_write_register;
+cc->gdb_num_core_regs = 35;
+cc->gdb_core_xml_file = "avr-cpu.xml";
 }
diff --git a/target/avr/gdbstub.c b/target/avr/gdbstub.c
new file mode 100644
index 00..c28ed67efe
--- /dev/null
+++ b/target/avr/gdbstub.c
@@ -0,0 +1,84 @@
+/*
+ * QEMU AVR gdbstub
+ *
+ * Copyright (c) 2016-2020 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 "exec/gdbstub.h"
+
+int avr_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
+{
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = >env;
+
+/*  R */
+if (n < 32) {
+return gdb_get_reg8(mem_buf, env->r[n]);
+}
+
+/*  SREG */
+if (n == 32) {
+uint8_t sreg = cpu_get_sreg(env);
+
+return gdb_get_reg8(mem_buf, sreg);
+}
+
+/*  SP */
+if (n == 33) {
+return gdb_get_reg16(mem_buf, env->sp & 0x);
+}
+
+/*  PC */
+if (n == 34) {
+return gdb_get_reg32(mem_buf, env->pc_w * 2);
+}
+
+return 0;
+}
+
+int avr_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = >env;
+
+/*  R */
+if (n < 32) {
+env->r[n] = *mem_buf;
+return 1;
+}
+
+/*  SREG */
+if (n == 32) {
+cpu_set_sreg(env, *mem_buf);
+return 1;
+}
+
+/*  SP */
+if (n == 33) {
+env->sp = lduw_p(mem_buf);
+return 2;
+}
+
+/*  PC */
+if (n == 34) {
+env->pc_w = ldl_p(mem_buf) / 2;
+return 4;
+}
+
+return 0;
+}
diff --git a/MAINTAINERS b/MAINTAINERS
index 6a012646eb..d439aa41b6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -171,6 +171,7 @@ AVR TCG CPUs
 M: Michael Rolnik 
 R: Sarah Harris 
 S: Maintained
+F: gdb-xml/avr-cpu.xml
 F: target/avr/
 
 CRIS TCG CPUs
diff --git a/gdb-xml/avr-cpu.xml b/gdb-xml/avr-cpu.xml
new file mode 100644
index 00..c4747f5b40
--- /dev/null
+++ b/gdb-xml/avr-cpu.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
-- 
2.21.3




[PULL 04/32] target/avr: CPU class: Add memory menagement support

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

This patch introduces three memory-management-related functions
that will become part of AVR CPU class object.

[AM: Split a larger AVR introduction patch into logical units]
Suggested-by: Aleksandar Markovic 
Co-developed-by: Michael Rolnik 
Co-developed-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Signed-off-by: Sarah Harris 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Acked-by: Igor Mammedov 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-5-h...@tuxfamily.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/avr/cpu.c|  3 +++
 target/avr/helper.c | 50 +
 2 files changed, 53 insertions(+)

diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index 864cb6b102..a8636015a3 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -203,6 +203,9 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
 cc->cpu_exec_interrupt = avr_cpu_exec_interrupt;
 cc->dump_state = avr_cpu_dump_state;
 cc->set_pc = avr_cpu_set_pc;
+cc->memory_rw_debug = avr_cpu_memory_rw_debug;
+cc->get_phys_page_debug = avr_cpu_get_phys_page_debug;
+cc->tlb_fill = avr_cpu_tlb_fill;
 cc->disas_set_info = avr_cpu_disas_set_info;
 cc->tcg_initialize = avr_cpu_tcg_init;
 cc->synchronize_from_tb = avr_cpu_synchronize_from_tb;
diff --git a/target/avr/helper.c b/target/avr/helper.c
index 7174e4858e..66ab648218 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -87,3 +87,53 @@ void avr_cpu_do_interrupt(CPUState *cs)
 
 cs->exception_index = -1;
 }
+
+int avr_cpu_memory_rw_debug(CPUState *cs, vaddr addr, uint8_t *buf,
+int len, bool is_write)
+{
+return cpu_memory_rw_debug(cs, addr, buf, len, is_write);
+}
+
+hwaddr avr_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
+{
+return addr; /* I assume 1:1 address correspondance */
+}
+
+bool avr_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+MMUAccessType access_type, int mmu_idx,
+bool probe, uintptr_t retaddr)
+{
+int prot = 0;
+MemTxAttrs attrs = {};
+uint32_t paddr;
+
+address &= TARGET_PAGE_MASK;
+
+if (mmu_idx == MMU_CODE_IDX) {
+/* access to code in flash */
+paddr = OFFSET_CODE + address;
+prot = PAGE_READ | PAGE_EXEC;
+if (paddr + TARGET_PAGE_SIZE > OFFSET_DATA) {
+error_report("execution left flash memory");
+exit(1);
+}
+} else if (address < NUMBER_OF_CPU_REGISTERS + NUMBER_OF_IO_REGISTERS) {
+/*
+ * access to CPU registers, exit and rebuilt this TB to use full access
+ * incase it touches specially handled registers like SREG or SP
+ */
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = >env;
+env->fullacc = 1;
+cpu_loop_exit_restore(cs, retaddr);
+} else {
+/* access to memory. nothing special */
+paddr = OFFSET_DATA + address;
+prot = PAGE_READ | PAGE_WRITE;
+}
+
+tlb_set_page_with_attrs(
+cs, address, paddr, attrs, prot, mmu_idx, TARGET_PAGE_SIZE);
+
+return true;
+}
-- 
2.21.3




[PULL 03/32] target/avr: CPU class: Add interrupt handling support

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

This patch introduces functions avr_cpu_do_interrupt() and
avr_cpu_exec_interrupt() that are part of AVR CPU class object.

[AM: Split a larger AVR introduction patch into logical units]
Suggested-by: Aleksandar Markovic 
Co-developed-by: Michael Rolnik 
Co-developed-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Signed-off-by: Sarah Harris 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Acked-by: Igor Mammedov 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-4-h...@tuxfamily.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/avr/cpu.c|  2 +
 target/avr/helper.c | 89 +
 2 files changed, 91 insertions(+)
 create mode 100644 target/avr/helper.c

diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index 7895a5ecaa..864cb6b102 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -199,6 +199,8 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
 cc->class_by_name = avr_cpu_class_by_name;
 
 cc->has_work = avr_cpu_has_work;
+cc->do_interrupt = avr_cpu_do_interrupt;
+cc->cpu_exec_interrupt = avr_cpu_exec_interrupt;
 cc->dump_state = avr_cpu_dump_state;
 cc->set_pc = avr_cpu_set_pc;
 cc->disas_set_info = avr_cpu_disas_set_info;
diff --git a/target/avr/helper.c b/target/avr/helper.c
new file mode 100644
index 00..7174e4858e
--- /dev/null
+++ b/target/avr/helper.c
@@ -0,0 +1,89 @@
+/*
+ * QEMU AVR CPU helpers
+ *
+ * Copyright (c) 2016-2020 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 "cpu.h"
+#include "exec/exec-all.h"
+#include "exec/helper-proto.h"
+
+bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+bool ret = false;
+CPUClass *cc = CPU_GET_CLASS(cs);
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = >env;
+
+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 = ctz32(env->intsrc);
+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_t ret = env->pc_w;
+int vector = 0;
+int size = avr_feature(env, AVR_FEATURE_JMP_CALL) ? 2 : 1;
+int base = 0;
+
+if (cs->exception_index == EXCP_RESET) {
+vector = 0;
+} else if (env->intsrc != 0) {
+vector = ctz32(env->intsrc) + 1;
+}
+
+if (avr_feature(env, AVR_FEATURE_3_BYTE_PC)) {
+cpu_stb_data(env, env->sp--, (ret & 0xff));
+cpu_stb_data(env, env->sp--, (ret & 0x00ff00) >> 8);
+cpu_stb_data(env, env->sp--, (ret & 0xff) >> 16);
+} else if (avr_feature(env, AVR_FEATURE_2_BYTE_PC)) {
+cpu_stb_data(env, env->sp--, (ret & 0xff));
+cpu_stb_data(env, env->sp--, (ret & 0x00ff00) >> 8);
+} else {
+cpu_stb_data(env, env->sp--, (ret & 0xff));
+}
+
+env->pc_w = base + vector * size;
+env->sregI = 0; /* clear Global Interrupt Flag */
+
+cs->exception_index = -1;
+}
-- 
2.21.3




[PULL 05/32] target/avr: CPU class: Add migration support

2020-07-07 Thread Philippe Mathieu-Daudé
From: Michael Rolnik 

Add migration-related functions of AVR CPU class object.

[AM: Split a larger AVR introduction patch into logical units]
Suggested-by: Aleksandar Markovic 
Co-developed-by: Michael Rolnik 
Co-developed-by: Sarah Harris 
Signed-off-by: Michael Rolnik 
Signed-off-by: Sarah Harris 
Signed-off-by: Richard Henderson 
Signed-off-by: Aleksandar Markovic 
Acked-by: Igor Mammedov 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Thomas Huth 
Message-Id: <20200705140315.260514-6-h...@tuxfamily.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/avr/cpu.h |   2 +
 target/avr/cpu.c |   1 +
 target/avr/machine.c | 121 +++
 3 files changed, 124 insertions(+)
 create mode 100644 target/avr/machine.c

diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index bac12dc684..59b89a3a71 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -118,6 +118,8 @@ typedef struct AVRCPU {
 CPUAVRState env;
 } AVRCPU;
 
+extern const struct VMStateDescription vms_avr_cpu;
+
 void avr_cpu_do_interrupt(CPUState *cpu);
 bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req);
 hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index a8636015a3..f4b2d6f55c 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -206,6 +206,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
 cc->memory_rw_debug = avr_cpu_memory_rw_debug;
 cc->get_phys_page_debug = avr_cpu_get_phys_page_debug;
 cc->tlb_fill = avr_cpu_tlb_fill;
+cc->vmsd = _avr_cpu;
 cc->disas_set_info = avr_cpu_disas_set_info;
 cc->tcg_initialize = avr_cpu_tcg_init;
 cc->synchronize_from_tb = avr_cpu_synchronize_from_tb;
diff --git a/target/avr/machine.c b/target/avr/machine.c
new file mode 100644
index 00..e61ea0519a
--- /dev/null
+++ b/target/avr/machine.c
@@ -0,0 +1,121 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2016-2020 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 "cpu.h"
+#include "migration/cpu.h"
+
+static int get_sreg(QEMUFile *f, void *opaque, size_t size,
+const VMStateField *field)
+{
+CPUAVRState *env = opaque;
+uint8_t sreg;
+
+sreg = qemu_get_byte(f);
+cpu_set_sreg(env, sreg);
+return 0;
+}
+
+static int put_sreg(
+QEMUFile *f, void *opaque, size_t size,
+const VMStateField *field, QJSON *vmdesc)
+{
+CPUAVRState *env = opaque;
+uint8_t sreg = cpu_get_sreg(env);
+
+qemu_put_byte(f, sreg);
+return 0;
+}
+
+static const VMStateInfo vms_sreg = {
+.name = "sreg",
+.get = get_sreg,
+.put = put_sreg,
+};
+
+static int get_segment(
+QEMUFile *f, void *opaque, size_t size, const VMStateField *field)
+{
+uint32_t *ramp = opaque;
+uint8_t temp;
+
+temp = qemu_get_byte(f);
+*ramp = ((uint32_t)temp) << 16;
+return 0;
+}
+
+static int put_segment(
+QEMUFile *f, void *opaque, size_t size,
+const VMStateField *field, QJSON *vmdesc)
+{
+uint32_t *ramp = opaque;
+uint8_t temp = *ramp >> 16;
+
+qemu_put_byte(f, temp);
+return 0;
+}
+
+static const VMStateInfo vms_rampD = {
+.name = "rampD",
+.get = get_segment,
+.put = put_segment,
+};
+static const VMStateInfo vms_rampX = {
+.name = "rampX",
+.get = get_segment,
+.put = put_segment,
+};
+static const VMStateInfo vms_rampY = {
+.name = "rampY",
+.get = get_segment,
+.put = put_segment,
+};
+static const VMStateInfo vms_rampZ = {
+.name = "rampZ",
+.get = get_segment,
+.put = put_segment,
+};
+static const VMStateInfo vms_eind = {
+.name = "eind",
+.get = get_segment,
+.put = put_segment,
+};
+
+const VMStateDescription vms_avr_cpu = {
+.name = "cpu",
+.version_id = 0,
+.minimum_version_id = 0,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32(env.pc_w, AVRCPU),
+VMSTATE_UINT32(env.sp, AVRCPU),
+VMSTATE_UINT32(env.skip, AVRCPU),
+
+VMSTATE_UINT32_ARRAY(env.r, AVRCPU, NUMBER_OF_CPU_REGISTERS),
+
+VMSTATE_SINGLE(env, AVRCPU, 0, vms_sreg, CPUAVRState),
+VMSTATE_SINGLE(env.rampD, AVRCPU, 0, vms_rampD, uint32_t),
+VMSTATE_SINGLE(env.rampX, AVRCPU, 0, vms_rampX, uint32_t),
+VMSTATE_SINGLE(env.rampY, AVRCPU, 0, vms_rampY, 

  1   2   3   4   5   >