Re: [PATCH v3 6/7] docs: gpio: Add GPIO Aggregator/Repeater documentation

2019-11-27 Thread Ulrich Hecht
; +gpios = < 19 GPIO_ACTIVE_HIGH>,
> +< 20 GPIO_ACTIVE_LOW>;
> +};
> +
> +it can be bound to the GPIO Aggregator by either:
> +
> +1. Adding its compatible value to ``gpio_aggregator_dt_ids[]``,
> +2. Binding manually using "driver_override":
> +
> +.. code-block:: bash
> +
> +    echo gpio-aggregator > 
> /sys/bus/platform/devices/frobnicator/driver_override
> +echo frobnicator > /sys/bus/platform/drivers/gpio-aggregator/bind
> diff --git a/Documentation/admin-guide/gpio/index.rst 
> b/Documentation/admin-guide/gpio/index.rst
> index a244ba4e87d5398a..ef2838638e96 100644
> --- a/Documentation/admin-guide/gpio/index.rst
> +++ b/Documentation/admin-guide/gpio/index.rst
> @@ -7,6 +7,7 @@ gpio
>  .. toctree::
>  :maxdepth: 1
>  
> +gpio-aggregator
>  sysfs
>  
>  .. only::  subproject and html
> -- 
> 2.17.1
>

Reviewed-by: Ulrich Hecht 

CU
Uli



Re: [PATCH v3 3/7] gpiolib: Add support for GPIO line table lookup

2019-11-27 Thread Ulrich Hecht


> On November 27, 2019 at 9:42 AM Geert Uytterhoeven  
> wrote:
> 
> 
> Currently GPIOs can only be referred to by GPIO controller and offset in
> GPIO lookup tables.
> 
> Add support for looking them up by line name.
> 
> Signed-off-by: Geert Uytterhoeven 
> ---
> If this is rejected, the GPIO Aggregator documentation and code must be
> updated.
> 
> v3:
>   - New.
> ---
>  drivers/gpio/gpiolib.c   | 12 
>  include/linux/gpio/machine.h |  2 +-
>  2 files changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> index d24a3d79dcfe69ad..cb608512ad6bbded 100644
> --- a/drivers/gpio/gpiolib.c
> +++ b/drivers/gpio/gpiolib.c
> @@ -4475,6 +4475,18 @@ static struct gpio_desc *gpiod_find(struct device 
> *dev, const char *con_id,
>   if (p->con_id && (!con_id || strcmp(p->con_id, con_id)))
>   continue;
>  
> + if (p->chip_hwnum == (u16)-1) {
> + desc = gpio_name_to_desc(p->chip_label);
> + if (desc) {
> + *flags = p->flags;
> + return desc;
> + }
> +
> + dev_warn(dev, "cannot find GPIO line %s, deferring\n",
> +  p->chip_label);
> + return ERR_PTR(-EPROBE_DEFER);
> + }
> +
>   chip = find_chip_by_name(p->chip_label);
>  
>   if (!chip) {
> diff --git a/include/linux/gpio/machine.h b/include/linux/gpio/machine.h
> index 1ebe5be05d5f81fa..84c1c097e55eefaf 100644
> --- a/include/linux/gpio/machine.h
> +++ b/include/linux/gpio/machine.h
> @@ -31,7 +31,7 @@ enum gpio_lookup_flags {
>   */
>  struct gpiod_lookup {
>   const char *chip_label;
> - u16 chip_hwnum;
> + u16 chip_hwnum; /* if -1, chip_label is named line */

The magic number "-1" might deserve a #define.

>   const char *con_id;
>   unsigned int idx;
>   unsigned long flags;
> -- 
> 2.17.1
>

With or without #define,
Reviewed-by: Ulrich Hecht 

CU
Uli



Re: [PATCH v3 5/7] gpio: Add GPIO Aggregator/Repeater driver

2019-11-27 Thread Ulrich Hecht
Thank you for this series!

> On November 27, 2019 at 9:42 AM Geert Uytterhoeven  
> wrote:
> 
> 
> GPIO controllers are exported to userspace using /dev/gpiochip*
> character devices.  Access control to these devices is provided by
> standard UNIX file system permissions, on an all-or-nothing basis:
> either a GPIO controller is accessible for a user, or it is not.
> Currently no mechanism exists to control access to individual GPIOs.
> 
> Hence add a GPIO driver to aggregate existing GPIOs, and expose them as
> a new gpiochip.
> 
> This supports the following use cases:
>   1. Aggregating GPIOs using Sysfs
>  This is useful for implementing access control, and assigning a set
>  of GPIOs to a specific user or virtual machine.
> 
>   2. GPIO Repeater in Device Tree
>  This supports modelling e.g. GPIO inverters in DT.
> 
>   3. Generic GPIO Driver
>  This provides userspace access to a simple GPIO-operated device
>  described in DT, cfr. e.g. spidev for SPI-operated devices.
> 
> Signed-off-by: Geert Uytterhoeven 
> ---
> v3:
>   - Absorb GPIO forwarder,
>   - Integrate GPIO Repeater and Generic GPIO driver functionality,
>   - Use the aggregator parameters to create a GPIO lookup table instead
> of an array of GPIO descriptors, which allows to simplify the code:
>   1. This removes the need for calling gpio_name_to_desc(),
>  gpiochip_find(), gpiochip_get_desc(), and gpiod_request(),
>   2. This allows the platform device to always use
>  devm_gpiod_get_index(), regardless of the origin of the GPIOs,
>   - Move parameter parsing from platform device probe to sysfs attribute
> store, removing the need for platform data passing,
>   - Use more devm_*() functions to simplify cleanup,
>   - Add pr_fmt(),
>   - General refactoring.
> 
> v2:
>   - Add missing initialization of i in gpio_virt_agg_probe(),
>   - Update for removed .need_valid_mask field and changed
> .init_valid_mask() signature,
>   - Drop "virtual", rename to gpio-aggregator,
>   - Drop bogus FIXME related to gpiod_set_transitory() expectations,
>   - Use new GPIO Forwarder Helper,
>   - Lift limit on the maximum number of GPIOs,
>   - Improve parsing:
>   - add support for specifying GPIOs by line name,
>   - add support for specifying GPIO chips by ID,
>   - add support for GPIO offset ranges,
>   - names and offset specifiers must be separated by whitespace,
>   - GPIO offsets must separated by spaces,
>   - Use str_has_prefix() and kstrtouint().
> ---
>  drivers/gpio/Kconfig   |  13 +
>  drivers/gpio/Makefile  |   1 +
>  drivers/gpio/gpio-aggregator.c | 587 +
>  3 files changed, 601 insertions(+)
>  create mode 100644 drivers/gpio/gpio-aggregator.c
> 
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 8adffd42f8cb0559..36b6b57a6b05e906 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -1507,6 +1507,19 @@ config GPIO_VIPERBOARD
>  
>  endmenu
>  
> +config GPIO_AGGREGATOR
> + tristate "GPIO Aggregator/Repeater"
> + help
> +   Say yes here to enable the GPIO Aggregator and repeater, which

Inconsistent capitalization (Aggregator vs. repeater).

> +   provides a way to aggregate and/or repeat existing GPIOs into a new
> +   GPIO device.
> +   This can serve the following purposes:
> + 1. Assign a collection of GPIOs to a user, or export them to a
> +virtual machine,
> + 2. Support GPIOs that are connected to a physical inverter,
> + 3. Provide a generic driver for a GPIO-operated device, to be
> +   controlled from userspace using the GPIO chardev interface.
> +
>  config GPIO_MOCKUP
>   tristate "GPIO Testing Driver"
>   select IRQ_SIM
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index 34eb8b2b12dd656c..f9971eeb1f32335f 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -25,6 +25,7 @@ obj-$(CONFIG_GPIO_74XX_MMIO)+= 
> gpio-74xx-mmio.o
>  obj-$(CONFIG_GPIO_ADNP)  += gpio-adnp.o
>  obj-$(CONFIG_GPIO_ADP5520)   += gpio-adp5520.o
>  obj-$(CONFIG_GPIO_ADP5588)   += gpio-adp5588.o
> +obj-$(CONFIG_GPIO_AGGREGATOR)+= gpio-aggregator.o
>  obj-$(CONFIG_GPIO_ALTERA_A10SR)  += gpio-altera-a10sr.o
>  obj-$(CONFIG_GPIO_ALTERA)+= gpio-altera.o
>  obj-$(CONFIG_GPIO_AMD8111)   += gpio-amd8111.o
> diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c
> new file mode 100644
> index ..873578c6f9683db8
> --- /dev/null
> +++ b/drivers/gpio/gpio-aggregator.c
> @@ -0,0 +1,587 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +//
> +// GPIO Aggregator and Repeater
> +//
> +// Copyright (C) 2019 Glider bvba
> +
> +#define DRV_NAME   "gpio-aggregator"
> +#define pr_fmt(fmt)  DRV_NAME ": " fmt
> +
> +#include 
> +#include 
> +#include 
> +#include 
> 

Re: [PATCH v3 4/7] dt-bindings: gpio: Add gpio-repeater bindings

2019-11-27 Thread Ulrich Hecht


> On November 27, 2019 at 9:42 AM Geert Uytterhoeven  
> wrote:
> 
> 
> Add Device Tree bindings for a GPIO repeater, with optional translation
> of physical signal properties.  This is useful for describing explicitly
> the presence of e.g. an inverter on a GPIO line, and was inspired by the
> non-YAML gpio-inverter bindings by Harish Jenny K N
> [1].
> 
> Note that this is different from a GPIO Nexus Node[2], which cannot do
> physical signal property translation.
> 
> While an inverter can be described implicitly by exchanging the
> GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags, this has its limitations.
> Each GPIO line has only a single GPIO_ACTIVE_* flag, but applies to both
> th provider and consumer sides:
>   1. The GPIO provider (controller) looks at the flags to know the
>  polarity, so it can translate between logical (active/not active)
>  and physical (high/low) signal levels.
>   2. While the signal polarity is usually fixed on the GPIO consumer
>  side (e.g. an LED is tied to either the supply voltage or GND),
>  it may be configurable on some devices, and both sides need to
>  agree.  Hence the GPIO_ACTIVE_* flag as seen by the consumer must
>  match the actual polarity.
>  There exists a similar issue with interrupt flags, where both the
>  interrupt controller and the device generating the interrupt need
>  to agree, which breaks in the presence of a physical inverter not
>  described in DT (see e.g. [3]).
> 
> [1] "[PATCH V4 2/2] gpio: inverter: document the inverter bindings"
> 
> https://lore.kernel.org/linux-gpio/1561699236-18620-3-git-send-email-harish_kand...@mentor.com/
> 
> [2] Devicetree Specification v0.3-rc2, Section 2.5
> 
> https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.3-rc2
> 
> [3] "[PATCH] wlcore/wl18xx: Add invert-irq OF property for physically
> inverted IRQ"
> 
> https://lore.kernel.org/linux-renesas-soc/20190607172958.20745-1-ero...@de.adit-jv.com/
> 
> Signed-off-by: Geert Uytterhoeven 
> ---
> v3:
>   - New.
> ---
>  .../bindings/gpio/gpio-repeater.yaml  | 53 +++
>  1 file changed, 53 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/gpio-repeater.yaml
> 
> diff --git a/Documentation/devicetree/bindings/gpio/gpio-repeater.yaml 
> b/Documentation/devicetree/bindings/gpio/gpio-repeater.yaml
> new file mode 100644
> index ..efdee0c3be43f731
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/gpio-repeater.yaml
> @@ -0,0 +1,53 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/gpio/gpio-repeater.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: GPIO Repeater
> +
> +maintainers:
> +  - Harish Jenny K N 
> +  - Geert Uytterhoeven 
> +
> +description:
> +  This represents a repeater for one or more GPIOs, possibly including 
> physical
> +  signal property translation (e.g. polarity inversion).
> +
> +properties:
> +  compatible:
> +const: gpio-repeater
> +
> +  "#gpio-cells":
> +const: 2
> +
> +  gpio-controller: true
> +
> +  gpios:
> +description:
> +  Phandle and specifier, one for each repeated GPIO.
> +
> +  gpio-line-names:
> +description:
> +  Strings defining the names of the GPIO lines going out of the GPIO
> +  controller.
> +
> +required:
> +  - compatible
> +  - "#gpio-cells"
> +  - gpio-controller
> +  - gpios
> +
> +additionalProperties: false
> +
> +examples:
> +  # Device node describing a polarity inverter for a single GPIO
> +  - |
> +#include 
> +
> +inverter: gpio-repeater {
> +compatible = "gpio-repeater";
> +#gpio-cells = <2>;
> +gpio-controller;
> +gpios = < 95 GPIO_ACTIVE_LOW>;
> +};
> -- 
> 2.17.1
>

Reviewed-by: Ulrich Hecht 

CU
Uli



Re: [PATCH v3 1/7] gpiolib: Add GPIOCHIP_NAME definition

2019-11-27 Thread Ulrich Hecht


> On November 27, 2019 at 9:42 AM Geert Uytterhoeven  
> wrote:
> 
> 
> The string literal "gpiochip" is used in several places.
> Add a definition for it, and use it everywhere, to make sure everything
> stays in sync.
> 
> Signed-off-by: Geert Uytterhoeven 
> ---
> v3:
>   - New.
> ---
>  drivers/gpio/gpiolib-sysfs.c | 7 +++
>  drivers/gpio/gpiolib.c   | 4 ++--
>  drivers/gpio/gpiolib.h   | 2 ++
>  3 files changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
> index fbf6b1a0a4fae6ce..23e3d335cd543d53 100644
> --- a/drivers/gpio/gpiolib-sysfs.c
> +++ b/drivers/gpio/gpiolib-sysfs.c
> @@ -762,10 +762,9 @@ int gpiochip_sysfs_register(struct gpio_device *gdev)
>   parent = >dev;
>  
>   /* use chip->base for the ID; it's already known to be unique */
> - dev = device_create_with_groups(_class, parent,
> - MKDEV(0, 0),
> - chip, gpiochip_groups,
> - "gpiochip%d", chip->base);
> + dev = device_create_with_groups(_class, parent, MKDEV(0, 0), chip,
> + gpiochip_groups, GPIOCHIP_NAME "%d",
> + chip->base);
>   if (IS_ERR(dev))
>   return PTR_ERR(dev);
>  
> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> index dce0b31f4125a6b3..c9e47620d2434983 100644
> --- a/drivers/gpio/gpiolib.c
> +++ b/drivers/gpio/gpiolib.c
> @@ -1419,7 +1419,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, 
> void *data,
>   ret = gdev->id;
>   goto err_free_gdev;
>   }
> - dev_set_name(>dev, "gpiochip%d", gdev->id);
> + dev_set_name(>dev, GPIOCHIP_NAME "%d", gdev->id);
>   device_initialize(>dev);
>   dev_set_drvdata(>dev, gdev);
>   if (chip->parent && chip->parent->driver)
> @@ -5105,7 +5105,7 @@ static int __init gpiolib_dev_init(void)
>   return ret;
>   }
>  
> - ret = alloc_chrdev_region(_devt, 0, GPIO_DEV_MAX, "gpiochip");
> + ret = alloc_chrdev_region(_devt, 0, GPIO_DEV_MAX, GPIOCHIP_NAME);
>   if (ret < 0) {
>   pr_err("gpiolib: failed to allocate char dev region\n");
>   bus_unregister(_bus_type);
> diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
> index ca9bc1e4803c2979..a4a759920faa48ab 100644
> --- a/drivers/gpio/gpiolib.h
> +++ b/drivers/gpio/gpiolib.h
> @@ -16,6 +16,8 @@
>  #include 
>  #include 
>  
> +#define GPIOCHIP_NAME"gpiochip"
> +
>  /**
>   * struct gpio_device - internal state container for GPIO devices
>   * @id: numerical ID number for the GPIO chip
> -- 
> 2.17.1
>

Reviewed-by: Ulrich Hecht 

CU
Uli



Re: [PATCH v3 2/7] gpiolib: Add support for gpiochipN-based table lookup

2019-11-27 Thread Ulrich Hecht


> On November 27, 2019 at 9:42 AM Geert Uytterhoeven  
> wrote:
> 
> 
> Currently GPIO controllers can only be referred to by label in GPIO
> lookup tables.
> 
> Add support for looking them up by "gpiochipN" name, with "N" either the
> corresponding GPIO device's ID number, or the GPIO controller's first
> GPIO number.
> 
> Signed-off-by: Geert Uytterhoeven 
> ---
> If this is rejected, the GPIO Aggregator documentation must be updated.
> 
> The second variant is currently used by the legacy sysfs interface only,
> so perhaps the chip->base check should be dropped?
> 
> v3:
>   - New.
> ---
>  drivers/gpio/gpiolib.c | 22 +-
>  1 file changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> index c9e47620d2434983..d24a3d79dcfe69ad 100644
> --- a/drivers/gpio/gpiolib.c
> +++ b/drivers/gpio/gpiolib.c
> @@ -1746,9 +1746,29 @@ static int gpiochip_match_name(struct gpio_chip *chip, 
> void *data)
>   return !strcmp(chip->label, name);
>  }
>  
> +static int gpiochip_match_id(struct gpio_chip *chip, void *data)
> +{
> + int id = (uintptr_t)data;
> +
> + return id == chip->base || id == chip->gpiodev->id;
> +}
> +
>  static struct gpio_chip *find_chip_by_name(const char *name)
>  {
> - return gpiochip_find((void *)name, gpiochip_match_name);
> + struct gpio_chip *chip;
> + int id;
> +
> + chip = gpiochip_find((void *)name, gpiochip_match_name);
> + if (chip)
> + return chip;
> +
> + if (!str_has_prefix(name, GPIOCHIP_NAME))
> + return NULL;
> +
> + if (kstrtoint(name + strlen(GPIOCHIP_NAME), 10, ))
> + return NULL;
> +
> + return gpiochip_find((void *)(uintptr_t)id, gpiochip_match_id);
>  }
>  
>  #ifdef CONFIG_GPIOLIB_IRQCHIP
> -- 
> 2.17.1
>

Reviewed-by: Ulrich Hecht 

CU
Uli



Re: [Qemu-devel] [PATCH QEMU] hw/char/sh_serial: Add timeout handling to unbreak serial input

2018-07-30 Thread Ulrich Hecht


> On July 30, 2018 at 3:02 PM Geert Uytterhoeven  
> wrote:
> 
> 
> As of commit 18e8cf159177100e ("serial: sh-sci: increase RX FIFO trigger
> defaults for (H)SCIF") in Linux v4.11-rc1, the serial console on the
> QEMU SH4 target is broken: it delays serial input until enough data has
> been received.
> 
> Since aformentioned commit, the Linux SCIF driver programs the Receive
> FIFO Data Count Trigger bits in the FIFO Control Register, to postpone
> generating a receive interrupt until:
>   1. At least the receive trigger count of bytes of data are available
>  in the receive FIFO, OR
>   2. No further data has been received for at least 15 etu after the
>  last received data.
> 
> While QEMU implements the former, it does not implement the latter.
> Hence the receive interrupt is not generated until the former condition
> is met.
> 
> Fix this by adding basic timeout handling.  As the QEMU SCIF emulation
> ignores any serial speed programming, the timeout value used conforms to
> a default speed of 9600 bps, which is fine for any interative console.
> 
> Reported-by: Rob Landley 
> Signed-off-by: Geert Uytterhoeven 

Works for me, kernel 4.18-rc7 for rts7751r2dplus.

Tested-by: Ulrich Hecht 

CU
Uli



[Qemu-devel] [PATCH] linux-user: fail execve() if env/args too big

2012-01-31 Thread Ulrich Hecht
If the host's page size is equal to or smaller than the target's, native
execve() will fail appropriately with E2BIG if called with too big an
environment for the target to handle. It may falsely succeed, however, if
the host's page size is bigger, and feed the executed target process an
environment that is too big for it to handle, at which point QEMU barfs and
exits, confusing procmail's autoconf script and causing the build to fail.

This patch makes sure that execve() will return E2BIG if the environment is
too large for the target.

Signed-off-by: Ulrich Hecht u...@suse.de
---
 linux-user/syscall.c |9 +
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 2bf9e7e..fba3f29 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4797,6 +4797,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 abi_ulong guest_envp;
 abi_ulong addr;
 char **q;
+int total_size = 0;
 
 argc = 0;
 guest_argp = arg2;
@@ -4828,6 +4829,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 break;
 if (!(*q = lock_user_string(addr)))
 goto execve_efault;
+total_size += strlen(*q) + 1;
 }
 *q = NULL;
 
@@ -4839,9 +4841,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 break;
 if (!(*q = lock_user_string(addr)))
 goto execve_efault;
+total_size += strlen(*q) + 1;
 }
 *q = NULL;
 
+/* This case will not be caught by the host's execve() if its
+   page size is bigger than the target's. */
+if (total_size  MAX_ARG_PAGES * TARGET_PAGE_SIZE) {
+ret = -TARGET_E2BIG;
+goto execve_end;
+}
 if (!(p = lock_user_string(arg1)))
 goto execve_efault;
 ret = get_errno(execve(p, argp, envp));
-- 
1.7.1




Re: [Qemu-devel] [PATCH 2/9] S/390 CPU emulation

2009-11-11 Thread Ulrich Hecht
On Tuesday 10 November 2009, Aurelien Jarno wrote:
 I have tested it by removing all the block around tb_add_jump in
 cpu_exec.c. I have a speed loss of about 2.5x in the boot time of an
 x86_64 image.

I just tried it with qemu-system-x86_64, and with that I can observe a 
noticable performance gain using TB chaining as well. Maybe it's simply 
a lot more effective in system than in userspace emulation.

Anyway, having implemented it for BRC already, I might as well leave it 
in for future generations to enjoy.

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)




Re: [Qemu-devel] [PATCH 3/4] S/390 host support for TCG

2009-11-09 Thread Ulrich Hecht
On Monday 02 November 2009, Aurelien Jarno wrote:
 First of all I have a question about s390/s390x. It seems that you
 plan to support both s390 and s390x in the same file. Is that correct?

Actually, I didn't think about supporting s390 hosts at all, but it 
should be possible.

 Do you know how far the 32-bit support is far from compiling/working?

It is not entirely unlikely that it's close. You obviously can't use the 
64-bit instructions on a 31-bit host, but other than that...

 Would it be really possible to support both in the same file?

It would, but we would need different implementations for the 64-bit 
operations.

From a practical point of view, I don't see any merit in supporting 
31-bit hosts, simply because there aren't many in use anymore. (It's a 
different story for the target: 31-bit _software_ is still widespread.)

  +SEARCH_DIR(/usr/s390x-suse-linux/lib64);
  SEARCH_DIR(/usr/local/lib64); SEARCH_DIR(/lib64);
  SEARCH_DIR(/usr/lib64); SEARCH_DIR(/usr/s390x-suse-linux/lib);
  SEARCH_DIR(/usr/lib64); SEARCH_DIR(/usr/local/lib);
  SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib);

 Why adding some search directories manually here? The one you are
 adding are SuSE specific. They should already be detected by the
 configure script and added to config-host.ld.

