Re: [Qemu-devel] [RFC PATCH 18/21] target-arm: switch banked CP registers

2013-12-22 Thread Peter Maydell
On 22 December 2013 01:08, Peter Crosthwaite
 wrote:
> On Sat, Dec 21, 2013 at 12:33 AM, Peter Maydell
>  wrote:
>> On 20 December 2013 14:12, Fedorov Sergey  wrote:
>>> I've briefly looked at the v8 ARM ARM. As I can see there is no banked
>>> system control registers in AArch64. Seems the concept is changed to provide
>>> separate registers for each meaningful execution level. Please, correct me
>>> if I am wrong.
>
> Isn't that just another definition of banking?

No: the crn/crm/op values differ for eg ESR_EL1, ESR_EL2 and
ESR_EL3, and if you're in EL3 you can access all three of them
(the access permissions are what stop EL1 from messing with
EL3's ESR). Banked registers are where the same access
instruction reads or writes different state depending on the value
of something else (whether we're secure/nonsecure, in this case).

thanks
-- PMM



Re: [Qemu-devel] vhost-net issue: does not survive reboot on ppc64

2013-12-22 Thread Michael S. Tsirkin
On Sun, Dec 22, 2013 at 02:01:23AM +1100, Alexey Kardashevskiy wrote:
> Hi!
> 
> I am having a problem with virtio-net + vhost on POWER7 machine - it does
> not survive reboot of the guest.
> 
> Steps to reproduce:
> 1. boot the guest
> 2. configure eth0 and do ping - everything works
> 3. reboot the guest (i.e. type "reboot")
> 4. when it is booted, eth0 can be configured but will not work at all.
> 
> The test is:
> ifconfig eth0 172.20.1.2 up
> ping 172.20.1.23
> 
> If to run tcpdump on the host's "tap-id3" interface, it shows no trafic
> coming from the guest. If to compare how it works before and after reboot,
> I can see the guest doing an ARP request for 172.20.1.23 and receives the
> response and it does the same after reboot but the answer does not come.

So you see the arp packet in guest but not in host?

One thing to try is to boot debug kernel - where pr_debug is
enabled - then you might see some errors in the kernel log.

> If to remove vhost=on, it is all good. If to try Fedora19
> (v3.10-something), it all good again - works before and after reboot.
> 
> 
> And there 2 questions:
> 
> 1. does anybody have any clue what might go wrong after reboot?
> 
> 2. Is there any good material to read about what exactly and how vhost
> accelerates?
> 
> My understanding is that packets from the guest to the real network are
> going as:
> 1. guest's virtio-pci-net does ioport(VIRTIO_PCI_QUEUE_NOTIFY)
> 2. QEMU's net/virtio-net.c calls qemu_net_queue_deliver()
> 3. QEMU's net/tap.c calls tap_write_packet() and this is how the host knows
> that there is a new packet.
> 
> 
> Thanks!
> 
> 
> This how I run QEMU:
> ./qemu-system-ppc64 \
> -enable-kvm \
> -m 2048 \
> -machine pseries \
> -initrd 1.cpio \
> -kernel vml312_virtio_net_dbg \
> -nographic \
> -vga none \
> -netdev
> tap,id=id3,ifname=tap-id3,script=ifup.sh,downscript=ifdown.sh,vhost=on \
> -device virtio-net-pci,id=id4,netdev=id3,mac=C0:41:49:4b:00:00
> 
> 
> That is bridge config:
> [aik@dyn232 ~]$ brctl show
> bridge name   bridge id   STP enabled interfaces
> brtest8000.00145e992e88   no  pin eth4
> 
> 
> The ifup.sh script:
> ifconfig $1 hw ether ee:01:02:03:04:05
> /sbin/ifconfig $1 up
> /usr/sbin/brctl addif brtest $1
> 
> 
> 
> 
> -- 
> Alexey



Re: [Qemu-devel] [PATCH v2] Add DSDT node for AppleSMC

2013-12-22 Thread Michael S. Tsirkin
On Fri, Dec 20, 2013 at 03:52:24PM -0500, Gabriel L. Somlo wrote:
> AppleSMC (-device isa-applesmc) is required to boot OS X guests.
> OS X expects a SMC node to be present in the ACPI DSDT. This patch
> adds a SMC node to the DSDT, and dynamically patches the return value
> of SMC._STA to either 0x0B if the chip is present, or otherwise to 0x00,
> before booting the guest.
> 
> Signed-off-by: Gabriel Somlo 
> ---
> 
> On Fri, Dec 20, 2013 at 05:39:53PM +0100, Alexander Graf wrote:
> > I haven't checked for the actual functionality, but please make sure
> > the patch passes checkpatch.pl. I spot at least one case of missing
> > braces - and it'd be a shame if it gets rejected over that.
> 
> OK, here's v2 complete with braces:
> 
> $ qemu/scripts/checkpatch.pl qemu-applesmc-20131220-v2.patch 
> total: 0 errors, 0 warnings, 86 lines checked
> 
> qemu-applesmc-20131220-v2.patch has no obvious style problems and is ready 
> for submission.
> 
> Thanks,
>   Gabriel
> 
>  hw/misc/applesmc.c|  1 -
>  include/hw/isa/isa.h  |  2 ++
>  hw/i386/acpi-dsdt.dsl |  1 +
>  hw/i386/q35-acpi-dsdt.dsl |  1 +
>  hw/i386/acpi-dsdt-isa.dsl | 14 ++
>  hw/i386/acpi-build.c  | 11 +++
>  6 files changed, 29 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
> index 1e8d183..627adb9 100644
> --- a/hw/misc/applesmc.c
> +++ b/hw/misc/applesmc.c
> @@ -66,7 +66,6 @@ struct AppleSMCData {
>  QLIST_ENTRY(AppleSMCData) node;
>  };
>  
> -#define TYPE_APPLE_SMC "isa-applesmc"
>  #define APPLE_SMC(obj) OBJECT_CHECK(AppleSMCState, (obj), TYPE_APPLE_SMC)
>  
>  typedef struct AppleSMCState AppleSMCState;
> diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
> index fa45a5b..5596cdc 100644
> --- a/include/hw/isa/isa.h
> +++ b/include/hw/isa/isa.h
> @@ -20,6 +20,8 @@
>  #define TYPE_ISA_BUS "ISA"
>  #define ISA_BUS(obj) OBJECT_CHECK(ISABus, (obj), TYPE_ISA_BUS)
>  
> +#define TYPE_APPLE_SMC "isa-applesmc"
> +
>  typedef struct ISADeviceClass {
>  DeviceClass parent_class;
>  } ISADeviceClass;
> diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl
> index a377424..7f8f147 100644
> --- a/hw/i386/acpi-dsdt.dsl
> +++ b/hw/i386/acpi-dsdt.dsl
> @@ -114,6 +114,7 @@ DefinitionBlock (
>  }
>  }
>  
> +#define SMC_PFX piix_
>  #include "acpi-dsdt-isa.dsl"
>  
>  
> diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl
> index 575c5d7..7609e78 100644
> --- a/hw/i386/q35-acpi-dsdt.dsl
> +++ b/hw/i386/q35-acpi-dsdt.dsl
> @@ -171,6 +171,7 @@ DefinitionBlock (
>  }
>  }
>  
> +#define SMC_PFX q35_
>  #include "acpi-dsdt-isa.dsl"
>  
>  
> diff --git a/hw/i386/acpi-dsdt-isa.dsl b/hw/i386/acpi-dsdt-isa.dsl
> index 89caa16..410e658 100644
> --- a/hw/i386/acpi-dsdt-isa.dsl
> +++ b/hw/i386/acpi-dsdt-isa.dsl
> @@ -13,9 +13,23 @@
>   * with this program; if not, see .
>   */
>  
> +#define _CONCAT_SYM(a, b) a##b
> +#define CONCAT_SYM(a, b) _CONCAT_SYM(a, b)
> +

Seems too complex. If one looks for q35_smc_sta one can not
find it since no indexing tool or grep have a chance to
understand this trickery.
Also, let's call it apple_smc not just smc everywhere.

Also, please add prefix like dsdt so it's easy to figure
out where this comes from.

So something like

#define DSDT_APPLE_SMC_STA q35_dsdt_apple_smc_sta
and
#define DSDT_APPLE_SMC_STA piix_dsdt_apple_smc_sta

and then use these everywhere.