I merely copied the linker script and made some minor adjustments, I 
didn't really pay much attention to what it actually contains...

  +tcg_out32(s, 0xa784); /* je label1 (offset will be patched
  in later) */

 Would be nice to have the corresponding tcg_out_ function and the
 corresponding value instead of the magic value. Also I am not sure the
 comment is correct here, je being an x86_64 instruction.

objdump disassembles it as je, though the POP doesn't specify any 
aliases for the different mask values for BRC.

  +tcg_out_sh64(s, SH64_SRAG, data_reg, data_reg,
  SH64_REG_NONE, 48); +break;
  +case 2 | 4:
  +tcg_out_b9(s, B9_LGFR, data_reg, arg0);
  +break;
  +case 0: case 1: case 2: case 3: default:
  +/* unsigned - just copy */
  +tcg_out_b9(s, B9_LGR, data_reg, arg0);

 Is it always correct? On x86_64, starting with gcc 4.3, it is not
 guaranteed anymore that non used bits are set to 0.

Do I understand you correctly in that you are suggesting to do an 
explicit zero extension here? (But what does GCC have to do with 
TCG-generated code?)

  +case INDEX_op_call:
  +//fprintf(stderr,op 0x%x call 0x%lx 0x%lx
  0x%lx\n,opc,args[0],args[1],args[2]); +if (const_args[0]) {
  +tcg_target_long off = (args[0] -
  (tcg_target_long)s-code_ptr + 4)  1; /* FIXME: + 4? Where did
  that come from? */ +if (off  -0x8000  off 
  0x7fff) { /* relative call */ +tcg_out_brasl(s,
  TCG_REG_R14, off  1);
  +tcg_abort(); // untested

 If not tested, it's probably better to remove this part and do not
 mark call accepting constants.

I suppose so. It's obviously never used anyway.


  +}
  +else { /* too far for a relative call, load full
  address */ +tcg_out_movi(s, TCG_TYPE_PTR,
  TCG_REG_R13, args[0]); +tcg_out_rr(s, RR_BASR,
  TCG_REG_R14, TCG_REG_R13);

 Not sure it is very useful here. It's probably better to redefine the
 constraints of the constant, so that the reg allocator use a register
 to pass the value.

  +}
  +}
  +else { /* call function in register args[0] */
  +tcg_out_rr(s, RR_BASR, TCG_REG_R14, args[0]);
  +}
  +break;
  +case INDEX_op_jmp:
  +fprintf(stderr,op 0x%x jmp 0x%lx 0x%lx
  0x%lx\n,opc,args[0],args[1],args[2]); +tcg_abort();
  +break;

 What about implementing that?

Do you know a target that actually uses it? I try to avoid implementing 
stuff that I can't test.

  +static inline void tcg_out_addi(TCGContext *s, int reg,
  tcg_target_long val) +{
  +tcg_abort();
  +}

 Why this one is not implemented? This is definitely needed so that
 arguments can be passed on the stack.