>  /* Common legacy ISA style devices. */
>  Scope(\_SB.PCI0.ISA) {
>  
> +Device (SMC) {
> +Name(_HID, EisaId("APP0001"))
> +/* _STA will be patched to 0x0B if AppleSMC is present */
> +ACPI_EXTRACT_NAME_WORD_CONST CONCAT_SYM(SMC_PFX, smc_sta)
> +Name(_STA, 0xFF00)
> +Name(_CRS, ResourceTemplate () {
> +IO (Decode16, 0x0300, 0x0300, 0x01, 0x20)
> +IRQNoFlags() { 6 }
> +})
> +}
> +
>  Device(RTC) {
>  Name(_HID, EisaId("PNP0B00"))
>  Name(_CRS, ResourceTemplate() {
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 48312f5..d0cb574 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -36,6 +36,7 @@
>  #include "hw/nvram/fw_cfg.h"
>  #include "bios-linker-loader.h"
>  #include "hw/loader.h"
> +#include "hw/isa/isa.h"
>  
>  /* Supported chipsets: */
>  #include "hw/acpi/piix4.h"
> @@ -80,6 +81,8 @@ typedef struct AcpiMiscInfo {
>  
>  static void acpi_get_dsdt(AcpiMiscInfo *info)
>  {
> +unsigned short smc_sta_val = 0x00;

Better initialize this in the else branch below.

> +unsigned short *smc_sta_off;
>  Object *piix = piix4_pm_find();
>  Object *lpc = ich9_lpc_find();
>  assert(!!piix != !!lpc);
> @@ -87,11 +90,19 @@ static void acpi_get_dsdt(AcpiMiscInfo *info)
>  if (piix) {
>  info->dsdt_code = AcpiDsdtAmlCode;
>  info->dsdt_size = sizeof AcpiDsdtAmlCode;
> +smc_sta_off = piix_smc_sta;
>  }
>  if (lpc) {
>  info->dsdt_

Re: [Qemu-devel] [PATCH 03/27] pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS

2013-12-22 Thread Michael S. Tsirkin
On Fri, Dec 20, 2013 at 01:48:47PM +0100, Igor Mammedov wrote:
> On Thu, 19 Dec 2013 16:35:05 +0200
> "Michael S. Tsirkin"  wrote:
> 
> > On Thu, Nov 21, 2013 at 03:38:24AM +0100, Igor Mammedov wrote:
> > > 'etc/reserved-memory-end' will allow QEMU to tell BIOS where PCI
> > > BARs mapping could safely start in high memory.
> > > 
> > > Allowing BIOS to start mapping 64-bit PCI BARs at address where it
> > > wouldn't conflict with other mappings QEMU might place before it.
> > > 
> > > That permits QEMU to reserve extra address space before
> > > 64-bit PCI hole for memory hotplug.
> > > 
> > > Signed-off-by: Igor Mammedov 
> > > ---
> > > v2:
> > >* disable 'etc/reserved-memory-end' for 1.7 and older machine types
> > > ---
> > >  hw/i386/pc.c |   27 +--
> > >  hw/i386/pc_piix.c|1 +
> > >  hw/i386/pc_q35.c |1 +
> > >  hw/pci-host/piix.c   |3 ++-
> > >  hw/pci-host/q35.c|3 ++-
> > >  include/hw/i386/pc.h |   11 +--
> > >  6 files changed, 40 insertions(+), 6 deletions(-)
> > > 
> > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > index 6c82ada..ba82c67 100644
> > > --- a/hw/i386/pc.c
> > > +++ b/hw/i386/pc.c
> > > @@ -1094,14 +1094,37 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t 
> > > below_4g_mem_size,
> > >  }
> > >  
> > >  /* setup pci memory address space mapping into system address space */
> > > -void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory,
> > > -MemoryRegion *pci_address_space)
> > > +void pc_pci_as_mapping_init_1_7(Object *owner, MemoryRegion 
> > > *system_memory,
> > > +MemoryRegion *pci_address_space,
> > > +uint64_t reserved_memory_end)
> > >  {
> > >  /* Set to lower priority than RAM */
> > >  memory_region_add_subregion_overlap(system_memory, 0x0,
> > >  pci_address_space, -1);
> > >  }
> > >  
> > > +static
> > > +void pc_pci_as_mapping_init_1_8(Object *owner, MemoryRegion 
> > > *system_memory,
> > > +MemoryRegion *pci_address_space,
> > > +uint64_t reserved_memory_end)
> > > +{
> > > +uint64_t *val;
> > > +FWCfgState *fw_cfg = fw_cfg_find();
> > > +g_assert(fw_cfg);
> > > +/*
> > > + *  Align address at 1G, this makes sure it can be exactly covered
> > > + *  with a PAT entry even when using huge pages.
> > > + */
> > > +val = g_malloc(sizeof(*val));
> > > +*val = cpu_to_le64(ROUND_UP(reserved_memory_end, 0x1ULL << 30));
> > > +fw_cfg_add_file(fw_cfg, "etc/reserved-memory-end", val, 
> > > sizeof(*val));
> > > +
> > > +pc_pci_as_mapping_init_1_7(owner, system_memory, pci_address_space,
> > > +   reserved_memory_end);
> > > +}
> > > +
> > > +pc_pci_as_mapping_init_fn pc_pci_as_mapping_init = 
> > > pc_pci_as_mapping_init_1_8;
> > > +
> > >  void pc_acpi_init(const char *default_dsdt)
> > >  {
> > >  char *filename;
> > > diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> > > index 36f2495..e1fe85a 100644
> > > --- a/hw/i386/pc_piix.c
> > > +++ b/hw/i386/pc_piix.c
> > > @@ -249,6 +249,7 @@ static void pc_init_pci(QEMUMachineInitArgs *args)
> > >  static void pc_compat_1_7(QEMUMachineInitArgs *args)
> > >  {
> > >  smbios_type1_defaults = false;
> > > +pc_pci_as_mapping_init = pc_pci_as_mapping_init_1_7;
> > >  }
> > >  
> > >  static void pc_compat_1_6(QEMUMachineInitArgs *args)
> > > diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
> > > index 50ca458..5525465 100644
> > > --- a/hw/i386/pc_q35.c
> > > +++ b/hw/i386/pc_q35.c
> > > @@ -233,6 +233,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
> > >  static void pc_compat_1_7(QEMUMachineInitArgs *args)
> > >  {
> > >  smbios_type1_defaults = false;
> > > +pc_pci_as_mapping_init = pc_pci_as_mapping_init_1_7;
> > >  }
> > >  
> > >  static void pc_compat_1_6(QEMUMachineInitArgs *args)
> > 
> > I don't much like this: why not use a global flag like we do
> > for other properties?
> because flag would add extra branching clattering code, while
> overriding function makes caller cleaner and potentially maps
> well into method override when machines are converted to QOM objects.
> So why not to try this vs flags?

For consistency with other code. We have too many unfinished
conversions across the codebase, they are a bigger problem
than some branches here and there.

So I would say let's delay these experiments until this QOM
cleanup happens.

> > 
> > Also, 1_8 should be replaced with 2_0 now.
> sure
> 
> > 
> > > diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
> > > index 63be7f6..615ab0d 100644
> > > --- a/hw/pci-host/piix.c
> > > +++ b/hw/pci-host/piix.c
> > > @@ -352,7 +352,8 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
> > >  
> > >  /* setup pci memory mapping */
> > >  pc_pci_as_mapping_init(OBJECT(f), f->system_mem

Re: [Qemu-devel] [PATCH 0/5] tcg/i386: use movbe instruction in qemu_ldst routines

2013-12-22 Thread Aurelien Jarno
I forgot to Cc: Richard on this patch set, doing that now...

On Sat, Dec 21, 2013 at 05:43:39PM +0100, Aurelien Jarno wrote:
> This patchset enable the usage of the movbe instruction, available on
> Intel Atom and Intel Haswell CPU, in qemu_ldst routines, avoiding bswap
> instructions before or after the store or loads. The availability of
> this instruction is done at runtime using the cpuid instruction.
> 
> The last patch of the series is not fully related, but I spotted the
> issue when working on this patchset, so I thought it's a good idea to
> fix it.
> 
> Aurelien Jarno (5):
>   disas/i386.c: disassemble movbe instruction
>   tcg/i386: remove hardcoded P_REXW value
>   tcg/i386: add support for three-byte opcodes
>   tcg/i386: use movbe instruction in qemu_ldst routines
>   tcg/i386: cleanup useless #ifdef
> 
>  disas/i386.c  |8 +--
>  tcg/i386/tcg-target.c |  178 
> ++---
>  2 files changed, 128 insertions(+), 58 deletions(-)
> 
> -- 
> 1.7.10.4
> 
> 

-- 
Aurelien Jarno  GPG: 1024D/F1BCDB73
aurel...@aurel32.net http://www.aurel32.net



Re: [Qemu-devel] [PATCH 7/8] target-sh4: factorize fmov implementation

2013-12-22 Thread Aurelien Jarno
On Sat, Dec 21, 2013 at 06:52:26PM +, Peter Maydell wrote:
> On 21 December 2013 16:59, Aurelien Jarno  wrote:
> > Signed-off-by: Aurelien Jarno 
> > ---
> >  target-sh4/translate.c |   31 ++-
> >  1 file changed, 14 insertions(+), 17 deletions(-)
> >
> > diff --git a/target-sh4/translate.c b/target-sh4/translate.c
> > index 26b45c1..23d51c6 100644
> > --- a/target-sh4/translate.c
> > +++ b/target-sh4/translate.c
> > @@ -1024,23 +1024,20 @@ static void _decode_opc(DisasContext * ctx)
> > return;
> >  case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
> > CHECK_FPU_ENABLED
> > -if (ctx->flags & FPSCR_SZ) {
> > -   TCGv addr = tcg_temp_new_i32();
> > -   int fr = XREG(B7_4);
> > -   tcg_gen_subi_i32(addr, REG(B11_8), 4);
> > -   tcg_gen_qemu_st32(cpu_fregs[fr+1], addr, ctx->memidx);
> > -   tcg_gen_subi_i32(addr, addr, 4);
> > -   tcg_gen_qemu_st32(cpu_fregs[fr  ], addr, ctx->memidx);
> > -   tcg_gen_mov_i32(REG(B11_8), addr);
> > -   tcg_temp_free(addr);
> > -   } else {
> > -   TCGv addr;
> > -   addr = tcg_temp_new_i32();
> > -   tcg_gen_subi_i32(addr, REG(B11_8), 4);
> > -   tcg_gen_qemu_st32(cpu_fregs[FREG(B7_4)], addr, ctx->memidx);
> > -   tcg_gen_mov_i32(REG(B11_8), addr);
> > -   tcg_temp_free(addr);
> > -   }
> > +{
> > +const int fr = XREG(B7_4);
> > +TCGv addr = tcg_temp_new_i32();
> > +tcg_gen_subi_i32(addr, REG(B11_8), 4);
> > +if (ctx->flags & FPSCR_SZ) {
> > +tcg_gen_qemu_st32(cpu_fregs[fr+1], addr, ctx->memidx);
> > +tcg_gen_subi_i32(addr, addr, 4);
> > +tcg_gen_qemu_st32(cpu_fregs[fr], addr, ctx->memidx);
> > +} else {
> > +tcg_gen_qemu_st32(cpu_fregs[fr], addr, ctx->memidx);
> > +}
> > +tcg_gen_mov_i32(REG(B11_8), addr);
> > +tcg_temp_free(addr);
> > +}
> > return;
> >  case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
> > CHECK_FPU_ENABLED
> 
> Isn't this going to conflict with the "update to new qemu ld/st ops"
> patch you posted earlier?

They indeed conflicts, and I haven't realized that before as I
developed them separately. This patchset was actually sitting for quite
some time in my git. I'll post a new version soon.

-- 
Aurelien Jarno  GPG: 1024D/F1BCDB73
aurel...@aurel32.net http://www.aurel32.net



[Qemu-devel] [PATCH] target-ppc: fix VSX extension TCG code

2013-12-22 Thread Aurelien Jarno
The VSX TCG code is using _i64 types mixed wiht _tl types. While this
is correct for 64-bit targets, this breaks the compilation with 32-bit
targets and --enable-debug-tcg.

This patch fixes that by always using the correct type. Note that we can
probably do better for the load/stores using the new load/store TCG
instructions, but that would need changes to other places of the code,
while this patch intents to be a bug fix patch only.

Cc: Tom Musta 
Cc: Alexander Graf 
Signed-off-by: Aurelien Jarno 
---
 target-ppc/translate.c |  132 +---
 1 file changed, 70 insertions(+), 62 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index ea58dc9..2f9e9ac 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7048,13 +7048,13 @@ static void gen_lxvdsx(DisasContext *ctx)
 EA = tcg_temp_new();
 gen_addr_reg_index(ctx, EA);
 gen_qemu_ld64(ctx, cpu_vsrh(xT(ctx->opcode)), EA);
-tcg_gen_mov_tl(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xT(ctx->opcode)));
+tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xT(ctx->opcode)));
 tcg_temp_free(EA);
 }
 
 static void gen_lxvw4x(DisasContext *ctx)
 {
-TCGv EA, tmp;
+TCGv EA, lo, hi;
 TCGv_i64 xth = cpu_vsrh(xT(ctx->opcode));
 TCGv_i64 xtl = cpu_vsrl(xT(ctx->opcode));
 if (unlikely(!ctx->vsx_enabled)) {
@@ -7063,21 +7063,23 @@ static void gen_lxvw4x(DisasContext *ctx)
 }
 gen_set_access_type(ctx, ACCESS_INT);
 EA = tcg_temp_new();
-tmp = tcg_temp_new();
+lo = tcg_temp_new();
+hi = tcg_temp_new();
 gen_addr_reg_index(ctx, EA);
-gen_qemu_ld32u(ctx, tmp, EA);
+gen_qemu_ld32u(ctx, lo, EA);
 tcg_gen_addi_tl(EA, EA, 4);
-gen_qemu_ld32u(ctx, xth, EA);
-tcg_gen_deposit_i64(xth, xth, tmp, 32, 32);
+gen_qemu_ld32u(ctx, hi, EA);
+tcg_gen_concat_tl_i64(xth, lo, hi);
 
 tcg_gen_addi_tl(EA, EA, 4);
-gen_qemu_ld32u(ctx, tmp, EA);
+gen_qemu_ld32u(ctx, lo, EA);
 tcg_gen_addi_tl(EA, EA, 4);
-gen_qemu_ld32u(ctx, xtl, EA);
-tcg_gen_deposit_i64(xtl, xtl, tmp, 32, 32);
+gen_qemu_ld32u(ctx, hi, EA);
+tcg_gen_concat_tl_i64(xtl, lo, hi);
 
 tcg_temp_free(EA);
-tcg_temp_free(tmp);
+tcg_temp_free(hi);
+tcg_temp_free(lo);
 }
 
 static void gen_stxsdx(DisasContext *ctx)
@@ -7113,6 +7115,7 @@ static void gen_stxvd2x(DisasContext *ctx)
 static void gen_stxvw4x(DisasContext *ctx)
 {
 TCGv EA, tmp;
+TCGv_i64 tmp64;
 if (unlikely(!ctx->vsx_enabled)) {
 gen_exception(ctx, POWERPC_EXCP_VSXU);
 return;
@@ -7121,19 +7124,24 @@ static void gen_stxvw4x(DisasContext *ctx)
 EA = tcg_temp_new();
 gen_addr_reg_index(ctx, EA);
 tmp = tcg_temp_new();
+tmp64 = tcg_temp_new_i64();
 
-tcg_gen_shri_i64(tmp, cpu_vsrh(xS(ctx->opcode)), 32);
+tcg_gen_shri_i64(tmp64, cpu_vsrh(xS(ctx->opcode)), 32);
+tcg_gen_trunc_i64_tl(tmp, tmp64);
 gen_qemu_st32(ctx, tmp, EA);
 tcg_gen_addi_tl(EA, EA, 4);
-gen_qemu_st32(ctx, cpu_vsrh(xS(ctx->opcode)), EA);
+tcg_gen_trunc_i64_tl(tmp, cpu_vsrh(xS(ctx->opcode)));
+gen_qemu_st32(ctx, tmp, EA);
 
-tcg_gen_shri_i64(tmp, cpu_vsrl(xS(ctx->opcode)), 32);
-tcg_gen_addi_tl(EA, EA, 4);
+tcg_gen_shri_i64(tmp64, cpu_vsrl(xS(ctx->opcode)), 32);
+tcg_gen_trunc_i64_tl(tmp, tmp64);
 gen_qemu_st32(ctx, tmp, EA);
 tcg_gen_addi_tl(EA, EA, 4);
-gen_qemu_st32(ctx, cpu_vsrl(xS(ctx->opcode)), EA);
+tcg_gen_trunc_i64_tl(tmp, cpu_vsrl(xS(ctx->opcode)));
+gen_qemu_st32(ctx, tmp, EA);
 
 tcg_temp_free(EA);
+tcg_temp_free_i64(tmp64);
 tcg_temp_free(tmp);
 }
 
@@ -7171,8 +7179,8 @@ static void glue(gen_, name)(DisasContext * ctx)  
\
 gen_exception(ctx, POWERPC_EXCP_VSXU);\
 return;   \
 } \
-xb = tcg_temp_new();  \
-sgm = tcg_temp_new(); \
+xb = tcg_temp_new_i64();  \
+sgm = tcg_temp_new_i64(); \
 tcg_gen_mov_i64(xb, cpu_vsrh(xB(ctx->opcode)));   \
 tcg_gen_movi_i64(sgm, sgn_mask);  \
 switch (op) { \
@@ -7189,18 +7197,18 @@ static void glue(gen_, name)(DisasContext * ctx)
  \
 break;\
 } \
 case OP_CPSGN: {  \
-TCGv_i64 xa = tcg_temp_new(); \
+TCGv_i64 xa = tcg_temp_new_i64(); \
 tcg_gen_mov_i64(xa, cpu_vsrh(xA(ctx->opcode)));   \
 tcg_gen_and_i64(xa, xa, sgm);  

Re: [Qemu-devel] [PATCH 2/2] ppc-e500: implement PCI INTx routing

2013-12-22 Thread Michael S. Tsirkin
On Fri, Dec 20, 2013 at 11:31:17AM +0100, Alexander Graf wrote:
> 
> On 20.12.2013, at 10:42, Bharat Bhushan  wrote:
> 
> > This patch adds pci pin to irq_num routing callback.
> > This callback is called from pci_device_route_intx_to_irq to find which pci 
> > device
> > maps to which irq. This is used for pci-device passthrough using vfio.
> > 
> > Also without this patch we gets below warning
> > 
> > "
> >  PCI: Bug - unimplemented PCI INTx routing (e500-pcihost)
> >  qemu-system-ppc64: PCI: Bug - unimplemented PCI INTx routing (e500-pcihost)
> > "
> > and Legacy interrupt does not work with pci device passthrough.
> > 
> > Signed-off-by: Bharat Bhushan 
> > Acked-by: Michael S. Tsirkin 
> > ---
> > hw/pci-host/ppce500.c |   20 ++--
> > 1 files changed, 18 insertions(+), 2 deletions(-)
> > 
> > diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
> > index 71e5ca9..ffea782 100644
> > --- a/hw/pci-host/ppce500.c
> > +++ b/hw/pci-host/ppce500.c
> > @@ -88,6 +88,7 @@ struct PPCE500PCIState {
> > struct pci_inbound pib[PPCE500_PCI_NR_PIBS];
> > uint32_t gasket_time;
> > qemu_irq irq[PCI_NUM_PINS];
> > +uint32_t irq_num[PCI_NUM_PINS];
> > uint32_t first_slot;
> > /* mmio maps */
> > MemoryRegion container;
> > @@ -267,13 +268,26 @@ static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, 
> > int pin)
> > 
> > static void mpc85xx_pci_set_irq(void *opaque, int pin, int level)
> > {
> > -qemu_irq *irq = opaque;
> > +PPCE500PCIState *s = opaque;
> > +qemu_irq *pic = s->irq;
> > 
> > pci_debug("%s: PCI irq %d, level:%d\n", __func__, pin , level);
> > 
> > qemu_set_irq(irq[pin], level);
> > }
> > 
> > +static PCIINTxRoute e500_route_intx_pin_to_irq(void *opaque, int pin)
> > +{
> > +PCIINTxRoute route;
> > +PPCE500PCIState *s = opaque;
> > +
> > +route.mode = PCI_INTX_ENABLED;
> > +route.irq = s->irq_num[pin];
> > +
> > +pci_debug("%s: PCI irq-pin = %d, irq_num= %d\n", __func__, pin, 
> > route.irq);
> > +return route;
> > +}
> > +
> > static const VMStateDescription vmstate_pci_outbound = {
> > .name = "pci_outbound",
> > .version_id = 0,
> > @@ -350,12 +364,13 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
> > 
> > for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
> > sysbus_init_irq(dev, &s->irq[i]);
> > +s->irq_num[i] = i + 1;
> 
> I still don't like how you duplicate the logic which MPIC irq line is 
> associated with which pci host controller irq line. Please pass this 
> information into the pcihost object somehow from ppce500_init() so that it's 
> only at a single spot.
> 
> If you like, you can just use qom/qdev properties for that, but it needs to 
> be configured from the outside.
> 
> 
> Alex


Maybe just call ppce500_pci_map_irq_slot instead of using irq_num?





Re: [Qemu-devel] [PATCH v3] piix: fix 32bit pci hole

2013-12-22 Thread Michael S. Tsirkin
On Sat, Dec 21, 2013 at 03:02:50AM +0100, Laszlo Ersek wrote:
> From: Gerd Hoffmann 
> 
> Make the 32bit pci hole start at end of ram, so all possible address
> space is covered.  Of course the firmware can use less than that.
> Leaving space unused is no problem, mapping pci bars outside the
> hole causes problems though.
> 
> Signed-off-by: Gerd Hoffmann 
> 
> Forward ported to 83d08f26 ("pc: map PCI address space as catchall region
> for not mapped addresses").
> 
> Signed-off-by: Laszlo Ersek 

I tweaked the commit log a bit and applied this.
Thanks!

> ---
>  include/hw/i386/pc.h |  1 +
>  hw/i386/pc_piix.c|  1 +
>  hw/pci-host/piix.c   | 11 ++-
>  3 files changed, 4 insertions(+), 9 deletions(-)
> 
> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> index 24eb3de..eb3da96 100644
> --- a/include/hw/i386/pc.h
> +++ b/include/hw/i386/pc.h
> @@ -182,6 +182,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int 
> *piix_devfn,
>  MemoryRegion *address_space_mem,
>  MemoryRegion *address_space_io,
>  ram_addr_t ram_size,
> +ram_addr_t below_4g_mem_size,
>  ram_addr_t above_4g_mem_size,
>  MemoryRegion *pci_memory,
>  MemoryRegion *ram_memory);
> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> index 4e0dae7..eed892b 100644
> --- a/hw/i386/pc_piix.c
> +++ b/hw/i386/pc_piix.c
> @@ -157,6 +157,7 @@ static void pc_init1(QEMUMachineInitArgs *args,
>  if (pci_enabled) {
>  pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, &isa_bus, gsi,
>system_memory, system_io, args->ram_size,
> +  below_4g_mem_size,
>above_4g_mem_size,
>pci_memory, ram_memory);
>  } else {
> diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
> index 63be7f6..4229d09 100644
> --- a/hw/pci-host/piix.c
> +++ b/hw/pci-host/piix.c
> @@ -311,6 +311,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
>  MemoryRegion *address_space_mem,
>  MemoryRegion *address_space_io,
>  ram_addr_t ram_size,
> +ram_addr_t below_4g_mem_size,
>  ram_addr_t above_4g_mem_size,
>  MemoryRegion *pci_address_space,
>  MemoryRegion *ram_memory)
> @@ -340,15 +341,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
>  f->ram_memory = ram_memory;
>  
>  i440fx = I440FX_PCI_HOST_BRIDGE(dev);
> -/* Set PCI window size the way seabios has always done it. */
> -/* Power of 2 so bios can cover it with a single MTRR */
> -if (ram_size <= 0x8000) {
> -i440fx->pci_info.w32.begin = 0x8000;
> -} else if (ram_size <= 0xc000) {
> -i440fx->pci_info.w32.begin = 0xc000;
> -} else {
> -i440fx->pci_info.w32.begin = 0xe000;
> -}
> +i440fx->pci_info.w32.begin = below_4g_mem_size;
>  
>  /* setup pci memory mapping */
>  pc_pci_as_mapping_init(OBJECT(f), f->system_memory,
> -- 
> 1.8.3.1



[Qemu-devel] [PATCH] bitops: provide an inline implementation of find_first_bit

2013-12-22 Thread Aurelien Jarno
find_first_bit has started to be used heavily in TCG code. The current
implementation based on find_next_bit is not optimal and can't be
optimized be the compiler if the bit array has a fixed size, which is
the case most of the time.

This new implementation does not use find_next_bit and is yet small
enough to be inlined.

Cc: Richard Henderson 
Cc: Corentin Chary 

Signed-off-by: Aurelien Jarno 
---
 include/qemu/bitops.h |   12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h
index 304c90c..041142a 100644
--- a/include/qemu/bitops.h
+++ b/include/qemu/bitops.h
@@ -157,7 +157,17 @@ unsigned long find_next_zero_bit(const unsigned long *addr,
 static inline unsigned long find_first_bit(const unsigned long *addr,
unsigned long size)
 {
-return find_next_bit(addr, size, 0);
+unsigned long result, tmp;
+
+for (result = 0; result < size; result += BITS_PER_LONG) {
+tmp = *addr++;
+if (tmp) {
+result += ctzl(tmp);
+return result < size ? result : size;
+}
+}
+/* Not found */
+return size;
 }
 
 /**
-- 
1.7.10.4




Re: [Qemu-devel] vhost-net issue: does not survive reboot on ppc64

2013-12-22 Thread Zhi Yong Wu
On Sat, Dec 21, 2013 at 11:01 PM, Alexey Kardashevskiy  wrote:
> Hi!
HI, Alexey

>
> I am having a problem with virtio-net + vhost on POWER7 machine - it does
> not survive reboot of the guest.
Can you let me login to your environment for debug? I am interested in
trying to fix this issue.

>
> Steps to reproduce:
> 1. boot the guest
> 2. configure eth0 and do ping - everything works
> 3. reboot the guest (i.e. type "reboot")
> 4. when it is booted, eth0 can be configured but will not work at all.
>
> The test is:
> ifconfig eth0 172.20.1.2 up
> ping 172.20.1.23
>
> If to run tcpdump on the host's "tap-id3" interface, it shows no trafic
> coming from the guest. If to compare how it works before and after reboot,
> I can see the guest doing an ARP request for 172.20.1.23 and receives the
> response and it does the same after reboot but the answer does not come.
>
> If to remove vhost=on, it is all good. If to try Fedora19
> (v3.10-something), it all good again - works before and after reboot.
>
>
> And there 2 questions:
>
> 1. does anybody have any clue what might go wrong after reboot?
>
> 2. Is there any good material to read about what exactly and how vhost
> accelerates?
>
> My understanding is that packets from the guest to the real network are
> going as:
> 1. guest's virtio-pci-net does ioport(VIRTIO_PCI_QUEUE_NOTIFY)
> 2. QEMU's net/virtio-net.c calls qemu_net_queue_deliver()
> 3. QEMU's net/tap.c calls tap_write_packet() and this is how the host knows
> that there is a new packet.
>
>
> Thanks!
>
>
> This how I run QEMU:
> ./qemu-system-ppc64 \
> -enable-kvm \
> -m 2048 \
> -machine pseries \
> -initrd 1.cpio \
> -kernel vml312_virtio_net_dbg \
> -nographic \
> -vga none \
> -netdev
> tap,id=id3,ifname=tap-id3,script=ifup.sh,downscript=ifdown.sh,vhost=on \
> -device virtio-net-pci,id=id4,netdev=id3,mac=C0:41:49:4b:00:00
>
>
> That is bridge config:
> [aik@dyn232 ~]$ brctl show
> bridge name bridge id   STP enabled interfaces
> brtest  8000.00145e992e88   no  pin eth4
>
>
> The ifup.sh script:
> ifconfig $1 hw ether ee:01:02:03:04:05
> /sbin/ifconfig $1 up
> /usr/sbin/brctl addif brtest $1
>
>
>
>
> --
> Alexey
>



-- 
Regards,

Zhi Yong Wu



[Qemu-devel] [PATCH v2 6/9] target-sh4: split out Q and M from of SR and optimize div1

2013-12-22 Thread Aurelien Jarno
Splitting Q and M out of SR, it's possible to optimize div1 by using
TCG code instead of an helper.

Signed-off-by: Aurelien Jarno 
---
 target-sh4/cpu.h   |   13 --
 target-sh4/helper.h|1 -
 target-sh4/op_helper.c |  118 
 target-sh4/translate.c |   67 +++
 4 files changed, 68 insertions(+), 131 deletions(-)

diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index b7dd7ab..82221c8 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -140,6 +140,8 @@ typedef struct CPUSH4State {
 uint32_t gregs[24];/* general registers */
 float32 fregs[32]; /* floating point registers */
 uint32_t sr;/* status register (with T split out) */
+uint32_t sr_m;  /* M bit of status register */
+uint32_t sr_q;  /* Q bit of status register */
 uint32_t sr_t;  /* T bit of status register */
 uint32_t ssr;  /* saved status register */
 uint32_t spc;  /* saved program counter */
@@ -342,13 +344,18 @@ static inline int cpu_ptel_pr (uint32_t ptel)
 
 static inline target_ulong cpu_read_sr(CPUSH4State *env)
 {
-return (env->sr & ~(1u << SR_T)) | (env->sr_t << SR_T);
+return (env->sr & ~((1u << SR_M) | (1u << SR_Q) | (1u << SR_T))) |
+   (env->sr_m << SR_M) |
+   (env->sr_q << SR_Q) |
+   (env->sr_t << SR_T);
 }
 
 static inline void cpu_write_sr(CPUSH4State *env, target_ulong sr)
 {
-env->sr_t = sr & (1u << SR_T);
-env->sr = sr & ~(1u << SR_T);
+env->sr_m = (sr >> SR_M) & 1;
+env->sr_q = (sr >> SR_Q) & 1;
+env->sr_t = (sr >> SR_T) & 1;
+env->sr = sr & ~((1u << SR_M) | (1u << SR_Q) | (1u << SR_T));
 }
 
 static inline void cpu_get_tb_cpu_state(CPUSH4State *env, target_ulong *pc,
diff --git a/target-sh4/helper.h b/target-sh4/helper.h
index 7162448..fbbe264 100644
--- a/target-sh4/helper.h
+++ b/target-sh4/helper.h
@@ -13,7 +13,6 @@ DEF_HELPER_3(movcal, void, env, i32, i32)
 DEF_HELPER_1(discard_movcal_backup, void, env)
 DEF_HELPER_2(ocbi, void, env, i32)
 
-DEF_HELPER_3(div1, i32, env, i32, i32)
 DEF_HELPER_3(macl, void, env, i32, i32)
 DEF_HELPER_3(macw, void, env, i32, i32)
 
diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
index 0e881a8..3ed0e2d 100644
--- a/target-sh4/op_helper.c
+++ b/target-sh4/op_helper.c
@@ -166,124 +166,6 @@ void helper_ocbi(CPUSH4State *env, uint32_t address)
 }
 }
 
-#define T (env->sr_t)
-#define Q (env->sr & (1u << SR_Q) ? 1 : 0)
-#define M (env->sr & (1u << SR_M) ? 1 : 0)
-#define SETT (env->sr_t = 1)
-#define CLRT (env->sr_t = 0)
-#define SETQ (env->sr |= (1u << SR_Q))
-#define CLRQ (env->sr &= ~(1u << SR_Q))
-#define SETM (env->sr |= (1u << SR_M))
-#define CLRM (env->sr &= ~(1u << SR_M))
-
-uint32_t helper_div1(CPUSH4State *env, uint32_t arg0, uint32_t arg1)
-{
-uint32_t tmp0, tmp2;
-uint8_t old_q, tmp1 = 0xff;
-
-//printf("div1 arg0=0x%08x arg1=0x%08x M=%d Q=%d T=%d\n", arg0, arg1, M, 
Q, T);
-old_q = Q;
-if ((0x8000 & arg1) != 0)
-   SETQ;
-else
-   CLRQ;
-tmp2 = arg0;
-arg1 <<= 1;
-arg1 |= T;
-switch (old_q) {
-case 0:
-   switch (M) {
-   case 0:
-   tmp0 = arg1;
-   arg1 -= tmp2;
-   tmp1 = arg1 > tmp0;
-   switch (Q) {
-   case 0:
-   if (tmp1)
-   SETQ;
-   else
-   CLRQ;
-   break;
-   case 1:
-   if (tmp1 == 0)
-   SETQ;
-   else
-   CLRQ;
-   break;
-   }
-   break;
-   case 1:
-   tmp0 = arg1;
-   arg1 += tmp2;
-   tmp1 = arg1 < tmp0;
-   switch (Q) {
-   case 0:
-   if (tmp1 == 0)
-   SETQ;
-   else
-   CLRQ;
-   break;
-   case 1:
-   if (tmp1)
-   SETQ;
-   else
-   CLRQ;
-   break;
-   }
-   break;
-   }
-   break;
-case 1:
-   switch (M) {
-   case 0:
-   tmp0 = arg1;
-   arg1 += tmp2;
-   tmp1 = arg1 < tmp0;
-   switch (Q) {
-   case 0:
-   if (tmp1)
-   SETQ;
-   else
-   CLRQ;
-   break;
-   case 1:
-   if (tmp1 == 0)
-   SETQ;
-   else
-   CLRQ;
-   break;
-   }
-   break;
-   case 1:
-   tmp0 = arg1;
-   arg1 -= tmp2;
-   tmp1 = arg1 > tmp0;
-   switch (Q) {
-   case 0:
-   if (tmp1 == 0)
-   SETQ;
-   else
-   CLRQ;
-   break;
-   case 1:
-   if (tmp1)
-   SETQ;
-   

[Qemu-devel] [PATCH v2 2/9] target-sh4: Split out T from SR

2013-12-22 Thread Aurelien Jarno
In preparation for more efficient setting of this field.

Signed-off-by: Aurelien Jarno 
---
 target-sh4/cpu.h   |   14 +++-
 target-sh4/gdbstub.c   |4 +-
 target-sh4/helper.c|2 +-
 target-sh4/op_helper.c |   32 ++--
 target-sh4/translate.c |  205 
 5 files changed, 110 insertions(+), 147 deletions(-)

diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index c8ba70f..b7dd7ab 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -139,7 +139,8 @@ typedef struct CPUSH4State {
 uint32_t flags;/* general execution flags */
 uint32_t gregs[24];/* general registers */
 float32 fregs[32]; /* floating point registers */
-uint32_t sr;   /* status register */
+uint32_t sr;/* status register (with T split out) */
+uint32_t sr_t;  /* T bit of status register */
 uint32_t ssr;  /* saved status register */
 uint32_t spc;  /* saved program counter */
 uint32_t gbr;  /* global base register */
@@ -339,6 +340,17 @@ static inline int cpu_ptel_pr (uint32_t ptel)
 
 #define TB_FLAG_PENDING_MOVCA  (1 << 4)
 
+static inline target_ulong cpu_read_sr(CPUSH4State *env)
+{
+return (env->sr & ~(1u << SR_T)) | (env->sr_t << SR_T);
+}
+
+static inline void cpu_write_sr(CPUSH4State *env, target_ulong sr)
+{
+env->sr_t = sr & (1u << SR_T);
+env->sr = sr & ~(1u << SR_T);
+}
+
 static inline void cpu_get_tb_cpu_state(CPUSH4State *env, target_ulong *pc,
 target_ulong *cs_base, int *flags)
 {
diff --git a/target-sh4/gdbstub.c b/target-sh4/gdbstub.c
index 05ba728..a365a27 100644
--- a/target-sh4/gdbstub.c
+++ b/target-sh4/gdbstub.c
@@ -51,7 +51,7 @@ int superh_cpu_gdb_read_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 case 21:
 return gdb_get_regl(mem_buf, env->macl);
 case 22:
-return gdb_get_regl(mem_buf, env->sr);
+return gdb_get_regl(mem_buf, cpu_read_sr(env));
 case 23:
 return gdb_get_regl(mem_buf, env->fpul);
 case 24:
@@ -111,7 +111,7 @@ int superh_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 env->macl = ldl_p(mem_buf);
 break;
 case 22:
-env->sr = ldl_p(mem_buf);
+cpu_write_sr(env, ldl_p(mem_buf));
 break;
 case 23:
 env->fpul = ldl_p(mem_buf);
diff --git a/target-sh4/helper.c b/target-sh4/helper.c
index 07f8e91..a33db4d 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -162,7 +162,7 @@ void superh_cpu_do_interrupt(CPUState *cs)
 log_cpu_state(cs, 0);
 }
 
-env->ssr = env->sr;
+env->ssr = cpu_read_sr(env);
 env->spc = env->pc;
 env->sgr = env->gregs[15];
 env->sr |= (1u << SR_BL) | (1u << SR_MD) | (1u << SR_RB);
diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
index 6d56df2..0e881a8 100644
--- a/target-sh4/op_helper.c
+++ b/target-sh4/op_helper.c
@@ -166,11 +166,11 @@ void helper_ocbi(CPUSH4State *env, uint32_t address)
 }
 }
 
-#define T (env->sr & (1u << SR_T))
+#define T (env->sr_t)
 #define Q (env->sr & (1u << SR_Q) ? 1 : 0)
 #define M (env->sr & (1u << SR_M) ? 1 : 0)
-#define SETT (env->sr |= (1u << SR_T))
-#define CLRT (env->sr &= ~(1u << SR_T))
+#define SETT (env->sr_t = 1)
+#define CLRT (env->sr_t = 0)
 #define SETQ (env->sr |= (1u << SR_Q))
 #define CLRQ (env->sr &= ~(1u << SR_Q))
 #define SETM (env->sr |= (1u << SR_M))
@@ -319,16 +319,6 @@ void helper_macw(CPUSH4State *env, uint32_t arg0, uint32_t 
arg1)
 }
 }
 
-static inline void set_t(CPUSH4State *env)
-{
-env->sr |= (1u << SR_T);
-}
-
-static inline void clr_t(CPUSH4State *env)
-{
-env->sr &= ~(1u << SR_T);
-}
-
 void helper_ld_fpscr(CPUSH4State *env, uint32_t val)
 {
 env->fpscr = val & FPSCR_MASK;
@@ -413,10 +403,8 @@ void helper_fcmp_eq_FT(CPUSH4State *env, float32 t0, 
float32 t1)
 relation = float32_compare(t0, t1, &env->fp_status);
 if (unlikely(relation == float_relation_unordered)) {
 update_fpscr(env, GETPC());
-} else if (relation == float_relation_equal) {
-set_t(env);
 } else {
-clr_t(env);
+env->sr_t = (relation == float_relation_equal);
 }
 }
 
@@ -428,10 +416,8 @@ void helper_fcmp_eq_DT(CPUSH4State *env, float64 t0, 
float64 t1)
 relation = float64_compare(t0, t1, &env->fp_status);
 if (unlikely(relation == float_relation_unordered)) {
 update_fpscr(env, GETPC());
-} else if (relation == float_relation_equal) {
-set_t(env);
 } else {
-clr_t(env);
+env->sr_t = (relation == float_relation_equal);
 }
 }
 
@@ -443,10 +429,8 @@ void helper_fcmp_gt_FT(CPUSH4State *env, float32 t0, 
float32 t1)
 relation = float32_compare(t0, t1, &env->fp_status);
 if (unlikely(relation == float_relation_unordered)) {
 update_fpscr(env, GETPC());
-} else if (relation == float_relation_greater) {

[Qemu-devel] [PATCH v2 9/9] target-sh4: simplify tas instruction

2013-12-22 Thread Aurelien Jarno
Now that setcondi is used instead of branches, temp_local are not needed
anymore.

Signed-off-by: Aurelien Jarno 
---
 target-sh4/translate.c |   10 +++---
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 9a878d0..e73932c 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -1673,16 +1673,12 @@ static void _decode_opc(DisasContext * ctx)
return;
 case 0x401b:   /* tas.b @Rn */
{
-   TCGv addr, val;
-   addr = tcg_temp_local_new();
-   tcg_gen_mov_i32(addr, REG(B11_8));
-   val = tcg_temp_local_new();
-tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
+   TCGv val = tcg_temp_new();
+tcg_gen_qemu_ld_i32(val, REG(B11_8), ctx->memidx, MO_UB);
 tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
tcg_gen_ori_i32(val, val, 0x80);
-tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
+tcg_gen_qemu_st_i32(val, REG(B11_8), ctx->memidx, MO_UB);
tcg_temp_free(val);
-   tcg_temp_free(addr);
}
return;
 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
-- 
1.7.10.4




[Qemu-devel] [PATCH v2 5/9] target-sh4: optimize negc using add2 and sub2

2013-12-22 Thread Aurelien Jarno
Signed-off-by: Aurelien Jarno 
---
 target-sh4/translate.c |   12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 21605b0..4ef0398 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -797,12 +797,12 @@ static void _decode_opc(DisasContext * ctx)
return;
 case 0x600a:   /* negc Rm,Rn */
 {
-TCGv t0 = tcg_temp_new();
-tcg_gen_neg_i32(t0, REG(B7_4));
-tcg_gen_sub_i32(REG(B11_8), t0, cpu_sr_t);
-tcg_gen_setcondi_i32(TCG_COND_GTU, cpu_sr_t, t0, 0);
-tcg_gen_setcond_i32(TCG_COND_GTU, t0, REG(B11_8), t0);
-tcg_gen_or_i32(cpu_sr_t, cpu_sr_t, t0);
+TCGv t0 = tcg_const_i32(0);
+tcg_gen_add2_i32(REG(B11_8), cpu_sr_t,
+ REG(B7_4), t0, cpu_sr_t, t0);
+tcg_gen_sub2_i32(REG(B11_8), cpu_sr_t,
+ t0, t0, REG(B11_8), cpu_sr_t);
+tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
 tcg_temp_free(t0);
 }
return;
-- 
1.7.10.4




[Qemu-devel] [PATCH v2 3/9] target-sh4: optimize addc using add2

2013-12-22 Thread Aurelien Jarno
Signed-off-by: Aurelien Jarno 
---
 target-sh4/translate.c |   14 ++
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index fad9869..31d47b3 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -640,17 +640,15 @@ static void _decode_opc(DisasContext * ctx)
return;
 case 0x300e:   /* addc Rm,Rn */
 {
-TCGv t0, t1;
-t0 = tcg_temp_new();
+TCGv t0, t1, t2;
+t0 = tcg_const_tl(0);
 t1 = tcg_temp_new();
-tcg_gen_add_i32(t0, REG(B7_4), REG(B11_8));
-tcg_gen_add_i32(t1, cpu_sr_t, t0);
-tcg_gen_setcond_i32(TCG_COND_GTU, cpu_sr_t, REG(B11_8), t0);
-tcg_gen_setcond_i32(TCG_COND_GTU, t0, t0, t1);
-tcg_gen_or_i32(cpu_sr_t, cpu_sr_t, t0);
+t2 = tcg_temp_new();
+tcg_gen_add2_i32(t1, t2, REG(B11_8), t0, REG(B7_4), t0);
+tcg_gen_add2_i32(REG(B11_8), cpu_sr_t, t1, t2, cpu_sr_t, t0);
 tcg_temp_free(t0);
-tcg_gen_mov_i32(REG(B11_8), t1);
 tcg_temp_free(t1);
+tcg_temp_free(t2);
 }
return;
 case 0x300f:   /* addv Rm,Rn */
-- 
1.7.10.4




[Qemu-devel] [PATCH v2 1/9] target-sh4: use bit number for SR constants

2013-12-22 Thread Aurelien Jarno
Use the bit number for SR constants instead of using a bit mask. This
make possible to also use the constants for shifts.

Signed-off-by: Aurelien Jarno 
---
 target-sh4/cpu.c   |3 +-
 target-sh4/cpu.h   |   30 +--
 target-sh4/gdbstub.c   |4 +--
 target-sh4/helper.c|   27 -
 target-sh4/op_helper.c |   26 -
 target-sh4/translate.c |   75 +---
 6 files changed, 85 insertions(+), 80 deletions(-)

diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index c23294d..1d80f47 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -56,7 +56,8 @@ static void superh_cpu_reset(CPUState *s)
 env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
 set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! 
*/
 #else
-env->sr = SR_MD | SR_RB | SR_BL | SR_I3 | SR_I2 | SR_I1 | SR_I0;
+env->sr = (1u << SR_MD) | (1u << SR_RB) | (1u << SR_BL) |
+  (1u << SR_I3) | (1u << SR_I2) | (1u << SR_I1) | (1u << SR_I0);
 env->fpscr = FPSCR_DN | FPSCR_RM_ZERO; /* CPU reset value according to SH4 
manual */
 set_float_rounding_mode(float_round_to_zero, &env->fp_status);
 set_flush_to_zero(1, &env->fp_status);
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index c181dda..c8ba70f 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -48,18 +48,18 @@
 #define TARGET_PHYS_ADDR_SPACE_BITS 32
 #define TARGET_VIRT_ADDR_SPACE_BITS 32
 
-#define SR_MD (1 << 30)
-#define SR_RB (1 << 29)
-#define SR_BL (1 << 28)
-#define SR_FD (1 << 15)
-#define SR_M  (1 << 9)
-#define SR_Q  (1 << 8)
-#define SR_I3 (1 << 7)
-#define SR_I2 (1 << 6)
-#define SR_I1 (1 << 5)
-#define SR_I0 (1 << 4)
-#define SR_S  (1 << 1)
-#define SR_T  (1 << 0)
+#define SR_MD 30
+#define SR_RB 29
+#define SR_BL 28
+#define SR_FD 15
+#define SR_M  9
+#define SR_Q  8
+#define SR_I3 7
+#define SR_I2 6
+#define SR_I1 5
+#define SR_I0 4
+#define SR_S  1
+#define SR_T  0
 
 #define FPSCR_MASK (0x003f)
 #define FPSCR_FR   (1 << 21)
@@ -242,7 +242,7 @@ static inline CPUSH4State *cpu_init(const char *cpu_model)
 #define MMU_USER_IDX 1
 static inline int cpu_mmu_index (CPUSH4State *env)
 {
-return (env->sr & SR_MD) == 0 ? 1 : 0;
+return (env->sr & (1u << SR_MD)) == 0 ? 1 : 0;
 }
 
 #include "exec/cpu-all.h"
@@ -347,8 +347,8 @@ static inline void cpu_get_tb_cpu_state(CPUSH4State *env, 
target_ulong *pc,
 *flags = (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL
 | DELAY_SLOT_TRUE | DELAY_SLOT_CLEARME))   /* Bits  0- 3 */
 | (env->fpscr & (FPSCR_FR | FPSCR_SZ | FPSCR_PR))  /* Bits 19-21 */
-| (env->sr & (SR_MD | SR_RB))  /* Bits 29-30 */
-| (env->sr & SR_FD)/* Bit 15 */
+| (env->sr & ((1u << SR_MD) | (1u << SR_RB)))  /* Bits 29-30 */
+| (env->sr & (1u << SR_FD))/* Bit 15 */
 | (env->movcal_backup ? TB_FLAG_PENDING_MOVCA : 0); /* Bit 4 */
 }
 
diff --git a/target-sh4/gdbstub.c b/target-sh4/gdbstub.c
index df4fa2a..05ba728 100644
--- a/target-sh4/gdbstub.c
+++ b/target-sh4/gdbstub.c
@@ -31,7 +31,7 @@ int superh_cpu_gdb_read_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 
 switch (n) {
 case 0 ... 7:
-if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
+if ((env->sr & (1u << SR_MD)) && (env->sr & (1u << SR_RB))) {
 return gdb_get_regl(mem_buf, env->gregs[n + 16]);
 } else {
 return gdb_get_regl(mem_buf, env->gregs[n]);
@@ -83,7 +83,7 @@ int superh_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 
 switch (n) {
 case 0 ... 7:
-if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
+if ((env->sr & (1u << SR_MD)) && (env->sr & (1u << SR_RB))) {
 env->gregs[n + 16] = ldl_p(mem_buf);
 } else {
 env->gregs[n] = ldl_p(mem_buf);
diff --git a/target-sh4/helper.c b/target-sh4/helper.c
index 9ac2825..07f8e91 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -93,7 +93,7 @@ void superh_cpu_do_interrupt(CPUState *cs)
 do_exp = env->exception_index != -1;
 do_irq = do_irq && (env->exception_index == -1);
 
-if (env->sr & SR_BL) {
+if (env->sr & (1u << SR_BL)) {
 if (do_exp && env->exception_index != 0x1e0) {
 env->exception_index = 0x000; /* masked exception -> reset */
 }
@@ -165,7 +165,7 @@ void superh_cpu_do_interrupt(CPUState *cs)
 env->ssr = env->sr;
 env->spc = env->pc;
 env->sgr = env->gregs[15];
-env->sr |= SR_BL | SR_MD | SR_RB;
+env->sr |= (1u << SR_BL) | (1u << SR_MD) | (1u << SR_RB);
 
 if (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
 /* Branch instruction should be executed again before delay slot. */
@@ -182,7 +182,7 @@ void superh_cpu_do_interrupt(CPUState *cs)
 case 0x000:
 

Re: [Qemu-devel] [PATCH 0/5] tcg/i386: use movbe instruction in qemu_ldst routines

2013-12-22 Thread Aurelien Jarno
And now I just realized you send such a patch before me. I am going to
review yours then.

On Sun, Dec 22, 2013 at 12:24:38PM +0100, Aurelien Jarno wrote:
> I forgot to Cc: Richard on this patch set, doing that now...
> 
> On Sat, Dec 21, 2013 at 05:43:39PM +0100, Aurelien Jarno wrote:
> > This patchset enable the usage of the movbe instruction, available on
> > Intel Atom and Intel Haswell CPU, in qemu_ldst routines, avoiding bswap
> > instructions before or after the store or loads. The availability of
> > this instruction is done at runtime using the cpuid instruction.
> > 
> > The last patch of the series is not fully related, but I spotted the
> > issue when working on this patchset, so I thought it's a good idea to
> > fix it.
> > 
> > Aurelien Jarno (5):
> >   disas/i386.c: disassemble movbe instruction
> >   tcg/i386: remove hardcoded P_REXW value
> >   tcg/i386: add support for three-byte opcodes
> >   tcg/i386: use movbe instruction in qemu_ldst routines
> >   tcg/i386: cleanup useless #ifdef
> > 
> >  disas/i386.c  |8 +--
> >  tcg/i386/tcg-target.c |  178 
> > ++---
> >  2 files changed, 128 insertions(+), 58 deletions(-)
> > 
> > -- 
> > 1.7.10.4
> > 
> > 
> 
> -- 
> Aurelien Jarno  GPG: 1024D/F1BCDB73
> aurel...@aurel32.net http://www.aurel32.net

-- 
Aurelien Jarno  GPG: 1024D/F1BCDB73
aurel...@aurel32.net http://www.aurel32.net



[Qemu-devel] [PATCH v2 8/9] target-sh4: remove dead code

2013-12-22 Thread Aurelien Jarno
Signed-off-by: Aurelien Jarno 
---
 target-sh4/translate.c |1 -
 1 file changed, 1 deletion(-)

diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 45eb839..9a878d0 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -18,7 +18,6 @@
  */
 
 #define DEBUG_DISAS
-//#define SH4_SINGLE_STEP
 
 #include "cpu.h"
 #include "disas/disas.h"
-- 
1.7.10.4




[Qemu-devel] [PATCH v2 7/9] target-sh4: factorize fmov implementation

2013-12-22 Thread Aurelien Jarno
Signed-off-by: Aurelien Jarno 
---
 target-sh4/translate.c |   18 ++
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index d4046f8..45eb839 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -1030,24 +1030,18 @@ static void _decode_opc(DisasContext * ctx)
return;
 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
CHECK_FPU_ENABLED
+   const int fr = XREG(B7_4);
+   TCGv addr = tcg_temp_new_i32();
+   tcg_gen_subi_i32(addr, REG(B11_8), 4);
 if (ctx->flags & FPSCR_SZ) {
-   TCGv addr = tcg_temp_new_i32();
-   int fr = XREG(B7_4);
-   tcg_gen_subi_i32(addr, REG(B11_8), 4);
 tcg_gen_qemu_st_i32(cpu_fregs[fr+1], addr, ctx->memidx, MO_TEUL);
tcg_gen_subi_i32(addr, addr, 4);
 tcg_gen_qemu_st_i32(cpu_fregs[fr], addr, ctx->memidx, MO_TEUL);
-   tcg_gen_mov_i32(REG(B11_8), addr);
-   tcg_temp_free(addr);
} else {
-   TCGv addr;
-   addr = tcg_temp_new_i32();
-   tcg_gen_subi_i32(addr, REG(B11_8), 4);
-tcg_gen_qemu_st_i32(cpu_fregs[FREG(B7_4)], addr,
-ctx->memidx, MO_TEUL);
-   tcg_gen_mov_i32(REG(B11_8), addr);
-   tcg_temp_free(addr);
+tcg_gen_qemu_st_i32(cpu_fregs[fr], addr, ctx->memidx, MO_TEUL);
}
+   tcg_gen_mov_i32(REG(B11_8), addr);
+   tcg_temp_free(addr);
return;
 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
CHECK_FPU_ENABLED
-- 
1.7.10.4




Re: [Qemu-devel] [PATCH] tcg-i386: Use MOVBE if available

2013-12-22 Thread Aurelien Jarno
On Sat, Dec 21, 2013 at 03:08:21PM +0100, Paolo Bonzini wrote:
> Il 21/12/2013 00:00, Richard Henderson ha scritto:
> > +if (real_bswap && have_movbe) {
> > +tcg_out_modrm_offset(s, OPC_MOVBE_GyMy + P_DATA16 + seg,
> > + datalo, base, ofs);
> > +tcg_out_ext16u(s, datalo, datalo);
> 
> Do partial register stalls still exist on Atom and Haswell?  I don't
> remember exactly what you had to do to prevent them, but IIRC you first
> moved zero to the register and then overwrote the the low 16 bits.

Note that for unsigned 16-bit load you can do either movzw + bswap or 
movbe + movzw.

-- 
Aurelien Jarno  GPG: 1024D/F1BCDB73
aurel...@aurel32.net http://www.aurel32.net



[Qemu-devel] [PATCH v2 4/9] target-sh4: optimize subc using sub2

2013-12-22 Thread Aurelien Jarno
Signed-off-by: Aurelien Jarno 
---
 target-sh4/translate.c |   15 ++-
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 31d47b3..21605b0 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -883,18 +883,15 @@ static void _decode_opc(DisasContext * ctx)
 case 0x300a:   /* subc Rm,Rn */
 {
 TCGv t0, t1, t2;
-t0 = tcg_temp_new();
+t0 = tcg_const_tl(0);
 t1 = tcg_temp_new();
-tcg_gen_sub_i32(t1, REG(B11_8), REG(B7_4));
-tcg_gen_sub_i32(t0, t1, cpu_sr_t);
 t2 = tcg_temp_new();
-tcg_gen_setcond_i32(TCG_COND_LTU, t2, REG(B11_8), t1);
-tcg_gen_setcond_i32(TCG_COND_LTU, t1, t1, t0);
-tcg_gen_or_i32(cpu_sr_t, t1, t2);
-tcg_temp_free(t2);
-tcg_temp_free(t1);
-tcg_gen_mov_i32(REG(B11_8), t0);
+tcg_gen_sub2_i32(t1, t2, REG(B11_8), t0, REG(B7_4), t0);
+tcg_gen_sub2_i32(REG(B11_8), cpu_sr_t, t1, t2, cpu_sr_t, t0);
+tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
 tcg_temp_free(t0);
+tcg_temp_free(t1);
+tcg_temp_free(t2);
 }
return;
 case 0x300b:   /* subv Rm,Rn */
-- 
1.7.10.4




[Qemu-devel] [PATCH v2 0/9] target-sh4: optimizations and cleanups

2013-12-22 Thread Aurelien Jarno
This patchset improves the SH4 emulation by using the lately added
TCG instructions, namely add2, sub2 and movcond. For that the T, Q and
M bits are split out from the SR register.

The last three patches are doing cleanup in the code.

Changes v1 -> v2:
- rebased
- added last patch

Aurelien Jarno (9):
  target-sh4: use bit number for SR constants
  target-sh4: Split out T from SR
  target-sh4: optimize addc using add2
  target-sh4: optimize subc using sub2
  target-sh4: optimize negc using add2 and sub2
  target-sh4: split out Q and M from of SR and optimize div1
  target-sh4: factorize fmov implementation
  target-sh4: remove dead code
  target-sh4: simplify tas instruction

 target-sh4/cpu.c   |3 +-
 target-sh4/cpu.h   |   51 +---
 target-sh4/gdbstub.c   |8 +-
 target-sh4/helper.c|   29 ++---
 target-sh4/helper.h|1 -
 target-sh4/op_helper.c |  148 +--
 target-sh4/translate.c |  313 
 7 files changed, 221 insertions(+), 332 deletions(-)

--
1.7.10.4




Re: [Qemu-devel] [PATCH] target-ppc: fix VSX extension TCG code

2013-12-22 Thread Alexander Graf


> Am 22.12.2013 um 12:26 schrieb Aurelien Jarno :
> 
> The VSX TCG code is using _i64 types mixed wiht _tl types. While this
> is correct for 64-bit targets, this breaks the compilation with 32-bit
> targets and --enable-debug-tcg.
> 
> This patch fixes that by always using the correct type. Note that we can
> probably do better for the load/stores using the new load/store TCG
> instructions, but that would need changes to other places of the code,
> while this patch intents to be a bug fix patch only.
> 
> Cc: Tom Musta 
> Cc: Alexander Graf 
> Signed-off-by: Aurelien Jarno 

I've sent a similar patch last week. Would you mind to review that one and 
maybe ack it?

Thanks a lot!

Alex




Re: [Qemu-devel] [PATCH] tcg-i386: Use MOVBE if available

2013-12-22 Thread Paolo Bonzini
Il 22/12/2013 13:24, Aurelien Jarno ha scritto:
> On Sat, Dec 21, 2013 at 03:08:21PM +0100, Paolo Bonzini wrote:
>> Il 21/12/2013 00:00, Richard Henderson ha scritto:
>>> +if (real_bswap && have_movbe) {
>>> +tcg_out_modrm_offset(s, OPC_MOVBE_GyMy + P_DATA16 + seg,
>>> + datalo, base, ofs);
>>> +tcg_out_ext16u(s, datalo, datalo);
>>
>> Do partial register stalls still exist on Atom and Haswell?  I don't
>> remember exactly what you had to do to prevent them, but IIRC you first
>> moved zero to the register and then overwrote the the low 16 bits.
> 
> Note that for unsigned 16-bit load you can do either movzw + bswap or 
> movbe + movzw.

Yeah, I was asking if xor + movbe would be faster.  Benchmarking could
tell, but anyway xor + movbe is likely the smallest code you can produce.

Paolo




Re: [Qemu-devel] [PATCH v2] qdev: Keep global allocation counter per bus

2013-12-22 Thread Paolo Bonzini
Il 21/12/2013 11:42, Markus Armbruster ha scritto:
> Suggest to add: ", killing migration."

Not good.  But perhaps we can give a reason for this 2.0 thing.

It is certainly nice to schedule incompatible changes for obscure
machine types every 2 years.

> Which boards are affected?  Should be listed in the commit message!
> 
> I ran a quick test for all boards that actually make it to the monitor
> without special parameters or files, and survive "info qtree".  164
> boards can do that, 59 refuse to start, one crashes on start, 10 make it
> to the monitor but crash in info qtree.  Not nice.  If there's a way to
> start *any* board to the monitor, please let me know.

"-machine accel=qtest" probably helps with those that refuse to start.

Paolo

> Anyway, I found the following machines sporting non-unique bus names
> before your patch:
> 
> target  machine bus id  times
> aarch64 n800i2c-bus.0   2
> aarch64 n810i2c-bus.0   2
> aarch64 nurii2c 9
> aarch64 smdkc210i2c 9
> aarch64 vexpress-a15virtio-mmio-bus.0   4
> aarch64 vexpress-a9 virtio-mmio-bus.0   4
> aarch64 virtvirtio-mmio-bus.0   32
> aarch64 xilinx-zynq-a9  usb-bus.0   2
> aarch64 xilinx-zynq-a9  spi03
> arm n800i2c-bus.0   2
> arm n810i2c-bus.0   2
> arm nurii2c 9
> arm smdkc210i2c 9
> arm vexpress-a15virtio-mmio-bus.0   4
> arm vexpress-a9 virtio-mmio-bus.0   4
> arm virtvirtio-mmio-bus.0   32
> arm xilinx-zynq-a9  usb-bus.0   2
> arm xilinx-zynq-a9  spi03
> i386isapc   ide.0   2
> mipsmipside.0   2
> mips64  mipside.0   2
> mips64elmipside.0   2
> mipsel  mipside.0   2
> ppc g3beige ide.0   2
> ppc mac99   ide.0   2
> ppc prepide.0   2
> ppc64   g3beige ide.0   2
> ppc64   mac99   ide.0   2
> ppc64   prepide.0   2
> x86_64  isapc   ide.0   2
> 
> The isapc crash with v1 demonstrates that such machines need testing
> with your patch.
> 
> Not yet covered:
> 
> target  machine reason
> aarch64 akita   info qtree crashes
> aarch64 borzoi  info qtree crashes
> aarch64 canon-a1100 refuses to start
> aarch64 cheetah refuses to start
> aarch64 connex  refuses to start
> aarch64 lm3s6965evb refuses to start
> aarch64 lm3s811evb  refuses to start
> aarch64 mainstone   refuses to start
> aarch64 spitz   info qtree crashes
> aarch64 sx1 refuses to start
> aarch64 sx1-v1  refuses to start
> aarch64 terrier info qtree crashes
> aarch64 tosainfo qtree crashes
> aarch64 verdex  refuses to start
> aarch64 z2  refuses to start
> arm akita   info qtree crashes
> arm borzoi  info qtree crashes
> arm canon-a1100 refuses to start
> arm cheetah refuses to start
> arm connex  refuses to start
> arm lm3s6965evb refuses to start
> arm lm3s811evb  refuses to start
> arm mainstone   refuses to start
> arm spitz   info qtree crashes
> arm sx1 refuses to start
> arm sx1-v1  refuses to start
> arm terrier info qtree crashes
> arm tosainfo qtree crashes
> arm verdex  refuses to start
> arm z2  refuses to start
> crisaxis-dev88  refuses to start
> i386xenfv   refuses to start
> i386xenpv   refuses to start
> lm32milkymist   refuses to start
> m68kan5206  refuses to start
> m68kmcf5208evb  refuses to start
> mipsmagnum  refuses to start
> mipsmalta   refuses to start
> mipsmipssim refuses to start
> mipspica61  refuses to start
> mips64  magnum  refuses to start
> mips64  malta   refuses to start
> mips64  mipssim refuses to start
> mips64  pica61  r

[Qemu-devel] [PATCH v2] scsi-disk: add UNMAP limits to block limits VPD page

2013-12-22 Thread Paolo Bonzini
Linux prefers WRITE SAME to UNMAP if the limits are zero, and WRITE
SAME does not discard anything unless the device can guarantee that
the resulting block is zero.

Setting the maximum unmap block and descriptor counts to non-zero
makes Linux choose UNMAP and fixes thin provisioning on glusterfs.

While the maximum unmap block count can have some effect on performance,
the (suggested) maximum number of descriptors is not particularly
important so I didn't add a customization option.  SCSI drivers are
used to online firmware updates so I'm not yet adding versioning support
for SCSI, but we're probably getting close to the point when it's worth
thinking about it.

Reported-by: Bharata B Rao 
Signed-off-by: Paolo Bonzini 
---
 hw/scsi/scsi-disk.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 7653411..f6c 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -47,6 +47,7 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
 #define SCSI_MAX_MODE_LEN   256
 
 #define DEFAULT_DISCARD_GRANULARITY 4096
+#define DEFAULT_MAX_UNMAP_SIZE  (1 << 30)   /* 1 GB */
 
 typedef struct SCSIDiskState SCSIDiskState;
 
@@ -74,6 +75,7 @@ struct SCSIDiskState
 bool media_event;
 bool eject_request;
 uint64_t wwn;
+uint64_t max_unmap_size;
 QEMUBH *bh;
 char *version;
 char *serial;
@@ -625,6 +627,8 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, 
uint8_t *outbuf)
 s->qdev.conf.min_io_size / s->qdev.blocksize;
 unsigned int opt_io_size =
 s->qdev.conf.opt_io_size / s->qdev.blocksize;
+unsigned int max_unmap_sectors =
+s->max_unmap_size / s->qdev.blocksize;
 
 if (s->qdev.type == TYPE_ROM) {
 DPRINTF("Inquiry (EVPD[%02X] not supported for CDROM\n",
@@ -647,6 +651,18 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, 
uint8_t *outbuf)
 outbuf[14] = (opt_io_size >> 8) & 0xff;
 outbuf[15] = opt_io_size & 0xff;
 
+/* max unmap LBA count, hardcoded to 1GB */
+outbuf[20] = (max_unmap_sectors >> 24) & 0xff;
+outbuf[21] = (max_unmap_sectors >> 16) & 0xff;
+outbuf[22] = (max_unmap_sectors >> 8) & 0xff;
+outbuf[23] = max_unmap_sectors & 0xff;
+
+/* max unmap descriptors, 255 fit in 4 kb with an 8-byte header.  
*/
+outbuf[24] = 0;
+outbuf[25] = 0;
+outbuf[26] = 0;
+outbuf[27] = 255;
+
 /* optimal unmap granularity */
 outbuf[28] = (unmap_sectors >> 24) & 0xff;
 outbuf[29] = (unmap_sectors >> 16) & 0xff;
@@ -2519,6 +2535,8 @@ static Property scsi_hd_properties[] = {
 DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
 SCSI_DISK_F_DPOFUA, false),
 DEFINE_PROP_HEX64("wwn", SCSIDiskState, wwn, 0),
+DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
+   DEFAULT_MAX_UNMAP_SIZE),
 DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
 DEFINE_PROP_END_OF_LIST(),
 };
@@ -2628,6 +2646,8 @@ static Property scsi_disk_properties[] = {
 DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
 SCSI_DISK_F_DPOFUA, false),
 DEFINE_PROP_HEX64("wwn", SCSIDiskState, wwn, 0),
+DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
+   DEFAULT_MAX_UNMAP_SIZE),
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
1.8.4.2




[Qemu-devel] [PULL v2 0/2] SCSI changes for 2013-12-22

2013-12-22 Thread Paolo Bonzini
Anthony,

The following changes since commit e157b8fdd412d48eacfbb8c67d3d58780154faa3:

  Merge remote-tracking branch 'bonzini/virtio' into staging (2013-12-13 
11:10:33 -0800)

are available in the git repository at:


  git://github.com/bonzini/qemu.git scsi-next

for you to fetch changes up to 8a1bd2973ed5f99a3c37c9afdff823c4a22152b1:

  scsi-disk: add UNMAP limits to block limits VPD page (2013-12-22 14:59:33 
+0100)

Includes a new version of the scsi-disk patch.


Paolo Bonzini (1):
  scsi-disk: add UNMAP limits to block limits VPD page

Peter Lieven (1):
  block/iscsi: use a bh to schedule co reentrance

 block/iscsi.c   | 11 ++-
 hw/scsi/scsi-disk.c | 20 
 2 files changed, 30 insertions(+), 1 deletion(-)
-- 
1.8.4.2




[Qemu-devel] [PULL v2 1/2] block/iscsi: use a bh to schedule co reentrance

2013-12-22 Thread Paolo Bonzini
From: Peter Lieven 

this fixes a potential segfault and performance regression.

If the coroutine is reentered directly in the iscsi_co_generic_cb
iscsi_process_{read,write} are interrupted and reentered any
time later. One the one hand this could happen after an iscsi_close
where the iscsi context is already gone (segfault). On the
other hand this limits the number of processed callbacks
in each aio_dispatch to one (potential performance regression).

Cc: qemu-sta...@nongnu.org
Signed-off-by: Peter Lieven 
Signed-off-by: Paolo Bonzini 
---
 block/iscsi.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/block/iscsi.c b/block/iscsi.c
index fa69408..b0e6eea 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -68,6 +68,7 @@ typedef struct IscsiTask {
 int do_retry;
 struct scsi_task *task;
 Coroutine *co;
+QEMUBH *bh;
 } IscsiTask;
 
 typedef struct IscsiAIOCB {
@@ -123,6 +124,13 @@ iscsi_schedule_bh(IscsiAIOCB *acb)
 qemu_bh_schedule(acb->bh);
 }
 
+static void iscsi_co_generic_bh_cb(void *opaque)
+{
+struct IscsiTask *iTask = opaque;
+qemu_bh_delete(iTask->bh);
+qemu_coroutine_enter(iTask->co, NULL);
+}
+
 static void
 iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
 void *command_data, void *opaque)
@@ -147,7 +155,8 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
 
 out:
 if (iTask->co) {
-qemu_coroutine_enter(iTask->co, NULL);
+iTask->bh = qemu_bh_new(iscsi_co_generic_bh_cb, iTask);
+qemu_bh_schedule(iTask->bh);
 }
 }
 
-- 
1.8.4.2





[Qemu-devel] [PULL v2 2/2] scsi-disk: add UNMAP limits to block limits VPD page

2013-12-22 Thread Paolo Bonzini
Linux prefers WRITE SAME to UNMAP if the limits are zero, and WRITE
SAME does not discard anything unless the device can guarantee that
the resulting block is zero.

Setting the maximum unmap block and descriptor counts to non-zero
makes Linux choose UNMAP and fixes thin provisioning on glusterfs.

While the maximum unmap block count can have some effect on performance,
the (suggested) maximum number of descriptors is not particularly
important so I didn't add a customization option.  SCSI drivers are
used to online firmware updates so I'm not yet adding versioning support
for SCSI, but we're probably getting close to the point when it's worth
thinking about it.

Reported-by: Bharata B Rao 
Signed-off-by: Paolo Bonzini 
---
 hw/scsi/scsi-disk.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 7653411..f6c 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -47,6 +47,7 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
 #define SCSI_MAX_MODE_LEN   256
 
 #define DEFAULT_DISCARD_GRANULARITY 4096
+#define DEFAULT_MAX_UNMAP_SIZE  (1 << 30)   /* 1 GB */
 
 typedef struct SCSIDiskState SCSIDiskState;
 
@@ -74,6 +75,7 @@ struct SCSIDiskState
 bool media_event;
 bool eject_request;
 uint64_t wwn;
+uint64_t max_unmap_size;
 QEMUBH *bh;
 char *version;
 char *serial;
@@ -625,6 +627,8 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, 
uint8_t *outbuf)
 s->qdev.conf.min_io_size / s->qdev.blocksize;
 unsigned int opt_io_size =
 s->qdev.conf.opt_io_size / s->qdev.blocksize;
+unsigned int max_unmap_sectors =
+s->max_unmap_size / s->qdev.blocksize;
 
 if (s->qdev.type == TYPE_ROM) {
 DPRINTF("Inquiry (EVPD[%02X] not supported for CDROM\n",
@@ -647,6 +651,18 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, 
uint8_t *outbuf)
 outbuf[14] = (opt_io_size >> 8) & 0xff;
 outbuf[15] = opt_io_size & 0xff;
 
+/* max unmap LBA count, default is 1GB */
+outbuf[20] = (max_unmap_sectors >> 24) & 0xff;
+outbuf[21] = (max_unmap_sectors >> 16) & 0xff;
+outbuf[22] = (max_unmap_sectors >> 8) & 0xff;
+outbuf[23] = max_unmap_sectors & 0xff;
+
+/* max unmap descriptors, 255 fit in 4 kb with an 8-byte header.  
*/
+outbuf[24] = 0;
+outbuf[25] = 0;
+outbuf[26] = 0;
+outbuf[27] = 255;
+
 /* optimal unmap granularity */
 outbuf[28] = (unmap_sectors >> 24) & 0xff;
 outbuf[29] = (unmap_sectors >> 16) & 0xff;
@@ -2519,6 +2535,8 @@ static Property scsi_hd_properties[] = {
 DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
 SCSI_DISK_F_DPOFUA, false),
 DEFINE_PROP_HEX64("wwn", SCSIDiskState, wwn, 0),
+DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
+   DEFAULT_MAX_UNMAP_SIZE),
 DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
 DEFINE_PROP_END_OF_LIST(),
 };
@@ -2628,6 +2646,8 @@ static Property scsi_disk_properties[] = {
 DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
 SCSI_DISK_F_DPOFUA, false),
 DEFINE_PROP_HEX64("wwn", SCSIDiskState, wwn, 0),
+DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
+   DEFAULT_MAX_UNMAP_SIZE),
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
1.8.4.2




Re: [Qemu-devel] [PATCH 2/2] ppc-e500: implement PCI INTx routing

2013-12-22 Thread Alexander Graf


> Am 22.12.2013 um 12:31 schrieb "Michael S. Tsirkin" :
> 
>> On Fri, Dec 20, 2013 at 11:31:17AM +0100, Alexander Graf wrote:
>> 
>>> On 20.12.2013, at 10:42, Bharat Bhushan  wrote:
>>> 
>>> This patch adds pci pin to irq_num routing callback.
>>> This callback is called from pci_device_route_intx_to_irq to find which pci 
>>> device
>>> maps to which irq. This is used for pci-device passthrough using vfio.
>>> 
>>> Also without this patch we gets below warning
>>> 
>>> "
>>> PCI: Bug - unimplemented PCI INTx routing (e500-pcihost)
>>> qemu-system-ppc64: PCI: Bug - unimplemented PCI INTx routing (e500-pcihost)
>>> "
>>> and Legacy interrupt does not work with pci device passthrough.
>>> 
>>> Signed-off-by: Bharat Bhushan 
>>> Acked-by: Michael S. Tsirkin 
>>> ---
>>> hw/pci-host/ppce500.c |   20 ++--
>>> 1 files changed, 18 insertions(+), 2 deletions(-)
>>> 
>>> diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
>>> index 71e5ca9..ffea782 100644
>>> --- a/hw/pci-host/ppce500.c
>>> +++ b/hw/pci-host/ppce500.c
>>> @@ -88,6 +88,7 @@ struct PPCE500PCIState {
>>>struct pci_inbound pib[PPCE500_PCI_NR_PIBS];
>>>uint32_t gasket_time;
>>>qemu_irq irq[PCI_NUM_PINS];
>>> +uint32_t irq_num[PCI_NUM_PINS];
>>>uint32_t first_slot;
>>>/* mmio maps */
>>>MemoryRegion container;
>>> @@ -267,13 +268,26 @@ static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, 
>>> int pin)
>>> 
>>> static void mpc85xx_pci_set_irq(void *opaque, int pin, int level)
>>> {
>>> -qemu_irq *irq = opaque;
>>> +PPCE500PCIState *s = opaque;
>>> +qemu_irq *pic = s->irq;
>>> 
>>>pci_debug("%s: PCI irq %d, level:%d\n", __func__, pin , level);
>>> 
>>>qemu_set_irq(irq[pin], level);
>>> }
>>> 
>>> +static PCIINTxRoute e500_route_intx_pin_to_irq(void *opaque, int pin)
>>> +{
>>> +PCIINTxRoute route;
>>> +PPCE500PCIState *s = opaque;
>>> +
>>> +route.mode = PCI_INTX_ENABLED;
>>> +route.irq = s->irq_num[pin];
>>> +
>>> +pci_debug("%s: PCI irq-pin = %d, irq_num= %d\n", __func__, pin, 
>>> route.irq);
>>> +return route;
>>> +}
>>> +
>>> static const VMStateDescription vmstate_pci_outbound = {
>>>.name = "pci_outbound",
>>>.version_id = 0,
>>> @@ -350,12 +364,13 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
>>> 
>>>for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
>>>sysbus_init_irq(dev, &s->irq[i]);
>>> +s->irq_num[i] = i + 1;
>> 
>> I still don't like how you duplicate the logic which MPIC irq line is 
>> associated with which pci host controller irq line. Please pass this 
>> information into the pcihost object somehow from ppce500_init() so that it's 
>> only at a single spot.
>> 
>> If you like, you can just use qom/qdev properties for that, but it needs to 
>> be configured from the outside.
>> 
>> 
>> Alex
> 
> 
> Maybe just call ppce500_pci_map_irq_slot instead of using irq_num?

That'd be a step into the wrong direction. Wiring is a configuration thing.

Alex

> 
> 



[Qemu-devel] [PATCH] mainstone: Fix duplicate array values for key 'space'

2013-12-22 Thread Stefan Weil
cgcc reported a duplicate initialisation. Mainstone includes a matrix
keyboard where two different positions map to 'space'.

QEMU uses the reversed mapping and cannot map 'space' to two different
matrix positions.

Signed-off-by: Stefan Weil 
---

Of course we could also randomly select one of the two matrix positions,
but I assume that this is not necessary.

I don't know any mainstone internals, so I had to look into the Linux
code where I noticed some discrepancies which should be clarified:

Extract from Linux:

KEY(1, 5, KEY_LEFTSHIFT),
KEY(2, 5, KEY_SPACE),
KEY(3, 5, KEY_SPACE),
KEY(4, 5, KEY_ENTER),
KEY(5, 5, KEY_BACKSPACE),

Extract from QEMU:

[0x2a] = {5,1}, /* shift */
[0x39] = {5,2}, /* space */
[0x39] = {5,3}, /* space */
[0x1c] = {5,5}, /*  enter */

It looks like the 'enter' key is not mapped correctly,
and 'backspace' is missing.

Regards,
Stefan

 hw/arm/mainstone.c |2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index 9402c84..223a4b1 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -76,7 +76,9 @@ static struct keymap map[0xE0] = {
 [0xc7] = {5,0}, /* Home */
 [0x2a] = {5,1}, /* shift */
 [0x39] = {5,2}, /* space */
+#if 0 /* always map to first column, row pair */
 [0x39] = {5,3}, /* space */
+#endif
 [0x1c] = {5,5}, /*  enter */
 [0xc8] = {6,0}, /* up */
 [0xd0] = {6,1}, /* down */
-- 
1.7.10.4




[Qemu-devel] [PATCH] pxa27x: Add 'const' attribute to keyboard maps

2013-12-22 Thread Stefan Weil
The mapping is a hardware feature, so it is relatively constant.

Signed-off-by: Stefan Weil 
---
 hw/arm/mainstone.c   |2 +-
 hw/arm/z2.c  |2 +-
 hw/input/pxa2xx_keypad.c |6 +++---
 include/hw/arm/pxa.h |4 ++--
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index 223a4b1..082627e 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -45,7 +45,7 @@
 #define S1_STSCHG_IRQ 14
 #define S1_IRQ15
 
-static struct keymap map[0xE0] = {
+static const struct keymap map[0xE0] = {
 [0 ... 0xDF] = { -1, -1 },
 [0x1e] = {0,0}, /* a */
 [0x30] = {0,1}, /* b */
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index d52c501..97367b1 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -33,7 +33,7 @@
 #define DPRINTF(fmt, ...)
 #endif
 
-static struct keymap map[0x100] = {
+static const struct keymap map[0x100] = {
 [0 ... 0xff] = { -1, -1 },
 [0x3b] = {0, 0}, /* Option = F1 */
 [0xc8] = {0, 1}, /* Up */
diff --git a/hw/input/pxa2xx_keypad.c b/hw/input/pxa2xx_keypad.c
index 846d137..b90b0ba 100644
--- a/hw/input/pxa2xx_keypad.c
+++ b/hw/input/pxa2xx_keypad.c
@@ -85,7 +85,7 @@
 struct PXA2xxKeyPadState {
 MemoryRegion iomem;
 qemu_irqirq;
-struct  keymap *map;
+const struct  keymap *map;
 int pressed_cnt;
 int alt_code;
 
@@ -322,8 +322,8 @@ PXA2xxKeyPadState *pxa27x_keypad_init(MemoryRegion *sysmem,
 return s;
 }
 
-void pxa27x_register_keypad(PXA2xxKeyPadState *kp, struct keymap *map,
-int size)
+void pxa27x_register_keypad(PXA2xxKeyPadState *kp,
+const struct keymap *map, int size)
 {
 if(!map || size < 0x80) {
 fprintf(stderr, "%s - No PXA keypad map defined\n", __FUNCTION__);
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
index a4e1a66..d146c58 100644
--- a/include/hw/arm/pxa.h
+++ b/include/hw/arm/pxa.h
@@ -109,8 +109,8 @@ typedef struct PXA2xxKeyPadState PXA2xxKeyPadState;
 PXA2xxKeyPadState *pxa27x_keypad_init(MemoryRegion *sysmem,
   hwaddr base,
   qemu_irq irq);
-void pxa27x_register_keypad(PXA2xxKeyPadState *kp, struct keymap *map,
-int size);
+void pxa27x_register_keypad(PXA2xxKeyPadState *kp,
+const struct keymap *map, int size);
 
 /* pxa2xx.c */
 typedef struct PXA2xxI2CState PXA2xxI2CState;
-- 
1.7.10.4




Re: [Qemu-devel] [PATCH v2] scsi-disk: add UNMAP limits to block limits VPD page

2013-12-22 Thread Bharata B Rao
On Sun, Dec 22, 2013 at 02:57:27PM +0100, Paolo Bonzini wrote:
> Linux prefers WRITE SAME to UNMAP if the limits are zero, and WRITE
> SAME does not discard anything unless the device can guarantee that
> the resulting block is zero.
> 
> Setting the maximum unmap block and descriptor counts to non-zero
> makes Linux choose UNMAP and fixes thin provisioning on glusterfs.
> 
> While the maximum unmap block count can have some effect on performance,
> the (suggested) maximum number of descriptors is not particularly
> important so I didn't add a customization option.  SCSI drivers are
> used to online firmware updates so I'm not yet adding versioning support
> for SCSI, but we're probably getting close to the point when it's worth
> thinking about it.
> 
> Reported-by: Bharata B Rao 
> Signed-off-by: Paolo Bonzini 

This patch fixes thin provisioning on gluster.

Tested-by: Bharata B Rao 

Regards,
Bharata.




[Qemu-devel] [PATCH] pxa27x: Reduce size of keyboard matrix mapping

2013-12-22 Thread Stefan Weil
The row and column values use only a very limited range (-1 ... 7),
so a byte value is sufficient.

Signed-off-by: Stefan Weil 
---
 include/hw/arm/pxa.h |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
index d146c58..7ca330a 100644
--- a/include/hw/arm/pxa.h
+++ b/include/hw/arm/pxa.h
@@ -102,8 +102,8 @@ void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, 
qemu_irq cd_irq);
 
 /* pxa2xx_keypad.c */
 struct  keymap {
-int column;
-int row;
+int8_t column;
+int8_t row;
 };
 typedef struct PXA2xxKeyPadState PXA2xxKeyPadState;
 PXA2xxKeyPadState *pxa27x_keypad_init(MemoryRegion *sysmem,
-- 
1.7.10.4




Re: [Qemu-devel] vhost-net issue: does not survive reboot on ppc64

2013-12-22 Thread Alexey Kardashevskiy
On 12/22/2013 09:56 PM, Michael S. Tsirkin wrote:
> On Sun, Dec 22, 2013 at 02:01:23AM +1100, Alexey Kardashevskiy wrote:
>> Hi!
>>
>> I am having a problem with virtio-net + vhost on POWER7 machine - it does
>> not survive reboot of the guest.
>>
>> Steps to reproduce:
>> 1. boot the guest
>> 2. configure eth0 and do ping - everything works
>> 3. reboot the guest (i.e. type "reboot")
>> 4. when it is booted, eth0 can be configured but will not work at all.
>>
>> The test is:
>> ifconfig eth0 172.20.1.2 up
>> ping 172.20.1.23
>>
>> If to run tcpdump on the host's "tap-id3" interface, it shows no trafic
>> coming from the guest. If to compare how it works before and after reboot,
>> I can see the guest doing an ARP request for 172.20.1.23 and receives the
>> response and it does the same after reboot but the answer does not come.
> 
> So you see the arp packet in guest but not in host?

Yes.


> One thing to try is to boot debug kernel - where pr_debug is
> enabled - then you might see some errors in the kernel log.

Tried and added lot more debug printk myself, not clear at all what is
happening there.

One more hint - if I boot the guest and the guest does not bring eth0 up
AND wait more than 200 seconds (and less than 210 seconds), then eth0 will
not work at all. I.e. this script produces not-working-eth0:


ifconfig eth0 172.20.1.2 down
sleep 210
ifconfig eth0 172.20.1.2 up
ping 172.20.1.23

s/210/200/ - and it starts working. No reboot is required to reproduce.

No "vhost" == always works. The only difference I can see here is vhost's
thread which may get suspended if not used for a while after the start and
does not wake up but this is almost a blind guess.



>> If to remove vhost=on, it is all good. If to try Fedora19
>> (v3.10-something), it all good again - works before and after reboot.
>>
>>
>> And there 2 questions:
>>
>> 1. does anybody have any clue what might go wrong after reboot?
>>
>> 2. Is there any good material to read about what exactly and how vhost
>> accelerates?
>>
>> My understanding is that packets from the guest to the real network are
>> going as:
>> 1. guest's virtio-pci-net does ioport(VIRTIO_PCI_QUEUE_NOTIFY)
>> 2. QEMU's net/virtio-net.c calls qemu_net_queue_deliver()
>> 3. QEMU's net/tap.c calls tap_write_packet() and this is how the host knows
>> that there is a new packet.


What about the documentation? :) or the idea?


>>
>>
>> Thanks!
>>
>>
>> This how I run QEMU:
>> ./qemu-system-ppc64 \
>> -enable-kvm \
>> -m 2048 \
>> -machine pseries \
>> -initrd 1.cpio \
>> -kernel vml312_virtio_net_dbg \
>> -nographic \
>> -vga none \
>> -netdev
>> tap,id=id3,ifname=tap-id3,script=ifup.sh,downscript=ifdown.sh,vhost=on \
>> -device virtio-net-pci,id=id4,netdev=id3,mac=C0:41:49:4b:00:00
>>
>>
>> That is bridge config:
>> [aik@dyn232 ~]$ brctl show
>> bridge name  bridge id   STP enabled interfaces
>> brtest   8000.00145e992e88   no  pin eth4
>>
>>
>> The ifup.sh script:
>> ifconfig $1 hw ether ee:01:02:03:04:05
>> /sbin/ifconfig $1 up
>> /usr/sbin/brctl addif brtest $1


-- 
Alexey



Re: [Qemu-devel] vhost-net issue: does not survive reboot on ppc64

2013-12-22 Thread Alexey Kardashevskiy
On 12/22/2013 10:41 PM, Zhi Yong Wu wrote:
> On Sat, Dec 21, 2013 at 11:01 PM, Alexey Kardashevskiy  wrote:
>> Hi!
> HI, Alexey
> 
>>
>> I am having a problem with virtio-net + vhost on POWER7 machine - it does
>> not survive reboot of the guest.
> Can you let me login to your environment for debug? I am interested in
> trying to fix this issue.


You do not need my environment, just make sure your guest does not bring
the virtio's ethernet up, wait for 4 minutes and try to bring it up and use
(ping, for example). Any POWER7, POWER8 machine should be able to reproduce it.



> 
>>
>> Steps to reproduce:
>> 1. boot the guest
>> 2. configure eth0 and do ping - everything works
>> 3. reboot the guest (i.e. type "reboot")
>> 4. when it is booted, eth0 can be configured but will not work at all.
>>
>> The test is:
>> ifconfig eth0 172.20.1.2 up
>> ping 172.20.1.23
>>
>> If to run tcpdump on the host's "tap-id3" interface, it shows no trafic
>> coming from the guest. If to compare how it works before and after reboot,
>> I can see the guest doing an ARP request for 172.20.1.23 and receives the
>> response and it does the same after reboot but the answer does not come.
>>
>> If to remove vhost=on, it is all good. If to try Fedora19
>> (v3.10-something), it all good again - works before and after reboot.
>>
>>
>> And there 2 questions:
>>
>> 1. does anybody have any clue what might go wrong after reboot?
>>
>> 2. Is there any good material to read about what exactly and how vhost
>> accelerates?
>>
>> My understanding is that packets from the guest to the real network are
>> going as:
>> 1. guest's virtio-pci-net does ioport(VIRTIO_PCI_QUEUE_NOTIFY)
>> 2. QEMU's net/virtio-net.c calls qemu_net_queue_deliver()
>> 3. QEMU's net/tap.c calls tap_write_packet() and this is how the host knows
>> that there is a new packet.
>>
>>
>> Thanks!
>>
>>
>> This how I run QEMU:
>> ./qemu-system-ppc64 \
>> -enable-kvm \
>> -m 2048 \
>> -machine pseries \
>> -initrd 1.cpio \
>> -kernel vml312_virtio_net_dbg \
>> -nographic \
>> -vga none \
>> -netdev
>> tap,id=id3,ifname=tap-id3,script=ifup.sh,downscript=ifdown.sh,vhost=on \
>> -device virtio-net-pci,id=id4,netdev=id3,mac=C0:41:49:4b:00:00
>>
>>
>> That is bridge config:
>> [aik@dyn232 ~]$ brctl show
>> bridge name bridge id   STP enabled interfaces
>> brtest  8000.00145e992e88   no  pin eth4
>>
>>
>> The ifup.sh script:
>> ifconfig $1 hw ether ee:01:02:03:04:05
>> /sbin/ifconfig $1 up
>> /usr/sbin/brctl addif brtest $1


-- 
Alexey



[Qemu-devel] [PATCH] virtio: Fix return value for dummy function vhost_net_virtqueue_pending

2013-12-22 Thread Stefan Weil
cgcc complains that -ENOSYS is not a good value for 'bool'.

A dummy virtio will never have pending queue entries, so let us return
false.

Signed-off-by: Stefan Weil 
---

Could we also use g_assert_not_reached or hw_error in those dummy functions?

Regards
Stefan

 hw/net/vhost_net.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 006576d..854997d 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -321,7 +321,7 @@ void vhost_net_ack_features(struct vhost_net *net, unsigned 
features)
 
 bool vhost_net_virtqueue_pending(VHostNetState *net, int idx)
 {
-return -ENOSYS;
+return false;
 }
 
 void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
-- 
1.7.10.4




Re: [Qemu-devel] [PATCH 09/11] ACPI: move PRST OperationRegion into SSDT

2013-12-22 Thread Igor Mammedov
On Mon, 16 Dec 2013 21:53:07 +0200
"Michael S. Tsirkin"  wrote:

> On Fri, Dec 13, 2013 at 05:22:14PM +0100, Igor Mammedov wrote:
> > .. and report range used by it to OSPM via _CRS.
> > PRST is needed in SSDT since its base will depend on
> > chipset and will be dynamically set by QEMU.
> > Also move PRSC() method along with PRST since cross
> > table reference to PRST doesn't work.
> > 
> > Signed-off-by: Igor Mammedov 
> > ---
> >  hw/i386/acpi-dsdt-cpu-hotplug.dsl | 39 +--
> >  hw/i386/acpi-dsdt.dsl |  2 +-
> >  hw/i386/q35-acpi-dsdt.dsl |  2 +-
> >  hw/i386/ssdt-misc.dsl | 65 
> > +++
> >  4 files changed, 68 insertions(+), 40 deletions(-)
> > 
> > diff --git a/hw/i386/acpi-dsdt-cpu-hotplug.dsl 
> > b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
> > index 995b415..f26f81b 100644
> > --- a/hw/i386/acpi-dsdt-cpu-hotplug.dsl
> > +++ b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
> > @@ -20,6 +20,7 @@
> >  Scope(\_SB) {
> >  /* Objects filled in by run-time generated SSDT */
> >  External(NTFY, MethodObj)
> > +External(\_SB.CPHD.PRSC, MethodObj)
> >  External(CPON, PkgObj)
> >  
> >  /* Methods called by run-time generated SSDT Processor objects */
> > @@ -51,42 +52,4 @@ Scope(\_SB) {
> >  // _EJ0 method - eject callback
> >  Sleep(200)
> >  }
> > -
> > -OperationRegion(PRST, SystemIO, 0xaf00, 32)
> > -Field(PRST, ByteAcc, NoLock, Preserve) {
> > -PRS, 256
> > -}
> > -Method(PRSC, 0) {
> > -// Local5 = active cpu bitmap
> > -Store(PRS, Local5)
> > -// Local2 = last read byte from bitmap
> > -Store(Zero, Local2)
> > -// Local0 = Processor ID / APIC ID iterator
> > -Store(Zero, Local0)
> > -While (LLess(Local0, SizeOf(CPON))) {
> > -// Local1 = CPON flag for this cpu
> > -Store(DerefOf(Index(CPON, Local0)), Local1)
> > -If (And(Local0, 0x07)) {
> > -// Shift down previously read bitmap byte
> > -ShiftRight(Local2, 1, Local2)
> > -} Else {
> > -// Read next byte from cpu bitmap
> > -Store(DerefOf(Index(Local5, ShiftRight(Local0, 3))), 
> > Local2)
> > -}
> > -// Local3 = active state for this cpu
> > -Store(And(Local2, 1), Local3)
> > -
> > -If (LNotEqual(Local1, Local3)) {
> > -// State change - update CPON with new state
> > -Store(Local3, Index(CPON, Local0))
> > -// Do CPU notify
> > -If (LEqual(Local3, 1)) {
> > -NTFY(Local0, 1)
> > -} Else {
> > -NTFY(Local0, 3)
> > -}
> > -}
> > -Increment(Local0)
> > -}
> > -}
> >  }
> > diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl
> > index 90efce0..fa9f2d4 100644
> > --- a/hw/i386/acpi-dsdt.dsl
> > +++ b/hw/i386/acpi-dsdt.dsl
> > @@ -311,7 +311,7 @@ DefinitionBlock (
> >  }
> >  Method(_E02) {
> >  // CPU hotplug event
> > -\_SB.PRSC()
> > +\_SB.CPHD.PRSC()
> >  }
> >  Method(_L03) {
> >  }
> > diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl
> > index 22baa58..9ccc543 100644
> > --- a/hw/i386/q35-acpi-dsdt.dsl
> > +++ b/hw/i386/q35-acpi-dsdt.dsl
> > @@ -420,7 +420,7 @@ DefinitionBlock (
> >  }
> >  Method(_E02) {
> >  // CPU hotplug event
> > -\_SB.PRSC()
> > +\_SB.CPHD.PRSC()
> >  }
> >  Method(_L03) {
> >  }
> > diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl
> > index a4484b8..ec8893c 100644
> > --- a/hw/i386/ssdt-misc.dsl
> > +++ b/hw/i386/ssdt-misc.dsl
> > @@ -116,4 +116,69 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, 
> > "BXPC", "BXSSDTSUSP", 0x1)
> >  }
> >  }
> >  }
> > +Scope(\_SB) {
> > +External(NTFY, MethodObj)
> > +External(CPON, PkgObj)
> > +
> > +Device(CPHD) {
> > +Name(_HID, EISAID("PNP0C08"))
> > +Name(CPPL, 32) // cpu-gpe length
> > +Name(CPHP, 0xaf00)
> > +
> > +OperationRegion(PRST, SystemIO, CPHP, CPPL)
> > +Field(PRST, ByteAcc, NoLock, Preserve) {
> > +PRS, 256
> > +}
> > +
> > +Method(PRSC, 0) {
> > +// Local5 = active cpu bitmap
> > +Store(PRS, Local5)
> > +// Local2 = last read byte from bitmap
> > +Store(Zero, Local2)
> > +// Local0 = Processor ID / APIC ID iterator
> > +Store(Zero, Local0)
> > +While (LLess(Local0, SizeOf(CPON))) {
> > +// Local1 = CPON flag for this cpu
> > +Store(DerefOf(Index(CPON, Local0)), Local1)
> > +

Re: [Qemu-devel] vhost-net issue: does not survive reboot on ppc64

2013-12-22 Thread Alexey Kardashevskiy
On 12/23/2013 01:46 AM, Alexey Kardashevskiy wrote:
> On 12/22/2013 09:56 PM, Michael S. Tsirkin wrote:
>> On Sun, Dec 22, 2013 at 02:01:23AM +1100, Alexey Kardashevskiy wrote:
>>> Hi!
>>>
>>> I am having a problem with virtio-net + vhost on POWER7 machine - it does
>>> not survive reboot of the guest.
>>>
>>> Steps to reproduce:
>>> 1. boot the guest
>>> 2. configure eth0 and do ping - everything works
>>> 3. reboot the guest (i.e. type "reboot")
>>> 4. when it is booted, eth0 can be configured but will not work at all.
>>>
>>> The test is:
>>> ifconfig eth0 172.20.1.2 up
>>> ping 172.20.1.23
>>>
>>> If to run tcpdump on the host's "tap-id3" interface, it shows no trafic
>>> coming from the guest. If to compare how it works before and after reboot,
>>> I can see the guest doing an ARP request for 172.20.1.23 and receives the
>>> response and it does the same after reboot but the answer does not come.
>>
>> So you see the arp packet in guest but not in host?
> 
> Yes.
> 
> 
>> One thing to try is to boot debug kernel - where pr_debug is
>> enabled - then you might see some errors in the kernel log.
> 
> Tried and added lot more debug printk myself, not clear at all what is
> happening there.
> 
> One more hint - if I boot the guest and the guest does not bring eth0 up
> AND wait more than 200 seconds (and less than 210 seconds), then eth0 will
> not work at all. I.e. this script produces not-working-eth0:
> 
> 
> ifconfig eth0 172.20.1.2 down
> sleep 210
> ifconfig eth0 172.20.1.2 up
> ping 172.20.1.23
> 
> s/210/200/ - and it starts working. No reboot is required to reproduce.
> 
> No "vhost" == always works. The only difference I can see here is vhost's
> thread which may get suspended if not used for a while after the start and
> does not wake up but this is almost a blind guess.


Yet another clue - this host kernel patch seems to help with the guest
reboot but does not help with the initial 210 seconds delay:

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 69068e0..5e67650 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -162,10 +162,10 @@ void vhost_work_queue(struct vhost_dev *dev, struct
vhost_work *work)
list_add_tail(&work->node, &dev->work_list);
work->queue_seq++;
spin_unlock_irqrestore(&dev->work_lock, flags);
-   wake_up_process(dev->worker);
} else {
spin_unlock_irqrestore(&dev->work_lock, flags);
}
+   wake_up_process(dev->worker);
 }
 EXPORT_SYMBOL_GPL(vhost_work_queue);





>>> If to remove vhost=on, it is all good. If to try Fedora19
>>> (v3.10-something), it all good again - works before and after reboot.
>>>
>>>
>>> And there 2 questions:
>>>
>>> 1. does anybody have any clue what might go wrong after reboot?
>>>
>>> 2. Is there any good material to read about what exactly and how vhost
>>> accelerates?
>>>
>>> My understanding is that packets from the guest to the real network are
>>> going as:
>>> 1. guest's virtio-pci-net does ioport(VIRTIO_PCI_QUEUE_NOTIFY)
>>> 2. QEMU's net/virtio-net.c calls qemu_net_queue_deliver()
>>> 3. QEMU's net/tap.c calls tap_write_packet() and this is how the host knows
>>> that there is a new packet.
> 
> 
> What about the documentation? :) or the idea?
> 
> 
>>>
>>>
>>> Thanks!
>>>
>>>
>>> This how I run QEMU:
>>> ./qemu-system-ppc64 \
>>> -enable-kvm \
>>> -m 2048 \
>>> -machine pseries \
>>> -initrd 1.cpio \
>>> -kernel vml312_virtio_net_dbg \
>>> -nographic \
>>> -vga none \
>>> -netdev
>>> tap,id=id3,ifname=tap-id3,script=ifup.sh,downscript=ifdown.sh,vhost=on \
>>> -device virtio-net-pci,id=id4,netdev=id3,mac=C0:41:49:4b:00:00
>>>
>>>
>>> That is bridge config:
>>> [aik@dyn232 ~]$ brctl show
>>> bridge name bridge id   STP enabled interfaces
>>> brtest  8000.00145e992e88   no  pin eth4
>>>
>>>
>>> The ifup.sh script:
>>> ifconfig $1 hw ether ee:01:02:03:04:05
>>> /sbin/ifconfig $1 up
>>> /usr/sbin/brctl addif brtest $1
> 
> 


-- 
Alexey



Re: [Qemu-devel] [PATCH] pxa27x: Reduce size of keyboard matrix mapping

2013-12-22 Thread Peter Maydell
On 22 December 2013 14:32, Stefan Weil  wrote:
> The row and column values use only a very limited range (-1 ... 7),
> so a byte value is sufficient.
>
> Signed-off-by: Stefan Weil 

It's not like we have a ton of pxa2xx keymaps eating up
space, but yeah, this is an OK change.

Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [Qemu-devel] [PATCH] pxa27x: Add 'const' attribute to keyboard maps

2013-12-22 Thread Peter Maydell
On 22 December 2013 14:22, Stefan Weil  wrote:
> The mapping is a hardware feature, so it is relatively constant.

This is true but not particularly relevant to whether we should be
marking the structs and parameters as 'const' or not. Still,
the change is good, so

Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [Qemu-devel] [PATCH v2] Add DSDT node for AppleSMC

2013-12-22 Thread Gabriel L. Somlo
On Fri, Dec 20, 2013 at 10:38:30PM +0100, Igor Mammedov wrote:
> > +Device (SMC) {
> > +Name(_HID, EisaId("APP0001"))
> > +/* _STA will be patched to 0x0B if AppleSMC is present */
> > +ACPI_EXTRACT_NAME_WORD_CONST CONCAT_SYM(SMC_PFX, smc_sta)
> typically dynamic variables are put in SSDT

When I tried statically building the SMC node as part of the SSDT, it
was not recognized by Mac OS X -- it only seems to work when it's part
of the DSDT.

> > +Name(_STA, 0xFF00)
> > +Name(_CRS, ResourceTemplate () {
> > +IO (Decode16, 0x0300, 0x0300, 0x01, 0x20)
> > +IRQNoFlags() { 6 }
> > +})
> > +}
> Device looks pretty simplistic, Have you considered building it completely
> dynamically?
> See build_ssdt() for examples, you might need to add extra building block for
> ResourceTemplate{} the rest could be done with existing build_* primitives.

If we consider "pasting" the SMC into the DSDT or not, based on
whether it was configured via -device applesmc or not, it comes
down to compiling the following ASL:

Device (SMC) {
Name(_HID, EisaId("APP0001"))
Name(_STA, 0x0B)
Name(_CRS, ResourceTemplate () {
IO (Decode16, 0x0300, 0x0300, 0x01, 0x20)
IRQNoFlags() { 6 }
})
}

into AML, and somehow conditionally appending the resulting blob,
unmodified, to the DSDT.

I would explore this approach before I'd consider compiling the blob
dynamically each time during QEMU startup, which would IMHO be harder
to follow.

However, I thought flipping one uint16_t from 0x0B to 0x00 (i.e., the
return value of SMC._STA) is much less intrusive to the DSDT than
pasting an entire blob dynamically during startup, which is why I
thought my approach was a bit cleaner.

Let me know what you think.

Thanks,
--Gabriel



[Qemu-devel] [PATCH v3] Add DSDT node for AppleSMC

2013-12-22 Thread Gabriel L. Somlo
AppleSMC (-device isa-applesmc) is required to boot OS X guests.
OS X expects a SMC node to be present in the ACPI DSDT. This patch
adds a SMC node to the DSDT, and dynamically patches the return value
of SMC._STA to either 0x0B if the chip is present, or otherwise to 0x00,
before booting the guest.

Signed-off-by: Gabriel Somlo 
---

On Sun, Dec 22, 2013 at 01:07:13PM +0200, Michael S. Tsirkin wrote:
>> +#define _CONCAT_SYM(a, b) a##b
>> +#define CONCAT_SYM(a, b) _CONCAT_SYM(a, b)
>
> Seems too complex. If one looks for q35_smc_sta one can not find it

You're right, I went all "Rube Goldberg" on that one - thanks for
pulling me back from the edge :)

>> +unsigned short smc_sta_val = 0x00;
> 
> Better initialize this in the else branch below.

I threw in "applesmc_find()" to make that even cleaner and easier to
follow.

Thanks,
  Gabriel

 hw/misc/applesmc.c|  1 -
 include/hw/isa/isa.h  |  7 +++
 hw/i386/acpi-dsdt.dsl |  1 +
 hw/i386/q35-acpi-dsdt.dsl |  1 +
 hw/i386/acpi-dsdt-isa.dsl | 11 +++
 hw/i386/acpi-build.c  |  9 +
 6 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 1e8d183..627adb9 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -66,7 +66,6 @@ struct AppleSMCData {
 QLIST_ENTRY(AppleSMCData) node;
 };
 
-#define TYPE_APPLE_SMC "isa-applesmc"
 #define APPLE_SMC(obj) OBJECT_CHECK(AppleSMCState, (obj), TYPE_APPLE_SMC)
 
 typedef struct AppleSMCState AppleSMCState;
diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index fa45a5b..e0c749f 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -20,6 +20,13 @@
 #define TYPE_ISA_BUS "ISA"
 #define ISA_BUS(obj) OBJECT_CHECK(ISABus, (obj), TYPE_ISA_BUS)
 
+#define TYPE_APPLE_SMC "isa-applesmc"
+
+static inline bool applesmc_find(void)
+{
+return object_resolve_path_type("", TYPE_APPLE_SMC, NULL);
+}
+
 typedef struct ISADeviceClass {
 DeviceClass parent_class;
 } ISADeviceClass;
diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl
index a377424..b87c6e0 100644
--- a/hw/i386/acpi-dsdt.dsl
+++ b/hw/i386/acpi-dsdt.dsl
@@ -114,6 +114,7 @@ DefinitionBlock (
 }
 }
 
+#define DSDT_APPLESMC_STA piix_dsdt_applesmc_sta
 #include "acpi-dsdt-isa.dsl"
 
 
diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl
index 575c5d7..12ff544 100644
--- a/hw/i386/q35-acpi-dsdt.dsl
+++ b/hw/i386/q35-acpi-dsdt.dsl
@@ -171,6 +171,7 @@ DefinitionBlock (
 }
 }
 
+#define DSDT_APPLESMC_STA q35_dsdt_applesmc_sta
 #include "acpi-dsdt-isa.dsl"
 
 
diff --git a/hw/i386/acpi-dsdt-isa.dsl b/hw/i386/acpi-dsdt-isa.dsl
index 89caa16..46942c1 100644
--- a/hw/i386/acpi-dsdt-isa.dsl
+++ b/hw/i386/acpi-dsdt-isa.dsl
@@ -16,6 +16,17 @@
 /* Common legacy ISA style devices. */
 Scope(\_SB.PCI0.ISA) {
 
+Device (SMC) {
+Name(_HID, EisaId("APP0001"))
+/* _STA will be patched to 0x0B if AppleSMC is present */
+ACPI_EXTRACT_NAME_WORD_CONST DSDT_APPLESMC_STA
+Name(_STA, 0xFF00)
+Name(_CRS, ResourceTemplate () {
+IO (Decode16, 0x0300, 0x0300, 0x01, 0x20)
+IRQNoFlags() { 6 }
+})
+}
+
 Device(RTC) {
 Name(_HID, EisaId("PNP0B00"))
 Name(_CRS, ResourceTemplate() {
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 48312f5..30bfcd2 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -36,6 +36,7 @@
 #include "hw/nvram/fw_cfg.h"
 #include "bios-linker-loader.h"
 #include "hw/loader.h"
+#include "hw/isa/isa.h"
 
 /* Supported chipsets: */
 #include "hw/acpi/piix4.h"
@@ -80,6 +81,7 @@ typedef struct AcpiMiscInfo {
 
 static void acpi_get_dsdt(AcpiMiscInfo *info)
 {
+unsigned short applesmc_sta_val, *applesmc_sta_off;
 Object *piix = piix4_pm_find();
 Object *lpc = ich9_lpc_find();
 assert(!!piix != !!lpc);
@@ -87,11 +89,18 @@ static void acpi_get_dsdt(AcpiMiscInfo *info)
 if (piix) {
 info->dsdt_code = AcpiDsdtAmlCode;
 info->dsdt_size = sizeof AcpiDsdtAmlCode;
+applesmc_sta_off = piix_dsdt_applesmc_sta;
 }
 if (lpc) {
 info->dsdt_code = Q35AcpiDsdtAmlCode;
 info->dsdt_size = sizeof Q35AcpiDsdtAmlCode;
+applesmc_sta_off = q35_dsdt_applesmc_sta;
 }
+
+/* Patch in appropriate value for AppleSMC _STA */
+applesmc_sta_val = applesmc_find() ? 0x0b : 0x00;
+*(uint16_t *)(info->dsdt_code + *applesmc_sta_off) =
+cpu_to_le16(applesmc_sta_val);
 }
 
 static
-- 
1.8.1.4




[Qemu-devel] [PATCH 2/7] rc4030: create custom DMA address space

2013-12-22 Thread Hervé Poussineau
Keep it up to date by catching writes to DMA translation table.

Signed-off-by: Hervé Poussineau 
---
 hw/dma/rc4030.c |  153 ---
 1 file changed, 113 insertions(+), 40 deletions(-)

diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c
index af26632..9b505c5 100644
--- a/hw/dma/rc4030.c
+++ b/hw/dma/rc4030.c
@@ -25,6 +25,7 @@
 #include "hw/hw.h"
 #include "hw/mips/mips.h"
 #include "qemu/timer.h"
+#include "exec/address-spaces.h"
 
 //
 /* debug rc4030 */
@@ -47,6 +48,8 @@ do { fprintf(stderr, "rc4030 ERROR: %s: " fmt, __func__ , ## 
__VA_ARGS__); } whi
 //
 /* rc4030 emulation */
 
+#define MAX_TL_ENTRIES 512
+
 typedef struct dma_pagetable_entry {
 int32_t frame;
 int32_t owner;
@@ -96,6 +99,11 @@ typedef struct rc4030State
 qemu_irq timer_irq;
 qemu_irq jazz_bus_irq;
 
+MemoryRegion dma_table; /* translation table */
+MemoryRegion dma_aliases[MAX_TL_ENTRIES]; /* translation aliases */
+MemoryRegion dma_region; /* whole DMA memory region */
+AddressSpace dma_as;
+
 MemoryRegion iomem_chipset;
 MemoryRegion iomem_jazzio;
 } rc4030State;
@@ -265,6 +273,92 @@ static uint32_t rc4030_readb(void *opaque, hwaddr addr)
 return (v >> (8 * (addr & 0x3))) & 0xff;
 }
 
+static void rc4030_dma_as_update_one(rc4030State *s, int index,
+ uint32_t new_frame)
+{
+if (index < MAX_TL_ENTRIES) {
+memory_region_set_enabled(&s->dma_aliases[index], false);
+}
+
+if (!new_frame) {
+return;
+}
+
+if (index >= MAX_TL_ENTRIES) {
+qemu_log_mask(LOG_UNIMP,
+  "rc4030: trying to use too high "
+  "translation table entry %d (max allowed=%d)",
+  index, MAX_TL_ENTRIES);
+return;
+}
+memory_region_set_alias_offset(&s->dma_aliases[index], new_frame);
+memory_region_set_enabled(&s->dma_aliases[index], true);
+}
+
+static void rc4030_dma_table_write(void *opaque, hwaddr addr, uint64_t data,
+   unsigned int size)
+{
+rc4030State *s = opaque;
+
+/* write memory */
+memcpy(memory_region_get_ram_ptr(&s->dma_table) + addr, &data, size);
+
+/* update dma address space (only if frame field has been written) */
+if (addr % sizeof(dma_pagetable_entry) == 0) {
+int index = addr / sizeof(dma_pagetable_entry);
+memory_region_transaction_begin();
+rc4030_dma_as_update_one(s, index, (uint32_t)data);
+memory_region_transaction_commit();
+}
+}
+
+static const MemoryRegionOps rc4030_dma_table_ops = {
+.write = rc4030_dma_table_write,
+.impl.min_access_size = 4,
+.impl.max_access_size = 4,
+};
+
+static void rc4030_dma_table_update(rc4030State *s, uint32_t new_tl_base,
+uint32_t new_tl_limit)
+{
+int entries, i;
+dma_pagetable_entry *dma_tl_contents;
+
+if (s->dma_tl_limit) {
+/* write old dma tl table to physical memory */
+memory_region_del_subregion(get_system_memory(), &s->dma_table);
+cpu_physical_memory_write(s->dma_tl_limit & 0x7fff,
+  memory_region_get_ram_ptr(&s->dma_table),
+  s->dma_tl_limit);
+}
+memory_region_destroy(&s->dma_table);
+
+s->dma_tl_base = new_tl_base;
+s->dma_tl_limit = new_tl_limit;
+new_tl_base &= 0x7fff;
+
+if (s->dma_tl_limit) {
+memory_region_init_rom_device(&s->dma_table, NULL,
+  &rc4030_dma_table_ops, s,
+  "dma-translation-table", 
s->dma_tl_limit);
+dma_tl_contents = memory_region_get_ram_ptr(&s->dma_table);
+cpu_physical_memory_read(new_tl_base, dma_tl_contents, 
s->dma_tl_limit);
+
+memory_region_transaction_begin();
+entries = s->dma_tl_limit / sizeof(dma_pagetable_entry);
+for (i = 0; i < entries; i++) {
+rc4030_dma_as_update_one(s, i, dma_tl_contents[i].frame);
+}
+memory_region_add_subregion(get_system_memory(), new_tl_base,
+&s->dma_table);
+memory_region_transaction_commit();
+} else {
+memory_region_init(&s->dma_table, NULL,
+   "dma-translation-table", 0);
+}
+}
+
+
 static void rc4030_writel(void *opaque, hwaddr addr, uint32_t val)
 {
 rc4030State *s = opaque;
@@ -279,11 +373,11 @@ static void rc4030_writel(void *opaque, hwaddr addr, 
uint32_t val)
 break;
 /* DMA transl. table base */
 case 0x0018:
-s->dma_tl_base = val;
+rc4030_dma_table_update(s, val, s->dma_tl_limit);
 break;
 /* DMA transl. table limit */
 case 0x0020:
-s->dma_tl_limit = val;
+rc4030_dma_

[Qemu-devel] [PATCH 0/7] rc4030 chipset: misc cleanup

2013-12-22 Thread Hervé Poussineau
Hi,

This patchset improves rc4030 chipset emulation to current QEMU
standards, ie QOM, tracing facilities, AddressSpace usage.
No behaviour change in emulation is expected.

Hervé

Hervé Poussineau (7):
  mips jazz: compile only in 64 bit little endian
  rc4030: create custom DMA address space
  rc4030: use AddressSpace and address_space_rw in users
  rc4030: do not use old_mmio accesses
  rc4030: document register at offset 0x210 (memory refresh rate)
  rc4030: use trace events instead of custom logging
  rc4030: convert to QOM

 default-configs/mips-softmmu.mak |5 -
 default-configs/mips64-softmmu.mak   |5 -
 default-configs/mips64el-softmmu.mak |1 +
 default-configs/mipsel-softmmu.mak   |5 -
 hw/dma/rc4030.c  |  456 +-
 hw/mips/Makefile.objs|3 +-
 hw/mips/mips_jazz.c  |   44 ++--
 hw/net/dp8393x.c |   38 ++-
 include/hw/mips/mips.h   |8 +-
 trace-events |6 +
 10 files changed, 282 insertions(+), 289 deletions(-)

-- 
1.7.10.4




[Qemu-devel] [PATCH 5/7] rc4030: document register at offset 0x210 (memory refresh rate)

2013-12-22 Thread Hervé Poussineau
Register name is known, but its format is not known.

Signed-off-by: Hervé Poussineau 
---
 hw/dma/rc4030.c |   16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c
index 432a4e4..09d235e 100644
--- a/hw/dma/rc4030.c
+++ b/hw/dma/rc4030.c
@@ -86,7 +86,7 @@ typedef struct rc4030State
 uint32_t cache_bmask; /* 0x0058: I/O Cache Byte Mask */
 
 uint32_t nmi_interrupt; /* 0x0200: interrupt source */
-uint32_t offset210;
+uint32_t memory_refresh_rate; /* 0x0210: memory refresh rate */
 uint32_t nvram_protect; /* 0x0220: NV ram protect register */
 uint32_t rem_speed[16];
 uint32_t imr_jazz; /* Local bus int enable mask */
@@ -228,9 +228,9 @@ static uint64_t rc4030_read(void *opaque, hwaddr addr, 
unsigned int size)
 case 0x0208:
 val = 0;
 break;
-/* Offset 0x0210 */
+/* Memory refresh rate */
 case 0x0210:
-val = s->offset210;
+val = s->memory_refresh_rate;
 break;
 /* NV ram protect register */
 case 0x0220:
@@ -451,9 +451,9 @@ static void rc4030_write(void *opaque, hwaddr addr, 
uint64_t data,
 s->dma_regs[entry][idx] = val;
 }
 break;
-/* Offset 0x0210 */
+/* Memory refresh rate */
 case 0x0210:
-s->offset210 = val;
+s->memory_refresh_rate = val;
 break;
 /* Interval timer reload */
 case 0x0228:
@@ -611,7 +611,7 @@ static void rc4030_reset(void *opaque)
 s->cache_ptag = s->cache_ltag = 0;
 s->cache_bmask = 0;
 
-s->offset210 = 0x18186;
+s->memory_refresh_rate = 0x18186;
 s->nvram_protect = 7;
 for (i = 0; i < 15; i++)
 s->rem_speed[i] = 7;
@@ -645,7 +645,7 @@ static int rc4030_load(QEMUFile *f, void *opaque, int 
version_id)
 s->cache_ptag = qemu_get_be32(f);
 s->cache_ltag = qemu_get_be32(f);
 s->cache_bmask = qemu_get_be32(f);
-s->offset210 = qemu_get_be32(f);
+s->memory_refresh_rate = qemu_get_be32(f);
 s->nvram_protect = qemu_get_be32(f);
 for (i = 0; i < 15; i++)
 s->rem_speed[i] = qemu_get_be32(f);
@@ -677,7 +677,7 @@ static void rc4030_save(QEMUFile *f, void *opaque)
 qemu_put_be32(f, s->cache_ptag);
 qemu_put_be32(f, s->cache_ltag);
 qemu_put_be32(f, s->cache_bmask);
-qemu_put_be32(f, s->offset210);
+qemu_put_be32(f, s->memory_refresh_rate);
 qemu_put_be32(f, s->nvram_protect);
 for (i = 0; i < 15; i++)
 qemu_put_be32(f, s->rem_speed[i]);
-- 
1.7.10.4




[Qemu-devel] [PATCH 3/7] rc4030: use AddressSpace and address_space_rw in users

2013-12-22 Thread Hervé Poussineau
Now that rc4030 internally uses an AddressSpace for DMA handling, make it 
public.
This is especially usefull for dp8393x netcard, which now uses well known QEMU
types and methods.

Signed-off-by: Hervé Poussineau 
---
 hw/dma/rc4030.c|   14 --
 hw/mips/mips_jazz.c|8 
 hw/net/dp8393x.c   |   38 ++
 include/hw/mips/mips.h |   10 --
 4 files changed, 30 insertions(+), 40 deletions(-)

diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c
index 9b505c5..97214de 100644
--- a/hw/dma/rc4030.c
+++ b/hw/dma/rc4030.c
@@ -766,12 +766,6 @@ static void rc4030_save(QEMUFile *f, void *opaque)
 qemu_put_be32(f, s->itr);
 }
 
-void rc4030_dma_memory_rw(void *opaque, hwaddr addr, uint8_t *buf, int len, 
int is_write)
-{
-rc4030State *s = opaque;
-address_space_rw(&s->dma_as, addr, buf, len, is_write);
-}
-
 static void rc4030_do_dma(void *opaque, int n, uint8_t *buf, int len, int 
is_write)
 {
 rc4030State *s = opaque;
@@ -857,9 +851,9 @@ static rc4030_dma *rc4030_allocate_dmas(void *opaque, int n)
 return s;
 }
 
-void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus,
-  qemu_irq **irqs, rc4030_dma **dmas,
-  MemoryRegion *sysmem)
+AddressSpace *rc4030_init(qemu_irq timer, qemu_irq jazz_bus,
+  qemu_irq **irqs, rc4030_dma **dmas,
+  MemoryRegion *sysmem)
 {
 rc4030State *s;
 int i;
@@ -894,5 +888,5 @@ void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus,
 }
 address_space_init(&s->dma_as, &s->dma_region, "rc4030_dma");
 rc4030_reset(s);
-return s;
+return &s->dma_as;
 }
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index 1e6ed50..41806af 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -133,7 +133,7 @@ static void mips_jazz_init(MemoryRegion *address_space,
 CPUMIPSState *env;
 qemu_irq *rc4030, *i8259;
 rc4030_dma *dmas;
-void* rc4030_opaque;
+AddressSpace *rc4030_as;
 MemoryRegion *isa = g_new(MemoryRegion, 1);
 MemoryRegion *rtc = g_new(MemoryRegion, 1);
 MemoryRegion *i8042 = g_new(MemoryRegion, 1);
@@ -207,8 +207,8 @@ static void mips_jazz_init(MemoryRegion *address_space,
 cpu_mips_clock_init(env);
 
 /* Chipset */
-rc4030_opaque = rc4030_init(env->irq[6], env->irq[3], &rc4030, &dmas,
-address_space);
+rc4030_as = rc4030_init(env->irq[6], env->irq[3], &rc4030, &dmas,
+address_space);
 memory_region_init_io(dma_dummy, NULL, &dma_dummy_ops, NULL, "dummy_dma", 
0x1000);
 memory_region_add_subregion(address_space, 0x8000d000, dma_dummy);
 
@@ -261,7 +261,7 @@ static void mips_jazz_init(MemoryRegion *address_space,
 nd->model = g_strdup("dp83932");
 if (strcmp(nd->model, "dp83932") == 0) {
 dp83932_init(nd, 0x80001000, 2, get_system_memory(), rc4030[4],
- rc4030_opaque, rc4030_dma_memory_rw);
+ rc4030_as);
 break;
 } else if (is_help_option(nd->model)) {
 fprintf(stderr, "qemu: Supported NICs: dp83932\n");
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index 789d385..d6f472a 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -168,8 +168,7 @@ typedef struct dp8393xState {
 int loopback_packet;
 
 /* Memory access */
-void (*memory_rw)(void *opaque, hwaddr addr, uint8_t *buf, int len, int 
is_write);
-void* mem_opaque;
+AddressSpace *as;
 } dp8393xState;
 
 static void dp8393x_update_irq(dp8393xState *s)
@@ -201,7 +200,7 @@ static void do_load_cam(dp8393xState *s)
 
 while (s->regs[SONIC_CDC] & 0x1f) {
 /* Fill current entry */
-s->memory_rw(s->mem_opaque,
+address_space_rw(s->as,
 (s->regs[SONIC_URRA] << 16) | s->regs[SONIC_CDP],
 (uint8_t *)data, size, 0);
 s->cam[index][0] = data[1 * width] & 0xff;
@@ -220,7 +219,7 @@ static void do_load_cam(dp8393xState *s)
 }
 
 /* Read CAM enable */
-s->memory_rw(s->mem_opaque,
+address_space_rw(s->as,
 (s->regs[SONIC_URRA] << 16) | s->regs[SONIC_CDP],
 (uint8_t *)data, size, 0);
 s->regs[SONIC_CE] = data[0 * width];
@@ -240,7 +239,7 @@ static void do_read_rra(dp8393xState *s)
 /* Read memory */
 width = (s->regs[SONIC_DCR] & SONIC_DCR_DW) ? 2 : 1;
 size = sizeof(uint16_t) * 4 * width;
-s->memory_rw(s->mem_opaque,
+address_space_rw(s->as,
 (s->regs[SONIC_URRA] << 16) | s->regs[SONIC_RRP],
 (uint8_t *)data, size, 0);
 
@@ -353,7 +352,7 @@ static void do_transmit_packets(dp8393xState *s)
 (s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_CTDA]);
 size = sizeof(uint16_t) * 6 * width;
 s->regs[SONIC_TTDA] = s->regs[SONIC_CTDA];
-s->memory_rw(s->mem_opaque,
+address_space_rw(s->as,
 ((s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_TTDA]) + 

[Qemu-devel] [PATCH 1/7] mips jazz: compile only in 64 bit little endian

2013-12-22 Thread Hervé Poussineau
Remove now useless device models from other MIPS configurations

We're now compiling 18 files less than before.

Signed-off-by: Hervé Poussineau 
---
 default-configs/mips-softmmu.mak |5 -
 default-configs/mips64-softmmu.mak   |5 -
 default-configs/mips64el-softmmu.mak |1 +
 default-configs/mipsel-softmmu.mak   |5 -
 hw/mips/Makefile.objs|3 ++-
 hw/mips/mips_jazz.c  |5 -
 6 files changed, 3 insertions(+), 21 deletions(-)

diff --git a/default-configs/mips-softmmu.mak b/default-configs/mips-softmmu.mak
index 71177ef..3cedb60 100644
--- a/default-configs/mips-softmmu.mak
+++ b/default-configs/mips-softmmu.mak
@@ -23,14 +23,9 @@ CONFIG_PIIX4=y
 CONFIG_IDE_ISA=y
 CONFIG_IDE_PIIX=y
 CONFIG_NE2000_ISA=y
-CONFIG_RC4030=y
-CONFIG_DP8393X=y
-CONFIG_DS1225Y=y
 CONFIG_MIPSNET=y
 CONFIG_PFLASH_CFI01=y
-CONFIG_G364FB=y
 CONFIG_I8259=y
-CONFIG_JAZZ_LED=y
 CONFIG_MC146818RTC=y
 CONFIG_VT82C686=y
 CONFIG_ISA_TESTDEV=y
diff --git a/default-configs/mips64-softmmu.mak 
b/default-configs/mips64-softmmu.mak
index 617301b..4ffec4e 100644
--- a/default-configs/mips64-softmmu.mak
+++ b/default-configs/mips64-softmmu.mak
@@ -23,14 +23,9 @@ CONFIG_PIIX4=y
 CONFIG_IDE_ISA=y
 CONFIG_IDE_PIIX=y
 CONFIG_NE2000_ISA=y
-CONFIG_RC4030=y
-CONFIG_DP8393X=y
-CONFIG_DS1225Y=y
 CONFIG_MIPSNET=y
 CONFIG_PFLASH_CFI01=y
-CONFIG_G364FB=y
 CONFIG_I8259=y
-CONFIG_JAZZ_LED=y
 CONFIG_MC146818RTC=y
 CONFIG_VT82C686=y
 CONFIG_ISA_TESTDEV=y
diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index 317b151..b95e721 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -30,6 +30,7 @@ CONFIG_DS1225Y=y
 CONFIG_MIPSNET=y
 CONFIG_PFLASH_CFI01=y
 CONFIG_FULONG=y
+CONFIG_JAZZ=y
 CONFIG_G364FB=y
 CONFIG_I8259=y
 CONFIG_JAZZ_LED=y
diff --git a/default-configs/mipsel-softmmu.mak 
b/default-configs/mipsel-softmmu.mak
index 532a9ae..737692b 100644
--- a/default-configs/mipsel-softmmu.mak
+++ b/default-configs/mipsel-softmmu.mak
@@ -23,14 +23,9 @@ CONFIG_PIIX4=y
 CONFIG_IDE_ISA=y
 CONFIG_IDE_PIIX=y
 CONFIG_NE2000_ISA=y
-CONFIG_RC4030=y
-CONFIG_DP8393X=y
-CONFIG_DS1225Y=y
 CONFIG_MIPSNET=y
 CONFIG_PFLASH_CFI01=y
-CONFIG_G364FB=y
 CONFIG_I8259=y
-CONFIG_JAZZ_LED=y
 CONFIG_MC146818RTC=y
 CONFIG_VT82C686=y
 CONFIG_ISA_TESTDEV=y
diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs
index 0a652f8..9633f3a 100644
--- a/hw/mips/Makefile.objs
+++ b/hw/mips/Makefile.objs
@@ -1,4 +1,5 @@
-obj-y += mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o
+obj-y += mips_r4k.o mips_malta.o mips_mipssim.o
 obj-y += addr.o cputimer.o mips_int.o
+obj-$(CONFIG_JAZZ) += mips_jazz.o
 obj-$(CONFIG_FULONG) += mips_fulong2e.o
 obj-y += gt64xxx_pci.o
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index 5f6dd9f..1e6ed50 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -152,12 +152,7 @@ static void mips_jazz_init(MemoryRegion *address_space,
 
 /* init CPUs */
 if (cpu_model == NULL) {
-#ifdef TARGET_MIPS64
 cpu_model = "R4000";
-#else
-/* FIXME: All wrong, this maybe should be R3000 for the older JAZZs. */
-cpu_model = "24Kf";
-#endif
 }
 cpu = cpu_mips_init(cpu_model);
 if (cpu == NULL) {
-- 
1.7.10.4




[Qemu-devel] [PATCH 4/7] rc4030: do not use old_mmio accesses

2013-12-22 Thread Hervé Poussineau

Signed-off-by: Hervé Poussineau 
---
 hw/dma/rc4030.c |  112 ---
 1 file changed, 16 insertions(+), 96 deletions(-)

diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c
index 97214de..432a4e4 100644
--- a/hw/dma/rc4030.c
+++ b/hw/dma/rc4030.c
@@ -120,7 +120,7 @@ static void set_next_tick(rc4030State *s)
 }
 
 /* called for accesses to rc4030 */
-static uint32_t rc4030_readl(void *opaque, hwaddr addr)
+static uint64_t rc4030_read(void *opaque, hwaddr addr, unsigned int size)
 {
 rc4030State *s = opaque;
 uint32_t val;
@@ -258,21 +258,6 @@ static uint32_t rc4030_readl(void *opaque, hwaddr addr)
 return val;
 }
 
-static uint32_t rc4030_readw(void *opaque, hwaddr addr)
-{
-uint32_t v = rc4030_readl(opaque, addr & ~0x3);
-if (addr & 0x2)
-return v >> 16;
-else
-return v & 0x;
-}
-
-static uint32_t rc4030_readb(void *opaque, hwaddr addr)
-{
-uint32_t v = rc4030_readl(opaque, addr & ~0x3);
-return (v >> (8 * (addr & 0x3))) & 0xff;
-}
-
 static void rc4030_dma_as_update_one(rc4030State *s, int index,
  uint32_t new_frame)
 {
@@ -358,10 +343,11 @@ static void rc4030_dma_table_update(rc4030State *s, 
uint32_t new_tl_base,
 }
 }
 
-
-static void rc4030_writel(void *opaque, hwaddr addr, uint32_t val)
+static void rc4030_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned int size)
 {
 rc4030State *s = opaque;
+uint32_t val = data;
 addr &= 0x3fff;
 
 DPRINTF("write 0x%02x at " TARGET_FMT_plx "\n", val, addr);
@@ -484,43 +470,11 @@ static void rc4030_writel(void *opaque, hwaddr addr, 
uint32_t val)
 }
 }
 
-static void rc4030_writew(void *opaque, hwaddr addr, uint32_t val)
-{
-uint32_t old_val = rc4030_readl(opaque, addr & ~0x3);
-
-if (addr & 0x2)
-val = (val << 16) | (old_val & 0x);
-else
-val = val | (old_val & 0x);
-rc4030_writel(opaque, addr & ~0x3, val);
-}
-
-static void rc4030_writeb(void *opaque, hwaddr addr, uint32_t val)
-{
-uint32_t old_val = rc4030_readl(opaque, addr & ~0x3);
-
-switch (addr & 3) {
-case 0:
-val = val | (old_val & 0xff00);
-break;
-case 1:
-val = (val << 8) | (old_val & 0x00ff);
-break;
-case 2:
-val = (val << 16) | (old_val & 0xff00);
-break;
-case 3:
-val = (val << 24) | (old_val & 0x00ff);
-break;
-}
-rc4030_writel(opaque, addr & ~0x3, val);
-}
-
 static const MemoryRegionOps rc4030_ops = {
-.old_mmio = {
-.read = { rc4030_readb, rc4030_readw, rc4030_readl, },
-.write = { rc4030_writeb, rc4030_writew, rc4030_writel, },
-},
+.read = rc4030_read,
+.write = rc4030_write,
+.impl.min_access_size = 4,
+.impl.max_access_size = 4,
 .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
@@ -573,7 +527,7 @@ static void rc4030_periodic_timer(void *opaque)
 qemu_irq_raise(s->timer_irq);
 }
 
-static uint32_t jazzio_readw(void *opaque, hwaddr addr)
+static uint64_t jazzio_read(void *opaque, hwaddr addr, unsigned int size)
 {
 rc4030State *s = opaque;
 uint32_t val;
@@ -611,24 +565,11 @@ static uint32_t jazzio_readw(void *opaque, hwaddr addr)
 return val;
 }
 
-static uint32_t jazzio_readb(void *opaque, hwaddr addr)
-{
-uint32_t v;
-v = jazzio_readw(opaque, addr & ~0x1);
-return (v >> (8 * (addr & 0x1))) & 0xff;
-}
-
-static uint32_t jazzio_readl(void *opaque, hwaddr addr)
-{
-uint32_t v;
-v = jazzio_readw(opaque, addr);
-v |= jazzio_readw(opaque, addr + 2) << 16;
-return v;
-}
-
-static void jazzio_writew(void *opaque, hwaddr addr, uint32_t val)
+static void jazzio_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned int size)
 {
 rc4030State *s = opaque;
+uint32_t val = data;
 addr &= 0xfff;
 
 DPRINTF("(jazz io controller) write 0x%04x at " TARGET_FMT_plx "\n", val, 
addr);
@@ -645,32 +586,11 @@ static void jazzio_writew(void *opaque, hwaddr addr, 
uint32_t val)
 }
 }
 
-static void jazzio_writeb(void *opaque, hwaddr addr, uint32_t val)
-{
-uint32_t old_val = jazzio_readw(opaque, addr & ~0x1);
-
-switch (addr & 1) {
-case 0:
-val = val | (old_val & 0xff00);
-break;
-case 1:
-val = (val << 8) | (old_val & 0x00ff);
-break;
-}
-jazzio_writew(opaque, addr & ~0x1, val);
-}
-
-static void jazzio_writel(void *opaque, hwaddr addr, uint32_t val)
-{
-jazzio_writew(opaque, addr, val & 0x);
-jazzio_writew(opaque, addr + 2, (val >> 16) & 0x);
-}
-
 static const MemoryRegionOps jazzio_ops = {
-.old_mmio = {
-.read = { jazzio_readb, jazzio_readw, jazzio_readl, },
-.write = { jazzio_writeb, jazzio_writew, jazzio_writel, },
-},
+.read = jazzio_read,
+.write = jazzio_write,
+.impl.min_access_size = 2,
+.impl.max_access_size = 2,
 .en

[Qemu-devel] [PATCH 6/7] rc4030: use trace events instead of custom logging

2013-12-22 Thread Hervé Poussineau
Remove also unneeded debug logs.

Signed-off-by: Hervé Poussineau 
---
 hw/dma/rc4030.c |   81 +++
 trace-events|6 +
 2 files changed, 22 insertions(+), 65 deletions(-)

diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c
index 09d235e..198bbdd 100644
--- a/hw/dma/rc4030.c
+++ b/hw/dma/rc4030.c
@@ -26,24 +26,7 @@
 #include "hw/mips/mips.h"
 #include "qemu/timer.h"
 #include "exec/address-spaces.h"
-
-//
-/* debug rc4030 */
-
-//#define DEBUG_RC4030
-//#define DEBUG_RC4030_DMA
-
-#ifdef DEBUG_RC4030
-#define DPRINTF(fmt, ...) \
-do { printf("rc4030: " fmt , ## __VA_ARGS__); } while (0)
-static const char* irq_names[] = { "parallel", "floppy", "sound", "video",
-"network", "scsi", "keyboard", "mouse", "serial0", "serial1" };
-#else
-#define DPRINTF(fmt, ...)
-#endif
-
-#define RC4030_ERROR(fmt, ...) \
-do { fprintf(stderr, "rc4030 ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } 
while (0)
+#include "trace.h"
 
 //
 /* rc4030 emulation */
@@ -246,13 +229,14 @@ static uint64_t rc4030_read(void *opaque, hwaddr addr, 
unsigned int size)
 val = 7; /* FIXME: should be read from EISA controller */
 break;
 default:
-RC4030_ERROR("invalid read [" TARGET_FMT_plx "]\n", addr);
+qemu_log_mask(LOG_GUEST_ERROR,
+  "rc4030: invalid read at 0x%x", (int)addr);
 val = 0;
 break;
 }
 
 if ((addr & ~3) != 0x230) {
-DPRINTF("read 0x%02x at " TARGET_FMT_plx "\n", val, addr);
+trace_rc4030_read(addr, val);
 }
 
 return val;
@@ -350,7 +334,7 @@ static void rc4030_write(void *opaque, hwaddr addr, 
uint64_t data,
 uint32_t val = data;
 addr &= 0x3fff;
 
-DPRINTF("write 0x%02x at " TARGET_FMT_plx "\n", val, addr);
+trace_rc4030_write(addr, val);
 
 switch (addr & ~0x3) {
 /* Global config register */
@@ -465,7 +449,9 @@ static void rc4030_write(void *opaque, hwaddr addr, 
uint64_t data,
 case 0x0238:
 break;
 default:
-RC4030_ERROR("invalid write of 0x%02x at [" TARGET_FMT_plx "]\n", val, 
addr);
+qemu_log_mask(LOG_GUEST_ERROR,
+  "rc4030: invalid write of 0x%02x at 0x%x",
+  val, (int)addr);
 break;
 }
 }
@@ -484,22 +470,6 @@ static void update_jazz_irq(rc4030State *s)
 
 pending = s->isr_jazz & s->imr_jazz;
 
-#ifdef DEBUG_RC4030
-if (s->isr_jazz != 0) {
-uint32_t irq = 0;
-DPRINTF("pending irqs:");
-for (irq = 0; irq < ARRAY_SIZE(irq_names); irq++) {
-if (s->isr_jazz & (1 << irq)) {
-printf(" %s", irq_names[irq]);
-if (!(s->imr_jazz & (1 << irq))) {
-printf("(ignored)");
-}
-}
-}
-printf("\n");
-}
-#endif
-
 if (pending != 0)
 qemu_irq_raise(s->jazz_bus_irq);
 else
@@ -542,7 +512,6 @@ static uint64_t jazzio_read(void *opaque, hwaddr addr, 
unsigned int size)
 irq = 0;
 while (pending) {
 if (pending & 1) {
-DPRINTF("returning irq %s\n", irq_names[irq]);
 val = (irq + 1) << 2;
 break;
 }
@@ -556,11 +525,13 @@ static uint64_t jazzio_read(void *opaque, hwaddr addr, 
unsigned int size)
 val = s->imr_jazz;
 break;
 default:
-RC4030_ERROR("(jazz io controller) invalid read [" TARGET_FMT_plx 
"]\n", addr);
+qemu_log_mask(LOG_GUEST_ERROR,
+  "rc4030/jazzio: invalid read at 0x%x", (int)addr);
 val = 0;
+break;
 }
 
-DPRINTF("(jazz io controller) read 0x%04x at " TARGET_FMT_plx "\n", val, 
addr);
+trace_jazzio_read(addr, val);
 
 return val;
 }
@@ -572,7 +543,7 @@ static void jazzio_write(void *opaque, hwaddr addr, 
uint64_t data,
 uint32_t val = data;
 addr &= 0xfff;
 
-DPRINTF("(jazz io controller) write 0x%04x at " TARGET_FMT_plx "\n", val, 
addr);
+trace_jazzio_write(addr, val);
 
 switch (addr) {
 /* Local bus int enable mask */
@@ -581,7 +552,9 @@ static void jazzio_write(void *opaque, hwaddr addr, 
uint64_t data,
 update_jazz_irq(s);
 break;
 default:
-RC4030_ERROR("(jazz io controller) invalid write of 0x%04x at [" 
TARGET_FMT_plx "]\n", val, addr);
+qemu_log_mask(LOG_GUEST_ERROR,
+  "rc4030/jazzio: invalid write of 0x%02x at 0x%x",
+  val, (int)addr);
 break;
 }
 }
@@ -713,28 +686,6 @@ static void rc4030_do_dma(void *opaque, int n, uint8_t 
*buf, int len, int is_wri
 
 s->dma_regs[n][DMA_REG_ENABLE] |= DMA_FLAG_TC_INTR;
 s->dma_regs[n][DMA_REG_COUNT] -= len;
-
-#ifdef DEBUG_RC4030_DMA
-{
-int i, j;
-printf("rc4030 dma: Copying %d bytes %s hos

[Qemu-devel] [PATCH 7/7] rc4030: convert to QOM

2013-12-22 Thread Hervé Poussineau

Signed-off-by: Hervé Poussineau 
---
 hw/dma/rc4030.c|  118 +---
 hw/mips/mips_jazz.c|   37 +--
 include/hw/mips/mips.h |4 +-
 3 files changed, 115 insertions(+), 44 deletions(-)

diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c
index 198bbdd..5aa861d 100644
--- a/hw/dma/rc4030.c
+++ b/hw/dma/rc4030.c
@@ -1,7 +1,7 @@
 /*
  * QEMU JAZZ RC4030 chipset
  *
- * Copyright (c) 2007-2009 Herve Poussineau
+ * Copyright (c) 2007-2013 Hervé Poussineau
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to 
deal
@@ -24,6 +24,7 @@
 
 #include "hw/hw.h"
 #include "hw/mips/mips.h"
+#include "hw/sysbus.h"
 #include "qemu/timer.h"
 #include "exec/address-spaces.h"
 #include "trace.h"
@@ -49,8 +50,14 @@ typedef struct dma_pagetable_entry {
 #define DMA_FLAG_MEM_INTR   0x0200
 #define DMA_FLAG_ADDR_INTR  0x0400
 
+#define TYPE_RC4030 "rc4030"
+#define RC4030(obj) \
+OBJECT_CHECK(rc4030State, (obj), TYPE_RC4030)
+
 typedef struct rc4030State
 {
+SysBusDevice parent_obj;
+
 uint32_t config; /* 0x: RC4030 config register */
 uint32_t revision; /* 0x0008: RC4030 Revision register */
 uint32_t invalid_address_register; /* 0x0010: Invalid Address register */
@@ -307,7 +314,7 @@ static void rc4030_dma_table_update(rc4030State *s, 
uint32_t new_tl_base,
 new_tl_base &= 0x7fff;
 
 if (s->dma_tl_limit) {
-memory_region_init_rom_device(&s->dma_table, NULL,
+memory_region_init_rom_device(&s->dma_table, OBJECT(s),
   &rc4030_dma_table_ops, s,
   "dma-translation-table", 
s->dma_tl_limit);
 dma_tl_contents = memory_region_get_ram_ptr(&s->dma_table);
@@ -322,7 +329,7 @@ static void rc4030_dma_table_update(rc4030State *s, 
uint32_t new_tl_base,
 &s->dma_table);
 memory_region_transaction_commit();
 } else {
-memory_region_init(&s->dma_table, NULL,
+memory_region_init(&s->dma_table, OBJECT(s),
"dma-translation-table", 0);
 }
 }
@@ -567,9 +574,9 @@ static const MemoryRegionOps jazzio_ops = {
 .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void rc4030_reset(void *opaque)
+static void rc4030_reset(DeviceState *dev)
 {
-rc4030State *s = opaque;
+rc4030State *s = RC4030(dev);
 int i;
 
 s->config = 0x410; /* some boards seem to accept 0x104 too */
@@ -722,42 +729,99 @@ static rc4030_dma *rc4030_allocate_dmas(void *opaque, int 
n)
 return s;
 }
 
-AddressSpace *rc4030_init(qemu_irq timer, qemu_irq jazz_bus,
-  qemu_irq **irqs, rc4030_dma **dmas,
-  MemoryRegion *sysmem)
+static void rc4030_initfn(Object *obj)
 {
-rc4030State *s;
-int i;
-
-s = g_malloc0(sizeof(rc4030State));
+DeviceState *dev = DEVICE(obj);
+rc4030State *s = RC4030(obj);
+SysBusDevice *sysbus = SYS_BUS_DEVICE(obj);
 
-*irqs = qemu_allocate_irqs(rc4030_irq_jazz_request, s, 16);
-*dmas = rc4030_allocate_dmas(s, 4);
+qdev_init_gpio_in(dev, rc4030_irq_jazz_request, 16);
 
-s->periodic_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 
rc4030_periodic_timer, s);
-s->timer_irq = timer;
-s->jazz_bus_irq = jazz_bus;
+sysbus_init_irq(sysbus, &s->timer_irq);
+sysbus_init_irq(sysbus, &s->jazz_bus_irq);
 
-qemu_register_reset(rc4030_reset, s);
 register_savevm(NULL, "rc4030", 0, 2, rc4030_save, rc4030_load, s);
 
-memory_region_init_io(&s->iomem_chipset, NULL, &rc4030_ops, s,
+sysbus_init_mmio(sysbus, &s->iomem_chipset);
+sysbus_init_mmio(sysbus, &s->iomem_jazzio);
+}
+
+static void rc4030_realize(DeviceState *dev, Error **errp)
+{
+rc4030State *s = RC4030(dev);
+Object *o = OBJECT(dev);
+int i;
+
+s->periodic_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, rc4030_periodic_timer,
+ s);
+
+memory_region_init_io(&s->iomem_chipset, o, &rc4030_ops, s,
   "rc4030", 0x300);
-memory_region_add_subregion(sysmem, 0x8000, &s->iomem_chipset);
-memory_region_init_io(&s->iomem_jazzio, NULL, &jazzio_ops, s,
+memory_region_init_io(&s->iomem_jazzio, o, &jazzio_ops, s,
   "jazzio", 0x1000);
-memory_region_add_subregion(sysmem, 0xf000, &s->iomem_jazzio);
 
-memory_region_init(&s->dma_table, NULL, "dma-translation-table", 0);
-memory_region_init(&s->dma_region, NULL, "dma-region", INT32_MAX);
+memory_region_init(&s->dma_table, o, "dma-translation-table", 0);
+memory_region_init(&s->dma_region, o, "dma-region", INT32_MAX);
 for (i = 0; i < MAX_TL_ENTRIES; ++i) {
-memory_region_init_alias(&s->dma_aliases[i], NULL, "dma-alias",
+memory_region_init_alias(&s->dma_aliases[i], o, "dma-alias",
 

Re: [Qemu-devel] [PATCH] mainstone: Fix duplicate array values for key 'space'

2013-12-22 Thread Peter Maydell
On 22 December 2013 14:11, Stefan Weil  wrote:
> cgcc reported a duplicate initialisation. Mainstone includes a matrix
> keyboard where two different positions map to 'space'.
>
> QEMU uses the reversed mapping and cannot map 'space' to two different
> matrix positions.
>
> Signed-off-by: Stefan Weil 
> ---
>
> Of course we could also randomly select one of the two matrix positions,
> but I assume that this is not necessary.

That would be kind of silly :-)  We can either map 'space' to just
one of the emulated mainstone keys, or we pick another key
to map to the second 'space'. I don't know the hardware either,
so don't know which would be preferable.

> I don't know any mainstone internals, so I had to look into the Linux
> code where I noticed some discrepancies which should be clarified:
>
> Extract from Linux:
>
> KEY(1, 5, KEY_LEFTSHIFT),
> KEY(2, 5, KEY_SPACE),
> KEY(3, 5, KEY_SPACE),
> KEY(4, 5, KEY_ENTER),
> KEY(5, 5, KEY_BACKSPACE),
>
> Extract from QEMU:
>
> [0x2a] = {5,1}, /* shift */
> [0x39] = {5,2}, /* space */
> [0x39] = {5,3}, /* space */
> [0x1c] = {5,5}, /*  enter */
>
> It looks like the 'enter' key is not mapped correctly,
> and 'backspace' is missing.

There are some other missing keys if you believe the Linux
mapping. See also the kernel commit message 55c26e40
which suggests there are still further hardware keys which
aren't handled by a single simple row/column.

In all I would classify this under "don't bother fixing
unless somebody actually complains, preferably with
a confirmation that the kernel they're using does work
correctly on real hardware".

>  hw/arm/mainstone.c |2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
> index 9402c84..223a4b1 100644
> --- a/hw/arm/mainstone.c
> +++ b/hw/arm/mainstone.c
> @@ -76,7 +76,9 @@ static struct keymap map[0xE0] = {
>  [0xc7] = {5,0}, /* Home */
>  [0x2a] = {5,1}, /* shift */
>  [0x39] = {5,2}, /* space */
> +#if 0 /* always map to first column, row pair */
>  [0x39] = {5,3}, /* space */
> +#endif

A few remarks here. Firstly, this is a change of behaviour,
because  with the previous duplicate the compiler picks the
last of the dup entries, so {5, 3}. (checked vs gcc and clang.)
In the absence of any definite reason to switch we should
definitely prefer to make no change in behaviour.

Secondly, no #if 0, please. Add a descriptive comment about
the lack of a key to map to the other matrix position.

Thirdly, is this really stable material? It's been this way for
six years, and the only actual effect is that you get a warning
from a picky static analysis tool...

thanks
-- PMM



Re: [Qemu-devel] [PATCH v3] Add DSDT node for AppleSMC

2013-12-22 Thread Laszlo Ersek
On 12/22/13 16:34, Gabriel L. Somlo wrote:
> AppleSMC (-device isa-applesmc) is required to boot OS X guests.
> OS X expects a SMC node to be present in the ACPI DSDT. This patch
> adds a SMC node to the DSDT, and dynamically patches the return value
> of SMC._STA to either 0x0B if the chip is present, or otherwise to 0x00,
> before booting the guest.
> 
> Signed-off-by: Gabriel Somlo 
> ---
> 
> On Sun, Dec 22, 2013 at 01:07:13PM +0200, Michael S. Tsirkin wrote:
>>> +#define _CONCAT_SYM(a, b) a##b
>>> +#define CONCAT_SYM(a, b) _CONCAT_SYM(a, b)
>>
>> Seems too complex. If one looks for q35_smc_sta one can not find it
> 
> You're right, I went all "Rube Goldberg" on that one - thanks for
> pulling me back from the edge :)
> 
>>> +unsigned short smc_sta_val = 0x00;
>>
>> Better initialize this in the else branch below.
> 
> I threw in "applesmc_find()" to make that even cleaner and easier to
> follow.
> 
> Thanks,
>   Gabriel
> 
>  hw/misc/applesmc.c|  1 -
>  include/hw/isa/isa.h  |  7 +++
>  hw/i386/acpi-dsdt.dsl |  1 +
>  hw/i386/q35-acpi-dsdt.dsl |  1 +
>  hw/i386/acpi-dsdt-isa.dsl | 11 +++
>  hw/i386/acpi-build.c  |  9 +
>  6 files changed, 29 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
> index 1e8d183..627adb9 100644
> --- a/hw/misc/applesmc.c
> +++ b/hw/misc/applesmc.c
> @@ -66,7 +66,6 @@ struct AppleSMCData {
>  QLIST_ENTRY(AppleSMCData) node;
>  };
>  
> -#define TYPE_APPLE_SMC "isa-applesmc"
>  #define APPLE_SMC(obj) OBJECT_CHECK(AppleSMCState, (obj), TYPE_APPLE_SMC)
>  
>  typedef struct AppleSMCState AppleSMCState;
> diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
> index fa45a5b..e0c749f 100644
> --- a/include/hw/isa/isa.h
> +++ b/include/hw/isa/isa.h
> @@ -20,6 +20,13 @@
>  #define TYPE_ISA_BUS "ISA"
>  #define ISA_BUS(obj) OBJECT_CHECK(ISABus, (obj), TYPE_ISA_BUS)
>  
> +#define TYPE_APPLE_SMC "isa-applesmc"
> +
> +static inline bool applesmc_find(void)
> +{
> +return object_resolve_path_type("", TYPE_APPLE_SMC, NULL);
> +}
> +
>  typedef struct ISADeviceClass {
>  DeviceClass parent_class;
>  } ISADeviceClass;
> diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl
> index a377424..b87c6e0 100644
> --- a/hw/i386/acpi-dsdt.dsl
> +++ b/hw/i386/acpi-dsdt.dsl
> @@ -114,6 +114,7 @@ DefinitionBlock (
>  }
>  }
>  
> +#define DSDT_APPLESMC_STA piix_dsdt_applesmc_sta
>  #include "acpi-dsdt-isa.dsl"
>  
>  
> diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl
> index 575c5d7..12ff544 100644
> --- a/hw/i386/q35-acpi-dsdt.dsl
> +++ b/hw/i386/q35-acpi-dsdt.dsl
> @@ -171,6 +171,7 @@ DefinitionBlock (
>  }
>  }
>  
> +#define DSDT_APPLESMC_STA q35_dsdt_applesmc_sta
>  #include "acpi-dsdt-isa.dsl"
>  
>  
> diff --git a/hw/i386/acpi-dsdt-isa.dsl b/hw/i386/acpi-dsdt-isa.dsl
> index 89caa16..46942c1 100644
> --- a/hw/i386/acpi-dsdt-isa.dsl
> +++ b/hw/i386/acpi-dsdt-isa.dsl
> @@ -16,6 +16,17 @@
>  /* Common legacy ISA style devices. */
>  Scope(\_SB.PCI0.ISA) {
>  
> +Device (SMC) {
> +Name(_HID, EisaId("APP0001"))
> +/* _STA will be patched to 0x0B if AppleSMC is present */
> +ACPI_EXTRACT_NAME_WORD_CONST DSDT_APPLESMC_STA
> +Name(_STA, 0xFF00)
> +Name(_CRS, ResourceTemplate () {
> +IO (Decode16, 0x0300, 0x0300, 0x01, 0x20)
> +IRQNoFlags() { 6 }
> +})
> +}
> +
>  Device(RTC) {
>  Name(_HID, EisaId("PNP0B00"))
>  Name(_CRS, ResourceTemplate() {
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 48312f5..30bfcd2 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -36,6 +36,7 @@
>  #include "hw/nvram/fw_cfg.h"
>  #include "bios-linker-loader.h"
>  #include "hw/loader.h"
> +#include "hw/isa/isa.h"
>  
>  /* Supported chipsets: */
>  #include "hw/acpi/piix4.h"
> @@ -80,6 +81,7 @@ typedef struct AcpiMiscInfo {
>  
>  static void acpi_get_dsdt(AcpiMiscInfo *info)
>  {
> +unsigned short applesmc_sta_val, *applesmc_sta_off;
>  Object *piix = piix4_pm_find();
>  Object *lpc = ich9_lpc_find();
>  assert(!!piix != !!lpc);
> @@ -87,11 +89,18 @@ static void acpi_get_dsdt(AcpiMiscInfo *info)
>  if (piix) {
>  info->dsdt_code = AcpiDsdtAmlCode;
>  info->dsdt_size = sizeof AcpiDsdtAmlCode;
> +applesmc_sta_off = piix_dsdt_applesmc_sta;
>  }
>  if (lpc) {
>  info->dsdt_code = Q35AcpiDsdtAmlCode;
>  info->dsdt_size = sizeof Q35AcpiDsdtAmlCode;
> +applesmc_sta_off = q35_dsdt_applesmc_sta;
>  }
> +
> +/* Patch in appropriate value for AppleSMC _STA */
> +applesmc_sta_val = applesmc_find() ? 0x0b : 0x00;
> +*(uint16_t *)(info->dsdt_code + *applesmc_sta_off) =
> +cpu_to_le16(applesmc_sta_val);
>  }
>  
>  static
> 

My comments below don't constitute a review by any means, this is just a
note for your consideration.

After this patch, ISA interrupt 6 is

Re: [Qemu-devel] [PATCH v2] softfloat: Fix factor 2 error for scalbn on denormal inputs

2013-12-22 Thread Aurelien Jarno
On Sat, Dec 21, 2013 at 09:08:19PM +, Peter Maydell wrote:
> If the input to float*_scalbn() is denormal then it represents
> a number 0.[mantissabits] * 2^(1-exponentbias) (and the actual
> exponent field is all zeroes). This means that when we convert
> it to our unpacked encoding the unpacked exponent must be one
> greater than for a normal number, which represents
> 1.[mantissabits] * 2^(e-exponentbias) for an exponent field e.
> 
> This meant we were giving answers too small by a factor of 2 for
> all denormal inputs.
> 
> Note that the float-to-int routines also have this behaviour
> of not adjusting the exponent for denormals; however there it is
> harmless because denormals will all convert to integer zero anyway.
> 
> Signed-off-by: Peter Maydell 
> ---
> Changes v1->v2: propagated fix to 80 bit and 128 bit float functions.
> 
> These function names remind me of Ken Thompson's reply to a question
> about what he'd do differently if he were redesigning UNIX:
> "I'd spell creat with an e."
> 
>  fpu/softfloat.c | 29 +
>  1 file changed, 21 insertions(+), 8 deletions(-)
> 
> diff --git a/fpu/softfloat.c b/fpu/softfloat.c
> index dbda61b..7f5e8c7 100644
> --- a/fpu/softfloat.c
> +++ b/fpu/softfloat.c
> @@ -6795,10 +6795,13 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM 
> )
>  }
>  return a;
>  }
> -if ( aExp != 0 )
> +if (aExp != 0) {
>  aSig |= 0x0080;
> -else if ( aSig == 0 )
> +} else if (aSig == 0) {
>  return a;
> +} else {
> +aExp++;
> +}
>  
>  if (n > 0x200) {
>  n = 0x200;
> @@ -6828,10 +6831,13 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM 
> )
>  }
>  return a;
>  }
> -if ( aExp != 0 )
> +if (aExp != 0) {
>  aSig |= LIT64( 0x0010 );
> -else if ( aSig == 0 )
> +} else if (aSig == 0) {
>  return a;
> +} else {
> +aExp++;
> +}
>  
>  if (n > 0x1000) {
>  n = 0x1000;
> @@ -6861,8 +6867,12 @@ floatx80 floatx80_scalbn( floatx80 a, int n 
> STATUS_PARAM )
>  return a;
>  }
>  
> -if (aExp == 0 && aSig == 0)
> -return a;
> +if (aExp == 0) {
> +if (aSig == 0) {
> +return a;
> +}
> +aExp++;
> +}
>  
>  if (n > 0x1) {
>  n = 0x1;
> @@ -6891,10 +6901,13 @@ float128 float128_scalbn( float128 a, int n 
> STATUS_PARAM )
>  }
>  return a;
>  }
> -if ( aExp != 0 )
> +if (aExp != 0) {
>  aSig0 |= LIT64( 0x0001 );
> -else if ( aSig0 == 0 && aSig1 == 0 )
> +} else if (aSig0 == 0 && aSig1 == 0) {
>  return a;
> +} else {
> +aExp++;
> +}
>  
>  if (n > 0x1) {
>  n = 0x1;

Reviewed-by: Aurelien Jarno 

-- 
Aurelien Jarno  GPG: 1024D/F1BCDB73
aurel...@aurel32.net http://www.aurel32.net



Re: [Qemu-devel] [PATCH] PPC: Fix compilation with TCG debug

2013-12-22 Thread Aurelien Jarno
On Fri, Dec 20, 2013 at 11:01:50AM +0100, Alexander Graf wrote:
> The recent VSX patches broken compilation of QEMU when configurated
> with --enable-debug, as it was treating "target long" TCG variables
> as "i64" which is not true for 32bit targets.
> 
> This patch fixes all the places that the compiler has found to use
> the correct variable type and if necessary manually cast.
> 
> Reported-by: Stefan Weil 
> Signed-off-by: Alexander Graf 
> ---
>  target-ppc/translate.c | 143 
> -
>  1 file changed, 81 insertions(+), 62 deletions(-)
> 
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index ea58dc9..c5c1108 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -2567,6 +2567,14 @@ static inline void gen_qemu_ld32u(DisasContext *ctx, 
> TCGv arg1, TCGv arg2)
>  }
>  }
>  
> +static void gen_qemu_ld32u_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
> +{
> +TCGv tmp = tcg_temp_new();
> +gen_qemu_ld32u(ctx, tmp, addr);
> +tcg_gen_extu_tl_i64(val, tmp);
> +tcg_temp_free(tmp);
> +}
> +
>  static inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
>  {
>  if (unlikely(ctx->le_mode)) {
> @@ -2616,6 +2624,14 @@ static inline void gen_qemu_st32(DisasContext *ctx, 
> TCGv arg1, TCGv arg2)
>  }
>  }
>  
> +static void gen_qemu_st32_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
> +{
> +TCGv tmp = tcg_temp_new();
> +tcg_gen_trunc_i64_tl(tmp, val);
> +gen_qemu_st32(ctx, tmp, addr);
> +tcg_temp_free(tmp);
> +}
> +
>  static inline void gen_qemu_st64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
>  {
>  if (unlikely(ctx->le_mode)) {
> @@ -7048,13 +7064,14 @@ static void gen_lxvdsx(DisasContext *ctx)
>  EA = tcg_temp_new();
>  gen_addr_reg_index(ctx, EA);
>  gen_qemu_ld64(ctx, cpu_vsrh(xT(ctx->opcode)), EA);
> -tcg_gen_mov_tl(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xT(ctx->opcode)));
> +tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xT(ctx->opcode)));
>  tcg_temp_free(EA);
>  }
>  
>  static void gen_lxvw4x(DisasContext *ctx)
>  {
> -TCGv EA, tmp;
> +TCGv EA;
> +TCGv_i64 tmp;
>  TCGv_i64 xth = cpu_vsrh(xT(ctx->opcode));
>  TCGv_i64 xtl = cpu_vsrl(xT(ctx->opcode));
>  if (unlikely(!ctx->vsx_enabled)) {
> @@ -7063,21 +7080,22 @@ static void gen_lxvw4x(DisasContext *ctx)
>  }
>  gen_set_access_type(ctx, ACCESS_INT);
>  EA = tcg_temp_new();
> -tmp = tcg_temp_new();
> +tmp = tcg_temp_new_i64();
> +
>  gen_addr_reg_index(ctx, EA);
> -gen_qemu_ld32u(ctx, tmp, EA);
> +gen_qemu_ld32u_i64(ctx, tmp, EA);
>  tcg_gen_addi_tl(EA, EA, 4);
> -gen_qemu_ld32u(ctx, xth, EA);
> +gen_qemu_ld32u_i64(ctx, xth, EA);
>  tcg_gen_deposit_i64(xth, xth, tmp, 32, 32);
>  
>  tcg_gen_addi_tl(EA, EA, 4);
> -gen_qemu_ld32u(ctx, tmp, EA);
> +gen_qemu_ld32u_i64(ctx, tmp, EA);
>  tcg_gen_addi_tl(EA, EA, 4);
> -gen_qemu_ld32u(ctx, xtl, EA);
> +gen_qemu_ld32u_i64(ctx, xtl, EA);
>  tcg_gen_deposit_i64(xtl, xtl, tmp, 32, 32);
>  
>  tcg_temp_free(EA);
> -tcg_temp_free(tmp);
> +tcg_temp_free_i64(tmp);
>  }
>  
>  static void gen_stxsdx(DisasContext *ctx)
> @@ -7112,7 +7130,8 @@ static void gen_stxvd2x(DisasContext *ctx)
>  
>  static void gen_stxvw4x(DisasContext *ctx)
>  {
> -TCGv EA, tmp;
> +TCGv_i64 tmp;
> +TCGv EA;
>  if (unlikely(!ctx->vsx_enabled)) {
>  gen_exception(ctx, POWERPC_EXCP_VSXU);
>  return;
> @@ -7120,21 +7139,21 @@ static void gen_stxvw4x(DisasContext *ctx)
>  gen_set_access_type(ctx, ACCESS_INT);
>  EA = tcg_temp_new();
>  gen_addr_reg_index(ctx, EA);
> -tmp = tcg_temp_new();
> +tmp = tcg_temp_new_i64();
>  
>  tcg_gen_shri_i64(tmp, cpu_vsrh(xS(ctx->opcode)), 32);
> -gen_qemu_st32(ctx, tmp, EA);
> +gen_qemu_st32_i64(ctx, tmp, EA);
>  tcg_gen_addi_tl(EA, EA, 4);
> -gen_qemu_st32(ctx, cpu_vsrh(xS(ctx->opcode)), EA);
> +gen_qemu_st32_i64(ctx, cpu_vsrh(xS(ctx->opcode)), EA);
>  
>  tcg_gen_shri_i64(tmp, cpu_vsrl(xS(ctx->opcode)), 32);
>  tcg_gen_addi_tl(EA, EA, 4);
> -gen_qemu_st32(ctx, tmp, EA);
> +gen_qemu_st32_i64(ctx, tmp, EA);
>  tcg_gen_addi_tl(EA, EA, 4);
> -gen_qemu_st32(ctx, cpu_vsrl(xS(ctx->opcode)), EA);
> +gen_qemu_st32_i64(ctx, cpu_vsrl(xS(ctx->opcode)), EA);
>  
>  tcg_temp_free(EA);
> -tcg_temp_free(tmp);
> +tcg_temp_free_i64(tmp);
>  }
>  
>  static void gen_xxpermdi(DisasContext *ctx)
> @@ -7171,8 +7190,8 @@ static void glue(gen_, name)(DisasContext * ctx)
>   \
>  gen_exception(ctx, POWERPC_EXCP_VSXU);\
>  return;   \
>  } \
> -xb = tcg_temp_new();  \
> -sgm = tcg_temp_new(); \
> +

Re: [Qemu-devel] [PATCH] tcg-i386: Use MOVBE if available

2013-12-22 Thread Richard Henderson
On 12/22/2013 04:24 AM, Aurelien Jarno wrote:
> On Sat, Dec 21, 2013 at 03:08:21PM +0100, Paolo Bonzini wrote:
>> Il 21/12/2013 00:00, Richard Henderson ha scritto:
>>> +if (real_bswap && have_movbe) {
>>> +tcg_out_modrm_offset(s, OPC_MOVBE_GyMy + P_DATA16 + seg,
>>> + datalo, base, ofs);
>>> +tcg_out_ext16u(s, datalo, datalo);
>>
>> Do partial register stalls still exist on Atom and Haswell?  I don't
>> remember exactly what you had to do to prevent them, but IIRC you first
>> moved zero to the register and then overwrote the the low 16 bits.
> 
> Note that for unsigned 16-bit load you can do either movzw + bswap or 
> movbe + movzw.

>From the July 2013 Intel Opt Ref Manual,

"Delay of partial register stall is small in ... Intel Core and NetBurst
microarchitectures".  And for Atom "partial register access does not cause
additional delay".

While I agree with Paulo that xor + movbe is probably technically the best, one
has to check for output register overlap and have a fallback.  Thus I think we
can just discard that idea.

As for movzw + bswap, that forces a partial register stall on subsequent 32-bit
access to the value, while movbe + movzw does not.  In the later case we refer
to the unmerged portion of the register in the movzw.

But the optimization note suggests that it shouldn't matter much either way.


r~



Re: [Qemu-devel] [PATCH v2] softfloat: Fix factor 2 error for scalbn on denormal inputs

2013-12-22 Thread Richard Henderson
On 12/21/2013 01:08 PM, Peter Maydell wrote:
> If the input to float*_scalbn() is denormal then it represents
> a number 0.[mantissabits] * 2^(1-exponentbias) (and the actual
> exponent field is all zeroes). This means that when we convert
> it to our unpacked encoding the unpacked exponent must be one
> greater than for a normal number, which represents
> 1.[mantissabits] * 2^(e-exponentbias) for an exponent field e.
> 
> This meant we were giving answers too small by a factor of 2 for
> all denormal inputs.
> 
> Note that the float-to-int routines also have this behaviour
> of not adjusting the exponent for denormals; however there it is
> harmless because denormals will all convert to integer zero anyway.
> 
> Signed-off-by: Peter Maydell 
> ---
> Changes v1->v2: propagated fix to 80 bit and 128 bit float functions.
> 
> These function names remind me of Ken Thompson's reply to a question
> about what he'd do differently if he were redesigning UNIX:
> "I'd spell creat with an e."
> 
>  fpu/softfloat.c | 29 +
>  1 file changed, 21 insertions(+), 8 deletions(-)

Reviewed-by: Richard Henderson 


r~



Re: [Qemu-devel] [PATCH 2/5] tcg/i386: remove hardcoded P_REXW value

2013-12-22 Thread Richard Henderson
On 12/21/2013 08:43 AM, Aurelien Jarno wrote:
> P_REXW is defined has a constant at the beginning of i386/tcg-target.c,
> but the corresponding bit is later used in a harcoded way, which defeat
> the purpose of a constant.
> 
> Fix that by using a conditional expression operator instead of a shift.
> On x86 this actually makes the code slightly smaller as GCC does in
> practice (opc >> 8) & 8 instead of (opc & 0x800) >> 8 so the constants
> are smaller to load.
> 
> Signed-off-by: Aurelien Jarno 
> ---
>  tcg/i386/tcg-target.c |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)


Reviewed-by: Richard Henderson 


r~



Re: [Qemu-devel] [PATCH 1/5] disas/i386.c: disassemble movbe instruction

2013-12-22 Thread Richard Henderson
On 12/21/2013 08:43 AM, Aurelien Jarno wrote:
> Signed-off-by: Aurelien Jarno 
> ---
>  disas/i386.c |8 
>  1 file changed, 4 insertions(+), 4 deletions(-)

Reviewed-by: Richard Henderson 


r~



Re: [Qemu-devel] [PATCH 5/5] tcg/i386: cleanup useless #ifdef

2013-12-22 Thread Richard Henderson
On 12/21/2013 08:43 AM, Aurelien Jarno wrote:
> TCG_TARGET_HAS_movcond_i32 is always defined to 1 in tcg-target.h, so
> remove the corresponding #ifdef #endif sequence, left from a previous
> refactoring.
> 
> Signed-off-by: Aurelien Jarno 
> ---
>  tcg/i386/tcg-target.c |2 --
>  1 file changed, 2 deletions(-)


Reviewed-by: Richard Henderson 


r~



Re: [Qemu-devel] [PATCH 3/5] tcg/i386: add support for three-byte opcodes

2013-12-22 Thread Richard Henderson
On 12/21/2013 08:43 AM, Aurelien Jarno wrote:
> +#define P_EXT2  0x200   /* 0x0f 0x38 opcode prefix */

I'm not keen on the name.  It's not like the different extensions are numbered.


r~



Re: [Qemu-devel] [PATCH 4/5] tcg/i386: use movbe instruction in qemu_ldst routines

2013-12-22 Thread Richard Henderson
On 12/21/2013 08:43 AM, Aurelien Jarno wrote:
> +/* If bit_MOVBE is defined in cpuid.h (added in GCC version 4.6), we are
> +   going to attempt to determine at runtime whether movbe is available.  */
> +#if defined(CONFIG_CPUID_H) && defined(bit_MOVBE)
> +static bool have_movbe;
> +#else
> +# define have_movbe 0
> +#endif
> +

Good point about checking bit_MOVBE, I missed that in my version.

I do slightly prefer hoisting the mov opcode, as I do in my version.
I think that tidies the 32 and 64-bit paths a bit.  Nothing can really help
adding extra conditionals to the 16-bit load paths though.


r~



Re: [Qemu-devel] [PATCH] bitops: provide an inline implementation of find_first_bit

2013-12-22 Thread Richard Henderson
On 12/22/2013 03:32 AM, Aurelien Jarno wrote:
> find_first_bit has started to be used heavily in TCG code. The current
> implementation based on find_next_bit is not optimal and can't be
> optimized be the compiler if the bit array has a fixed size, which is
> the case most of the time.
> 
> This new implementation does not use find_next_bit and is yet small
> enough to be inlined.
> 
> Cc: Richard Henderson 
> Cc: Corentin Chary 
> 
> Signed-off-by: Aurelien Jarno 
> ---
>  include/qemu/bitops.h |   12 +++-
>  1 file changed, 11 insertions(+), 1 deletion(-)

Reviewed-by: Richard Henderson 


r~



Re: [Qemu-devel] [PATCH v3] Add DSDT node for AppleSMC

2013-12-22 Thread Gabriel L. Somlo
On Sun, Dec 22, 2013 at 04:58:58PM +0100, Laszlo Ersek wrote:
> After this patch, ISA interrupt 6 is used by both "SMC" and "FDC0". The
> latter depends on the FDEN object, but FDEN is currently constant 1.
> 
> Probably not a problem in practice (ie. most users won't try to specify
> both a floppy disk controller and an AppleSMC device), but you might
> want to handle that case nonetheless (exit with an error or some such).

I couldn't find a command line option to prevent QEMU from starting
with a floppy controller, so unless I missed it, we'd always detect
a "conflict".

According to the applesmc.c source, the emulated Apple SMC doesn't
support IRQ, so the number itself should be irrelevant. IRQ #6 is
what's used on real Apple hardware, but when I tried with a different
number (e.g. #5), OS X booted fine in QEMU (it does fail to boot if
we leave out IRQNoFlags entirely from the SMC DSDT node, though).

I could patch the value of FDEN to 0 whenever I enable the SMC _STA
method (i.e, when I patch its value to 0x0B), but that still wouldn't
take care of the fact that the emulated FDC is still present.

So, my preferred course of action would be, in this order:

1. Do nothing :)

or

2. Use "IRQNoFlags() { 5 }" with the SMC (or any other
   number that isn't already allocated.

Any other suggestions or ideas would be welcome !

Thanks,
--Gabriel



Re: [Qemu-devel] [PATCH] PPC: Fix compilation with TCG debug

2013-12-22 Thread Alexander Graf

On 22.12.2013, at 17:37, Aurelien Jarno  wrote:

> On Fri, Dec 20, 2013 at 11:01:50AM +0100, Alexander Graf wrote:
>> The recent VSX patches broken compilation of QEMU when configurated
>> with --enable-debug, as it was treating "target long" TCG variables
>> as "i64" which is not true for 32bit targets.
>> 
>> This patch fixes all the places that the compiler has found to use
>> the correct variable type and if necessary manually cast.
>> 
>> Reported-by: Stefan Weil 
>> Signed-off-by: Alexander Graf 
>> ---
>> target-ppc/translate.c | 143 
>> -
>> 1 file changed, 81 insertions(+), 62 deletions(-)
>> 
>> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
>> index ea58dc9..c5c1108 100644
>> --- a/target-ppc/translate.c
>> +++ b/target-ppc/translate.c
>> @@ -2567,6 +2567,14 @@ static inline void gen_qemu_ld32u(DisasContext *ctx, 
>> TCGv arg1, TCGv arg2)
>> }
>> }
>> 
>> +static void gen_qemu_ld32u_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
>> +{
>> +TCGv tmp = tcg_temp_new();
>> +gen_qemu_ld32u(ctx, tmp, addr);
>> +tcg_gen_extu_tl_i64(val, tmp);
>> +tcg_temp_free(tmp);
>> +}
>> +
>> static inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
>> {
>> if (unlikely(ctx->le_mode)) {
>> @@ -2616,6 +2624,14 @@ static inline void gen_qemu_st32(DisasContext *ctx, 
>> TCGv arg1, TCGv arg2)
>> }
>> }
>> 
>> +static void gen_qemu_st32_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
>> +{
>> +TCGv tmp = tcg_temp_new();
>> +tcg_gen_trunc_i64_tl(tmp, val);
>> +gen_qemu_st32(ctx, tmp, addr);
>> +tcg_temp_free(tmp);
>> +}
>> +
>> static inline void gen_qemu_st64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
>> {
>> if (unlikely(ctx->le_mode)) {
>> @@ -7048,13 +7064,14 @@ static void gen_lxvdsx(DisasContext *ctx)
>> EA = tcg_temp_new();
>> gen_addr_reg_index(ctx, EA);
>> gen_qemu_ld64(ctx, cpu_vsrh(xT(ctx->opcode)), EA);
>> -tcg_gen_mov_tl(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xT(ctx->opcode)));
>> +tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xT(ctx->opcode)));
>> tcg_temp_free(EA);
>> }
>> 
>> static void gen_lxvw4x(DisasContext *ctx)
>> {
>> -TCGv EA, tmp;
>> +TCGv EA;
>> +TCGv_i64 tmp;
>> TCGv_i64 xth = cpu_vsrh(xT(ctx->opcode));
>> TCGv_i64 xtl = cpu_vsrl(xT(ctx->opcode));
>> if (unlikely(!ctx->vsx_enabled)) {
>> @@ -7063,21 +7080,22 @@ static void gen_lxvw4x(DisasContext *ctx)
>> }
>> gen_set_access_type(ctx, ACCESS_INT);
>> EA = tcg_temp_new();
>> -tmp = tcg_temp_new();
>> +tmp = tcg_temp_new_i64();
>> +
>> gen_addr_reg_index(ctx, EA);
>> -gen_qemu_ld32u(ctx, tmp, EA);
>> +gen_qemu_ld32u_i64(ctx, tmp, EA);
>> tcg_gen_addi_tl(EA, EA, 4);
>> -gen_qemu_ld32u(ctx, xth, EA);
>> +gen_qemu_ld32u_i64(ctx, xth, EA);
>> tcg_gen_deposit_i64(xth, xth, tmp, 32, 32);
>> 
>> tcg_gen_addi_tl(EA, EA, 4);
>> -gen_qemu_ld32u(ctx, tmp, EA);
>> +gen_qemu_ld32u_i64(ctx, tmp, EA);
>> tcg_gen_addi_tl(EA, EA, 4);
>> -gen_qemu_ld32u(ctx, xtl, EA);
>> +gen_qemu_ld32u_i64(ctx, xtl, EA);
>> tcg_gen_deposit_i64(xtl, xtl, tmp, 32, 32);
>> 
>> tcg_temp_free(EA);
>> -tcg_temp_free(tmp);
>> +tcg_temp_free_i64(tmp);
>> }
>> 
>> static void gen_stxsdx(DisasContext *ctx)
>> @@ -7112,7 +7130,8 @@ static void gen_stxvd2x(DisasContext *ctx)
>> 
>> static void gen_stxvw4x(DisasContext *ctx)
>> {
>> -TCGv EA, tmp;
>> +TCGv_i64 tmp;
>> +TCGv EA;
>> if (unlikely(!ctx->vsx_enabled)) {
>> gen_exception(ctx, POWERPC_EXCP_VSXU);
>> return;
>> @@ -7120,21 +7139,21 @@ static void gen_stxvw4x(DisasContext *ctx)
>> gen_set_access_type(ctx, ACCESS_INT);
>> EA = tcg_temp_new();
>> gen_addr_reg_index(ctx, EA);
>> -tmp = tcg_temp_new();
>> +tmp = tcg_temp_new_i64();
>> 
>> tcg_gen_shri_i64(tmp, cpu_vsrh(xS(ctx->opcode)), 32);
>> -gen_qemu_st32(ctx, tmp, EA);
>> +gen_qemu_st32_i64(ctx, tmp, EA);
>> tcg_gen_addi_tl(EA, EA, 4);
>> -gen_qemu_st32(ctx, cpu_vsrh(xS(ctx->opcode)), EA);
>> +gen_qemu_st32_i64(ctx, cpu_vsrh(xS(ctx->opcode)), EA);
>> 
>> tcg_gen_shri_i64(tmp, cpu_vsrl(xS(ctx->opcode)), 32);
>> tcg_gen_addi_tl(EA, EA, 4);
>> -gen_qemu_st32(ctx, tmp, EA);
>> +gen_qemu_st32_i64(ctx, tmp, EA);
>> tcg_gen_addi_tl(EA, EA, 4);
>> -gen_qemu_st32(ctx, cpu_vsrl(xS(ctx->opcode)), EA);
>> +gen_qemu_st32_i64(ctx, cpu_vsrl(xS(ctx->opcode)), EA);
>> 
>> tcg_temp_free(EA);
>> -tcg_temp_free(tmp);
>> +tcg_temp_free_i64(tmp);
>> }
>> 
>> static void gen_xxpermdi(DisasContext *ctx)
>> @@ -7171,8 +7190,8 @@ static void glue(gen_, name)(DisasContext * ctx)   
>>\
>> gen_exception(ctx, POWERPC_EXCP_VSXU);\
>> return;   \
>> } \
>> -xb = tcg_t

Re: [Qemu-devel] [PATCH] softfloat: Only raise Invalid when conversions to int are out of range

2013-12-22 Thread Aurelien Jarno
On Thu, Dec 19, 2013 at 10:00:18PM +, Peter Maydell wrote:
> We implement a number of float-to-integer conversions using conversion
> to an integer type with a wider range and then a check against the
> narrower range we are actually converting to. If we find the result to
> be out of range we correctly raise the Invalid exception, but we must
> also suppress other exceptions which might have been raised by the
> conversion function we called.
> 
> This won't throw away exceptions we should have preserved, because for
> the 'core' exception flags the IEEE spec mandates that the only valid
> combinations of exception that can be raised by a single operation are
> Inexact + Overflow and Inexact + Underflow. For the non-IEEE softfloat
> flag for input denormals, we can guarantee that that flag won't have
> been set for out of range float-to-int conversions because a squashed
> denormal by definition goes to plus or minus zero, which is always in
> range after conversion to integer zero.
> 
> This bug has been fixed for some of the float-to-int conversion routines
> by previous patches; fix it for the remaining functions as well, so
> that they all restore the pre-conversion status flags prior to raising
> Invalid.
> 
> Signed-off-by: Peter Maydell 
> ---
> NB that I've worded the commit message on the assumption that the
> patches Tom Musta has written for PPC bugs go in first; as it happens
> the patches don't actually conflict, though.
> 
> Some of these fix wrong-exception-flags bugs in 32 bit ARM VCVT.
> 
>  fpu/softfloat.c | 28 
>  1 file changed, 16 insertions(+), 12 deletions(-)
> 
> diff --git a/fpu/softfloat.c b/fpu/softfloat.c
> index dbda61b..253e6b3 100644
> --- a/fpu/softfloat.c
> +++ b/fpu/softfloat.c
> @@ -6432,17 +6432,18 @@ uint32 float32_to_uint32( float32 a STATUS_PARAM )
>  {
>  int64_t v;
>  uint32 res;
> +int old_exc_flags = get_float_exception_flags(status);
>  
>  v = float32_to_int64(a STATUS_VAR);
>  if (v < 0) {
>  res = 0;
> -float_raise( float_flag_invalid STATUS_VAR);
>  } else if (v > 0x) {
>  res = 0x;
> -float_raise( float_flag_invalid STATUS_VAR);
>  } else {
> -res = v;
> +return v;
>  }
> +set_float_exception_flags(old_exc_flags, status);
> +float_raise(float_flag_invalid STATUS_VAR);
>  return res;
>  }
>  
> @@ -6450,17 +6451,18 @@ uint32 float32_to_uint32_round_to_zero( float32 a 
> STATUS_PARAM )
>  {
>  int64_t v;
>  uint32 res;
> +int old_exc_flags = get_float_exception_flags(status);
>  
>  v = float32_to_int64_round_to_zero(a STATUS_VAR);
>  if (v < 0) {
>  res = 0;
> -float_raise( float_flag_invalid STATUS_VAR);
>  } else if (v > 0x) {
>  res = 0x;
> -float_raise( float_flag_invalid STATUS_VAR);
>  } else {
> -res = v;
> +return v;
>  }
> +set_float_exception_flags(old_exc_flags, status);
> +float_raise(float_flag_invalid STATUS_VAR);
>  return res;
>  }
>  
> @@ -6468,17 +6470,18 @@ uint_fast16_t float32_to_uint16_round_to_zero(float32 
> a STATUS_PARAM)
>  {
>  int64_t v;
>  uint_fast16_t res;
> +int old_exc_flags = get_float_exception_flags(status);
>  
>  v = float32_to_int64_round_to_zero(a STATUS_VAR);
>  if (v < 0) {
>  res = 0;
> -float_raise( float_flag_invalid STATUS_VAR);
>  } else if (v > 0x) {
>  res = 0x;
> -float_raise( float_flag_invalid STATUS_VAR);
>  } else {
> -res = v;
> +return v;
>  }
> +set_float_exception_flags(old_exc_flags, status);
> +float_raise(float_flag_invalid STATUS_VAR);
>  return res;
>  }
>  
> @@ -6522,17 +6525,18 @@ uint_fast16_t float64_to_uint16_round_to_zero(float64 
> a STATUS_PARAM)
>  {
>  int64_t v;
>  uint_fast16_t res;
> +int old_exc_flags = get_float_exception_flags(status);
>  
>  v = float64_to_int64_round_to_zero(a STATUS_VAR);
>  if (v < 0) {
>  res = 0;
> -float_raise( float_flag_invalid STATUS_VAR);
>  } else if (v > 0x) {
>  res = 0x;
> -float_raise( float_flag_invalid STATUS_VAR);
>  } else {
> -res = v;
> +return v;
>  }
> +set_float_exception_flags(old_exc_flags, status);
> +float_raise(float_flag_invalid STATUS_VAR);
>  return res;
>  }
>  

Reviewed-by: Aurelien Jarno 

-- 
Aurelien Jarno  GPG: 1024D/F1BCDB73
aurel...@aurel32.net http://www.aurel32.net



Re: [Qemu-devel] [PATCH 1/2] cputlb: Use memset when flushing entries

2013-12-22 Thread Aurelien Jarno
On Sat, Dec 07, 2013 at 10:44:51AM +1300, Richard Henderson wrote:
> The size of tlb_table is 4k on a 64-bit host.  For overwriting
> memory at this size, cacheline tricks can help.
> 
> Signed-off-by: Richard Henderson 
> ---
>  cputlb.c | 19 ++-
>  1 file changed, 2 insertions(+), 17 deletions(-)
> 
> diff --git a/cputlb.c b/cputlb.c
> index fff0afb..d2da404 100644
> --- a/cputlb.c
> +++ b/cputlb.c
> @@ -33,13 +33,6 @@
>  /* statistics */
>  int tlb_flush_count;
>  
> -static const CPUTLBEntry s_cputlb_empty_entry = {
> -.addr_read  = -1,
> -.addr_write = -1,
> -.addr_code  = -1,
> -.addend = -1,
> -};
> -
>  /* NOTE:
>   * If flush_global is true (the usual case), flush all tlb entries.
>   * If flush_global is false, flush (at least) all tlb entries not
> @@ -55,7 +48,6 @@ static const CPUTLBEntry s_cputlb_empty_entry = {
>  void tlb_flush(CPUArchState *env, int flush_global)
>  {
>  CPUState *cpu = ENV_GET_CPU(env);
> -int i;
>  
>  #if defined(DEBUG_TLB)
>  printf("tlb_flush:\n");
> @@ -64,14 +56,7 @@ void tlb_flush(CPUArchState *env, int flush_global)
> links while we are modifying them */
>  cpu->current_tb = NULL;
>  
> -for (i = 0; i < CPU_TLB_SIZE; i++) {
> -int mmu_idx;
> -
> -for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
> -env->tlb_table[mmu_idx][i] = s_cputlb_empty_entry;
> -}
> -}
> -
> +memset(env->tlb_table, -1, sizeof(env->tlb_table));
>  memset(env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
>  
>  env->tlb_flush_addr = -1;
> @@ -87,7 +72,7 @@ static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, 
> target_ulong addr)
>   (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
>  addr == (tlb_entry->addr_code &
>   (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
> -*tlb_entry = s_cputlb_empty_entry;
> +memset(tlb_entry, -1, sizeof(*tlb_entry));
>  }
>  }

Reviewed-by: Aurelien Jarno 

-- 
Aurelien Jarno  GPG: 1024D/F1BCDB73
aurel...@aurel32.net http://www.aurel32.net



Re: [Qemu-devel] [PATCH 2/2] cputlb: Tidy memset of arrays

2013-12-22 Thread Aurelien Jarno
On Sat, Dec 07, 2013 at 10:44:52AM +1300, Richard Henderson wrote:
> Don't duplicate the array length computation in the memset
> when plain sizeof can produce the correct results.
> 
> Signed-off-by: Richard Henderson 
> ---
>  cputlb.c| 2 +-
>  translate-all.c | 5 ++---
>  2 files changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/cputlb.c b/cputlb.c
> index d2da404..9270055 100644
> --- a/cputlb.c
> +++ b/cputlb.c
> @@ -57,7 +57,7 @@ void tlb_flush(CPUArchState *env, int flush_global)
>  cpu->current_tb = NULL;
>  
>  memset(env->tlb_table, -1, sizeof(env->tlb_table));
> -memset(env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
> +memset(env->tb_jmp_cache, 0, sizeof(env->tb_jmp_cache));
>  
>  env->tlb_flush_addr = -1;
>  env->tlb_flush_mask = 0;
> diff --git a/translate-all.c b/translate-all.c
> index aeda54d..66755b1 100644
> --- a/translate-all.c
> +++ b/translate-all.c
> @@ -699,11 +699,10 @@ void tb_flush(CPUArchState *env1)
>  CPU_FOREACH(cpu) {
>  CPUArchState *env = cpu->env_ptr;
>  
> -memset(env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof(void *));
> +memset(env->tb_jmp_cache, 0, sizeof(env->tb_jmp_cache));
>  }
>  
> -memset(tcg_ctx.tb_ctx.tb_phys_hash, 0,
> -CODE_GEN_PHYS_HASH_SIZE * sizeof(void *));
> +memset(tcg_ctx.tb_ctx.tb_phys_hash, 0, 
> sizeof(tcg_ctx.tb_ctx.tb_phys_hash));
>  page_flush_tb();
>  
>  tcg_ctx.code_gen_ptr = tcg_ctx.code_gen_buffer;

Reviewed-by: Aurelien Jarno 

-- 
Aurelien Jarno  GPG: 1024D/F1BCDB73
aurel...@aurel32.net http://www.aurel32.net



[Qemu-devel] [PATCH v2] mainstone: Fix duplicate array values for key 'space'

2013-12-22 Thread Stefan Weil
cgcc reported a duplicate initialisation. Mainstone includes a matrix
keyboard where two different positions map to 'space'.

QEMU uses the reversed mapping and does not map 'space' to two different
matrix positions.

Some other keys are either missing or might be mapped wrongly (cf. Linux
kernel code). Don't fix these until someone can test them with real
hardware, but add TODO comments.

Signed-off-by: Stefan Weil 
---

v2: Address Peter Maydell's suggestions:
* Use first alternative, so there is no change of behaviour
* Don't use #if 0 ... #endif

As there won't be a follow up patch to fix the keyboard matrix,
this patch is no longer needed for qemu-stable.

Please note that checkpatch.pl reports a missing blank after
a comma. This was required to match the existing code.

Regards,
Stefan W.

 hw/arm/mainstone.c |   13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index 9402c84..bfb2b78 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -76,8 +76,17 @@ static struct keymap map[0xE0] = {
 [0xc7] = {5,0}, /* Home */
 [0x2a] = {5,1}, /* shift */
 [0x39] = {5,2}, /* space */
-[0x39] = {5,3}, /* space */
-[0x1c] = {5,5}, /*  enter */
+/*
+ * There are two matrix positions which map to space,
+ * but QEMU can only use one of them for the reverse
+ * mapping, so simply use the first one.
+ */
+/* [0x39] = {5,3}, space */
+/*
+ * Matrix position {5,4} and other keys are missing here.
+ * TODO: Compare with Linux code and test real hardware.
+ */
+[0x1c] = {5,5}, /* enter (TODO: might be wrong) */
 [0xc8] = {6,0}, /* up */
 [0xd0] = {6,1}, /* down */
 [0xcb] = {6,2}, /* left */
-- 
1.7.10.4




Re: [Qemu-devel] [PATCH v2] mainstone: Fix duplicate array values for key 'space'

2013-12-22 Thread Peter Maydell
On 22 December 2013 19:01, Stefan Weil  wrote:
>
> v2: Address Peter Maydell's suggestions:
> * Use first alternative, so there is no change of behaviour

No, I said that the compiler picked the last of the two, (5,3)

>  [0x39] = {5,2}, /* space */
> -[0x39] = {5,3}, /* space */
> -[0x1c] = {5,5}, /*  enter */
> +/*
> + * There are two matrix positions which map to space,
> + * but QEMU can only use one of them for the reverse
> + * mapping, so simply use the first one.
> + */
> +/* [0x39] = {5,3}, space */

So this is still wrong.

> +/*
> + * Matrix position {5,4} and other keys are missing here.
> + * TODO: Compare with Linux code and test real hardware.
> + */
> +[0x1c] = {5,5}, /* enter (TODO: might be wrong) */
>  [0xc8] = {6,0}, /* up */
>  [0xd0] = {6,1}, /* down */
>  [0xcb] = {6,2}, /* left */

thanks
-- PMM



[Qemu-devel] Communication between Windows 7 host and Linux guest

2013-12-22 Thread Gripon Sébastien
Hi,

I have the need to communicate efficiently between Windows 7 host and linux 
guest. I tried first to use an IP socket communication using TAP driver on 
Windows. Unfortunately, we reach a maximum of 4 Mbits/s where I would need 
faster communication (more than 10 Mb/s). I don’t know yet if the TAP driver is 
slow.

Anyway, I wonder if there are other way to do such communication. In the qemu 
reference help, I can see that there are some options to communicate through a 
pipe for example:

-chardev backend ,id=id [,mux=on|off] [,options]
Backend is one of: null, socket, udp, msmouse, vc, ringbuf, file, pipe, 
console, serial, pty, stdio, braille, tty, parallel, parport, spicevmc. 
spiceport. The specific backend will determine the applicable options.

But I don’t really understand what this exactly does and I never managed to use 
it. Is it supposed to map some hardware read/write on read/write on pipe? What 
kind of hardware? How to use it? Do I need modifications on the Linux guest?

Thanks a lot for your help,

sgripon


[Qemu-devel] [PATCH v3] mainstone: Fix duplicate array values for key 'space'

2013-12-22 Thread Stefan Weil
cgcc reported a duplicate initialisation. Mainstone includes a matrix
keyboard where two different positions map to 'space'.

QEMU uses the reversed mapping and does not map 'space' to two different
matrix positions.

Some other keys are either missing or might be mapped wrongly (cf. Linux
kernel code). Don't fix these until someone can test them with real
hardware, but add TODO comments.

Signed-off-by: Stefan Weil 
---

v3: 
Use 2nd alternative, so there is no change of behaviour.

 hw/arm/mainstone.c |   13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index 9402c84..ffbf4bd 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -75,9 +75,18 @@ static struct keymap map[0xE0] = {
 [0x2c] = {4,3}, /* z */
 [0xc7] = {5,0}, /* Home */
 [0x2a] = {5,1}, /* shift */
-[0x39] = {5,2}, /* space */
+/*
+ * There are two matrix positions which map to space,
+ * but QEMU can only use one of them for the reverse
+ * mapping, so simply use the second one.
+ */
+/* [0x39] = {5,2}, space */
 [0x39] = {5,3}, /* space */
-[0x1c] = {5,5}, /*  enter */
+/*
+ * Matrix position {5,4} and other keys are missing here.
+ * TODO: Compare with Linux code and test real hardware.
+ */
+[0x1c] = {5,5}, /* enter (TODO: might be wrong) */
 [0xc8] = {6,0}, /* up */
 [0xd0] = {6,1}, /* down */
 [0xcb] = {6,2}, /* left */
-- 
1.7.10.4




Re: [Qemu-devel] [PATCH 11/21] target-arm: Update generic cpreg code for AArch64

2013-12-22 Thread Peter Maydell
On 20 December 2013 22:16, Peter Maydell  wrote:
> More generally I think the way that AArch64 uses op1 to group
> the registers by exception-level-access-rights is going to make it
> a bit tricky to do the mapping; we either need to
> (1) have .opc1 be the AA32 opc1 and infer AA64 op1 from
> the permission flags
> (2) have .opc1 be the AA64 op1 and insist that the AA32 opc1
> is always zero  (or always same as AA64 op1?), and require
> split reginfo structs if this isn't so
> (3) have both op1 and opc1 fields in the reginfo struct

Having waded through the docs a bit more I think the correct
answer here is "opc1 is AA64 op1 and AA32 opc1". The
definitions line up in almost all cases. The few exceptions
are where the AA64 definition has been brought into line
with the "opc1 indicates exception level access rights" pattern
but the old AA32 definition had a zero opc1 despite not
being an EL1 register (typically because it was accessible
by EL0; the EL2 registers do match up with the AArch32
encodings). There aren't very many of these, but since the only
registers this patchset really cares about are the EL0-accessible
registers almost all the ones we're going to add here fall into
the "can't share reginfo" category. TPIDR_EL1 (AArch32
TPIDRPRW) is shareable but none of the others are.
So I'm going for the "all of opc1/opc2/crn/crm have to match
on AA32 and AA64 for a shared reginfo", but it's going to
look a little pointless until we get the system emulation
done next year :-)

thanks
-- PMM



Re: [Qemu-devel] [PATCH v3] mainstone: Fix duplicate array values for key 'space'

2013-12-22 Thread Peter Maydell
On 22 December 2013 19:42, Stefan Weil  wrote:
> cgcc reported a duplicate initialisation. Mainstone includes a matrix
> keyboard where two different positions map to 'space'.
>
> QEMU uses the reversed mapping and does not map 'space' to two different
> matrix positions.
>
> Some other keys are either missing or might be mapped wrongly (cf. Linux
> kernel code). Don't fix these until someone can test them with real
> hardware, but add TODO comments.
>
> Signed-off-by: Stefan Weil 

Reviewed-by: Peter Maydell 

thanks
-- PMM



[Qemu-devel] Missing vhost=on support on -netdev bridge.

2013-12-22 Thread Piotr Karbowski

Hi,

Looks like netdev bridge have no support for vhost=on switch. Would be 
ince if that could be added.


-- Piotr.



Re: [Qemu-devel] [PATCH] tcg-i386: Use MOVBE if available

2013-12-22 Thread Aurelien Jarno
On Fri, Dec 20, 2013 at 03:00:12PM -0800, Richard Henderson wrote:
> As present on Atom and Haswell processors.
> 
> Signed-off-by: Richard Henderson 
> ---
>  disas/i386.c  |   8 ++--
>  tcg/i386/tcg-target.c | 127 
> ++
>  2 files changed, 91 insertions(+), 44 deletions(-)
> 
> Here's to "stress testing" a Haswell laptop before Santa delivers it.  ;-)
> 
> 
> r~
> 
> 
> diff --git a/disas/i386.c b/disas/i386.c
> index 47f1f2e..beb33f0 100644
> --- a/disas/i386.c
> +++ b/disas/i386.c
> @@ -2632,16 +2632,16 @@ static const struct dis386 prefix_user_table[][4] = {
>  
>/* PREGRP87 */
>{
> -{ "(bad)",   { XX } },
> -{ "(bad)",   { XX } },
> +{ "movbe",   { Gv, M } },
> +{ "movbe",   { Gw, M } },

This is not correct, this disassemble movbe with the REPZ prefix.

>  { "(bad)",   { XX } },

You want it there, that is for the DATA prefix.

>  { "crc32",   { Gdq, { CRC32_Fixup, b_mode } } },
>},
>  
>/* PREGRP88 */
>{
> -{ "(bad)",   { XX } },
> -{ "(bad)",   { XX } },
> +{ "movbe",   { M, Gv } },
> +{ "movbe",   { M, Gw } },
>  { "(bad)",   { XX } },

Ditto.

>  { "crc32",   { Gdq, { CRC32_Fixup, v_mode } } },
>},
> diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
> index 7ac8e45..e76f3f3 100644
> --- a/tcg/i386/tcg-target.c
> +++ b/tcg/i386/tcg-target.c
> @@ -99,18 +99,28 @@ static const int tcg_target_call_oarg_regs[] = {
>  # define TCG_REG_L1 TCG_REG_EDX
>  #endif
>  
> +#ifdef CONFIG_CPUID_H
> +#include 
> +#endif
> +
>  /* For 32-bit, we are going to attempt to determine at runtime whether cmov
> is available.  However, the host compiler must supply , as we're
> not going to go so far as our own inline assembly.  */
>  #if TCG_TARGET_REG_BITS == 64
>  # define have_cmov 1
>  #elif defined(CONFIG_CPUID_H)
> -#include 
>  static bool have_cmov;
>  #else
>  # define have_cmov 0
>  #endif
>  
> +/* There is no pre-processor definition for MOVBE to fall back on.  */
> +#ifdef CONFIG_CPUID_H

As you already remarked, you should check for bit_MOVBE, as it is
something which has been introduced in GCC 4.6.

> +static bool have_movbe;
> +#else
> +#define have_movbe 0

Very minor nitpick, but you probably want to indent the define, like
above for cmov.

> +#endif
> +
>  static uint8_t *tb_ret_addr;
>  
>  static void patch_reloc(uint8_t *code_ptr, int type,
> @@ -254,6 +264,7 @@ static inline int tcg_target_const_match(tcg_target_long 
> val,
>  # define P_REXB_RM   0
>  # define P_GS   0
>  #endif
> +#define P_EXT38 0x8000  /* 0x0f 0x38 opcode prefix */
>  
>  #define OPC_ARITH_EvIz   (0x81)
>  #define OPC_ARITH_EvIb   (0x83)
> @@ -279,6 +290,8 @@ static inline int tcg_target_const_match(tcg_target_long 
> val,
>  #define OPC_MOVB_EvIz   (0xc6)
>  #define OPC_MOVL_EvIz(0xc7)
>  #define OPC_MOVL_Iv (0xb8)
> +#define OPC_MOVBE_GyMy  (0xf0 | P_EXT | P_EXT38)
> +#define OPC_MOVBE_MyGy  (0xf1 | P_EXT | P_EXT38)
>  #define OPC_MOVSBL   (0xbe | P_EXT)
>  #define OPC_MOVSWL   (0xbf | P_EXT)
>  #define OPC_MOVSLQ   (0x63 | P_REXW)
> @@ -400,6 +413,9 @@ static void tcg_out_opc(TCGContext *s, int opc, int r, 
> int rm, int x)
>  
>  if (opc & P_EXT) {
>  tcg_out8(s, 0x0f);
> +if (opc & P_EXT38) {
> +tcg_out8(s, 0x38);
> +}
>  }
>  tcg_out8(s, opc);
>  }
> @@ -411,6 +427,9 @@ static void tcg_out_opc(TCGContext *s, int opc)
>  }
>  if (opc & P_EXT) {
>  tcg_out8(s, 0x0f);
> +if (opc & P_EXT38) {
> +tcg_out8(s, 0x38);
> +}
>  }
>  tcg_out8(s, opc);
>  }
> @@ -1336,7 +1355,14 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, 
> TCGReg datalo, TCGReg datahi,
> TCGReg base, intptr_t ofs, int seg,
> TCGMemOp memop)
>  {
> -const TCGMemOp bswap = memop & MO_BSWAP;
> +const TCGMemOp real_bswap = memop & MO_BSWAP;
> +TCGMemOp bswap = real_bswap;
> +int movop = OPC_MOVL_GvEv;
> +
> +if (real_bswap && have_movbe) {
> +bswap = 0;
> +movop = OPC_MOVBE_GyMy;
> +}

Defining movop is clever, that said the name real_bswap doesn't sounds
very self describing. Moreover you still need to check for have_movbe
below...

>  switch (memop & MO_SSIZE) {
>  case MO_UB:
> @@ -1346,32 +1372,45 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, 
> TCGReg datalo, TCGReg datahi,
>  tcg_out_modrm_offset(s, OPC_MOVSBL + P_REXW + seg, datalo, base, 
> ofs);
>  break;
>  case MO_UW:
> -tcg_out_modrm_offset(s, OPC_MOVZWL + seg, datalo, base, ofs);
> -if (bswap) {
> -tcg_out_rolw_8(s, datalo);
> +if (real_bswap && have_movbe) {
> +tcg_out_modrm_offset(s, OPC_MOVBE_GyMy + P_DATA16 + seg,
> + datalo, base, ofs);

[Qemu-devel] qemu abuse cpu if connected to monitor socket and not red anything.

2013-12-22 Thread Piotr Karbowski

Hi,

Occasionally if I connect to monitor on unix socket and quickly 
disconnect qemu process goes to 100% cpu usage until I connect to the 
socket agian and actually read whatever there's, usually the qemu 
welcome banner is printed twice, after the output is recieved qemu goes 
back to not abusing cpu.


Confirmed on 1.6.1, no idea if older versions had this issue.

-- Piotr.



Re: [Qemu-devel] [PATCH] PPC: Fix compilation with TCG debug

2013-12-22 Thread Aurelien Jarno
On Sun, Dec 22, 2013 at 06:16:44PM +0100, Alexander Graf wrote:
> 
> On 22.12.2013, at 17:37, Aurelien Jarno  wrote:
> 
> > On Fri, Dec 20, 2013 at 11:01:50AM +0100, Alexander Graf wrote:
> >> The recent VSX patches broken compilation of QEMU when configurated
> >> with --enable-debug, as it was treating "target long" TCG variables
> >> as "i64" which is not true for 32bit targets.
> >> 
> >> This patch fixes all the places that the compiler has found to use
> >> the correct variable type and if necessary manually cast.
> >> 
> >> Reported-by: Stefan Weil 
> >> Signed-off-by: Alexander Graf 
> >> ---
> >> target-ppc/translate.c | 143 
> >> -
> >> 1 file changed, 81 insertions(+), 62 deletions(-)
> >> 
> >> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> >> index ea58dc9..c5c1108 100644
> >> --- a/target-ppc/translate.c
> >> +++ b/target-ppc/translate.c
> >> @@ -2567,6 +2567,14 @@ static inline void gen_qemu_ld32u(DisasContext 
> >> *ctx, TCGv arg1, TCGv arg2)
> >> }
> >> }
> >> 
> >> +static void gen_qemu_ld32u_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
> >> +{
> >> +TCGv tmp = tcg_temp_new();
> >> +gen_qemu_ld32u(ctx, tmp, addr);
> >> +tcg_gen_extu_tl_i64(val, tmp);
> >> +tcg_temp_free(tmp);
> >> +}
> >> +
> >> static inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
> >> {
> >> if (unlikely(ctx->le_mode)) {
> >> @@ -2616,6 +2624,14 @@ static inline void gen_qemu_st32(DisasContext *ctx, 
> >> TCGv arg1, TCGv arg2)
> >> }
> >> }
> >> 
> >> +static void gen_qemu_st32_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
> >> +{
> >> +TCGv tmp = tcg_temp_new();
> >> +tcg_gen_trunc_i64_tl(tmp, val);
> >> +gen_qemu_st32(ctx, tmp, addr);
> >> +tcg_temp_free(tmp);
> >> +}
> >> +
> >> static inline void gen_qemu_st64(DisasContext *ctx, TCGv_i64 arg1, TCGv 
> >> arg2)
> >> {
> >> if (unlikely(ctx->le_mode)) {
> >> @@ -7048,13 +7064,14 @@ static void gen_lxvdsx(DisasContext *ctx)
> >> EA = tcg_temp_new();
> >> gen_addr_reg_index(ctx, EA);
> >> gen_qemu_ld64(ctx, cpu_vsrh(xT(ctx->opcode)), EA);
> >> -tcg_gen_mov_tl(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xT(ctx->opcode)));
> >> +tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xT(ctx->opcode)));
> >> tcg_temp_free(EA);
> >> }
> >> 
> >> static void gen_lxvw4x(DisasContext *ctx)
> >> {
> >> -TCGv EA, tmp;
> >> +TCGv EA;
> >> +TCGv_i64 tmp;
> >> TCGv_i64 xth = cpu_vsrh(xT(ctx->opcode));
> >> TCGv_i64 xtl = cpu_vsrl(xT(ctx->opcode));
> >> if (unlikely(!ctx->vsx_enabled)) {
> >> @@ -7063,21 +7080,22 @@ static void gen_lxvw4x(DisasContext *ctx)
> >> }
> >> gen_set_access_type(ctx, ACCESS_INT);
> >> EA = tcg_temp_new();
> >> -tmp = tcg_temp_new();
> >> +tmp = tcg_temp_new_i64();
> >> +
> >> gen_addr_reg_index(ctx, EA);
> >> -gen_qemu_ld32u(ctx, tmp, EA);
> >> +gen_qemu_ld32u_i64(ctx, tmp, EA);
> >> tcg_gen_addi_tl(EA, EA, 4);
> >> -gen_qemu_ld32u(ctx, xth, EA);
> >> +gen_qemu_ld32u_i64(ctx, xth, EA);
> >> tcg_gen_deposit_i64(xth, xth, tmp, 32, 32);
> >> 
> >> tcg_gen_addi_tl(EA, EA, 4);
> >> -gen_qemu_ld32u(ctx, tmp, EA);
> >> +gen_qemu_ld32u_i64(ctx, tmp, EA);
> >> tcg_gen_addi_tl(EA, EA, 4);
> >> -gen_qemu_ld32u(ctx, xtl, EA);
> >> +gen_qemu_ld32u_i64(ctx, xtl, EA);
> >> tcg_gen_deposit_i64(xtl, xtl, tmp, 32, 32);
> >> 
> >> tcg_temp_free(EA);
> >> -tcg_temp_free(tmp);
> >> +tcg_temp_free_i64(tmp);
> >> }
> >> 
> >> static void gen_stxsdx(DisasContext *ctx)
> >> @@ -7112,7 +7130,8 @@ static void gen_stxvd2x(DisasContext *ctx)
> >> 
> >> static void gen_stxvw4x(DisasContext *ctx)
> >> {
> >> -TCGv EA, tmp;
> >> +TCGv_i64 tmp;
> >> +TCGv EA;
> >> if (unlikely(!ctx->vsx_enabled)) {
> >> gen_exception(ctx, POWERPC_EXCP_VSXU);
> >> return;
> >> @@ -7120,21 +7139,21 @@ static void gen_stxvw4x(DisasContext *ctx)
> >> gen_set_access_type(ctx, ACCESS_INT);
> >> EA = tcg_temp_new();
> >> gen_addr_reg_index(ctx, EA);
> >> -tmp = tcg_temp_new();
> >> +tmp = tcg_temp_new_i64();
> >> 
> >> tcg_gen_shri_i64(tmp, cpu_vsrh(xS(ctx->opcode)), 32);
> >> -gen_qemu_st32(ctx, tmp, EA);
> >> +gen_qemu_st32_i64(ctx, tmp, EA);
> >> tcg_gen_addi_tl(EA, EA, 4);
> >> -gen_qemu_st32(ctx, cpu_vsrh(xS(ctx->opcode)), EA);
> >> +gen_qemu_st32_i64(ctx, cpu_vsrh(xS(ctx->opcode)), EA);
> >> 
> >> tcg_gen_shri_i64(tmp, cpu_vsrl(xS(ctx->opcode)), 32);
> >> tcg_gen_addi_tl(EA, EA, 4);
> >> -gen_qemu_st32(ctx, tmp, EA);
> >> +gen_qemu_st32_i64(ctx, tmp, EA);
> >> tcg_gen_addi_tl(EA, EA, 4);
> >> -gen_qemu_st32(ctx, cpu_vsrl(xS(ctx->opcode)), EA);
> >> +gen_qemu_st32_i64(ctx, cpu_vsrl(xS(ctx->opcode)), EA);
> >> 
> >> tcg_temp_free(EA);
> >> -tcg_temp_free(tmp);
> >> +tcg_temp_free_i64(tmp);
> >> }
> >> 
> >> static void gen_xxpermdi(Disas

Re: [Qemu-devel] [PATCH v3] Add DSDT node for AppleSMC

2013-12-22 Thread Laszlo Ersek
On 12/22/13 18:14, Gabriel L. Somlo wrote:
> On Sun, Dec 22, 2013 at 04:58:58PM +0100, Laszlo Ersek wrote:
>> After this patch, ISA interrupt 6 is used by both "SMC" and "FDC0". The
>> latter depends on the FDEN object, but FDEN is currently constant 1.
>>
>> Probably not a problem in practice (ie. most users won't try to specify
>> both a floppy disk controller and an AppleSMC device), but you might
>> want to handle that case nonetheless (exit with an error or some such).
> 
> I couldn't find a command line option to prevent QEMU from starting
> with a floppy controller, so unless I missed it, we'd always detect
> a "conflict".
> 
> According to the applesmc.c source, the emulated Apple SMC doesn't
> support IRQ, so the number itself should be irrelevant. IRQ #6 is
> what's used on real Apple hardware, but when I tried with a different
> number (e.g. #5), OS X booted fine in QEMU (it does fail to boot if
> we leave out IRQNoFlags entirely from the SMC DSDT node, though).
> 
> I could patch the value of FDEN to 0 whenever I enable the SMC _STA
> method (i.e, when I patch its value to 0x0B), but that still wouldn't
> take care of the fact that the emulated FDC is still present.
> 
> So, my preferred course of action would be, in this order:
> 
>   1. Do nothing :)
> 
> or
> 
>   2. Use "IRQNoFlags() { 5 }" with the SMC (or any other
>  number that isn't already allocated.

I don't think there's anything left free:

 0 - system timer (not listed explicitly)
 1 - KBD (PNP0303)
 2 - cascade / PIC (PNP) (listed only in OVMF's builtin DSDT)
 3 - COM2 (PNP0501)
 4 - COM1 (PNP0501)
 5 - LNK[ABCD] (PNP0C0F)
 6 - FDC0 (PNP0700)
 7 - LPT (PNP0400)
 8 - RTC (PNP0B00)
 9 - LNKS (PNP0C0F)
10 - LNK[ABCD] (PNP0C0F)
11 - LNK[ABCD] (PNP0C0F)
12 - MOU (PNP0F13)
13 - FPU (PNP0C04) (listed only in OVMF's builtin DSDT)
14 - primary IDE (not listed explicitly)
15 - secondary IDE (not listed explicitly)

See also

http://www.plasma-online.de/english/identify/serial/pnp_id_pnp.html
http://www.webopedia.com/quick_ref/IRQnumbers.asp

You could reuse eg. #5, but then you'd have to distribute PCI LNK[ABCD]
over #10 and #11 only, which I guess is too high a price (both
patch-wise and at runtime). Rather don't touch that :)

> Any other suggestions or ideas would be welcome !

I guess the "by the book" solution would be to really stop the FDC from
being emulated when the AppleSMC is present, but I mention that idea
only because I like to waste bandwidth.

Option 1 ("Do nothing") sounds appropriate to me. Sorry for taking up
some of your time...

Thanks,
Laszlo



[Qemu-devel] [PATCH v2 25/25] default-configs: Add config for aarch64-linux-user

2013-12-22 Thread Peter Maydell
Add a config for aarch64-linux-user, thereby enabling it as
a valid target.

Signed-off-by: Peter Maydell 
Signed-off-by: Alexander Graf 
Reviewed-by: Richard Henderson 
---
 default-configs/aarch64-linux-user.mak | 3 +++
 1 file changed, 3 insertions(+)
 create mode 100644 default-configs/aarch64-linux-user.mak

diff --git a/default-configs/aarch64-linux-user.mak 
b/default-configs/aarch64-linux-user.mak
new file mode 100644
index 000..3df7de5
--- /dev/null
+++ b/default-configs/aarch64-linux-user.mak
@@ -0,0 +1,3 @@
+# Default configuration for aarch64-linux-user
+
+CONFIG_GDBSTUB_XML=y
-- 
1.8.5




[Qemu-devel] [PATCH v2 19/25] target-arm: aarch64: add support for ld lit

2013-12-22 Thread Peter Maydell
From: Alexander Graf 

Adds support for Load Register (literal), both normal
and SIMD/FP forms.

Signed-off-by: Alexander Graf 
Signed-off-by: Alex Bennée 
Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
---
 target-arm/translate-a64.c | 47 --
 1 file changed, 45 insertions(+), 2 deletions(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 538d69e..6197441 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1112,10 +1112,53 @@ static void disas_ldst_excl(DisasContext *s, uint32_t 
insn)
 unsupported_encoding(s, insn);
 }
 
-/* Load register (literal) */
+/*
+ * C3.3.5 Load register (literal)
+ *
+ *  31 30 29   27  26 25 24 235 4 0
+ * +-+---+---+-+---+---+
+ * | opc | 0 1 1 | V | 0 0 | imm19 |  Rt   |
+ * +-+---+---+-+---+---+
+ *
+ * V: 1 -> vector (simd/fp)
+ * opc (non-vector): 00 -> 32 bit, 01 -> 64 bit,
+ *   10-> 32 bit signed, 11 -> prefetch
+ * opc (vector): 00 -> 32 bit, 01 -> 64 bit, 10 -> 128 bit (11 unallocated)
+ */
 static void disas_ld_lit(DisasContext *s, uint32_t insn)
 {
-unsupported_encoding(s, insn);
+int rt = extract32(insn, 0, 5);
+int64_t imm = sextract32(insn, 5, 19) << 2;
+bool is_vector = extract32(insn, 26, 1);
+int opc = extract32(insn, 30, 2);
+bool is_signed = false;
+int size = 2;
+TCGv_i64 tcg_rt, tcg_addr;
+
+if (is_vector) {
+if (opc == 3) {
+unallocated_encoding(s);
+return;
+}
+size = 2 + opc;
+} else {
+if (opc == 3) {
+/* PRFM (literal) : prefetch */
+return;
+}
+size = 2 + extract32(opc, 0, 1);
+is_signed = extract32(opc, 1, 1);
+}
+
+tcg_rt = cpu_reg(s, rt);
+
+tcg_addr = tcg_const_i64((s->pc - 4) + imm);
+if (is_vector) {
+do_fp_ld(s, rt, tcg_addr, size);
+} else {
+do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false);
+}
+tcg_temp_free_i64(tcg_addr);
 }
 
 /*
-- 
1.8.5




[Qemu-devel] [PATCH v2 17/25] target-arm: A64: add support for add/sub with carry

2013-12-22 Thread Peter Maydell
From: Claudio Fontana 

This patch adds support for C3.5.3 Add/subtract (with carry):
instructions ADC, ADCS, SBC, SBCS.

Signed-off-by: Claudio Fontana 
Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
---
 target-arm/translate-a64.c | 105 -
 1 file changed, 103 insertions(+), 2 deletions(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index c8ed799..9f508b9 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -393,6 +393,71 @@ static void gen_sub_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, 
TCGv_i64 t1)
 }
 }
 
+/* dest = T0 + T1 + CF; do not compute flags. */
+static void gen_adc(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
+{
+TCGv_i64 flag = tcg_temp_new_i64();
+tcg_gen_extu_i32_i64(flag, cpu_CF);
+tcg_gen_add_i64(dest, t0, t1);
+tcg_gen_add_i64(dest, dest, flag);
+tcg_temp_free_i64(flag);
+
+if (!sf) {
+tcg_gen_ext32u_i64(dest, dest);
+}
+}
+
+/* dest = T0 + T1 + CF; compute C, N, V and Z flags. */
+static void gen_adc_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
+{
+if (sf) {
+TCGv_i64 result, cf_64, vf_64, tmp;
+result = tcg_temp_new_i64();
+cf_64 = tcg_temp_new_i64();
+vf_64 = tcg_temp_new_i64();
+tmp = tcg_const_i64(0);
+
+tcg_gen_extu_i32_i64(cf_64, cpu_CF);
+tcg_gen_add2_i64(result, cf_64, t0, tmp, cf_64, tmp);
+tcg_gen_add2_i64(result, cf_64, result, cf_64, t1, tmp);
+tcg_gen_trunc_i64_i32(cpu_CF, cf_64);
+gen_set_NZ64(result);
+
+tcg_gen_xor_i64(vf_64, result, t0);
+tcg_gen_xor_i64(tmp, t0, t1);
+tcg_gen_andc_i64(vf_64, vf_64, tmp);
+tcg_gen_shri_i64(vf_64, vf_64, 32);
+tcg_gen_trunc_i64_i32(cpu_VF, vf_64);
+
+tcg_gen_mov_i64(dest, result);
+
+tcg_temp_free_i64(tmp);
+tcg_temp_free_i64(vf_64);
+tcg_temp_free_i64(cf_64);
+tcg_temp_free_i64(result);
+} else {
+TCGv_i32 t0_32, t1_32, tmp;
+t0_32 = tcg_temp_new_i32();
+t1_32 = tcg_temp_new_i32();
+tmp = tcg_const_i32(0);
+
+tcg_gen_trunc_i64_i32(t0_32, t0);
+tcg_gen_trunc_i64_i32(t1_32, t1);
+tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, tmp, cpu_CF, tmp);
+tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1_32, tmp);
+
+tcg_gen_mov_i32(cpu_ZF, cpu_NF);
+tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
+tcg_gen_xor_i32(tmp, t0_32, t1_32);
+tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
+tcg_gen_extu_i32_i64(dest, cpu_NF);
+
+tcg_temp_free_i32(tmp);
+tcg_temp_free_i32(t1_32);
+tcg_temp_free_i32(t0_32);
+}
+}
+
 /*
  * Load/Store generators
  */
@@ -2376,10 +2441,46 @@ static void disas_data_proc_3src(DisasContext *s, 
uint32_t insn)
 tcg_temp_free_i64(tcg_tmp);
 }
 
-/* Add/subtract (with carry) */
+/* C3.5.3 - Add/subtract (with carry)
+ *  31 30 29 28 27 26 25 24 23 22 21  20  16  15   10  95 4   0
+ * +--+--+--++--+-+--+-+
+ * |sf|op| S| 1  1  0  1  0  0  0  0 |  rm  | opcode2 |  Rn  |  Rd |
+ * +--+--+--++--+-+--+-+
+ *[00]
+ */
+
 static void disas_adc_sbc(DisasContext *s, uint32_t insn)
 {
-unsupported_encoding(s, insn);
+unsigned int sf, op, setflags, rm, rn, rd;
+TCGv_i64 tcg_y, tcg_rn, tcg_rd;
+
+if (extract32(insn, 10, 6) != 0) {
+unallocated_encoding(s);
+return;
+}
+
+sf = extract32(insn, 31, 1);
+op = extract32(insn, 30, 1);
+setflags = extract32(insn, 29, 1);
+rm = extract32(insn, 16, 5);
+rn = extract32(insn, 5, 5);
+rd = extract32(insn, 0, 5);
+
+tcg_rd = cpu_reg(s, rd);
+tcg_rn = cpu_reg(s, rn);
+
+if (op) {
+tcg_y = new_tmp_a64(s);
+tcg_gen_not_i64(tcg_y, cpu_reg(s, rm));
+} else {
+tcg_y = cpu_reg(s, rm);
+}
+
+if (setflags) {
+gen_adc_CC(sf, tcg_rd, tcg_rn, tcg_y);
+} else {
+gen_adc(sf, tcg_rd, tcg_rn, tcg_y);
+}
 }
 
 /* Conditional compare (immediate) */
-- 
1.8.5




[Qemu-devel] [PATCH v2 10/25] target-arm: A64: implement FMOV

2013-12-22 Thread Peter Maydell
Implement FMOV, ie non-converting moves between general purpose
registers and floating point registers. This is a subtype of
the floating point <-> integer instruction class.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
---
 target-arm/translate-a64.c | 86 +-
 1 file changed, 85 insertions(+), 1 deletion(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 079c2f7..7d98337 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -2758,6 +2758,63 @@ static void disas_fp_fixed_conv(DisasContext *s, 
uint32_t insn)
 unsupported_encoding(s, insn);
 }
 
+static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
+{
+/* FMOV: gpr to or from float, double, or top half of quad fp reg,
+ * without conversion.
+ */
+
+if (itof) {
+int freg_offs = offsetof(CPUARMState, vfp.regs[rd * 2]);
+TCGv_i64 tcg_rn = cpu_reg(s, rn);
+
+switch (type) {
+case 0:
+{
+/* 32 bit */
+TCGv_i64 tmp = tcg_temp_new_i64();
+tcg_gen_ext32u_i64(tmp, tcg_rn);
+tcg_gen_st_i64(tmp, cpu_env, freg_offs);
+tcg_gen_movi_i64(tmp, 0);
+tcg_gen_st_i64(tmp, cpu_env, freg_offs + sizeof(float64));
+tcg_temp_free_i64(tmp);
+break;
+}
+case 1:
+{
+/* 64 bit */
+TCGv_i64 tmp = tcg_const_i64(0);
+tcg_gen_st_i64(tcg_rn, cpu_env, freg_offs);
+tcg_gen_st_i64(tmp, cpu_env, freg_offs + sizeof(float64));
+tcg_temp_free_i64(tmp);
+break;
+}
+case 2:
+/* 64 bit to top half. */
+tcg_gen_st_i64(tcg_rn, cpu_env, freg_offs + sizeof(float64));
+break;
+}
+} else {
+int freg_offs = offsetof(CPUARMState, vfp.regs[rn * 2]);
+TCGv_i64 tcg_rd = cpu_reg(s, rd);
+
+switch (type) {
+case 0:
+/* 32 bit */
+tcg_gen_ld32u_i64(tcg_rd, cpu_env, freg_offs);
+break;
+case 2:
+/* 64 bits from top half */
+freg_offs += sizeof(float64);
+/* fall through */
+case 1:
+/* 64 bit */
+tcg_gen_ld_i64(tcg_rd, cpu_env, freg_offs);
+break;
+}
+}
+}
+
 /* C3.6.30 Floating point <-> integer conversions
  *   31   30  29 28   24 23  22  21 20   19 18 16 15 10 9  5 4  0
  * ++---+---+---+--+---+---+-+-+++
@@ -2766,7 +2823,34 @@ static void disas_fp_fixed_conv(DisasContext *s, 
uint32_t insn)
  */
 static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
 {
-unsupported_encoding(s, insn);
+int rd = extract32(insn, 0, 5);
+int rn = extract32(insn, 5, 5);
+int opcode = extract32(insn, 16, 3);
+int rmode = extract32(insn, 19, 2);
+int type = extract32(insn, 22, 2);
+bool sbit = extract32(insn, 29, 1);
+bool sf = extract32(insn, 31, 1);
+
+if (!sbit && (rmode < 2) && (opcode > 5)) {
+/* FMOV */
+bool itof = opcode & 1;
+
+switch (sf << 3 | type << 1 | rmode) {
+case 0x0: /* 32 bit */
+case 0xa: /* 64 bit */
+case 0xd: /* 64 bit to top half of quad */
+break;
+default:
+/* all other sf/type/rmode combinations are invalid */
+unallocated_encoding(s);
+break;
+}
+
+handle_fmov(s, rd, rn, type, itof);
+} else {
+/* actual FP conversions */
+unsupported_encoding(s, insn);
+}
 }
 
 /* FP-specific subcases of table C3-6 (SIMD and FP data processing)
-- 
1.8.5




[Qemu-devel] [PATCH v2 00/25] target-arm: A64 decoder sets 3 and 4: everything but fp & simd

2013-12-22 Thread Peter Maydell
Hi; this is the second version of a64-third-fourth-set, which
implements support for more or less all A64 instructions except
 * FP [we support simple FP register load/store and
   transfer to/from the general purpose registers]
 * Neon
 * system instructions (either ones only available to system
   mode or which only make sense for system mode like LDRT)
(There may also be one or two obscure gaps like the CRC32 instruction.)

Changes v1->v2:
 * finally got the ld/st pair decode correct
 * cleaned up the other ld/st decode to use extract32 rather than bitops
 * special case the simple-multiply in 3-src data ops
 * move set_pc in mrs/msr down to the end-of-loop handling
 * fix use of tcg temp over bblk end and possible gcc warning in cond-compare
 * use new qemu ld ops in ldst excl
 * revised version of sysregs support:
   + new .state field to specify whether register is AA64, AA32 or both
   + support shared register definitions between both states
   + new patch pulling the inner loop body of the 'define a reginfo'
 function out into its own function, for clarity
   + move the AA64 TLS register definitions to be together with the AA32
 ones rather than in a completely different part of the file
 * added a couple of minor bugfixes to aarch64 linux-user support found
   in testing (the clone bugfix in particular is necessary for fork())
 * added a patch to add the aarch64 targets to the travis test matrix

(That looks like a long list but it's mostly minor stuff apart from
the adjustments to sysregs support.)

This patchset sits on top of upstream master (yay); git tree
available at:
 git://git.linaro.org/people/peter.maydell/qemu-arm.git a64-third-fourth-set
web UI:
 
https://git.linaro.org/people/peter.maydell/qemu-arm.git/shortlog/refs/heads/a64-third-fourth-set

(My plan for the next patchset is basically "softfloat
fixes and all of FP"; we have working and tested code
that basically just needs a touch more cleanup.)

thanks
-- PMM

Alex Bennée (6):
  target-arm: A64: add support for ld/st unsigned imm
  target-arm: A64: add support for ld/st with reg offset
  target-arm: A64: add support for ld/st with index
  target-arm: A64: add support for add, addi, sub, subi
  target-arm: A64: add support for move wide instructions
  .travis.yml: Add aarch64-* targets

Alexander Graf (3):
  target-arm: A64: add support for 3 src data proc insns
  target-arm: A64: implement SVC, BRK
  target-arm: aarch64: add support for ld lit

Claudio Fontana (3):
  target-arm: A64: add support for add/sub with carry
  target-arm: A64: add support for conditional compare insns
  linux-user: AArch64: define TARGET_CLONE_BACKWARDS

Michael Matz (1):
  target-arm: A64: support for ld/st/cl exclusive

Peter Maydell (11):
  target-arm: A64: add support for ld/st pair
  target-arm: A64: Add decoder skeleton for FP instructions
  target-arm: A64: implement FMOV
  target-arm: Pull "add one cpreg to hashtable" into its own function
  target-arm: Update generic cpreg code for AArch64
  target-arm: Remove ARMCPU/CPUARMState from cpregs APIs used by decoder
  target-arm: A64: Implement MRS/MSR/SYS/SYSL
  target-arm: A64: Implement minimal set of EL0-visible sysregs
  target-arm: Widen thread-local register state fields to 64 bits
  target-arm: Widen exclusive-access support struct fields to 64 bits
  default-configs: Add config for aarch64-linux-user

Will Newton (1):
  linux-user: AArch64: Use correct values for FPSR/FPCR in sigcontext

 .travis.yml|1 +
 default-configs/aarch64-linux-user.mak |3 +
 linux-user/aarch64/syscall.h   |1 +
 linux-user/aarch64/target_cpu.h|5 +-
 linux-user/arm/target_cpu.h|2 +-
 linux-user/main.c  |  154 ++-
 linux-user/signal.c|   10 +-
 target-arm/cpu.h   |  109 +-
 target-arm/helper.c|  284 -
 target-arm/kvm-consts.h|   37 +
 target-arm/machine.c   |   12 +-
 target-arm/translate-a64.c | 1949 ++--
 target-arm/translate.c |   72 +-
 target-arm/translate.h |2 +
 14 files changed, 2439 insertions(+), 202 deletions(-)
 create mode 100644 default-configs/aarch64-linux-user.mak

-- 
1.8.5




[Qemu-devel] [PATCH v2 11/25] target-arm: Pull "add one cpreg to hashtable" into its own function

2013-12-22 Thread Peter Maydell
define_one_arm_cp_reg_with_opaque() has a set of nested loops which
insert a cpreg entry into the hashtable for each of the possible
opc/crn/crm values allowed by wildcard specifications. We're about
to add an extra loop to this nesting, so pull the core of the loop
(which adds a single entry to the hashtable) out into its own
function for clarity.

Signed-off-by: Peter Maydell 
---
 target-arm/helper.c | 94 +
 1 file changed, 52 insertions(+), 42 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 6ebd7dc..d833163 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1937,6 +1937,57 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error 
**errp)
 return cpu_list;
 }
 
+static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
+   void *opaque, int crm, int opc1, int opc2)
+{
+/* Private utility function for define_one_arm_cp_reg_with_opaque():
+ * add a single reginfo struct to the hash table.
+ */
+uint32_t *key = g_new(uint32_t, 1);
+ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
+int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
+*key = ENCODE_CP_REG(r->cp, is64, r->crn, crm, opc1, opc2);
+if (opaque) {
+r2->opaque = opaque;
+}
+/* Make sure reginfo passed to helpers for wildcarded regs
+ * has the correct crm/opc1/opc2 for this reg, not CP_ANY:
+ */
+r2->crm = crm;
+r2->opc1 = opc1;
+r2->opc2 = opc2;
+/* By convention, for wildcarded registers only the first
+ * entry is used for migration; the others are marked as
+ * NO_MIGRATE so we don't try to transfer the register
+ * multiple times. Special registers (ie NOP/WFI) are
+ * never migratable.
+ */
+if ((r->type & ARM_CP_SPECIAL) ||
+((r->crm == CP_ANY) && crm != 0) ||
+((r->opc1 == CP_ANY) && opc1 != 0) ||
+((r->opc2 == CP_ANY) && opc2 != 0)) {
+r2->type |= ARM_CP_NO_MIGRATE;
+}
+
+/* Overriding of an existing definition must be explicitly
+ * requested.
+ */
+if (!(r->type & ARM_CP_OVERRIDE)) {
+ARMCPRegInfo *oldreg;
+oldreg = g_hash_table_lookup(cpu->cp_regs, key);
+if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
+fprintf(stderr, "Register redefined: cp=%d %d bit "
+"crn=%d crm=%d opc1=%d opc2=%d, "
+"was %s, now %s\n", r2->cp, 32 + 32 * is64,
+r2->crn, r2->crm, r2->opc1, r2->opc2,
+oldreg->name, r2->name);
+g_assert_not_reached();
+}
+}
+g_hash_table_insert(cpu->cp_regs, key, r2);
+}
+
+
 void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
const ARMCPRegInfo *r, void *opaque)
 {
@@ -1977,48 +2028,7 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
 for (crm = crmmin; crm <= crmmax; crm++) {
 for (opc1 = opc1min; opc1 <= opc1max; opc1++) {
 for (opc2 = opc2min; opc2 <= opc2max; opc2++) {
-uint32_t *key = g_new(uint32_t, 1);
-ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
-int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
-*key = ENCODE_CP_REG(r->cp, is64, r->crn, crm, opc1, opc2);
-if (opaque) {
-r2->opaque = opaque;
-}
-/* Make sure reginfo passed to helpers for wildcarded regs
- * has the correct crm/opc1/opc2 for this reg, not CP_ANY:
- */
-r2->crm = crm;
-r2->opc1 = opc1;
-r2->opc2 = opc2;
-/* By convention, for wildcarded registers only the first
- * entry is used for migration; the others are marked as
- * NO_MIGRATE so we don't try to transfer the register
- * multiple times. Special registers (ie NOP/WFI) are
- * never migratable.
- */
-if ((r->type & ARM_CP_SPECIAL) ||
-((r->crm == CP_ANY) && crm != 0) ||
-((r->opc1 == CP_ANY) && opc1 != 0) ||
-((r->opc2 == CP_ANY) && opc2 != 0)) {
-r2->type |= ARM_CP_NO_MIGRATE;
-}
-
-/* Overriding of an existing definition must be explicitly
- * requested.
- */
-if (!(r->type & ARM_CP_OVERRIDE)) {
-ARMCPRegInfo *oldreg;
-oldreg = g_hash_table_lookup(cpu->cp_regs, key);
-if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
-fprintf(stderr, "Register redefined: cp=%d %d bit "
-"crn=%d crm=%d opc1=%d opc2=%d, "
-"was %s, now %s\n", r2->cp, 32 + 32 * is64,
-r2->

[Qemu-devel] [PATCH v2 23/25] linux-user: AArch64: Use correct values for FPSR/FPCR in sigcontext

2013-12-22 Thread Peter Maydell
From: Will Newton 

Use the helpers provided for getting the correct FPSR and FPCR
values for the signal context.

Signed-off-by: Will Newton 
Signed-off-by: Peter Maydell 
---
 linux-user/signal.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 4e7148a..6c74b18 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -1189,8 +1189,8 @@ static int target_setup_sigframe(struct 
target_rt_sigframe *sf,
 __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
 #endif
 }
-__put_user(/*env->fpsr*/0, &aux->fpsimd.fpsr);
-__put_user(/*env->fpcr*/0, &aux->fpsimd.fpcr);
+__put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
+__put_user(vfp_get_fpcr(env), &aux->fpsimd.fpcr);
 __put_user(TARGET_FPSIMD_MAGIC, &aux->fpsimd.head.magic);
 __put_user(sizeof(struct target_fpsimd_context),
 &aux->fpsimd.head.size);
@@ -1209,7 +1209,7 @@ static int target_restore_sigframe(CPUARMState *env,
 int i;
 struct target_aux_context *aux =
 (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
-uint32_t magic, size;
+uint32_t magic, size, fpsr, fpcr;
 uint64_t pstate;
 
 target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
@@ -1235,6 +1235,10 @@ static int target_restore_sigframe(CPUARMState *env,
 for (i = 0; i < 32 * 2; i++) {
 __get_user(env->vfp.regs[i], &aux->fpsimd.vregs[i]);
 }
+__get_user(fpsr, &aux->fpsimd.fpsr);
+vfp_set_fpsr(env, fpsr);
+__get_user(fpcr, &aux->fpsimd.fpcr);
+vfp_set_fpcr(env, fpcr);
 
 return 0;
 }
-- 
1.8.5




[Qemu-devel] [PATCH v2 04/25] target-arm: A64: add support for ld/st with index

2013-12-22 Thread Peter Maydell
From: Alex Bennée 

This adds support for the pre/post-index ld/st forms with immediate
offsets as well as the un-scaled immediate form (which are all
variations on the same 9-bit immediate instruction form).

Signed-off-by: Alex Bennée 
Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
---
 target-arm/translate-a64.c | 125 -
 1 file changed, 124 insertions(+), 1 deletion(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 67efcf9..a2cc9f0 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -950,6 +950,110 @@ static void disas_ldst_pair(DisasContext *s, uint32_t 
insn)
 }
 
 /*
+ * C3.3.8 Load/store (immediate post-indexed)
+ * C3.3.9 Load/store (immediate pre-indexed)
+ * C3.3.12 Load/store (unscaled immediate)
+ *
+ * 31 30 29   27  26 25 24 23 22 21  2012 11 10 95 40
+ * ++---+---+-+-+---++-+--+--+
+ * |size| 1 1 1 | V | 0 0 | opc | 0 |  imm9  | idx |  Rn  |  Rt  |
+ * ++---+---+-+-+---++-+--+--+
+ *
+ * idx = 01 -> post-indexed, 11 pre-indexed, 00 unscaled imm. (no writeback)
+ * V = 0 -> non-vector
+ * size: 00 -> 8 bit, 01 -> 16 bit, 10 -> 32 bit, 11 -> 64bit
+ * opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
+ */
+static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn)
+{
+int rt = extract32(insn, 0, 5);
+int rn = extract32(insn, 5, 5);
+int imm9 = sextract32(insn, 12, 9);
+int opc = extract32(insn, 22, 2);
+int size = extract32(insn, 30, 2);
+int idx = extract32(insn, 10, 2);
+bool is_signed = false;
+bool is_store = false;
+bool is_extended = false;
+bool is_vector = extract32(insn, 26, 1);
+bool post_index;
+bool writeback;
+
+TCGv_i64 tcg_addr;
+
+if (is_vector) {
+size |= (opc & 2) << 1;
+if (size > 4) {
+unallocated_encoding(s);
+return;
+}
+is_store = ((opc & 1) == 0);
+} else {
+if (size == 3 && opc == 2) {
+/* PRFM - prefetch */
+return;
+}
+if (opc == 3 && size > 1) {
+unallocated_encoding(s);
+return;
+}
+is_store = (opc == 0);
+is_signed = opc & (1<<1);
+is_extended = (size < 3) && (opc & 1);
+}
+
+switch (idx) {
+case 0:
+post_index = false;
+writeback = false;
+break;
+case 1:
+post_index = true;
+writeback = true;
+break;
+case 3:
+post_index = false;
+writeback = true;
+break;
+case 2:
+g_assert(false);
+break;
+}
+
+if (rn == 31) {
+gen_check_sp_alignment(s);
+}
+tcg_addr = read_cpu_reg_sp(s, rn, 1);
+
+if (!post_index) {
+tcg_gen_addi_i64(tcg_addr, tcg_addr, imm9);
+}
+
+if (is_vector) {
+if (is_store) {
+do_fp_st(s, rt, tcg_addr, size);
+} else {
+do_fp_ld(s, rt, tcg_addr, size);
+}
+} else {
+TCGv_i64 tcg_rt = cpu_reg(s, rt);
+if (is_store) {
+do_gpr_st(s, tcg_rt, tcg_addr, size);
+} else {
+do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
+}
+}
+
+if (writeback) {
+TCGv_i64 tcg_rn = cpu_reg_sp(s, rn);
+if (post_index) {
+tcg_gen_addi_i64(tcg_addr, tcg_addr, imm9);
+}
+tcg_gen_mov_i64(tcg_rn, tcg_addr);
+}
+}
+
+/*
  * C3.3.10 Load/store (register offset)
  *
  * 31 30 29   27  26 25 24 23 22 21  20  16 15 13 12 11 10 9  5 4  0
@@ -1116,6 +1220,25 @@ static void disas_ldst_reg_unsigned_imm(DisasContext *s, 
uint32_t insn)
 }
 }
 
+/* Load/store register (immediate forms) */
+static void disas_ldst_reg_imm(DisasContext *s, uint32_t insn)
+{
+switch (extract32(insn, 10, 2)) {
+case 0: case 1: case 3:
+/* Load/store register (unscaled immediate) */
+/* Load/store immediate pre/post-indexed */
+disas_ldst_reg_imm9(s, insn);
+break;
+case 2:
+/* Load/store register unprivileged */
+unsupported_encoding(s, insn);
+break;
+default:
+unallocated_encoding(s);
+break;
+}
+}
+
 /* Load/store register (all forms) */
 static void disas_ldst_reg(DisasContext *s, uint32_t insn)
 {
@@ -1124,7 +1247,7 @@ static void disas_ldst_reg(DisasContext *s, uint32_t insn)
 if (extract32(insn, 21, 1) == 1 && extract32(insn, 10, 2) == 2) {
 disas_ldst_reg_roffset(s, insn);
 } else {
-unsupported_encoding(s, insn);
+disas_ldst_reg_imm(s, insn);
 }
 break;
 case 1:
-- 
1.8.5




[Qemu-devel] [PATCH v2 09/25] target-arm: A64: Add decoder skeleton for FP instructions

2013-12-22 Thread Peter Maydell
Add a top level decoder skeleton for FP instructions.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
---
 target-arm/translate-a64.c | 170 -
 1 file changed, 169 insertions(+), 1 deletion(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 9ca6460..079c2f7 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -2670,10 +2670,178 @@ static void disas_data_proc_reg(DisasContext *s, 
uint32_t insn)
 }
 }
 
+/* C3.6.22 Floating point compare
+ *   31  30  29 28   24 23  22  21 20  16 15 14 13  1095 4 0
+ * +---+---+---+---+--+---+--+-+-+--+---+
+ * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | op  | 1 0 0 0 |  Rn  |  op2  |
+ * +---+---+---+---+--+---+--+-+-+--+---+
+ */
+static void disas_fp_compare(DisasContext *s, uint32_t insn)
+{
+unsupported_encoding(s, insn);
+}
+
+/* C3.6.23 Floating point conditional compare
+ *   31  30  29 28   24 23  22  21 20  16 15  12 11 10 95  4   30
+ * +---+---+---+---+--+---+--+--+-+--++--+
+ * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | cond | 0 1 |  Rn  | op | nzcv |
+ * +---+---+---+---+--+---+--+--+-+--++--+
+ */
+static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
+{
+unsupported_encoding(s, insn);
+}
+
+/* C3.6.24 Floating point conditional select
+ *   31  30  29 28   24 23  22  21 20  16 15  12 11 10 95 40
+ * +---+---+---+---+--+---+--+--+-+--+--+
+ * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | cond | 1 1 |  Rn  |  Rd  |
+ * +---+---+---+---+--+---+--+--+-+--+--+
+ */
+static void disas_fp_csel(DisasContext *s, uint32_t insn)
+{
+unsupported_encoding(s, insn);
+}
+
+/* C3.6.25 Floating point data-processing (1 source)
+ *   31  30  29 28   24 23  22  21 2015 14   10 95 40
+ * +---+---+---+---+--+---++---+--+--+
+ * | M | 0 | S | 1 1 1 1 0 | type | 1 | opcode | 1 0 0 0 0 |  Rn  |  Rd  |
+ * +---+---+---+---+--+---++---+--+--+
+ */
+static void disas_fp_1src(DisasContext *s, uint32_t insn)
+{
+unsupported_encoding(s, insn);
+}
+
+/* C3.6.26 Floating point data-processing (2 source)
+ *   31  30  29 28   24 23  22  21 20  16 1512 11 10 95 40
+ * +---+---+---+---+--+---+--++-+--+--+
+ * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | opcode | 1 0 |  Rn  |  Rd  |
+ * +---+---+---+---+--+---+--++-+--+--+
+ */
+static void disas_fp_2src(DisasContext *s, uint32_t insn)
+{
+unsupported_encoding(s, insn);
+}
+
+/* C3.6.27 Floating point data-processing (3 source)
+ *   31  30  29 28   24 23  22  21  20  16  15  14  10 95 40
+ * +---+---+---+---+--++--++--+--+--+
+ * | M | 0 | S | 1 1 1 1 1 | type | o1 |  Rm  | o0 |  Ra  |  Rn  |  Rd  |
+ * +---+---+---+---+--++--++--+--+--+
+ */
+static void disas_fp_3src(DisasContext *s, uint32_t insn)
+{
+unsupported_encoding(s, insn);
+}
+
+/* C3.6.28 Floating point immediate
+ *   31  30  29 28   24 23  22  21 2013 12   10 95 40
+ * +---+---+---+---+--+---++---+--+--+
+ * | M | 0 | S | 1 1 1 1 0 | type | 1 |imm8| 1 0 0 | imm5 |  Rd  |
+ * +---+---+---+---+--+---++---+--+--+
+ */
+static void disas_fp_imm(DisasContext *s, uint32_t insn)
+{
+unsupported_encoding(s, insn);
+}
+
+/* C3.6.29 Floating point <-> fixed point conversions
+ *   31   30  29 28   24 23  22  21 20   19 1816 15   10 95 40
+ * ++---+---+---+--+---+---++---+--+--+
+ * | sf | 0 | S | 1 1 1 1 0 | type | 0 | rmode | opcode | scale |  Rn  |  Rd  |
+ * ++---+---+---+--+---+---++---+--+--+
+ */
+static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn)
+{
+unsupported_encoding(s, insn);
+}
+
+/* C3.6.30 Floating point <-> integer conversions
+ *   31   30  29 28   24 23  22  21 20   19 18 16 15 10 9  5 4  0
+ * ++---+---+---+--+---+---+-+-+++
+ * | sf | 0 | S | 1 1 1 1 0 | type | 0 | rmode | opc | 0 0 0 0 0 0 | Rn | Rd |
+ * ++---+---+---+--+---+---+-+-+++
+ */
+static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
+{
+unsupported_encoding(s, insn);
+}
+
+/* FP-specific subcases of table C3-6 (SIMD and FP data processing)
+ *   31  30  29 28 25 24  0
+ * +---+---+---+-+-+
+ * |   | 0 |   | 1 1 1 1 | |
+ * +---+---+---+-+--

[Qemu-devel] [PATCH v2 22/25] linux-user: AArch64: define TARGET_CLONE_BACKWARDS

2013-12-22 Thread Peter Maydell
From: Claudio Fontana 

The AArch64 linux-user support was written before but merged after
commit 4ce6243dc621 which cleaned up the handling of the clone()
syscall argument order, so we failed to notice that AArch64 also needs
TARGET_CLONE_BACKWARDS to be defined. Add this define so that clone
and fork syscalls work correctly.

Signed-off-by: Claudio Fontana 
Signed-off-by: Peter Maydell 
---
 linux-user/aarch64/syscall.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/linux-user/aarch64/syscall.h b/linux-user/aarch64/syscall.h
index aef419e..18f44a8 100644
--- a/linux-user/aarch64/syscall.h
+++ b/linux-user/aarch64/syscall.h
@@ -7,3 +7,4 @@ struct target_pt_regs {
 
 #define UNAME_MACHINE "aarch64"
 #define UNAME_MINIMUM_RELEASE "3.8.0"
+#define TARGET_CLONE_BACKWARDS
-- 
1.8.5




[Qemu-devel] [PATCH v2 02/25] target-arm: A64: add support for ld/st unsigned imm

2013-12-22 Thread Peter Maydell
From: Alex Bennée 

This adds support for the forms of ld/st with a 12 bit
unsigned immediate offset.

Signed-off-by: Alex Bennée 
Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
---
 target-arm/translate-a64.c | 89 +-
 1 file changed, 88 insertions(+), 1 deletion(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 0c3b994..0edcee1 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -901,10 +901,97 @@ static void disas_ldst_pair(DisasContext *s, uint32_t 
insn)
 }
 }
 
+/*
+ * C3.3.13 Load/store (unsigned immediate)
+ *
+ * 31 30 29   27  26 25 24 23 22 2110 9 5
+ * ++---+---+-+-++---+--+
+ * |size| 1 1 1 | V | 0 1 | opc |   imm12|  Rn   |  Rt  |
+ * ++---+---+-+-++---+--+
+ *
+ * For non-vector:
+ *   size: 00-> byte, 01 -> 16 bit, 10 -> 32bit, 11 -> 64bit
+ *   opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
+ * For vector:
+ *   size is opc<1>:size<1:0> so 100 -> 128 bit; 110 and 111 unallocated
+ *   opc<0>: 0 -> store, 1 -> load
+ * Rn: base address register (inc SP)
+ * Rt: target register
+ */
+static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn)
+{
+int rt = extract32(insn, 0, 5);
+int rn = extract32(insn, 5, 5);
+unsigned int imm12 = extract32(insn, 10, 12);
+bool is_vector = extract32(insn, 26, 1);
+int size = extract32(insn, 30, 2);
+int opc = extract32(insn, 22, 2);
+unsigned int offset;
+
+TCGv_i64 tcg_addr;
+
+bool is_store;
+bool is_signed = false;
+bool is_extended = false;
+
+if (is_vector) {
+size |= (opc & 2) << 1;
+if (size > 4) {
+unallocated_encoding(s);
+return;
+}
+is_store = !extract32(opc, 0, 1);
+} else {
+if (size == 3 && opc == 2) {
+/* PRFM - prefetch */
+return;
+}
+if (opc == 3 && size > 1) {
+unallocated_encoding(s);
+return;
+}
+is_store = (opc == 0);
+is_signed = extract32(opc, 1, 1);
+is_extended = (size < 3) && extract32(opc, 0, 1);
+}
+
+if (rn == 31) {
+gen_check_sp_alignment(s);
+}
+tcg_addr = read_cpu_reg_sp(s, rn, 1);
+offset = imm12 << size;
+tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
+
+if (is_vector) {
+if (is_store) {
+do_fp_st(s, rt, tcg_addr, size);
+} else {
+do_fp_ld(s, rt, tcg_addr, size);
+}
+} else {
+TCGv_i64 tcg_rt = cpu_reg(s, rt);
+if (is_store) {
+do_gpr_st(s, tcg_rt, tcg_addr, size);
+} else {
+do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
+}
+}
+}
+
 /* Load/store register (all forms) */
 static void disas_ldst_reg(DisasContext *s, uint32_t insn)
 {
-unsupported_encoding(s, insn);
+switch (extract32(insn, 24, 2)) {
+case 0:
+unsupported_encoding(s, insn);
+break;
+case 1:
+disas_ldst_reg_unsigned_imm(s, insn);
+break;
+default:
+unallocated_encoding(s);
+break;
+}
 }
 
 /* AdvSIMD load/store multiple structures */
-- 
1.8.5




[Qemu-devel] [PATCH v2 14/25] target-arm: A64: Implement MRS/MSR/SYS/SYSL

2013-12-22 Thread Peter Maydell
The AArch64 equivalent of the traditional AArch32
cp15 coprocessor registers is the set of instructions
MRS/MSR/SYS/SYSL, which cover between them both true
system registers and the "operations with side effects"
such as cache maintenance which in AArch32 are mixed
in with other cp15 registers. Implement these instructions
to look in the cpregs hashtable for the register or
operation.

Since we don't yet populate the cpregs hashtable with
any registers with the "AA64" bit set, everything will
still UNDEF at this point.

MSR/MRS is the first user of is_jmp = DISAS_UPDATE, so
fix an infelicity in its handling where the main loop
was requiring the caller to do the update of PC rather
than just doing it itself.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
---
 target-arm/translate-a64.c | 112 +
 1 file changed, 82 insertions(+), 30 deletions(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index e35d2f3..7a9ee82 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -733,28 +733,88 @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
 unsupported_encoding(s, insn);
 }
 
-/* C5.6.204 SYS */
-static void handle_sys(DisasContext *s, uint32_t insn, unsigned int l,
-   unsigned int op1, unsigned int op2,
+/* C5.6.129 MRS - move from system register
+ * C5.6.131 MSR (register) - move to system register
+ * C5.6.204 SYS
+ * C5.6.205 SYSL
+ * These are all essentially the same insn in 'read' and 'write'
+ * versions, with varying op0 fields.
+ */
+static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
+   unsigned int op0, unsigned int op1, unsigned int op2,
unsigned int crn, unsigned int crm, unsigned int rt)
 {
-unsupported_encoding(s, insn);
-}
+const ARMCPRegInfo *ri;
+TCGv_i64 tcg_rt;
 
-/* C5.6.129 MRS - move from system register */
-static void handle_mrs(DisasContext *s, uint32_t insn, unsigned int op0,
-   unsigned int op1, unsigned int op2,
-   unsigned int crn, unsigned int crm, unsigned int rt)
-{
-unsupported_encoding(s, insn);
-}
+ri = get_arm_cp_reginfo(s->cp_regs,
+ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP,
+   crn, crm, op0, op1, op2));
 
-/* C5.6.131 MSR (register) - move to system register */
-static void handle_msr(DisasContext *s, uint32_t insn, unsigned int op0,
-   unsigned int op1, unsigned int op2,
-   unsigned int crn, unsigned int crm, unsigned int rt)
-{
-unsupported_encoding(s, insn);
+if (!ri) {
+/* Unknown register */
+unallocated_encoding(s);
+return;
+}
+
+/* Check access permissions */
+if (!cp_access_ok(s->current_pl, ri, isread)) {
+unallocated_encoding(s);
+return;
+}
+
+/* Handle special cases first */
+switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
+case ARM_CP_NOP:
+return;
+default:
+break;
+}
+
+if (use_icount && (ri->type & ARM_CP_IO)) {
+gen_io_start();
+}
+
+tcg_rt = cpu_reg(s, rt);
+
+if (isread) {
+if (ri->type & ARM_CP_CONST) {
+tcg_gen_movi_i64(tcg_rt, ri->resetvalue);
+} else if (ri->readfn) {
+TCGv_ptr tmpptr;
+gen_a64_set_pc_im(s->pc - 4);
+tmpptr = tcg_const_ptr(ri);
+gen_helper_get_cp_reg64(tcg_rt, cpu_env, tmpptr);
+tcg_temp_free_ptr(tmpptr);
+} else {
+tcg_gen_ld_i64(tcg_rt, cpu_env, ri->fieldoffset);
+}
+} else {
+if (ri->type & ARM_CP_CONST) {
+/* If not forbidden by access permissions, treat as WI */
+return;
+} else if (ri->writefn) {
+TCGv_ptr tmpptr;
+gen_a64_set_pc_im(s->pc - 4);
+tmpptr = tcg_const_ptr(ri);
+gen_helper_set_cp_reg64(cpu_env, tmpptr, tcg_rt);
+tcg_temp_free_ptr(tmpptr);
+} else {
+tcg_gen_st_i64(tcg_rt, cpu_env, ri->fieldoffset);
+}
+}
+
+if (use_icount && (ri->type & ARM_CP_IO)) {
+/* I/O operations must end the TB here (whether read or write) */
+gen_io_end();
+s->is_jmp = DISAS_UPDATE;
+} else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
+/* We default to ending the TB on a coprocessor register write,
+ * but allow this to be suppressed by the register definition
+ * (usually only necessary to work around guest bugs).
+ */
+s->is_jmp = DISAS_UPDATE;
+}
 }
 
 /* C3.2.4 System
@@ -795,17 +855,7 @@ static void disas_system(DisasContext *s, uint32_t insn)
 }
 return;
 }
-
-if (op0 == 1) {
-/* C5.6.204 SYS */
-handle_sys(s, insn, l, op1, op2, crn, crm, rt);
-} else if (l) {

[Qemu-devel] [PATCH v2 24/25] .travis.yml: Add aarch64-* targets

2013-12-22 Thread Peter Maydell
From: Alex Bennée 

Now the AArch64 targets are in mainline we can include them in our
Travis test matrix.

Signed-off-by: Alex Bennée 
Signed-off-by: Peter Maydell 
---
 .travis.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.travis.yml b/.travis.yml
index 90f1676..c7ff4da 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,6 +16,7 @@ env:
   matrix:
   - TARGETS=alpha-softmmu,alpha-linux-user
   - TARGETS=arm-softmmu,arm-linux-user
+  - TARGETS=aarch64-softmmu,aarch64-linux-user
   - TARGETS=cris-softmmu
   - TARGETS=i386-softmmu,x86_64-softmmu
   - TARGETS=lm32-softmmu
-- 
1.8.5




[Qemu-devel] [PATCH v2 07/25] target-arm: A64: add support for 3 src data proc insns

2013-12-22 Thread Peter Maydell
From: Alexander Graf 

This patch adds emulation for the "Data-processing (3 source)"
family of instructions, namely MADD, MSUB, SMADDL, SMSUBL, SMULH,
UMADDL, UMSUBL, UMULH.

Signed-off-by: Alexander Graf 
Signed-off-by: Alex Bennée 
Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
---
 target-arm/translate-a64.c | 97 +-
 1 file changed, 95 insertions(+), 2 deletions(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index dbc865a..3a9ffdf 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -2128,10 +2128,103 @@ static void disas_add_sub_reg(DisasContext *s, 
uint32_t insn)
 tcg_temp_free_i64(tcg_result);
 }
 
-/* Data-processing (3 source) */
+/* C3.5.9 Data-processing (3 source)
+
+   31 30  29 28   24 23 21  20  16  15  14  10 95 40
+  +--+--+---+--+--++--+--+--+
+  |sf| op54 | 1 1 0 1 1 | op31 |  Rm  | o0 |  Ra  |  Rn  |  Rd  |
+  +--+--+---+--+--++--+--+--+
+
+ */
 static void disas_data_proc_3src(DisasContext *s, uint32_t insn)
 {
-unsupported_encoding(s, insn);
+int rd = extract32(insn, 0, 5);
+int rn = extract32(insn, 5, 5);
+int ra = extract32(insn, 10, 5);
+int rm = extract32(insn, 16, 5);
+int op_id = (extract32(insn, 29, 3) << 4) |
+(extract32(insn, 21, 3) << 1) |
+extract32(insn, 15, 1);
+bool sf = extract32(insn, 31, 1);
+bool is_sub = extract32(op_id, 0, 1);
+bool is_high = extract32(op_id, 2, 1);
+bool is_signed = false;
+TCGv_i64 tcg_op1;
+TCGv_i64 tcg_op2;
+TCGv_i64 tcg_tmp;
+
+/* Note that op_id is sf:op54:op31:o0 so it includes the 32/64 size flag */
+switch (op_id) {
+case 0x42: /* SMADDL */
+case 0x43: /* SMSUBL */
+case 0x44: /* SMULH */
+is_signed = true;
+break;
+case 0x0: /* MADD (32bit) */
+case 0x1: /* MSUB (32bit) */
+case 0x40: /* MADD (64bit) */
+case 0x41: /* MSUB (64bit) */
+case 0x4a: /* UMADDL */
+case 0x4b: /* UMSUBL */
+case 0x4c: /* UMULH */
+break;
+default:
+unallocated_encoding(s);
+return;
+}
+
+if (is_high) {
+TCGv_i64 low_bits = tcg_temp_new_i64(); /* low bits discarded */
+TCGv_i64 tcg_rd = cpu_reg(s, rd);
+TCGv_i64 tcg_rn = cpu_reg(s, rn);
+TCGv_i64 tcg_rm = cpu_reg(s, rm);
+
+if (is_signed) {
+tcg_gen_muls2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm);
+} else {
+tcg_gen_mulu2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm);
+}
+
+tcg_temp_free_i64(low_bits);
+return;
+}
+
+tcg_op1 = tcg_temp_new_i64();
+tcg_op2 = tcg_temp_new_i64();
+tcg_tmp = tcg_temp_new_i64();
+
+if (op_id < 0x42) {
+tcg_gen_mov_i64(tcg_op1, cpu_reg(s, rn));
+tcg_gen_mov_i64(tcg_op2, cpu_reg(s, rm));
+} else {
+if (is_signed) {
+tcg_gen_ext32s_i64(tcg_op1, cpu_reg(s, rn));
+tcg_gen_ext32s_i64(tcg_op2, cpu_reg(s, rm));
+} else {
+tcg_gen_ext32u_i64(tcg_op1, cpu_reg(s, rn));
+tcg_gen_ext32u_i64(tcg_op2, cpu_reg(s, rm));
+}
+}
+
+if (ra == 31 && !is_sub) {
+/* Special-case MADD with rA == XZR; it is the standard MUL alias */
+tcg_gen_mul_i64(cpu_reg(s, rd), tcg_op1, tcg_op2);
+} else {
+tcg_gen_mul_i64(tcg_tmp, tcg_op1, tcg_op2);
+if (is_sub) {
+tcg_gen_sub_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp);
+} else {
+tcg_gen_add_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp);
+}
+}
+
+if (!sf) {
+tcg_gen_ext32u_i64(cpu_reg(s, rd), cpu_reg(s, rd));
+}
+
+tcg_temp_free_i64(tcg_op1);
+tcg_temp_free_i64(tcg_op2);
+tcg_temp_free_i64(tcg_tmp);
 }
 
 /* Add/subtract (with carry) */
-- 
1.8.5




[Qemu-devel] [PATCH v2 06/25] target-arm: A64: add support for move wide instructions

2013-12-22 Thread Peter Maydell
From: Alex Bennée 

This patch adds emulation for the mov wide instructions
(MOVN, MOVZ, MOVK).

Signed-off-by: Alex Bennée 
Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
---
 target-arm/translate-a64.c | 51 --
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index c0057a2..dbc865a 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1644,10 +1644,57 @@ static void disas_logic_imm(DisasContext *s, uint32_t 
insn)
 }
 }
 
-/* Move wide (immediate) */
+/*
+ * C3.4.5 Move wide (immediate)
+ *
+ *  31 30 29 28 23 22 21 20 5 40
+ * +--+-+-+-++--+
+ * |sf| opc | 1 0 0 1 0 1 |  hw |  imm16 |  Rd  |
+ * +--+-+-+-++--+
+ *
+ * sf: 0 -> 32 bit, 1 -> 64 bit
+ * opc: 00 -> N, 10 -> Z, 11 -> K
+ * hw: shift/16 (0,16, and sf only 32, 48)
+ */
 static void disas_movw_imm(DisasContext *s, uint32_t insn)
 {
-unsupported_encoding(s, insn);
+int rd = extract32(insn, 0, 5);
+uint64_t imm = extract32(insn, 5, 16);
+int sf = extract32(insn, 31, 1);
+int opc = extract32(insn, 29, 2);
+int pos = extract32(insn, 21, 2) << 4;
+TCGv_i64 tcg_rd = cpu_reg(s, rd);
+TCGv_i64 tcg_imm;
+
+if (!sf && (pos >= 32)) {
+unallocated_encoding(s);
+return;
+}
+
+switch (opc) {
+case 0: /* MOVN */
+case 2: /* MOVZ */
+imm <<= pos;
+if (opc == 0) {
+imm = ~imm;
+}
+if (!sf) {
+imm &= 0xu;
+}
+tcg_gen_movi_i64(tcg_rd, imm);
+break;
+case 3: /* MOVK */
+tcg_imm = tcg_const_i64(imm);
+tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_imm, pos, 16);
+tcg_temp_free_i64(tcg_imm);
+if (!sf) {
+tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
+}
+break;
+default:
+unallocated_encoding(s);
+break;
+}
 }
 
 /* C3.4.2 Bitfield
-- 
1.8.5




[Qemu-devel] [PATCH v2 13/25] target-arm: Remove ARMCPU/CPUARMState from cpregs APIs used by decoder

2013-12-22 Thread Peter Maydell
The cpregs APIs used by the decoder (get_arm_cp_reginfo() and
cp_access_ok()) currently take either a CPUARMState* or an ARMCPU*.
This is problematic for the A64 decoder, which doesn't pass the
environment pointer around everywhere the way the 32 bit decoder
does. Adjust the parameters these functions take so that we can
copy only the relevant info from the CPUARMState into the
DisasContext and then use that.

Signed-off-by: Peter Maydell 
---
 target-arm/cpu.h   |  6 +++---
 target-arm/helper.c| 12 ++--
 target-arm/translate-a64.c |  2 ++
 target-arm/translate.c |  7 ---
 target-arm/translate.h |  2 ++
 5 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index b082bca..66490ce 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -849,7 +849,7 @@ static inline void define_one_arm_cp_reg(ARMCPU *cpu, const 
ARMCPRegInfo *regs)
 {
 define_one_arm_cp_reg_with_opaque(cpu, regs, 0);
 }
-const ARMCPRegInfo *get_arm_cp_reginfo(ARMCPU *cpu, uint32_t encoded_cp);
+const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t 
encoded_cp);
 
 /* CPWriteFn that can be used to implement writes-ignored behaviour */
 int arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -862,10 +862,10 @@ int arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo 
*ri, uint64_t *value);
  */
 void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque);
 
-static inline bool cp_access_ok(CPUARMState *env,
+static inline bool cp_access_ok(int current_pl,
 const ARMCPRegInfo *ri, int isread)
 {
-return (ri->access >> ((arm_current_pl(env) * 2) + isread)) & 1;
+return (ri->access >> ((current_pl * 2) + isread)) & 1;
 }
 
 /**
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 3dac694..66214293 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -186,7 +186,7 @@ bool write_cpustate_to_list(ARMCPU *cpu)
 uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
 const ARMCPRegInfo *ri;
 uint64_t v;
-ri = get_arm_cp_reginfo(cpu, regidx);
+ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
 if (!ri) {
 ok = false;
 continue;
@@ -214,7 +214,7 @@ bool write_list_to_cpustate(ARMCPU *cpu)
 uint64_t readback;
 const ARMCPRegInfo *ri;
 
-ri = get_arm_cp_reginfo(cpu, regidx);
+ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
 if (!ri) {
 ok = false;
 continue;
@@ -242,7 +242,7 @@ static void add_cpreg_to_list(gpointer key, gpointer opaque)
 const ARMCPRegInfo *ri;
 
 regidx = *(uint32_t *)key;
-ri = get_arm_cp_reginfo(cpu, regidx);
+ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
 
 if (!(ri->type & ARM_CP_NO_MIGRATE)) {
 cpu->cpreg_indexes[cpu->cpreg_array_len] = cpreg_to_kvm_id(regidx);
@@ -258,7 +258,7 @@ static void count_cpreg(gpointer key, gpointer opaque)
 const ARMCPRegInfo *ri;
 
 regidx = *(uint32_t *)key;
-ri = get_arm_cp_reginfo(cpu, regidx);
+ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
 
 if (!(ri->type & ARM_CP_NO_MIGRATE)) {
 cpu->cpreg_array_len++;
@@ -2136,9 +2136,9 @@ void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
 }
 }
 
-const ARMCPRegInfo *get_arm_cp_reginfo(ARMCPU *cpu, uint32_t encoded_cp)
+const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
 {
-return g_hash_table_lookup(cpu->cp_regs, &encoded_cp);
+return g_hash_table_lookup(cpregs, &encoded_cp);
 }
 
 int arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 7d98337..e35d2f3 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -3007,6 +3007,8 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
 dc->vfp_enabled = 0;
 dc->vec_len = 0;
 dc->vec_stride = 0;
+dc->cp_regs = cpu->cp_regs;
+dc->current_pl = arm_current_pl(env);
 
 init_tmp_a64_array(dc);
 
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 1403ecf..8bfe950 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6498,7 +6498,6 @@ static int disas_coproc_insn(CPUARMState * env, 
DisasContext *s, uint32_t insn)
 {
 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
 const ARMCPRegInfo *ri;
-ARMCPU *cpu = arm_env_get_cpu(env);
 
 cpnum = (insn >> 8) & 0xf;
 if (arm_feature(env, ARM_FEATURE_XSCALE)
@@ -6541,11 +6540,11 @@ static int disas_coproc_insn(CPUARMState * env, 
DisasContext *s, uint32_t insn)
 isread = (insn >> 20) & 1;
 rt = (insn >> 12) & 0xf;
 
-ri = get_arm_cp_reginfo(cpu,
+ri = get_arm_cp_reginfo(s->cp_regs,
 ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
 if (ri) {
 /* Check access permissions */
-if (!cp_access_ok(env, ri, isread)) {
+if (!cp

[Qemu-devel] [PATCH v2 20/25] target-arm: Widen exclusive-access support struct fields to 64 bits

2013-12-22 Thread Peter Maydell
In preparation for adding support for A64 load/store exclusive instructions,
widen the fields in the CPU state struct that deal with address and data values
for exclusives from 32 to 64 bits. Although in practice AArch64 and AArch32
exclusive accesses will be generally separate there are some odd theoretical
corner cases (eg you should be able to do the exclusive load in AArch32, take
an exception to AArch64 and successfully do the store exclusive there), and it's
also easier to reason about.

The changes in semantics for the variables are:
 exclusive_addr  -> extended to 64 bits; -1ULL for "monitor lost",
   otherwise always < 2^32 for AArch32
 exclusive_val   -> extended to 64 bits. 64 bit exclusives in AArch32 now
   use the high half of exclusive_val instead of a separate exclusive_high
 exclusive_high  -> is no longer used in AArch32; extended to 64 bits as
   it will be needed for AArch64's pair-of-64-bit-values exclusives.
 exclusive_test  -> extended to 64 bits, as it is an address. Since this is
   a linux-user-only field, in arm-linux-user it will always have the top
   32 bits zero.
 exclusive_info  -> stays 32 bits, as it is neither data nor address, but
   simply holds register indexes etc. AArch64 will be able to fit all its
   information into 32 bits as well.

Note that the refactoring of gen_store_exclusive() coincidentally fixes
a minor bug where ldrexd would incorrectly update the first CPU register
even if the load for the second register faulted.

Signed-off-by: Peter Maydell 
---
 linux-user/main.c  | 25 +++
 target-arm/cpu.h   |  8 +++
 target-arm/machine.c   | 12 +-
 target-arm/translate.c | 65 ++
 4 files changed, 64 insertions(+), 46 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index c0df8b5..20f9832 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -589,16 +589,21 @@ do_kernel_trap(CPUARMState *env)
 
 static int do_strex(CPUARMState *env)
 {
-uint32_t val;
+uint64_t val;
 int size;
 int rc = 1;
 int segv = 0;
 uint32_t addr;
 start_exclusive();
-addr = env->exclusive_addr;
-if (addr != env->exclusive_test) {
+if (env->exclusive_addr != env->exclusive_test) {
 goto fail;
 }
+/* We know we're always AArch32 so the address is in uint32_t range
+ * unless it was the -1 exclusive-monitor-lost value (which won't
+ * match exclusive_test above).
+ */
+assert(extract64(env->exclusive_addr, 32, 32) == 0);
+addr = env->exclusive_addr;
 size = env->exclusive_info & 0xf;
 switch (size) {
 case 0:
@@ -618,19 +623,19 @@ static int do_strex(CPUARMState *env)
 env->cp15.c6_data = addr;
 goto done;
 }
-if (val != env->exclusive_val) {
-goto fail;
-}
 if (size == 3) {
-segv = get_user_u32(val, addr + 4);
+uint32_t valhi;
+segv = get_user_u32(valhi, addr + 4);
 if (segv) {
 env->cp15.c6_data = addr + 4;
 goto done;
 }
-if (val != env->exclusive_high) {
-goto fail;
-}
+val = deposit64(val, 32, 32, valhi);
+}
+if (val != env->exclusive_val) {
+goto fail;
 }
+
 val = env->regs[(env->exclusive_info >> 8) & 0xf];
 switch (size) {
 case 0:
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 45f8973..6c84e22 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -278,11 +278,11 @@ typedef struct CPUARMState {
 float_status fp_status;
 float_status standard_fp_status;
 } vfp;
-uint32_t exclusive_addr;
-uint32_t exclusive_val;
-uint32_t exclusive_high;
+uint64_t exclusive_addr;
+uint64_t exclusive_val;
+uint64_t exclusive_high;
 #if defined(CONFIG_USER_ONLY)
-uint32_t exclusive_test;
+uint64_t exclusive_test;
 uint32_t exclusive_info;
 #endif
 
diff --git a/target-arm/machine.c b/target-arm/machine.c
index 74f010f..8f9e7d4 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -222,9 +222,9 @@ static int cpu_post_load(void *opaque, int version_id)
 
 const VMStateDescription vmstate_arm_cpu = {
 .name = "cpu",
-.version_id = 13,
-.minimum_version_id = 13,
-.minimum_version_id_old = 13,
+.version_id = 14,
+.minimum_version_id = 14,
+.minimum_version_id_old = 14,
 .pre_save = cpu_pre_save,
 .post_load = cpu_post_load,
 .fields = (VMStateField[]) {
@@ -253,9 +253,9 @@ const VMStateDescription vmstate_arm_cpu = {
 VMSTATE_VARRAY_INT32(cpreg_vmstate_values, ARMCPU,
  cpreg_vmstate_array_len,
  0, vmstate_info_uint64, uint64_t),
-VMSTATE_UINT32(env.exclusive_addr, ARMCPU),
-VMSTATE_UINT32(env.exclusive_val, ARMCPU),
-VMSTATE_UINT32(env.exclusive_high, ARMCPU),
+VMSTATE_UINT64(env.exclusive_addr, ARMCPU),
+VMSTATE_UINT64(env.exclusive_val,

[Qemu-devel] [PATCH v2 21/25] target-arm: A64: support for ld/st/cl exclusive

2013-12-22 Thread Peter Maydell
From: Michael Matz 

This implement exclusive loads/stores for aarch64 along the lines of
arm32 and ppc implementations. The exclusive load remembers the address
and loaded value. The exclusive store throws an an exception which uses
those values to check for equality in a proper exclusive region.

This is not actually the architecture mandated semantics (for either
AArch32 or AArch64) but it is close enough for typical guest code
sequences to work correctly, and saves us from having to monitor all
guest stores. It's fairly easy to come up with test cases where we
don't behave like hardware - we don't for example model cache line
behaviour. However in the common patterns this works, and the existing
32 bit ARM exclusive access implementation has the same limitations.

AArch64 also implements new acquire/release loads/stores (which may be
either exclusive or non-exclusive). These imposes extra ordering
constraints on memory operations (ie they act as if they have an implicit
barrier built into them). As TCG is single-threaded all our barriers
are no-ops, so these just behave like normal loads and stores.

Signed-off-by: Michael Matz 
Signed-off-by: Alex Bennée 
Signed-off-by: Peter Maydell 
---
 linux-user/main.c  | 127 +++-
 target-arm/translate-a64.c | 156 -
 2 files changed, 277 insertions(+), 6 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 20f9832..cabc9e1 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -585,8 +585,8 @@ do_kernel_trap(CPUARMState *env)
 
 return 0;
 }
-#endif
 
+/* Store exclusive handling for AArch32 */
 static int do_strex(CPUARMState *env)
 {
 uint64_t val;
@@ -670,7 +670,6 @@ done:
 return segv;
 }
 
-#ifdef TARGET_ABI32
 void cpu_loop(CPUARMState *env)
 {
 CPUState *cs = CPU(arm_env_get_cpu(env));
@@ -885,6 +884,122 @@ void cpu_loop(CPUARMState *env)
 
 #else
 
+/*
+ * Handle AArch64 store-release exclusive
+ *
+ * rs = gets the status result of store exclusive
+ * rt = is the register that is stored
+ * rt2 = is the second register store (in STP)
+ *
+ */
+static int do_strex_a64(CPUARMState *env)
+{
+uint64_t val;
+int size;
+bool is_pair;
+int rc = 1;
+int segv = 0;
+uint64_t addr;
+int rs, rt, rt2;
+
+start_exclusive();
+/* size | is_pair << 2 | (rs << 4) | (rt << 9) | (rt2 << 14)); */
+size = extract32(env->exclusive_info, 0, 2);
+is_pair = extract32(env->exclusive_info, 2, 1);
+rs = extract32(env->exclusive_info, 4, 5);
+rt = extract32(env->exclusive_info, 9, 5);
+rt2 = extract32(env->exclusive_info, 14, 5);
+
+addr = env->exclusive_addr;
+
+if (addr != env->exclusive_test) {
+goto finish;
+}
+
+switch (size) {
+case 0:
+segv = get_user_u8(val, addr);
+break;
+case 1:
+segv = get_user_u16(val, addr);
+break;
+case 2:
+segv = get_user_u32(val, addr);
+break;
+case 3:
+segv = get_user_u64(val, addr);
+break;
+default:
+abort();
+}
+if (segv) {
+env->cp15.c6_data = addr;
+goto error;
+}
+if (val != env->exclusive_val) {
+goto finish;
+}
+if (is_pair) {
+if (size == 2) {
+segv = get_user_u32(val, addr + 4);
+} else {
+segv = get_user_u64(val, addr + 8);
+}
+if (segv) {
+env->cp15.c6_data = addr + (size == 2 ? 4 : 8);
+goto error;
+}
+if (val != env->exclusive_high) {
+goto finish;
+}
+}
+val = env->xregs[rt];
+switch (size) {
+case 0:
+segv = put_user_u8(val, addr);
+break;
+case 1:
+segv = put_user_u16(val, addr);
+break;
+case 2:
+segv = put_user_u32(val, addr);
+break;
+case 3:
+segv = put_user_u64(val, addr);
+break;
+}
+if (segv) {
+goto error;
+}
+if (is_pair) {
+val = env->xregs[rt2];
+if (size == 2) {
+segv = put_user_u32(val, addr + 4);
+} else {
+segv = put_user_u64(val, addr + 8);
+}
+if (segv) {
+env->cp15.c6_data = addr + (size == 2 ? 4 : 8);
+goto error;
+}
+}
+rc = 0;
+finish:
+env->pc += 4;
+/* rs == 31 encodes a write to the ZR, thus throwing away
+ * the status return. This is rather silly but valid.
+ */
+if (rs < 31) {
+env->xregs[rs] = rc;
+}
+error:
+/* instruction faulted, PC does not advance */
+/* either way a strex releases any exclusive lock we have */
+env->exclusive_addr = -1;
+end_exclusive();
+return segv;
+}
+
 /* AArch64 main loop */
 void cpu_loop(CPUARMState *env)
 {
@@ -944,7 +1059,7 @@ void cpu_loop(CPUARMState *env)
 }
 break;
 case EXCP_STREX:
-if (do_strex(env)) {
+   

[Qemu-devel] [PATCH v2 08/25] target-arm: A64: implement SVC, BRK

2013-12-22 Thread Peter Maydell
From: Alexander Graf 

Add decoding for the exception generating instructions, and implement
SVC (syscalls) and BRK (software breakpoint).

Signed-off-by: Alexander Graf 
Signed-off-by: Alex Bennée 
Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
---
 target-arm/translate-a64.c | 51 --
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 3a9ffdf..9ca6460 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -808,10 +808,57 @@ static void disas_system(DisasContext *s, uint32_t insn)
 }
 }
 
-/* Exception generation */
+/* C3.2.3 Exception generation
+ *
+ *  31 24 23 21 20 5 4   2 1  0
+ * +-+-++-++
+ * | 1 1 0 1 0 1 0 0 | opc |  imm16 | op2 | LL |
+ * +---++--+
+ */
 static void disas_exc(DisasContext *s, uint32_t insn)
 {
-unsupported_encoding(s, insn);
+int opc = extract32(insn, 21, 3);
+int op2_ll = extract32(insn, 0, 5);
+
+switch (opc) {
+case 0:
+/* SVC, HVC, SMC; since we don't support the Virtualization
+ * or TrustZone extensions these all UNDEF except SVC.
+ */
+if (op2_ll != 1) {
+unallocated_encoding(s);
+break;
+}
+gen_exception_insn(s, 0, EXCP_SWI);
+break;
+case 1:
+if (op2_ll != 0) {
+unallocated_encoding(s);
+break;
+}
+/* BRK */
+gen_exception_insn(s, 0, EXCP_BKPT);
+break;
+case 2:
+if (op2_ll != 0) {
+unallocated_encoding(s);
+break;
+}
+/* HLT */
+unsupported_encoding(s, insn);
+break;
+case 5:
+if (op2_ll < 1 || op2_ll > 3) {
+unallocated_encoding(s);
+break;
+}
+/* DCPS1, DCPS2, DCPS3 */
+unsupported_encoding(s, insn);
+break;
+default:
+unallocated_encoding(s);
+break;
+}
 }
 
 /* C3.2.7 Unconditional branch (register)
-- 
1.8.5




[Qemu-devel] [PATCH v2 03/25] target-arm: A64: add support for ld/st with reg offset

2013-12-22 Thread Peter Maydell
From: Alex Bennée 

This adds support for the load/store forms using a register offset.

Signed-off-by: Alex Bennée 
Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
---
 target-arm/translate-a64.c | 144 -
 1 file changed, 143 insertions(+), 1 deletion(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 0edcee1..67efcf9 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -404,6 +404,54 @@ static void do_fp_ld(DisasContext *s, int destidx, 
TCGv_i64 tcg_addr, int size)
 tcg_temp_free_i64(tmphi);
 }
 
+/*
+ * This utility function is for doing register extension with an
+ * optional shift. You will likely want to pass a temporary for the
+ * destination register. See DecodeRegExtend() in the ARM ARM.
+ */
+static void ext_and_shift_reg(TCGv_i64 tcg_out, TCGv_i64 tcg_in,
+  int option, unsigned int shift)
+{
+int extsize = extract32(option, 0, 2);
+bool is_signed = extract32(option, 2, 1);
+
+if (is_signed) {
+switch (extsize) {
+case 0:
+tcg_gen_ext8s_i64(tcg_out, tcg_in);
+break;
+case 1:
+tcg_gen_ext16s_i64(tcg_out, tcg_in);
+break;
+case 2:
+tcg_gen_ext32s_i64(tcg_out, tcg_in);
+break;
+case 3:
+tcg_gen_mov_i64(tcg_out, tcg_in);
+break;
+}
+} else {
+switch (extsize) {
+case 0:
+tcg_gen_ext8u_i64(tcg_out, tcg_in);
+break;
+case 1:
+tcg_gen_ext16u_i64(tcg_out, tcg_in);
+break;
+case 2:
+tcg_gen_ext32u_i64(tcg_out, tcg_in);
+break;
+case 3:
+tcg_gen_mov_i64(tcg_out, tcg_in);
+break;
+}
+}
+
+if (shift) {
+tcg_gen_shli_i64(tcg_out, tcg_out, shift);
+}
+}
+
 static inline void gen_check_sp_alignment(DisasContext *s)
 {
 /* The AArch64 architecture mandates that (if enabled via PSTATE
@@ -902,6 +950,96 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
 }
 
 /*
+ * C3.3.10 Load/store (register offset)
+ *
+ * 31 30 29   27  26 25 24 23 22 21  20  16 15 13 12 11 10 9  5 4  0
+ * ++---+---+-+-+---+--+-+--+-+++
+ * |size| 1 1 1 | V | 0 0 | opc | 1 |  Rm  | opt | S| 1 0 | Rn | Rt |
+ * ++---+---+-+-+---+--+-+--+-+++
+ *
+ * For non-vector:
+ *   size: 00-> byte, 01 -> 16 bit, 10 -> 32bit, 11 -> 64bit
+ *   opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
+ * For vector:
+ *   size is opc<1>:size<1:0> so 100 -> 128 bit; 110 and 111 unallocated
+ *   opc<0>: 0 -> store, 1 -> load
+ * V: 1 -> vector/simd
+ * opt: extend encoding (see DecodeRegExtend)
+ * S: if S=1 then scale (essentially index by sizeof(size))
+ * Rt: register to transfer into/out of
+ * Rn: address register or SP for base
+ * Rm: offset register or ZR for offset
+ */
+static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn)
+{
+int rt = extract32(insn, 0, 5);
+int rn = extract32(insn, 5, 5);
+int shift = extract32(insn, 12, 1);
+int rm = extract32(insn, 16, 5);
+int opc = extract32(insn, 22, 2);
+int opt = extract32(insn, 13, 3);
+int size = extract32(insn, 30, 2);
+bool is_signed = false;
+bool is_store = false;
+bool is_extended = false;
+bool is_vector = extract32(insn, 26, 1);
+
+TCGv_i64 tcg_rm;
+TCGv_i64 tcg_addr;
+
+if (extract32(opt, 1, 1) == 0) {
+unallocated_encoding(s);
+return;
+}
+
+if (is_vector) {
+size |= (opc & 2) << 1;
+if (size > 4) {
+unallocated_encoding(s);
+return;
+}
+is_store = !extract32(opc, 0, 1);
+} else {
+if (size == 3 && opc == 2) {
+/* PRFM - prefetch */
+return;
+}
+if (opc == 3 && size > 1) {
+unallocated_encoding(s);
+return;
+}
+is_store = (opc == 0);
+is_signed = extract32(opc, 1, 1);
+is_extended = (size < 3) && extract32(opc, 0, 1);
+}
+
+if (rn == 31) {
+gen_check_sp_alignment(s);
+}
+tcg_addr = read_cpu_reg_sp(s, rn, 1);
+
+tcg_rm = read_cpu_reg(s, rm, 1);
+ext_and_shift_reg(tcg_rm, tcg_rm, opt, shift ? size : 0);
+
+tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_rm);
+
+if (is_vector) {
+if (is_store) {
+do_fp_st(s, rt, tcg_addr, size);
+} else {
+do_fp_ld(s, rt, tcg_addr, size);
+}
+} else {
+TCGv_i64 tcg_rt = cpu_reg(s, rt);
+if (is_store) {
+do_gpr_st(s, tcg_rt, tcg_addr, size);
+} else {
+do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, is_extended);
+}
+}
+}
+
+/*
  * C3.3.13 Load/store (unsigned immediate)
  *
  * 31 30 29   27  26 25 24 23 22 2110 

  1   2   >