Generally, if something is not implemented yet it's because it has never 
been used anywhere.

  +#define TCG_TARGET_HAS_div_i32
  +#undef TCG_TARGET_HAS_div_i64

 Is that corrects? It looks strange an architecture has different
 division in 32- and 64-bits mode.

The 64-bit instruction set actually has both. Maybe I just forgot to 
implement it.

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)




Re: [Qemu-devel] [PATCH 2/9] S/390 CPU emulation

2009-11-09 Thread Ulrich Hecht
On Monday 02 November 2009, Laurent Desnogues wrote:
 That indeed looks strange:  fixing the TB chaining on ARM
 made nbench i386 three times faster.  Note the gain was
 less for FP parts of the benchmark due to the use of
 helpers.

 out of curiosity could you post your tb_set_jmp_target1
 function?

I'm on an AMD64 host, so it's the same code as in mainline.

 The only thing I can think of at the moment that 
 could make the code slower is that the program you ran
 was not reusing blocks and/or cache flushing in
 tb_set_jmp_target1 is overkill.

There is no cache flushing in the AMD64 tb_set_jmp_target1() function, 
and the polarssl test suite is by nature rather repetitive.

I did some experiments, and it seems disabling the TB chaining (by 
emptying tb_set_jmp_target()) does not have any impact on performance at 
all on AMD64. I tested it with several CPU-intensive programs (md5sum 
and the like) with AMD64 on AMD64 userspace emulation (qemu-x86_64), and 
the difference in performance with TB chaining and without is hardly 
measurable. The chaining is performed as advertised if enabled, I 
checked that, but it does not seem to help performance.

How is this possible? Could this be related to cache size? I suspect the 
Phenom 9500 of mine is better equipped in that area than the average ARM 
controller.

And does the TB chaining actually work on AMD64 at all? I checked by 
adding some debug output, and it seems to patch the jumps correctly, but 
maybe somebody can verify that.

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)




Re: [Qemu-devel] [PATCH 2/9] S/390 CPU emulation

2009-11-02 Thread Ulrich Hecht
On Thursday 22 October 2009, Aurelien Jarno wrote:
 Probably the second. Changing the instruction pointer in the helper
 instead of using the proper goto_tb TCG op prevents TB chaining, and
 therefore as a huge impact on performance.

 It's something not difficult to implement, and that I would definitely
 want to see in the patch before getting it merged.

OK, I implemented it, and the surprising result is that performance  does 
not get any better; in fact it even suffers a little bit. (My standard 
quick test, the polarssl test suite, shows about a 2% performance impact 
when profiled with cachegrind).

Could there be anything I overlooked? I modelled my implementation after 
those in the existing targets. (See the attached patch that goes on top 
of my other S/390 patches.)

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
diff --git a/target-s390/helpers.h b/target-s390/helpers.h
index 0d16760..6009312 100644
--- a/target-s390/helpers.h
+++ b/target-s390/helpers.h
@@ -15,7 +15,6 @@ DEF_HELPER_FLAGS_1(set_cc_comp_s64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64)
 DEF_HELPER_FLAGS_1(set_cc_nz_u32, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32)
 DEF_HELPER_FLAGS_1(set_cc_nz_u64, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64)
 DEF_HELPER_FLAGS_2(set_cc_icm, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32)
-DEF_HELPER_4(brc, void, i32, i32, i64, s32)
 DEF_HELPER_3(brctg, void, i64, i64, s32)
 DEF_HELPER_3(brct, void, i32, i64, s32)
 DEF_HELPER_4(brcl, void, i32, i32, i64, s64)
diff --git a/target-s390/op_helper.c b/target-s390/op_helper.c
index 637d22f..f7f52ba 100644
--- a/target-s390/op_helper.c
+++ b/target-s390/op_helper.c
@@ -218,17 +218,6 @@ uint32_t HELPER(set_cc_icm)(uint32_t mask, uint32_t val)
 return cc;
 }
 
-/* relative conditional branch */
-void HELPER(brc)(uint32_t cc, uint32_t mask, uint64_t pc, int32_t offset)
-{
-if ( mask  ( 1  (3 - cc) ) ) {
-env-psw.addr = pc + offset;
-}
-else {
-env-psw.addr = pc + 4;
-}
-}
-
 /* branch relative on 64-bit count (condition is computed inline, this only
does the branch */
 void HELPER(brctg)(uint64_t flag, uint64_t pc, int32_t offset)
diff --git a/target-s390/translate.c b/target-s390/translate.c
index 9ffa7bd..5a7cfe7 100644
--- a/target-s390/translate.c
+++ b/target-s390/translate.c
@@ -49,6 +49,7 @@ struct DisasContext {
 uint64_t pc;
 int is_jmp;
 CPUS390XState *env;
+struct TranslationBlock *tb;
 };
 
 #define DISAS_EXCP 4
@@ -359,23 +360,55 @@ static void gen_bcr(uint32_t mask, int tr, uint64_t offset)
 tcg_temp_free(target);
 }
 
-static void gen_brc(uint32_t mask, uint64_t pc, int32_t offset)
+static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong pc)
 {
-TCGv p;
-TCGv_i32 m, o;
+TranslationBlock *tb;
+
+tb = s-tb;
+/* NOTE: we handle the case where the TB spans two pages here */
+if ((pc  TARGET_PAGE_MASK) == (tb-pc  TARGET_PAGE_MASK) ||
+(pc  TARGET_PAGE_MASK) == ((s-pc - 1)  TARGET_PAGE_MASK))  {
+/* jump to same page: we can use a direct jump */
+tcg_gen_mov_i32(global_cc, cc);
+tcg_gen_goto_tb(tb_num);
+tcg_gen_movi_i64(psw_addr, pc);
+tcg_gen_exit_tb((long)tb + tb_num);
+} else {
+/* jump to another page: currently not optimized */
+tcg_gen_movi_i64(psw_addr, pc);
+tcg_gen_mov_i32(global_cc, cc);
+tcg_gen_exit_tb(0);
+}
+}
+
+static void gen_brc(uint32_t mask, DisasContext *s, int32_t offset)
+{
+TCGv_i32 r;
+TCGv_i32 tmp, tmp2;
+int skip;
 
 if (mask == 0xf) {	/* unconditional */
-  tcg_gen_movi_i64(psw_addr, pc + offset);
+  //tcg_gen_movi_i64(psw_addr, s-pc + offset);
+  gen_goto_tb(s, 0, s-pc + offset);
 }
 else {
-  m = tcg_const_i32(mask);
-  p = tcg_const_i64(pc);
-  o = tcg_const_i32(offset);
-  gen_helper_brc(cc, m, p, o);
-  tcg_temp_free(m);
-  tcg_temp_free(p);
-  tcg_temp_free(o);
+  tmp = tcg_const_i32(3);
+  tcg_gen_sub_i32(tmp, tmp, cc);	/* 3 - cc */
+  tmp2 = tcg_const_i32(1);
+  tcg_gen_shl_i32(tmp2, tmp2, tmp);	/* 1  (3 - cc) */
+  r = tcg_const_i32(mask);
+  tcg_gen_and_i32(r, r, tmp2);	/* mask  (1  (3 - cc)) */
+  tcg_temp_free(tmp);
+  tcg_temp_free(tmp2);
+  skip = gen_new_label();
+  tcg_gen_brcondi_i32(TCG_COND_EQ, r, 0, skip);
+  gen_goto_tb(s, 0, s-pc + offset);
+  gen_set_label(skip);
+  gen_goto_tb(s, 1, s-pc + 4);
+  tcg_gen_mov_i32(global_cc, cc);
+  tcg_temp_free(r);
 }
+s-is_jmp = DISAS_TB_JUMP;
 }
 
 static void gen_set_cc_add64(TCGv v1, TCGv v2, TCGv vr)
@@ -1143,9 +1176,7 @@ static void disas_a7(DisasContext *s, int op, int r1, int i2)
 tcg_temp_free(tmp2);
 break;
 case 0x4: /* brc m1, i2 */
-/* FIXME: optimize m1 == 0xf (unconditional) case */
-gen_brc(r1, s-pc, i2 * 2);
-s-is_jmp = DISAS_JUMP;
+gen_brc(r1, s, i2 * 2);

[Qemu-devel] [PATCH 00/12] S/390 support

2009-10-21 Thread Ulrich Hecht
Here's the patches again, split and fixed as suggested by Aurelien.
It should now be possible to apply host and target support separately.
See the individual patches for details on what has changed.

CU
Uli

Ulrich Hecht (12):
  TCG sync op
  S/390 disassembler fixes
  S/390 CPU emulation
  S/390 host build system support
  S/390 target build system support
  S/390 host support for TCG
  linux-user: S/390 64-bit (s390x) support
  linux-user: don't do locking in single-threaded processes
  linux-user: dup3, fallocate syscalls
  linux-user: define a couple of syscalls for non-uid16 targets
  linux-user: getpriority errno fix
  enable CPU_QuadU for s390x

 configure|   58 +-
 cpu-all.h|2 +-
 cpu-defs.h   |8 +
 cpu-exec.c   |   16 +-
 disas.c  |3 +
 dyngen-exec.h|2 +-
 linux-user/elfload.c |   18 +
 linux-user/main.c|   89 ++
 linux-user/s390x/syscall.h   |   25 +
 linux-user/s390x/syscall_nr.h|  348 +
 linux-user/s390x/target_signal.h |   26 +
 linux-user/s390x/termbits.h  |  283 
 linux-user/signal.c  |  314 +
 linux-user/syscall.c |  156 ++-
 linux-user/syscall_defs.h|   56 +-
 qemu-binfmt-conf.sh  |5 +-
 s390-dis.c   |4 +-
 s390x.ld |  194 +++
 target-s390x/cpu.h   |  118 ++
 target-s390x/exec.h  |   51 +
 target-s390x/helper.c|   63 +
 target-s390x/helpers.h   |  128 ++
 target-s390x/op_helper.c | 1639 ++
 target-s390x/translate.c | 2834 ++
 tcg/s390/tcg-target.c| 1145 +++
 tcg/s390/tcg-target.h|   76 +
 tcg/tcg-op.h |   12 +
 tcg/tcg-opc.h|2 +
 tcg/tcg.c|6 +
 29 files changed, 7640 insertions(+), 41 deletions(-)
 create mode 100644 linux-user/s390x/syscall.h
 create mode 100644 linux-user/s390x/syscall_nr.h
 create mode 100644 linux-user/s390x/target_signal.h
 create mode 100644 linux-user/s390x/termbits.h
 create mode 100644 s390x.ld
 create mode 100644 target-s390x/cpu.h
 create mode 100644 target-s390x/exec.h
 create mode 100644 target-s390x/helper.c
 create mode 100644 target-s390x/helpers.h
 create mode 100644 target-s390x/op_helper.c
 create mode 100644 target-s390x/translate.c
 create mode 100644 tcg/s390/tcg-target.c
 create mode 100644 tcg/s390/tcg-target.h





[Qemu-devel] [PATCH 06/12] S/390 host support for TCG

2009-10-21 Thread Ulrich Hecht
S/390 TCG code generator as posted before

improvements since last time:
- don't use R0 (often means zero, not register zero)
- optimized add_i32 immediate
- formatted for better compliance with the QEMU coding style

Signed-off-by: Ulrich Hecht u...@suse.de
---
 dyngen-exec.h |2 +-
 linux-user/syscall.c  |2 +-
 s390x.ld  |  194 +
 tcg/s390/tcg-target.c | 1145 +
 tcg/s390/tcg-target.h |   76 
 5 files changed, 1417 insertions(+), 2 deletions(-)
 create mode 100644 s390x.ld
 create mode 100644 tcg/s390/tcg-target.c
 create mode 100644 tcg/s390/tcg-target.h

diff --git a/dyngen-exec.h b/dyngen-exec.h
index 86e61c3..0353f36 100644
--- a/dyngen-exec.h
+++ b/dyngen-exec.h
@@ -117,7 +117,7 @@ extern int printf(const char *, ...);
 
 /* The return address may point to the start of the next instruction.
Subtracting one gets us the call instruction itself.  */
-#if defined(__s390__)
+#if defined(__s390__)  !defined(__s390x__)
 # define GETPC() ((void*)(((unsigned long)__builtin_return_address(0)  
0x7fffUL) - 1))
 #elif defined(__arm__)
 /* Thumb return addresses have the low bit set, so we need to subtract two.
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index bf06d14..45ccef9 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -183,7 +183,7 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 
arg4,type5 arg5,   \
 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
 
-#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
+#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || 
defined(__s390x__)
 #define __NR__llseek __NR_lseek
 #endif
 
diff --git a/s390x.ld b/s390x.ld
new file mode 100644
index 000..7d1f2b7
--- /dev/null
+++ b/s390x.ld
@@ -0,0 +1,194 @@
+/* Default linker script, for normal executables */
+OUTPUT_FORMAT(elf64-s390, elf64-s390,
+ elf64-s390)
+OUTPUT_ARCH(s390:64-bit)
+ENTRY(_start)
+SEARCH_DIR(/usr/s390x-suse-linux/lib64); SEARCH_DIR(/usr/local/lib64); 
SEARCH_DIR(/lib64); SEARCH_DIR(/usr/lib64); 
SEARCH_DIR(/usr/s390x-suse-linux/lib); SEARCH_DIR(/usr/lib64); 
SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib);
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  PROVIDE (__executable_start = 0x6000); . = 0x6000 + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+  .hash   : { *(.hash) }
+  .gnu.hash   : { *(.gnu.hash) }
+  .dynsym : { *(.dynsym) }
+  .dynstr : { *(.dynstr) }
+  .gnu.version: { *(.gnu.version) }
+  .gnu.version_d  : { *(.gnu.version_d) }
+  .gnu.version_r  : { *(.gnu.version_r) }
+  .rel.init   : { *(.rel.init) }
+  .rela.init  : { *(.rela.init) }
+  .rel.text   : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
+  .rela.text  : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
+  .rel.fini   : { *(.rel.fini) }
+  .rela.fini  : { *(.rela.fini) }
+  .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
+  .rela.rodata: { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
+  .rel.data.rel.ro   : { *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*) }
+  .rela.data.rel.ro   : { *(.rela.data.rel.ro* .rela.gnu.linkonce.d.rel.ro.*) }
+  .rel.data   : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+  .rela.data  : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
+  .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
+  .rela.tdata: { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
+  .rel.tbss  : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
+  .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
+  .rel.ctors  : { *(.rel.ctors) }
+  .rela.ctors : { *(.rela.ctors) }
+  .rel.dtors  : { *(.rel.dtors) }
+  .rela.dtors : { *(.rela.dtors) }
+  .rel.got: { *(.rel.got) }
+  .rela.got   : { *(.rela.got) }
+  .rel.bss: { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
+  .rela.bss   : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
+  .rel.plt: { *(.rel.plt) }
+  .rela.plt   : { *(.rela.plt) }
+  .init   :
+  {
+KEEP (*(.init))
+  } =0x07070707
+  .plt: { *(.plt) }
+  .text   :
+  {
+*(.text .stub .text.* .gnu.linkonce.t.*)
+/* .gnu.warning sections are handled specially by elf32.em.  */
+*(.gnu.warning)
+  } =0x07070707
+  .fini   :
+  {
+KEEP (*(.fini))
+  } =0x07070707
+  PROVIDE (__etext = .);
+  PROVIDE (_etext = .);
+  PROVIDE (etext = .);
+  .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+  .rodata1: { *(.rodata1) }
+  .eh_frame_hdr : { *(.eh_frame_hdr) }
+  .eh_frame   : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table

[Qemu-devel] [PATCH 05/12] S/390 target build system support

2009-10-21 Thread Ulrich Hecht
changes to configure and makefiles for S/390 target support
---
 configure |9 +++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index df984a3..64be51f 100755
--- a/configure
+++ b/configure
@@ -793,6 +793,7 @@ sh4eb-linux-user \
 sparc-linux-user \
 sparc64-linux-user \
 sparc32plus-linux-user \
+s390x-linux-user \
 
 fi
 # the following are Darwin specific
@@ -2093,7 +2094,7 @@ target_arch2=`echo $target | cut -d '-' -f 1`
 target_bigendian=no
 
 case $target_arch2 in
-  
armeb|m68k|microblaze|mips|mipsn32|mips64|ppc|ppcemb|ppc64|ppc64abi32|sh4eb|sparc|sparc64|sparc32plus)
+  
armeb|m68k|microblaze|mips|mipsn32|mips64|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus)
   target_bigendian=yes
   ;;
 esac
@@ -2253,6 +2254,10 @@ case $target_arch2 in
 echo TARGET_ABI32=y  $config_target_mak
 target_phys_bits=64
   ;;
+  s390x)
+target_nptl=yes
+target_phys_bits=64
+  ;;
   *)
 echo Unsupported target CPU
 exit 1
@@ -2321,7 +2326,7 @@ if test ! -z $gdb_xml_files ; then
 fi
 
 case $target_arch2 in
-  
arm|armeb|m68k|microblaze|mips|mipsel|mipsn32|mipsn32el|mips64|mips64el|ppc|ppc64|ppc64abi32|ppcemb|sparc|sparc64|sparc32plus)
+  
arm|armeb|m68k|microblaze|mips|mipsel|mipsn32|mipsn32el|mips64|mips64el|ppc|ppc64|ppc64abi32|ppcemb|s390x|sparc|sparc64|sparc32plus)
 echo CONFIG_SOFTFLOAT=y  $config_target_mak
 ;;
   *)
-- 
1.6.2.1





[Qemu-devel] [PATCH 02/12] S/390 disassembler fixes

2009-10-21 Thread Ulrich Hecht
enable zArch (64-bit) instructions
enable disassembler for both s390 and s390x

Signed-off-by: Ulrich Hecht u...@suse.de
---
 configure  |2 +-
 disas.c|3 +++
 s390-dis.c |4 ++--
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index ca6d45c..350c742 100755
--- a/configure
+++ b/configure
@@ -2386,7 +2386,7 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   ppc*)
 echo CONFIG_PPC_DIS=y   $config_target_mak
   ;;
-  s390)
+  s390*)
 echo CONFIG_S390_DIS=y   $config_target_mak
   ;;
   sh4)
diff --git a/disas.c b/disas.c
index ce342bc..14c8901 100644
--- a/disas.c
+++ b/disas.c
@@ -195,6 +195,9 @@ void target_disas(FILE *out, target_ulong code, 
target_ulong size, int flags)
 #elif defined(TARGET_CRIS)
 disasm_info.mach = bfd_mach_cris_v32;
 print_insn = print_insn_crisv32;
+#elif defined(TARGET_S390X)
+disasm_info.mach = bfd_mach_s390_64;
+print_insn = print_insn_s390;
 #elif defined(TARGET_MICROBLAZE)
 disasm_info.mach = bfd_arch_microblaze;
 print_insn = print_insn_microblaze;
diff --git a/s390-dis.c b/s390-dis.c
index 86dd84f..9a73a57 100644
--- a/s390-dis.c
+++ b/s390-dis.c
@@ -191,10 +191,10 @@ init_disasm (struct disassemble_info *info)
 //  switch (info-mach)
 //{
 //case bfd_mach_s390_31:
-  current_arch_mask = 1  S390_OPCODE_ESA;
+//  current_arch_mask = 1  S390_OPCODE_ESA;
 //  break;
 //case bfd_mach_s390_64:
-//  current_arch_mask = 1  S390_OPCODE_ZARCH;
+  current_arch_mask = 1  S390_OPCODE_ZARCH;
 //  break;
 //default:
 //  abort ();
-- 
1.6.2.1





[Qemu-devel] [PATCH 01/12] TCG sync op

2009-10-21 Thread Ulrich Hecht
sync allows concurrent accesses to locations in memory through different TCG
variables. This comes in handy when you are emulating CPU registers that can
be used as either 32 or 64 bit, as TCG doesn't know anything about aliases.
See the s390x target for an example.

Fixed sync_i64 build failure on 32-bit targets.

Signed-off-by: Ulrich Hecht u...@suse.de
---
 tcg/tcg-op.h  |   12 
 tcg/tcg-opc.h |2 ++
 tcg/tcg.c |6 ++
 3 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index faf2e8b..c1b4710 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -316,6 +316,18 @@ static inline void tcg_gen_br(int label)
 tcg_gen_op1i(INDEX_op_br, label);
 }
 
+static inline void tcg_gen_sync_i32(TCGv_i32 arg)
+{
+tcg_gen_op1_i32(INDEX_op_sync_i32, arg);
+}
+
+#if TCG_TARGET_REG_BITS == 64
+static inline void tcg_gen_sync_i64(TCGv_i64 arg)
+{
+tcg_gen_op1_i64(INDEX_op_sync_i64, arg);
+}
+#endif
+
 static inline void tcg_gen_mov_i32(TCGv_i32 ret, TCGv_i32 arg)
 {
 if (!TCGV_EQUAL_I32(ret, arg))
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index b7f3fd7..5dcdeba 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -40,6 +40,7 @@ DEF2(call, 0, 1, 2, TCG_OPF_SIDE_EFFECTS) /* variable number 
of parameters */
 DEF2(jmp, 0, 1, 0, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
 DEF2(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
 
+DEF2(sync_i32, 0, 1, 0, 0)
 DEF2(mov_i32, 1, 1, 0, 0)
 DEF2(movi_i32, 1, 0, 1, 0)
 /* load/store */
@@ -109,6 +110,7 @@ DEF2(neg_i32, 1, 1, 0, 0)
 #endif
 
 #if TCG_TARGET_REG_BITS == 64
+DEF2(sync_i64, 0, 1, 0, 0)
 DEF2(mov_i64, 1, 1, 0, 0)
 DEF2(movi_i64, 1, 0, 1, 0)
 /* load/store */
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 3c0e296..8eb60f8 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1930,6 +1930,12 @@ static inline int tcg_gen_code_common(TCGContext *s, 
uint8_t *gen_code_buf,
 //dump_regs(s);
 #endif
 switch(opc) {
+case INDEX_op_sync_i32:
+#if TCG_TARGET_REG_BITS == 64
+case INDEX_op_sync_i64:
+#endif
+temp_save(s, args[0], s-reserved_regs);
+break;
 case INDEX_op_mov_i32:
 #if TCG_TARGET_REG_BITS == 64
 case INDEX_op_mov_i64:
-- 
1.6.2.1





[Qemu-devel] [PATCH 11/12] linux-user: getpriority errno fix

2009-10-21 Thread Ulrich Hecht
getpriority returned wrong errno; fixes LTP test getpriority02.

Signed-off-by: Ulrich Hecht u...@suse.de
---
 linux-user/syscall.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index da6f2e1..455c3fd 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5314,7 +5314,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 /* libc does special remapping of the return value of
  * sys_getpriority() so it's just easiest to call
  * sys_getpriority() directly rather than through libc. */
-ret = sys_getpriority(arg1, arg2);
+ret = get_errno(sys_getpriority(arg1, arg2));
 break;
 case TARGET_NR_setpriority:
 ret = get_errno(setpriority(arg1, arg2, arg3));
-- 
1.6.2.1





[Qemu-devel] [PATCH 04/12] S/390 host build system support

2009-10-21 Thread Ulrich Hecht
changes to configure and makefiles for S/390 host support
---
 configure |   11 ---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index 350c742..df984a3 100755
--- a/configure
+++ b/configure
@@ -157,9 +157,12 @@ case $cpu in
   parisc|parisc64)
 cpu=hppa
   ;;
-  s390*)
+  s390)
 cpu=s390
   ;;
+  s390x)
+cpu=s390x
+  ;;
   sparc|sun4[cdmuv])
 cpu=sparc
   ;;
@@ -855,7 +858,7 @@ fi
 # host long bits test
 hostlongbits=32
 case $cpu in
-  x86_64|alpha|ia64|sparc64|ppc64)
+  x86_64|alpha|ia64|sparc64|ppc64|s390x)
 hostlongbits=64
   ;;
 esac
@@ -1819,7 +1822,7 @@ echo  $config_host_mak
 echo CONFIG_QEMU_SHAREDIR=\$prefix$datasuffix\  $config_host_mak
 
 case $cpu in
-  
i386|x86_64|alpha|cris|hppa|ia64|m68k|microblaze|mips|mips64|ppc|ppc64|s390|sparc|sparc64)
+  
i386|x86_64|alpha|cris|hppa|ia64|m68k|microblaze|mips|mips64|ppc|ppc64|s390|s390x|sparc|sparc64)
 ARCH=$cpu
   ;;
   armv4b|armv4l)
@@ -2351,6 +2354,8 @@ ldflags=
 
 if test $ARCH = sparc64 ; then
   cflags=-I\$(SRC_PATH)/tcg/sparc $cflags
+elif test $ARCH = s390x ; then
+  cflags=-I\$(SRC_PATH)/tcg/s390 $cflags
 else
   cflags=-I\$(SRC_PATH)/tcg/\$(ARCH) $cflags
 fi
-- 
1.6.2.1





[Qemu-devel] [PATCH 12/12] enable CPU_QuadU for s390x

2009-10-21 Thread Ulrich Hecht
Signed-off-by: Ulrich Hecht u...@suse.de
---
 cpu-all.h |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

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





[Qemu-devel] [PATCH 08/12] linux-user: don't do locking in single-threaded processes

2009-10-21 Thread Ulrich Hecht
Skips setting the tb_lock if a process doesn't have more than one thread,
which is usually the case. Results in about 20% performance gain (measured
with the s390x target, but the effect should be similar with other targets).

Signed-off-by: Ulrich Hecht u...@suse.de
---
 cpu-defs.h   |8 
 cpu-exec.c   |   14 --
 linux-user/syscall.c |1 +
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/cpu-defs.h b/cpu-defs.h
index 95068b5..c50c59e 100644
--- a/cpu-defs.h
+++ b/cpu-defs.h
@@ -135,6 +135,13 @@ typedef struct CPUWatchpoint {
 } CPUWatchpoint;
 
 #define CPU_TEMP_BUF_NLONGS 128
+
+#ifdef CONFIG_USER_ONLY
+#define MULTITHREAD uint32_t multithreaded;
+#else
+#define MULTITHREAD
+#endif
+
 #define CPU_COMMON  \
 struct TranslationBlock *current_tb; /* currently executing TB  */  \
 /* soft mmu support */  \
@@ -149,6 +156,7 @@ typedef struct CPUWatchpoint {
 uint32_t stop;   /* Stop request */ \
 uint32_t stopped; /* Artificially stopped */\
 uint32_t interrupt_request; \
+MULTITHREAD /* needs locking when accessing TBs */  \
 volatile sig_atomic_t exit_request; \
 /* The meaning of the MMU modes is defined in the target code. */   \
 CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE];  \
diff --git a/cpu-exec.c b/cpu-exec.c
index 6b3391c..3fe2725 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -219,6 +219,9 @@ int cpu_exec(CPUState *env1)
 TranslationBlock *tb;
 uint8_t *tc_ptr;
 unsigned long next_tb;
+#ifdef CONFIG_USER_ONLY
+uint32_t multithreaded;
+#endif
 
 if (cpu_halted(env1) == EXCP_HALTED)
 return EXCP_HALTED;
@@ -576,7 +579,11 @@ int cpu_exec(CPUState *env1)
 #endif
 }
 #endif
-spin_lock(tb_lock);
+#ifdef CONFIG_USER_ONLY
+multithreaded = env-multithreaded;
+if (multithreaded)
+#endif
+spin_lock(tb_lock);
 tb = tb_find_fast();
 /* Note: we do it here to avoid a gcc bug on Mac OS X when
doing it in tb_find_slow */
@@ -600,7 +607,10 @@ int cpu_exec(CPUState *env1)
 tb_add_jump((TranslationBlock *)(next_tb  ~3), next_tb  
3, tb);
 }
 }
-spin_unlock(tb_lock);
+#ifdef CONFIG_USER_ONLY
+if (multithreaded)
+#endif
+spin_unlock(tb_lock);
 env-current_tb = tb;
 
 /* cpu_interrupt might be called while translating the
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 617e031..f2a53d5 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3549,6 +3549,7 @@ static int do_fork(CPUState *env, unsigned int flags, 
abi_ulong newsp,
 ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
 init_task_state(ts);
 new_stack = ts-stack;
+env-multithreaded = 1;
 /* we create a new CPU instance. */
 new_env = cpu_copy(env);
 /* Init regs that differ from the parent.  */
-- 
1.6.2.1





[Qemu-devel] [PATCH 07/12] linux-user: S/390 64-bit (s390x) support

2009-10-21 Thread Ulrich Hecht
code for running 64-bit S/390 Linux binaries

use CPU_DoubleU for FP regs
proper specification exception (SIGILL) handling

Signed-off-by: Ulrich Hecht u...@suse.de
---
 linux-user/elfload.c |   18 ++
 linux-user/main.c|   89 ++
 linux-user/s390x/syscall.h   |   25 +++
 linux-user/s390x/syscall_nr.h|  348 ++
 linux-user/s390x/target_signal.h |   26 +++
 linux-user/s390x/termbits.h  |  283 +++
 linux-user/signal.c  |  314 ++
 linux-user/syscall.c |   16 ++-
 linux-user/syscall_defs.h|   56 ++-
 qemu-binfmt-conf.sh  |5 +-
 10 files changed, 1173 insertions(+), 7 deletions(-)
 create mode 100644 linux-user/s390x/syscall.h
 create mode 100644 linux-user/s390x/syscall_nr.h
 create mode 100644 linux-user/s390x/target_signal.h
 create mode 100644 linux-user/s390x/termbits.h

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 62a3f2a..90e9268 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -679,6 +679,24 @@ static inline void init_thread(struct target_pt_regs 
*regs, struct image_info *i
 
 #endif /* TARGET_ALPHA */
 
+#ifdef TARGET_S390X
+
+#define ELF_START_MMAP (0x200ULL)
+
+#define elf_check_arch(x) ( (x) == ELF_ARCH )
+
+#define ELF_CLASS  ELFCLASS64
+#define ELF_DATA   ELFDATA2MSB
+#define ELF_ARCH   EM_S390
+
+static inline void init_thread(struct target_pt_regs *regs, struct image_info 
*infop)
+{
+regs-psw.addr = infop-entry;
+regs-gprs[15] = infop-start_stack;
+}
+
+#endif /* TARGET_S390X */
+
 #ifndef ELF_PLATFORM
 #define ELF_PLATFORM (NULL)
 #endif
diff --git a/linux-user/main.c b/linux-user/main.c
index 81a1ada..798b2d5 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2351,6 +2351,86 @@ void cpu_loop (CPUState *env)
 }
 #endif /* TARGET_ALPHA */
 
+#ifdef TARGET_S390X
+void cpu_loop(CPUS390XState *env)
+{
+int trapnr;
+target_siginfo_t info;
+
+while (1) {
+trapnr = cpu_s390x_exec (env);
+
+if ((trapnr  0x) == EXCP_EXECUTE_SVC) {
+int n = trapnr  0x;
+env-regs[2] = do_syscall(env, n,
+   env-regs[2],
+   env-regs[3],
+   env-regs[4],
+   env-regs[5],
+   env-regs[6],
+   env-regs[7]);
+}
+else switch (trapnr) {
+case EXCP_INTERRUPT:
+/* just indicate that signals should be handled asap */
+break;
+case EXCP_DEBUG:
+{
+int sig;
+
+sig = gdb_handlesig (env, TARGET_SIGTRAP);
+if (sig) {
+info.si_signo = sig;
+info.si_errno = 0;
+info.si_code = TARGET_TRAP_BRKPT;
+queue_signal(env, info.si_signo, info);
+}
+}
+break;
+case EXCP_SVC:
+{
+int n = ldub(env-psw.addr - 1);
+if (!n) n = env-regs[1];  /* syscalls  255 */
+env-regs[2] = do_syscall(env, n,
+   env-regs[2],
+   env-regs[3],
+   env-regs[4],
+   env-regs[5],
+   env-regs[6],
+   env-regs[7]);
+}
+break;
+case EXCP_ADDR:
+{
+info.si_signo = SIGSEGV;
+info.si_errno = 0;
+/* XXX: check env-error_code */
+info.si_code = TARGET_SEGV_MAPERR;
+info._sifields._sigfault._addr = env-__excp_addr;
+queue_signal(env, info.si_signo, info);
+}
+break;
+case EXCP_SPEC:
+{
+fprintf(stderr,specification exception insn 0x%08x%04x\n, 
ldl(env-psw.addr), lduw(env-psw.addr + 4));
+info.si_signo = SIGILL;
+info.si_errno = 0;
+info.si_code = TARGET_ILL_ILLOPC;
+info._sifields._sigfault._addr = env-__excp_addr;
+queue_signal(env, info.si_signo, info);
+}
+break;
+default:
+printf (Unhandled trap: 0x%x\n, trapnr);
+cpu_dump_state(env, stderr, fprintf, 0);
+exit (1);
+}
+process_pending_signals (env);
+}
+}
+
+#endif /* TARGET_S390X */
+
 static void usage(void)
 {
 printf(qemu- TARGET_ARCH  version  QEMU_VERSION QEMU_PKGVERSION , 
Copyright (c) 2003-2008 Fabrice Bellard\n
@@ -2987,6 +3067,15 @@ int main(int argc, char **argv, char **envp)
env-regs[15] = regs-acr;  
env-pc = regs-erp;
 }
+#elif defined(TARGET_S390X)
+{
+int i;
+for (i = 0; i  16; i

[Qemu-devel] [PATCH 10/12] linux-user: define a couple of syscalls for non-uid16 targets

2009-10-21 Thread Ulrich Hecht
Quite a number of syscalls are only defined on systems with USE_UID16
defined; this patch defines them on other systems as well.

Fixes a large number of uid/gid-related testcases on the s390x target
(and most likely on other targets as well)

Signed-off-by: Ulrich Hecht u...@suse.de
---
 linux-user/syscall.c |  125 ++
 1 files changed, 105 insertions(+), 20 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 4991154..da6f2e1 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -307,7 +307,7 @@ static int sys_fchmodat(int dirfd, const char *pathname, 
mode_t mode)
   return (fchmodat(dirfd, pathname, mode, 0));
 }
 #endif
-#if defined(TARGET_NR_fchownat)  defined(USE_UID16)
+#if defined(TARGET_NR_fchownat)
 static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
 gid_t group, int flags)
 {
@@ -416,7 +416,7 @@ _syscall3(int,sys_faccessat,int,dirfd,const char 
*,pathname,int,mode)
 #if defined(TARGET_NR_fchmodat)  defined(__NR_fchmodat)
 _syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
 #endif
-#if defined(TARGET_NR_fchownat)  defined(__NR_fchownat)  defined(USE_UID16)
+#if defined(TARGET_NR_fchownat)  defined(__NR_fchownat)
 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
   uid_t,owner,gid_t,group,int,flags)
 #endif
@@ -6371,18 +6371,35 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 case TARGET_NR_setfsgid:
 ret = get_errno(setfsgid(arg1));
 break;
+#else /* USE_UID16 */
+#if defined(TARGET_NR_fchownat)  defined(__NR_fchownat)
+case TARGET_NR_fchownat:
+if (!(p = lock_user_string(arg2))) 
+goto efault;
+ret = get_errno(sys_fchownat(arg1, p, arg3, arg4, arg5));
+unlock_user(p, arg2, 0);
+break;
+#endif
 #endif /* USE_UID16 */
 
-#ifdef TARGET_NR_lchown32
+#if defined(TARGET_NR_lchown32) || !defined(USE_UID16)
+#if defined(TARGET_NR_lchown32)
 case TARGET_NR_lchown32:
+#else
+case TARGET_NR_lchown:
+#endif
 if (!(p = lock_user_string(arg1)))
 goto efault;
 ret = get_errno(lchown(p, arg2, arg3));
 unlock_user(p, arg1, 0);
 break;
 #endif
-#ifdef TARGET_NR_getuid32
+#if defined(TARGET_NR_getuid32) || (defined(TARGET_NR_getuid)  
!defined(USE_UID16))
+#if defined(TARGET_NR_getuid32)
 case TARGET_NR_getuid32:
+#else
+case TARGET_NR_getuid:
+#endif
 ret = get_errno(getuid());
 break;
 #endif
@@ -6410,33 +6427,57 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 break;
 #endif
 
-#ifdef TARGET_NR_getgid32
+#if defined(TARGET_NR_getgid32) || (defined(TARGET_NR_getgid)  
!defined(USE_UID16))
+#if defined(TARGET_NR_getgid32)
 case TARGET_NR_getgid32:
+#else
+case TARGET_NR_getgid:
+#endif
 ret = get_errno(getgid());
 break;
 #endif
-#ifdef TARGET_NR_geteuid32
+#if defined(TARGET_NR_geteuid32) || (defined(TARGET_NR_geteuid)  
!defined(USE_UID16))
+#if defined(TARGET_NR_geteuid32)
 case TARGET_NR_geteuid32:
+#else
+case TARGET_NR_geteuid:
+#endif
 ret = get_errno(geteuid());
 break;
 #endif
-#ifdef TARGET_NR_getegid32
+#if defined(TARGET_NR_getegid32) || (defined(TARGET_NR_getegid)  
!defined(USE_UID16))
+#if defined(TARGET_NR_getegid32)
 case TARGET_NR_getegid32:
+#else
+case TARGET_NR_getegid:
+#endif
 ret = get_errno(getegid());
 break;
 #endif
-#ifdef TARGET_NR_setreuid32
+#if defined(TARGET_NR_setreuid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setreuid32)
 case TARGET_NR_setreuid32:
+#else
+case TARGET_NR_setreuid:
+#endif
 ret = get_errno(setreuid(arg1, arg2));
 break;
 #endif
-#ifdef TARGET_NR_setregid32
+#if defined(TARGET_NR_setregid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setregid32)
 case TARGET_NR_setregid32:
+#else
+case TARGET_NR_setregid:
+#endif
 ret = get_errno(setregid(arg1, arg2));
 break;
 #endif
-#ifdef TARGET_NR_getgroups32
+#if defined(TARGET_NR_getgroups32) || !defined(USE_UID16)
+#if defined(TARGET_NR_getgroups32)
 case TARGET_NR_getgroups32:
+#else
+case TARGET_NR_getgroups:
+#endif
 {
 int gidsetsize = arg1;
 uint32_t *target_grouplist;
@@ -6460,8 +6501,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 }
 break;
 #endif
-#ifdef TARGET_NR_setgroups32
+#if defined(TARGET_NR_setgroups32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setgroups32)
 case TARGET_NR_setgroups32:
+#else
+case TARGET_NR_setgroups:
+#endif
 {
 int gidsetsize = arg1;
 uint32_t *target_grouplist;
@@ -6481,18 +6526,30 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 }
 break;
 #endif
-#ifdef TARGET_NR_fchown32
+#if defined(TARGET_NR_fchown32) || !defined(USE_UID16)
+#if defined(TARGET_NR_fchown32)
 case

Re: [Qemu-devel] [PATCH 2/9] S/390 CPU emulation

2009-10-19 Thread Ulrich Hecht
On Saturday 17 October 2009, Aurelien Jarno wrote:
 On Fri, Oct 16, 2009 at 02:38:48PM +0200, Ulrich Hecht wrote:
 First of all a few general comments. Note that I know very few things
 about S390/S390X, so I may have dumb comments/questions. Also as the
 patch is very long, I probably have missed things, we should probably
 iterate with new versions of the patches.

 Is it possible given the current implementation to emulate S390 in
 addition to S390X?

Not as it stands. The S/390 instruction set is a subset of zArch 
(64-bit), but currently only 64-bit addressing is implemented (because 
that is the only mode used by 64-bit Linux binaries).

 If yes how different would be a S390 only target? 

It would need support for 31-bit addressing. 24-bit, too, if you want to 
run the really old stuff.

 If they won't be too different, it probably worth using _tl type
 registers and call it target-s390. A bit the way it is done with
 i386/x86_64, ppc/ppc64, mips/mips64 or sparc/sparc64.

If it's going to be implemented, it will certainly share most code with 
the 64-bit target, so having a common directory would most likely be a 
good idea.

There are some cases where _tl types might be appropriate, but generally 
everything that is shared between S/390 and zArch is 32-bit, and 
instructions present in both architectures also have the same operand 
size: L, for instance, is a 32-bit load to a 32-bit register on both 
architectures.

 Secondly there seems to be a lot of mix between 32-bit and 64-bit
 TCG registers. They should not be mixed. _i32 ops apply to TCGv_i32
 variables, _i64 ops apply to TCGv_i64 variables, and _tl ops to TGCv
 variables. TCGv/_tl types can map either to _i32 or _i64 depending on
 your target. You should try to build the target with
 --enable-debug-tcg

Er, reading the code and observing the behavior of the (AMD64) code 
generator, it seemed to me that neither frontends nor backends care one 
bit about that. I'll look into it, though. (I won't comment on those 
below, except in cases where the solution or, indeed, the problem is not 
clear to me.)

 It would be nice to split all the disassembling part in a separate
 combined with the related makefile changes. This way it can be applied
 separately.

Can do.

   //  switch (info-mach)
   //{
   //case bfd_mach_s390_31:
  -  current_arch_mask = 1  S390_OPCODE_ESA;
  +//  current_arch_mask = 1  S390_OPCODE_ESA;
   //  break;
   //case bfd_mach_s390_64:
  -//  current_arch_mask = 1  S390_OPCODE_ZARCH;
  +  current_arch_mask = 1  S390_OPCODE_ZARCH;
   //  break;
   //default:
   //  abort ();

 While I understand the second part, Why is it necessary to comment the
 bfd_mach_s390_31 case?

It's not necessary, but current_arch_mask can only hold one value...

  +typedef union FPReg {
  +struct {
  +#ifdef WORDS_BIGENDIAN
  +float32 e;
  +int32_t __pad;
  +#else
  +int32_t __pad;
  +float32 e;
  +#endif
  +};
  +float64 d;
  +uint64_t i;
  +} FPReg;

 WORDS_BIGENDIAN is wrong here. It should probably be
 HOST_WORDS_BIGENDIAN.

Indeed.

 Also it may be a better idea to 
 reuse CPU_FloatU and CPU_DoubleU here.

Yes. Didn't know about those.

  +CPUS390XState *cpu_s390x_init(const char *cpu_model)

 This function would probably be better in translate.c, so that
 s390x_translate_init() can be declared static.

I'll check that.

 Please use /* */ for comments (See CODING_STYLE).

OK.

  +/* FIXME: reset vector? */

 Yes, reset vector, MMU mode, default register values, ...

Works perfectly fine without. ;)

Also, the question remains what kind of reset cpu_reset() is supposed to 
be. For instance, a CPU Reset or Initial CPU Reset on S/390 leaves the 
general-purpose registers unchanged, a Clear Reset or Power-On Reset 
sets them to zero. See the table on p. 4-50 in the zArchitecture 
Principles of Operation (POP), 
http://publibfp.boulder.ibm.com/cgi-bin/bookmgr/download/A2278324.pdf, 
for the gory details.

  +//#define DEBUG_HELPER
  +#ifdef DEBUG_HELPER
  +#define HELPER_LOG(x...) qemu_log(x)
  +#else
  +#define HELPER_LOG(x...)
  +#endif

 Small comment for the rest of the file. While I understand HELPER_LOG
 is very handy while developing, I think some calls to it can be
 dropped in really simple functions.

Yes, a bit of cleanup will be in order.

  +for (i = 0; i = l; i++) {
  +x = ldub(dest + i)  ldub(src + i);
  +if (x) cc = 1;

 coding style

Maybe you are referring to Every indented statement is braced; even if 
the block contains just one statement., but I figured that that does 
not apply here because there is no indentation...

  +if (v  0) return 1;
  +else if (v  0) return 2;

 coding style

Same here.

 The last 6 helpers can probably be coded easily in TCG (they are very
 similar to some PowerPC code), though merging this patch with the
 helpers is not a problem at all.

Again, that would be detrimental

Re: [Qemu-devel] [PATCH 1/9] TCG sync op

2009-10-19 Thread Ulrich Hecht
On Friday 16 October 2009, Aurelien Jarno wrote:
 This example is a bit biased, as registers are only saved, and never
 reused. Let's comment on it though.

Yeah, well, I searched from the top for the first case where it makes a 
difference. If it's of any help, I can upload a complete dump of both 
versions somewhere.

 and I don't understand what is the gain compared to 
 the use of tcg_gen_ld/st.

There are two sets of TCG values, tcgregs (which would arguably better 
called tcgregs64) and tcgregs32. When doing a 32-bit access, tcgregs(64) 
is synced, which is a nop if tcgregs(64) hasn't been touched. When doing 
a 64-bit access, tcgregs32 is synced, which is a nop if tcgregs32 hasn't 
been touched. In practice, 32-bit accesses followed by 64-bit accesses 
and vice versa are very rare, so in most cases, sync is a nop. 
tcg_gen_ld/st is never a nop. That's the benefit.

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)




Re: [Qemu-devel] [PATCH 1/9] TCG sync op

2009-10-19 Thread Ulrich Hecht
On Saturday 17 October 2009, Edgar E. Iglesias wrote:
 I looked at the s390 patches and was also unsure about this sync op.
 I'm not convinced it's bad but my first feeling was as Aurelien points
 out that the translator shoud take care of it.

Indeed. I would have expected it to, in fact. But it doesn't. The sync op 
is the simplest and quickest way to get what I want that I could come up 
with. I'd be perfectly happy if TCG could handle aliases on its own, but 
doing a lot of ALU operations on every register access is not an option.

 Another thing I noticed was the large amount of helpers. Without
 looking at the details my feeling was that you could probably do more
 at translation time.

My experience is that helper functions have an undeservedly bad image. A 
pure const helper call is very easy to optimize away for TCG. Random bit 
shifting, comparing and branching isn't.

 Nice work!

Thank you.

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)




[Qemu-devel] [patch] s390-dis.c license

2008-01-17 Thread Ulrich Hecht
Hi!

Our Teenage Mutant Legal Turtles have discovered that s390-dis.c contains 
GPLv3 code. Fortunately, the actual code has not changed since the last 
GPLv2 binutils release, save for the license headers, so it suffices to 
change those back to fix the problem.

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
--- ./s390-dis.c	2007-08-01 15:11:55.0 +0200
+++ ./s390-dis.c	2005-08-22 21:27:46.0 +0200
@@ -1,23 +1,23 @@
 /* s390-dis.c -- Disassemble S390 instructions
-   Copyright 2000, 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+   Copyright 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky ([EMAIL PROTECTED]).
 
-   This file is part of the GNU opcodes library.
+   This file is part of GDB, GAS and the GNU binutils.
 
-   This library is free software; you can redistribute it and/or modify
+   This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3, or (at your option)
-   any later version.
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
 
-   It is distributed in the hope that it will be useful, but WITHOUT
-   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
-   License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
-   along with this file; see the file COPYING.  If not, write to the
-   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
-   MA 02110-1301, USA.  */
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
 #include stdio.h
 #include ansidecl.h
@@ -399,23 +399,23 @@
 /* s390-opc.c -- S390 opcode list
-   Copyright 2000, 2001, 2003, 2007 Free Software Foundation, Inc.
+   Copyright 2000, 2001, 2003 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky ([EMAIL PROTECTED]).
 
-   This file is part of the GNU opcodes library.
+   This file is part of GDB, GAS, and the GNU binutils.
 
-   This library is free software; you can redistribute it and/or modify
+   This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3, or (at your option)
-   any later version.
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
 
-   It is distributed in the hope that it will be useful, but WITHOUT
-   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
-   License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
-   along with this file; see the file COPYING.  If not, write to the
-   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
-   MA 02110-1301, USA.  */
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
 #include stdio.h
 #include ansidecl.h


Re: [Qemu-devel] Help needed! dyngen: Unsupported ELF class

2007-11-15 Thread Ulrich Hecht
On Thursday 15 November 2007, test test wrote:
 --
-- dyngen: Unsupported ELF class
 make[1]: *** [op.h] Error 1
 --
--

 What's the problem? Please help!

 For better analysis of the problem, I put the result of configure as
 below:

 WARNING: gcc looks like gcc 4.x
 Looking for gcc 3.x
 Found gcc-3.3
[...]
 host CPU  x86_64

Is it possible that your gcc-3.3 is an i386 compiler? If so, edit 
config-host.mak and replace ARCH=x86_64 with ARCH=i386, then 
rebuild.

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)




Re: [Qemu-devel] s390 host support

2007-11-12 Thread Ulrich Hecht
On Saturday 10 November 2007, Bastian Blank wrote:
 Thimo Seufer asked me to check if the s390 host supports works at all.
 It did not even build, dyngen failed.

A 31-bit build of the CVS code works fine for me. (At least if I add the 
br %rANY fix that is also in your patch and the jcc patch that Thiemo 
has not committed yet.)

A 31-bit build using your patch works as well, but it also needs the jcc 
patch. The only reason it needs to be compiled with -march=z900 is the 
use of larl in the inline assembly code, which can be avoided by simply 
omitting it in the PARAMx macros (the bras already writes the address to 
the register) and reverting to the code currently in CVS for 
GOTO_LABEL_PARAM. (The GOTO_TB hack does not seem to be necessary any 
more.)

 I digged into the problem and 
 found the following:
 gcc for s390 generates a data table after each function if necessary
 instead of immediate loads.

It actually generates it inline, doing something like

op_something:
bras %r13, 8
.long some data
...

In other words, it branches over the data, storing the return address 
(which is actually a pointer to the data) in r13.

 (g5, the oldest supported processor only 
 suports one halfword immediate load.) dyngen is not prepared for that
 and fails.

 I found that gcc moves this data into the .rodata section 
 if generating code for z900 and above, which looked like a possible
 way to support this.

(My) GCC only does this when generating 64-bit code.

 - Support R_390_PC32DBL relocation, including relocations into
 sections.

Again, my GCC only generates this relocation when compiling 64-bit code. 
With your patch and some obvious fixes (ELFCLASS64, GETPC, 
$hostlongbits)) it builds as 64-bit, but it segfaults in the first 
translation block.

CU
Uli

-- 
Heute ist
- Dr. Sun Yat-sens Geburtstag (in Taiwan)
- Gedenktag (in Bermuda, Cayman-Inseln)
- Tag der Veteranen (in den USA (26 Staaten))
- Unabhängigkeit von Cartagena (in Kolumbien)

SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)




Re: [Qemu-devel] Porting QEMU to Minix - op_goto_tb1 segfaults because tb_next[1] is NULL

2007-08-23 Thread Ulrich Hecht
On Wednesday 22 August 2007, Erik van der Kouwe wrote:
 My problem is the following: quickly after starting I get a
 segmentation fault while the generated code is running.

 This happens in the code generated from op_goto_tb1 and is caused by
 jumping to a NULL pointer. This NULL pointer originates from the
 tb_next[1] field of the translation block data structure passed as a
 parameter. I have verified in the disassembler that the parameter in
 the generated code is processed correctly and the field is indeed
 tb_next[1].

I had a similar problem when fixing S/390 hosts. IIRC it was caused by 
the portable GOTO_TB macro. On translation the goto is patched to jump 
out of the block, which is something the compiler does not reckon with. 
You may want to disassemble it and check if registers are overwritten 
before the jump takes place.

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)




Re: [Qemu-devel] [PATCH] S/390 host fixed

2007-08-01 Thread Ulrich Hecht
On Wednesday 01 August 2007 01:59, Thiemo Seufer wrote:
  -AIOLIBS=-lrt
  +AIOLIBS=-lrt -lpthread

 Why is this needed? Linux toolchains should add -lpthread implicitly.

Our SLES9 toolchain seems not to. It's a near-cosmetic change.

  +#ifdef __s390__
  +retaddr = (void*)((unsigned long)retaddr  0x7fffUL);
  +#endif

 All of those look weird. Is this a null-extension vs. sign-extension
 issue?

S/390 has a 31 (thirty-one) bit address space; the MSB of the PSW is not 
part of the address and must be masked out. This is simply part of the 
architecture, there's no way around it.

  +#ifdef __s390__
  +func = NULL; /* does not work on S/390 for unknown
  reasons */ +#else
   func = gen_jcc_sub[s-cc_op - CC_OP_SUBB][jcc_op];
  +#endif

 Hum. It wold be good to know what happens here.

Indeed. :)

  +#ifdef __s390__
  +if(!T1)
  +T0 = (int32_t)env-fcr0;
  +else if(T1 == 25)
[...]

 I guess this breaks when you _breathe_ at the compiler.

Probably, but that is true for a significant part of the QEMU codebase...

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)




[Qemu-devel] [PATCH] Z80 emulation updated

2007-07-06 Thread Ulrich Hecht
Hi!

Here's an update to Stuart Brady's ZX Spectrum system emulator, fixed to 
work with the code in CVS, with some dead code removed, implementing 
HALT (and a hack that makes the Spectrum ROM use it in the input loop), 
and with support for loading snapshots (-kernel commando.z80 :) using 
libspectrum. (Be sure to compile with --enable-libspectrum.)

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)


qemu-z80.diff.gz
Description: GNU Zip compressed data


Re: [Qemu-devel] [PATCH] ARM7TDMI emulation

2007-07-03 Thread Ulrich Hecht
On Monday 02 July 2007 18:14, Ulrich Hecht wrote:
 Anyway, here's the 920T version. The magic numbers may or may not be
 correct.

And here's an even better version that implements both 920T and 7TDMI 
(with base-updated aborts).

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
Index: target-arm/cpu.h
===
RCS file: /sources/qemu/qemu/target-arm/cpu.h,v
retrieving revision 1.28
diff -u -r1.28 cpu.h
--- target-arm/cpu.h	24 Jun 2007 12:09:48 -	1.28
+++ target-arm/cpu.h	3 Jul 2007 14:36:00 -
@@ -247,7 +247,10 @@
 ARM_FEATURE_AUXCR,  /* ARM1026 Auxiliary control register.  */
 ARM_FEATURE_XSCALE, /* Intel XScale extensions.  */
 ARM_FEATURE_IWMMXT, /* Intel iwMMXt extension.  */
-ARM_FEATURE_MPU /* Only has Memory Protection Unit, not full MMU.  */
+ARM_FEATURE_MPU,/* Only has Memory Protection Unit, not full MMU.  */
+ARM_FEATURE_V5, /* ARM v5 instruction set */
+ARM_FEATURE_NO_CP15, /* ARM7TDMI, ARM7TDMI-S, ARM7EJ-S, and ARM9TDMI cores do not have a CP15 */
+ARM_FEATURE_ABORT_BU /* base updated abort model, e.g. ARMxTDMI */
 };
 
 static inline int arm_feature(CPUARMState *env, int feature)
@@ -262,7 +265,9 @@
ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write,
void *opaque);
 
+#define ARM_CPUID_ARM7TDMI  0x41807000 /* guess; no CP15 on ARM7TDMI */
 #define ARM_CPUID_ARM1026   0x4106a262
+#define ARM_CPUID_ARM920T   0x41129200
 #define ARM_CPUID_ARM9260x41069265
 #define ARM_CPUID_ARM9460x41059461
 #define ARM_CPUID_PXA2500x69052100
Index: target-arm/helper.c
===
RCS file: /sources/qemu/qemu/target-arm/helper.c,v
retrieving revision 1.17
diff -u -r1.17 helper.c
--- target-arm/helper.c	24 Jun 2007 12:09:48 -	1.17
+++ target-arm/helper.c	3 Jul 2007 14:36:00 -
@@ -14,20 +14,31 @@
 {
 env-cp15.c0_cpuid = id;
 switch (id) {
+case ARM_CPUID_ARM7TDMI:
+set_feature(env, ARM_FEATURE_ABORT_BU);
+set_feature(env, ARM_FEATURE_NO_CP15);
+break;
+case ARM_CPUID_ARM920T:
+env-cp15.c0_cachetype = 0x0d172172;
+env-cp15.c1_sys = 0x0078;
+break;
 case ARM_CPUID_ARM926:
 set_feature(env, ARM_FEATURE_VFP);
+set_feature(env, ARM_FEATURE_V5);
 env-vfp.xregs[ARM_VFP_FPSID] = 0x41011090;
 env-cp15.c0_cachetype = 0x1dd20d2;
 env-cp15.c1_sys = 0x00090078;
 break;
 case ARM_CPUID_ARM946:
 set_feature(env, ARM_FEATURE_MPU);
+set_feature(env, ARM_FEATURE_V5);
 env-cp15.c0_cachetype = 0x0f004006;
 env-cp15.c1_sys = 0x0078;
 break;
 case ARM_CPUID_ARM1026:
 set_feature(env, ARM_FEATURE_VFP);
 set_feature(env, ARM_FEATURE_AUXCR);
+set_feature(env, ARM_FEATURE_V5);
 env-vfp.xregs[ARM_VFP_FPSID] = 0x410110a0;
 env-cp15.c0_cachetype = 0x1dd20d2;
 env-cp15.c1_sys = 0x00090078;
@@ -38,6 +49,7 @@
 case ARM_CPUID_PXA261:
 case ARM_CPUID_PXA262:
 set_feature(env, ARM_FEATURE_XSCALE);
+set_feature(env, ARM_FEATURE_V5);
 /* JTAG_ID is ((id  28) | 0x09265013) */
 env-cp15.c0_cachetype = 0xd172172;
 env-cp15.c1_sys = 0x0078;
@@ -49,6 +61,7 @@
 case ARM_CPUID_PXA270_C0:
 case ARM_CPUID_PXA270_C5:
 set_feature(env, ARM_FEATURE_XSCALE);
+set_feature(env, ARM_FEATURE_V5);
 /* JTAG_ID is ((id  28) | 0x09265013) */
 set_feature(env, ARM_FEATURE_IWMMXT);
 env-iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
@@ -98,6 +111,8 @@
 };
 
 static const struct arm_cpu_t arm_cpu_names[] = {
+{ ARM_CPUID_ARM7TDMI, arm7tdmi},
+{ ARM_CPUID_ARM920T, arm920t},
 { ARM_CPUID_ARM926, arm926},
 { ARM_CPUID_ARM946, arm946},
 { ARM_CPUID_ARM1026, arm1026},
Index: target-arm/translate.c
===
RCS file: /sources/qemu/qemu/target-arm/translate.c,v
retrieving revision 1.53
diff -u -r1.53 translate.c
--- target-arm/translate.c	11 Jun 2007 18:59:35 -	1.53
+++ target-arm/translate.c	3 Jul 2007 14:36:00 -
@@ -1589,7 +1589,7 @@
 uint32_t rd;
 
 /* ??? Some cp15 registers are accessible from userspace.  */
-if (IS_USER(s)) {
+if (IS_USER(s) || arm_feature(env, ARM_FEATURE_NO_CP15)) {
 return 1;
 }
 if ((insn  0x0fff0fff) == 0x0e070f90
@@ -2780,6 +2780,7 @@
 case 0x09:
 {
 int j, n, user, loaded_base;
+int crement;
 /* load/store multiple words */
 /* XXX: store correct base if write back */
 user = 0;
@@ -2819,6 +2820,36 @@
 }
 }
 j = 0;
+
+crement = 0;
+if(insn  (1  21

Re: [Qemu-devel] [PATCH] ARM (Thumb) read from R15

2007-07-02 Thread Ulrich Hecht
On Saturday 30 June 2007 04:19, Paul Brook wrote:
  QEMU does not set the Thumb bit when reading from R15 in Thumb mode.

 Neither does real hardware.

You are, unsurprisingly, right. The problem seems to be a different one. 
Quoting the ARM on pop pc:

In ARM architecture 5 and above, bit[0] of the loaded value determines 
whether execution continues after this branch in ARM state or in Thumb 
state[...] In T variants of architecture version 4, bit[0] of the loaded 
value is ignored and execution continues in Thumb state[...]

My code is supposed to run on a 4T. I guess I'll have to implement an 
ARM_FEATURE_THUMB1.

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)




[Qemu-devel] [PATCH] ARM7TDMI emulation

2007-07-02 Thread Ulrich Hecht
Hi!

This patch adds ARM7TDMI emulation with Thumb v1 (no BLX, no BKPT, ignore 
bit 0 on POP PC) and without CP15.

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
Index: cpu.h
===
RCS file: /sources/qemu/qemu/target-arm/cpu.h,v
retrieving revision 1.28
diff -u -r1.28 cpu.h
--- cpu.h	24 Jun 2007 12:09:48 -	1.28
+++ cpu.h	2 Jul 2007 13:16:12 -
@@ -247,7 +247,9 @@
 ARM_FEATURE_AUXCR,  /* ARM1026 Auxiliary control register.  */
 ARM_FEATURE_XSCALE, /* Intel XScale extensions.  */
 ARM_FEATURE_IWMMXT, /* Intel iwMMXt extension.  */
-ARM_FEATURE_MPU /* Only has Memory Protection Unit, not full MMU.  */
+ARM_FEATURE_MPU,/* Only has Memory Protection Unit, not full MMU.  */
+ARM_FEATURE_THUMB1, /* Thumb v1 (ARM v4 with Thumb) */
+ARM_FEATURE_NO_CP15 /* ARM7TDMI, ARM7TDMI-S, ARM7EJ-S, and ARM9TDMI cores do not have a CP15 */
 };
 
 static inline int arm_feature(CPUARMState *env, int feature)
@@ -262,6 +264,7 @@
ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write,
void *opaque);
 
+#define ARM_CPUID_ARM7TDMI  0x41807000 /* guess; no CP15 on ARM7TDMI */
 #define ARM_CPUID_ARM1026   0x4106a262
 #define ARM_CPUID_ARM9260x41069265
 #define ARM_CPUID_ARM9460x41059461
Index: helper.c
===
RCS file: /sources/qemu/qemu/target-arm/helper.c,v
retrieving revision 1.17
diff -u -r1.17 helper.c
--- helper.c	24 Jun 2007 12:09:48 -	1.17
+++ helper.c	2 Jul 2007 13:16:12 -
@@ -14,6 +14,11 @@
 {
 env-cp15.c0_cpuid = id;
 switch (id) {
+case ARM_CPUID_ARM7TDMI:
+set_feature(env, ARM_FEATURE_THUMB1);
+set_feature(env, ARM_FEATURE_NO_CP15);
+/* no CP15 here */
+break;
 case ARM_CPUID_ARM926:
 set_feature(env, ARM_FEATURE_VFP);
 env-vfp.xregs[ARM_VFP_FPSID] = 0x41011090;
@@ -98,6 +103,7 @@
 };
 
 static const struct arm_cpu_t arm_cpu_names[] = {
+{ ARM_CPUID_ARM7TDMI, arm7tdmi},
 { ARM_CPUID_ARM926, arm926},
 { ARM_CPUID_ARM946, arm946},
 { ARM_CPUID_ARM1026, arm1026},
Index: translate.c
===
RCS file: /sources/qemu/qemu/target-arm/translate.c,v
retrieving revision 1.53
diff -u -r1.53 translate.c
--- translate.c	11 Jun 2007 18:59:35 -	1.53
+++ translate.c	2 Jul 2007 13:16:13 -
@@ -1589,7 +1589,7 @@
 uint32_t rd;
 
 /* ??? Some cp15 registers are accessible from userspace.  */
-if (IS_USER(s)) {
+if (IS_USER(s) || arm_feature(env, ARM_FEATURE_NO_CP15)) {
 return 1;
 }
 if ((insn  0x0fff0fff) == 0x0e070f90
@@ -2958,7 +2958,7 @@
 }
 }
 
-static void disas_thumb_insn(DisasContext *s)
+static void disas_thumb_insn(CPUState *env, DisasContext *s)
 {
 uint32_t val, insn, op, rm, rn, rd, shift, cond;
 int32_t offset;
@@ -3058,6 +3058,7 @@
 break;
 case 3:/* branch [and link] exchange thumb register */
 if (insn  (1  7)) {
+if(arm_feature(env, ARM_FEATURE_THUMB1)) goto undef;
 val = (uint32_t)s-pc | 1;
 gen_op_movl_T1_im(val);
 gen_movl_reg_T1(s, 14);
@@ -3367,11 +3368,16 @@
 /* write back the new stack pointer */
 gen_movl_reg_T1(s, 13);
 /* set the new PC value */
-if ((insn  0x0900) == 0x0900)
-gen_bx(s);
+if ((insn  0x0900) == 0x0900) {
+if(arm_feature(env, ARM_FEATURE_THUMB1))
+  gen_movl_reg_T0(s, 15);
+else
+  gen_bx(s);
+}
 break;
 
 case 0xe: /* bkpt */
+if(arm_feature(env, ARM_FEATURE_THUMB1)) goto undef;
 gen_op_movl_T0_im((long)s-pc - 2);
 gen_op_movl_reg_TN[0][15]();
 gen_op_bkpt();
@@ -3442,6 +3448,7 @@
 /* unconditional branch */
 if (insn  (1  11)) {
 /* Second half of blx.  */
+if(arm_feature(env, ARM_FEATURE_THUMB1)) goto undef;
 offset = ((insn  0x7ff)  1);
 gen_movl_T0_reg(s, 14);
 gen_op_movl_T1_im(offset);
@@ -3571,7 +3578,7 @@
 }
 
 if (env-thumb)
-  disas_thumb_insn(dc);
+  disas_thumb_insn(env, dc);
 else
   disas_arm_insn(env, dc);
 


Re: [Qemu-devel] [PATCH] ARM7TDMI emulation

2007-07-02 Thread Ulrich Hecht
On Monday 02 July 2007 15:40, Paul Brook wrote:
 You should add/use ARM_FEATURE_V5/ARCH(5) instead.

Alright.

 The ARM7TDMI implements the base updated abort model.

Er, yes, but there is no MMU that could actually cause an abort, right?

Anyway, here's the 920T version. The magic numbers may or may not be 
correct.

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
Index: target-arm/cpu.h
===
RCS file: /sources/qemu/qemu/target-arm/cpu.h,v
retrieving revision 1.28
diff -u -r1.28 cpu.h
--- target-arm/cpu.h	24 Jun 2007 12:09:48 -	1.28
+++ target-arm/cpu.h	2 Jul 2007 15:09:41 -
@@ -247,7 +247,9 @@
 ARM_FEATURE_AUXCR,  /* ARM1026 Auxiliary control register.  */
 ARM_FEATURE_XSCALE, /* Intel XScale extensions.  */
 ARM_FEATURE_IWMMXT, /* Intel iwMMXt extension.  */
-ARM_FEATURE_MPU /* Only has Memory Protection Unit, not full MMU.  */
+ARM_FEATURE_MPU,/* Only has Memory Protection Unit, not full MMU.  */
+ARM_FEATURE_V5, /* ARM v5 instruction set */
+ARM_FEATURE_NO_CP15 /* ARM7TDMI, ARM7TDMI-S, ARM7EJ-S, and ARM9TDMI cores do not have a CP15 */
 };
 
 static inline int arm_feature(CPUARMState *env, int feature)
@@ -262,7 +264,9 @@
ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write,
void *opaque);
 
+#define ARM_CPUID_ARM7TDMI  0x41807000 /* guess; no CP15 on ARM7TDMI */
 #define ARM_CPUID_ARM1026   0x4106a262
+#define ARM_CPUID_ARM920T   0x41129200
 #define ARM_CPUID_ARM9260x41069265
 #define ARM_CPUID_ARM9460x41059461
 #define ARM_CPUID_PXA2500x69052100
Index: target-arm/helper.c
===
RCS file: /sources/qemu/qemu/target-arm/helper.c,v
retrieving revision 1.17
diff -u -r1.17 helper.c
--- target-arm/helper.c	24 Jun 2007 12:09:48 -	1.17
+++ target-arm/helper.c	2 Jul 2007 15:09:41 -
@@ -14,20 +14,27 @@
 {
 env-cp15.c0_cpuid = id;
 switch (id) {
+case ARM_CPUID_ARM920T:
+env-cp15.c0_cachetype = 0x0d172172;
+env-cp15.c1_sys = 0x0078;
+break;
 case ARM_CPUID_ARM926:
 set_feature(env, ARM_FEATURE_VFP);
+set_feature(env, ARM_FEATURE_V5);
 env-vfp.xregs[ARM_VFP_FPSID] = 0x41011090;
 env-cp15.c0_cachetype = 0x1dd20d2;
 env-cp15.c1_sys = 0x00090078;
 break;
 case ARM_CPUID_ARM946:
 set_feature(env, ARM_FEATURE_MPU);
+set_feature(env, ARM_FEATURE_V5);
 env-cp15.c0_cachetype = 0x0f004006;
 env-cp15.c1_sys = 0x0078;
 break;
 case ARM_CPUID_ARM1026:
 set_feature(env, ARM_FEATURE_VFP);
 set_feature(env, ARM_FEATURE_AUXCR);
+set_feature(env, ARM_FEATURE_V5);
 env-vfp.xregs[ARM_VFP_FPSID] = 0x410110a0;
 env-cp15.c0_cachetype = 0x1dd20d2;
 env-cp15.c1_sys = 0x00090078;
@@ -38,6 +45,7 @@
 case ARM_CPUID_PXA261:
 case ARM_CPUID_PXA262:
 set_feature(env, ARM_FEATURE_XSCALE);
+set_feature(env, ARM_FEATURE_V5);
 /* JTAG_ID is ((id  28) | 0x09265013) */
 env-cp15.c0_cachetype = 0xd172172;
 env-cp15.c1_sys = 0x0078;
@@ -49,6 +57,7 @@
 case ARM_CPUID_PXA270_C0:
 case ARM_CPUID_PXA270_C5:
 set_feature(env, ARM_FEATURE_XSCALE);
+set_feature(env, ARM_FEATURE_V5);
 /* JTAG_ID is ((id  28) | 0x09265013) */
 set_feature(env, ARM_FEATURE_IWMMXT);
 env-iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
@@ -98,6 +107,7 @@
 };
 
 static const struct arm_cpu_t arm_cpu_names[] = {
+{ ARM_CPUID_ARM920T, arm920t},
 { ARM_CPUID_ARM926, arm926},
 { ARM_CPUID_ARM946, arm946},
 { ARM_CPUID_ARM1026, arm1026},
Index: target-arm/translate.c
===
RCS file: /sources/qemu/qemu/target-arm/translate.c,v
retrieving revision 1.53
diff -u -r1.53 translate.c
--- target-arm/translate.c	11 Jun 2007 18:59:35 -	1.53
+++ target-arm/translate.c	2 Jul 2007 15:09:41 -
@@ -1589,7 +1589,7 @@
 uint32_t rd;
 
 /* ??? Some cp15 registers are accessible from userspace.  */
-if (IS_USER(s)) {
+if (IS_USER(s) || arm_feature(env, ARM_FEATURE_NO_CP15)) {
 return 1;
 }
 if ((insn  0x0fff0fff) == 0x0e070f90
@@ -2958,7 +2958,7 @@
 }
 }
 
-static void disas_thumb_insn(DisasContext *s)
+static void disas_thumb_insn(CPUState *env, DisasContext *s)
 {
 uint32_t val, insn, op, rm, rn, rd, shift, cond;
 int32_t offset;
@@ -3058,6 +3058,7 @@
 break;
 case 3:/* branch [and link] exchange thumb register */
 if (insn  (1  7)) {
+if(!arm_feature(env, ARM_FEATURE_V5)) goto undef;
 val = (uint32_t)s-pc | 1;
 gen_op_movl_T1_im(val);
 gen_movl_reg_T1(s, 14);
@@ -3367,11 +3368,16 @@
 /* 

[Qemu-devel] [PATCH] ARM (Thumb) read from R15

2007-06-28 Thread Ulrich Hecht
Hi!

QEMU does not set the Thumb bit when reading from R15 in Thumb mode. 
Here's the fix:

Index: target-arm/translate.c
===
RCS file: /sources/qemu/qemu/target-arm/translate.c,v
retrieving revision 1.53
diff -u -r1.53 translate.c
--- target-arm/translate.c  11 Jun 2007 18:59:35 -  1.53
+++ target-arm/translate.c  28 Jun 2007 14:29:15 -
@@ -307,7 +307,7 @@
 if (reg == 15) {
 /* normaly, since we updated PC, we need only to add one insn */
 if (s-thumb)
-val = (long)s-pc + 2;
+val = (long)s-pc + 3;
 else
 val = (long)s-pc + 4;
 gen_op_movl_TN_im[t](val);

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)




Re: [Qemu-devel] [PATCH] ARM (Thumb) read from R15

2007-06-28 Thread Ulrich Hecht
On Thursday 28 June 2007 16:31, Ulrich Hecht wrote:
 QEMU does not set the Thumb bit when reading from R15 in Thumb mode.
 Here's the fix:

Maybe not; this seems to break some cases ... :(

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)




Re: [Qemu-devel] [PATCH] ARM (Thumb) read from R15

2007-06-28 Thread Ulrich Hecht
On Thursday 28 June 2007 17:30, Ulrich Hecht wrote:
 On Thursday 28 June 2007 16:31, Ulrich Hecht wrote:
  QEMU does not set the Thumb bit when reading from R15 in Thumb mode.
  Here's the fix:

 Maybe not; this seems to break some cases ... :(

This works in all my cases, although I am not sure if it is correct:

Index: target-arm/translate.c
===
RCS file: /sources/qemu/qemu/target-arm/translate.c,v
retrieving revision 1.53
diff -u -r1.53 translate.c
--- target-arm/translate.c  11 Jun 2007 18:59:35 -  1.53
+++ target-arm/translate.c  28 Jun 2007 15:48:59 -
@@ -307,7 +307,7 @@
 if (reg == 15) {
 /* normaly, since we updated PC, we need only to add one insn */
 if (s-thumb)
-val = (long)s-pc + 2;
+val = (long)s-pc + 3;
 else
 val = (long)s-pc + 4;
 gen_op_movl_TN_im[t](val);
@@ -3062,7 +3062,10 @@
 gen_op_movl_T1_im(val);
 gen_movl_reg_T1(s, 14);
 }
-gen_movl_T0_reg(s, rm);
+if (rm == 15)
+  gen_op_movl_T0_im(s-pc + 2);
+else
+  gen_movl_T0_reg(s, rm);
 gen_bx(s);
 break;
 }

CU
Uli

-- 
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)




[Qemu-devel] Patch day

2006-03-08 Thread Ulrich Hecht
Hi!

Here's the current lot of patches from the SuSE QEMU package. As we have 
now arrived at the point where patches start to conflict with each 
other, I would be very grateful if at least some of these went into the 
next release.

qemu-0.7.0-binfmt.patch: some enhancements to the qemu-binfmt-conf.sh 
script

qemu-0.7.1-armfpaex.patch: proper FPA exception generation for arm-user 
targets

qemu-0.7.1-jobsignals.patch: handle SIGTTOU/SIGTTIN/SIGTSTP; makes job 
control work

qemu-0.7.1-syscalls.patch: implements acct, uselib, syslog, mincore, 
madvise, readahead, clock_gettime; I have not extensively checked these 
for correctness, but from experience I can say that with this patch 
applied a lot of breakage vanishes

qemu-0.8.0-ia64.patch: Itanium host fixes by Andreas Schwab

qemu-nwfpe-cpsr.patch: fixes ARM FPA CPSR updates; same as posted before, 
but fixed to work with qemu-0.7.1-armfpaex.patch

CU
Uli
--- qemu-binfmt-conf.sh
+++ qemu-binfmt-conf.sh
@@ -2,38 +2,46 @@
 # enable automatic i386/ARM/SPARC/PPC program execution by the kernel
 
 # load the binfmt_misc module
-/sbin/modprobe binfmt_misc
+
+if test ! -e /proc/sys/fs/binfmt_misc/register
+then
+	/sbin/modprobe binfmt_misc
+	mount -t binfmt_misc none /proc/sys/fs/binfmt_misc
+fi
 
 # probe cpu type
 cpu=`uname -m`
 case $cpu in
-  i386|i486|i586|i686|i86pc|BePC)
+  i386|i486|i586|i686|i86pc|BePC|x86_64)
 cpu=i386
   ;;
   Power Macintosh|ppc|ppc64)
 cpu=ppc
   ;;
-  armv4l)
+  armv[4-9]*l)
 cpu=arm
   ;;
+  sparc*)
+cpu=sparc
+  ;;
 esac
 
 # register the interpreter for each cpu except for the native one
 if [ $cpu != i386 ] ; then
-echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:'  /proc/sys/fs/binfmt_misc/register
-echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:'  /proc/sys/fs/binfmt_misc/register
+echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386:'  /proc/sys/fs/binfmt_misc/register
+echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386:'  /proc/sys/fs/binfmt_misc/register
 fi
 if [ $cpu != arm ] ; then
-echo   ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-arm:'  /proc/sys/fs/binfmt_misc/register
-echo   ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-armeb:'  /proc/sys/fs/binfmt_misc/register
+echo   ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm:'  /proc/sys/fs/binfmt_misc/register
+echo   ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-armeb:'  /proc/sys/fs/binfmt_misc/register
 fi
 if [ $cpu != sparc ] ; then
-echo   ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sparc:'  /proc/sys/fs/binfmt_misc/register
+echo   ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sparc:'  /proc/sys/fs/binfmt_misc/register
 fi
 if [ $cpu != ppc ] ; then
-echo   ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-ppc:'  /proc/sys/fs/binfmt_misc/register
+echo   ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc:'  /proc/sys/fs/binfmt_misc/register
 fi
 if [ $cpu != mips ] ; then
-echo   ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips:'  /proc/sys/fs/binfmt_misc/register
-echo