qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/37] target-arm queue
@ 2013-12-10 14:42 Peter Maydell
  2013-12-10 14:42 ` [Qemu-devel] [PULL 01/37] integrator/cp: add support for REFCNT register Peter Maydell
                   ` (36 more replies)
  0 siblings, 37 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:42 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

Here's the target-arm queue; first pullreq since 1.7 went out.
Please pull. (I expect I'll do another pullreq in a week or
two which will have AArch64 KVM control and most of the A64
decoder changes in it...)

thanks
--PMM


The following changes since commit 8f84271da83c0e9f92aa7c1c2d0d3875bf0a5cb8:

  target-mips: Use macro ARRAY_SIZE where possible (2013-12-09 16:44:04 +0100)

are available in the git repository at:

  git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20131210

for you to fetch changes up to 74f1c6ddec8dc7566d9b75574bb006214cc7d3b4:

  target-arm: fix TTBCR write masking (2013-12-10 13:28:50 +0000)

----------------------------------------------------------------
target-arm queue:
 * support REFCNT register on integrator/cp board
 * implement the A9MP's global timer
 * add the 'virt' platform
 * support '-cpu host' on KVM/ARM
 * Cadence GEM ethernet device bugfixes
 * Implement 32-bit ARMv8 VSEL, VMAXNM, VMINNM
 * fix TTBCR write masking
 * update 32 bit decoder to use new qemu_ld/st TCG opcodes

----------------------------------------------------------------
Edgar E. Iglesias (1):
      net/cadence_gem: Update DMA rx descriptors as we process them

François LEGAL (1):
      cpu/a9mpcore: Add Global Timer

Jan Petrous (1):
      integrator/cp: add support for REFCNT register

John Rigby (1):
      hw/arm/boot: Allow boards to provide an fdt blob

Peter Crosthwaite (16):
      cpu/a9mpcore: rename timerbusdev variable
      cpu/a9mpcore: reorder operations/declarations
      hw/timer: Introduce ARM A9 Global Timer.
      net/cadence_gem: Implement mac level loopback mode
      net/cadence_gem: Don't assert against 0 buffer address
      net/cadence_gem: simplify rx buf descriptor walking
      net/cadence_gem: Prefetch rx descriptors ASAP
      net/cadence_gem: Implement RX descriptor match mode flags
      net/cadence_gem: Implement SAR match bit in rx desc
      net/cadence_gem: Implement SAR (de)activation
      net/cadence_gem: Add missing VMSTATE_END_OF_LIST
      net/cadence_gem: Fix rx multi-fragment packets
      net/cadence_gem: Fix small packet FCS stripping
      net/cadence_gem: Fix register w1c logic
      net/cadence_gem: Improve can_receive debug printfery
      net/cadence_gem: Don't rx packets when no rx buffer available

Peter Maydell (9):
      target-arm: Provide mechanism for getting KVM constants even if not CONFIG_KVM
      device_tree.c: Terminate the empty reservemap in create_device_tree()
      target-arm: Provide PSCI constants to generic QEMU code
      target-arm: Add ARMCPU field for Linux device-tree 'compatible' string
      target-arm: Allow secondary KVM CPUs to be booted via PSCI
      hw/arm: Add 'virt' platform
      target-arm: Don't hardcode KVM target CPU to be A15
      target-arm: Provide '-cpu host' when running KVM
      hw/arm/virt: Support -cpu host

Richard Henderson (1):
      target-arm: Use new qemu_ld/st opcodes

Sergey Fedorov (1):
      target-arm: fix TTBCR write masking

Will Newton (6):
      target-arm: Move call to disas_vfp_insn out of disas_coproc_insn.
      target-arm: Implement ARMv8 VSEL instruction.
      softfloat: Remove unused argument from MINMAX macro.
      softfloat: Add minNum() and maxNum() functions to softfloat.
      target-arm: Implement ARMv8 FP VMAXNM and VMINNM instructions.
      target-arm: Implement ARMv8 SIMD VMAXNM and VMINNM instructions.

 default-configs/arm-softmmu.mak |   1 +
 device_tree.c                   |   4 +
 fpu/softfloat.c                 |  38 +++-
 hw/arm/Makefile.objs            |   2 +-
 hw/arm/boot.c                   |  32 +--
 hw/arm/integratorcp.c           |  13 +-
 hw/arm/virt.c                   | 452 ++++++++++++++++++++++++++++++++++++++++
 hw/cpu/a9mpcore.c               |  44 ++--
 hw/net/cadence_gem.c            | 278 +++++++++++++++---------
 hw/timer/Makefile.objs          |   1 +
 hw/timer/a9gtimer.c             | 369 ++++++++++++++++++++++++++++++++
 include/fpu/softfloat.h         |   4 +
 include/hw/arm/arm.h            |   7 +
 include/hw/cpu/a9mpcore.h       |   4 +-
 include/hw/timer/a9gtimer.h     |  97 +++++++++
 target-arm/cpu-qom.h            |  11 +
 target-arm/cpu.c                |  59 ++++++
 target-arm/cpu.h                |  13 +-
 target-arm/helper.c             |  33 ++-
 target-arm/helper.h             |   5 +
 target-arm/kvm-consts.h         |  64 ++++++
 target-arm/kvm.c                | 243 ++++++++++++++++++++-
 target-arm/kvm_arm.h            |  55 +++++
 target-arm/translate.c          | 302 +++++++++++++++++++++++----
 24 files changed, 1926 insertions(+), 205 deletions(-)
 create mode 100644 hw/arm/virt.c
 create mode 100644 hw/timer/a9gtimer.c
 create mode 100644 include/hw/timer/a9gtimer.h
 create mode 100644 target-arm/kvm-consts.h

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 01/37] integrator/cp: add support for REFCNT register
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
@ 2013-12-10 14:42 ` Peter Maydell
  2013-12-10 14:42 ` [Qemu-devel] [PULL 02/37] cpu/a9mpcore: rename timerbusdev variable Peter Maydell
                   ` (35 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:42 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Jan Petrous <jan.petrous@tieto.com>

Linux kernel from version 3.4 requires CM_REFCNT register for sched timer
for Integrator/CP board (integrator_defconfig).

See http://infocenter.arm.com/help/topic/com.arm.doc.dui0138e/ch04s06s11.html

Signed-off-by: Jan Petrous <jan.petrous@tieto.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/integratorcp.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index c44b2a4..a759689 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -36,6 +36,7 @@ typedef struct IntegratorCMState {
     uint32_t cm_init;
     uint32_t cm_flags;
     uint32_t cm_nvflags;
+    uint32_t cm_refcnt_offset;
     uint32_t int_level;
     uint32_t irq_enabled;
     uint32_t fiq_enabled;
@@ -82,9 +83,13 @@ static uint64_t integratorcm_read(void *opaque, hwaddr offset,
         return s->cm_sdram;
     case 9: /* CM_INIT */
         return s->cm_init;
-    case 10: /* CM_REFCT */
-        /* ??? High frequency timer.  */
-        hw_error("integratorcm_read: CM_REFCT");
+    case 10: /* CM_REFCNT */
+        /* This register, CM_REFCNT, provides a 32-bit count value.
+         * The count increments at the fixed reference clock frequency of 24MHz
+         * and can be used as a real-time counter.
+         */
+        return (uint32_t)muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24,
+                                  1000) - s->cm_refcnt_offset;
     case 12: /* CM_FLAGS */
         return s->cm_flags;
     case 14: /* CM_NVFLAGS */
@@ -257,6 +262,8 @@ static int integratorcm_init(SysBusDevice *dev)
     }
     memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
     s->cm_init = 0x00000112;
+    s->cm_refcnt_offset = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24,
+                                   1000);
     memory_region_init_ram(&s->flash, OBJECT(s), "integrator.flash", 0x100000);
     vmstate_register_ram_global(&s->flash);
 
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 02/37] cpu/a9mpcore: rename timerbusdev variable
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
  2013-12-10 14:42 ` [Qemu-devel] [PULL 01/37] integrator/cp: add support for REFCNT register Peter Maydell
@ 2013-12-10 14:42 ` Peter Maydell
  2013-12-10 14:42 ` [Qemu-devel] [PULL 03/37] cpu/a9mpcore: reorder operations/declarations Peter Maydell
                   ` (34 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:42 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

Rename this variable for consistency with the above defined mptimerdev
variable.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 28939ef95589a62414634e86c47cef76b21b15f7.1385969450.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/cpu/a9mpcore.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c
index 918a7d1..1123101 100644
--- a/hw/cpu/a9mpcore.c
+++ b/hw/cpu/a9mpcore.c
@@ -42,7 +42,7 @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
     A9MPPrivState *s = A9MPCORE_PRIV(dev);
     DeviceState *gicdev, *scudev, *mptimerdev, *wdtdev;
-    SysBusDevice *timerbusdev, *wdtbusdev, *gicbusdev, *scubusdev;
+    SysBusDevice *mptimerbusdev, *wdtbusdev, *gicbusdev, *scubusdev;
     Error *err = NULL;
     int i;
 
@@ -78,7 +78,7 @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
         error_propagate(errp, err);
         return;
     }
-    timerbusdev = SYS_BUS_DEVICE(&s->mptimer);
+    mptimerbusdev = SYS_BUS_DEVICE(&s->mptimer);
 
     wdtdev = DEVICE(&s->wdt);
     qdev_prop_set_uint32(wdtdev, "num-cpu", s->num_cpu);
@@ -109,7 +109,7 @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
      * memory region, not the "timer/watchdog for core X" ones 11MPcore has.
      */
     memory_region_add_subregion(&s->container, 0x600,
-                                sysbus_mmio_get_region(timerbusdev, 0));
+                                sysbus_mmio_get_region(mptimerbusdev, 0));
     memory_region_add_subregion(&s->container, 0x620,
                                 sysbus_mmio_get_region(wdtbusdev, 0));
     memory_region_add_subregion(&s->container, 0x1000,
@@ -120,7 +120,7 @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
      */
     for (i = 0; i < s->num_cpu; i++) {
         int ppibase = (s->num_irq - 32) + i * 32;
-        sysbus_connect_irq(timerbusdev, i,
+        sysbus_connect_irq(mptimerbusdev, i,
                            qdev_get_gpio_in(gicdev, ppibase + 29));
         sysbus_connect_irq(wdtbusdev, i,
                            qdev_get_gpio_in(gicdev, ppibase + 30));
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 03/37] cpu/a9mpcore: reorder operations/declarations
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
  2013-12-10 14:42 ` [Qemu-devel] [PULL 01/37] integrator/cp: add support for REFCNT register Peter Maydell
  2013-12-10 14:42 ` [Qemu-devel] [PULL 02/37] cpu/a9mpcore: rename timerbusdev variable Peter Maydell
@ 2013-12-10 14:42 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 04/37] hw/timer: Introduce ARM A9 Global Timer Peter Maydell
                   ` (33 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:42 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

To make it consistent for easier code reading. The order in which
variables are defined and functions are called is set to match the
address map ordering.

The new consistent order of doing stuff is:

SCU -> GIC -> MPTimer -> WDT.

0 functional change.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 8f31398e6d9a93f57291399f269039da1a77a2b5.1385969450.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/cpu/a9mpcore.c         | 28 ++++++++++++++--------------
 include/hw/cpu/a9mpcore.h |  2 +-
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c
index 1123101..a38464b 100644
--- a/hw/cpu/a9mpcore.c
+++ b/hw/cpu/a9mpcore.c
@@ -24,12 +24,12 @@ static void a9mp_priv_initfn(Object *obj)
     memory_region_init(&s->container, obj, "a9mp-priv-container", 0x2000);
     sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->container);
 
-    object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC);
-    qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default());
-
     object_initialize(&s->scu, sizeof(s->scu), TYPE_A9_SCU);
     qdev_set_parent_bus(DEVICE(&s->scu), sysbus_get_default());
 
+    object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC);
+    qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default());
+
     object_initialize(&s->mptimer, sizeof(s->mptimer), TYPE_ARM_MPTIMER);
     qdev_set_parent_bus(DEVICE(&s->mptimer), sysbus_get_default());
 
@@ -41,11 +41,20 @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
 {
     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
     A9MPPrivState *s = A9MPCORE_PRIV(dev);
-    DeviceState *gicdev, *scudev, *mptimerdev, *wdtdev;
-    SysBusDevice *mptimerbusdev, *wdtbusdev, *gicbusdev, *scubusdev;
+    DeviceState *scudev, *gicdev, *mptimerdev, *wdtdev;
+    SysBusDevice *scubusdev, *gicbusdev, *mptimerbusdev, *wdtbusdev;
     Error *err = NULL;
     int i;
 
+    scudev = DEVICE(&s->scu);
+    qdev_prop_set_uint32(scudev, "num-cpu", s->num_cpu);
+    object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+    scubusdev = SYS_BUS_DEVICE(&s->scu);
+
     gicdev = DEVICE(&s->gic);
     qdev_prop_set_uint32(gicdev, "num-cpu", s->num_cpu);
     qdev_prop_set_uint32(gicdev, "num-irq", s->num_irq);
@@ -62,15 +71,6 @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
     /* Pass through inbound GPIO lines to the GIC */
     qdev_init_gpio_in(dev, a9mp_priv_set_irq, s->num_irq - 32);
 
-    scudev = DEVICE(&s->scu);
-    qdev_prop_set_uint32(scudev, "num-cpu", s->num_cpu);
-    object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
-    if (err != NULL) {
-        error_propagate(errp, err);
-        return;
-    }
-    scubusdev = SYS_BUS_DEVICE(&s->scu);
-
     mptimerdev = DEVICE(&s->mptimer);
     qdev_prop_set_uint32(mptimerdev, "num-cpu", s->num_cpu);
     object_property_set_bool(OBJECT(&s->mptimer), true, "realized", &err);
diff --git a/include/hw/cpu/a9mpcore.h b/include/hw/cpu/a9mpcore.h
index 010489b..8eece07 100644
--- a/include/hw/cpu/a9mpcore.h
+++ b/include/hw/cpu/a9mpcore.h
@@ -28,8 +28,8 @@ typedef struct A9MPPrivState {
     MemoryRegion container;
     uint32_t num_irq;
 
-    GICState gic;
     A9SCUState scu;
+    GICState gic;
     ARMMPTimerState mptimer;
     ARMMPTimerState wdt;
 } A9MPPrivState;
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 04/37] hw/timer: Introduce ARM A9 Global Timer.
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (2 preceding siblings ...)
  2013-12-10 14:42 ` [Qemu-devel] [PULL 03/37] cpu/a9mpcore: reorder operations/declarations Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 05/37] cpu/a9mpcore: Add " Peter Maydell
                   ` (32 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

The ARM A9 MPCore has a timer that is global to all cores in the cluster.
The timer is shared but each core has a private independent comparator
and interrupt.

Based on version contributed by Francois LEGAL.

Signed-off-by: François LEGAL <devel@thom.fr.eu.org>
Message-id: 4918e89476b8da916be2964ec41578b50d569a37.1385969450.git.peter.crosthwaite@xilinx.com
[PC changes:
 * New commit message
 * Re-implemented as single timer model
 * Fixed backwards counting issue in polled mode
 * completed VMSD fields
 * macroified magic numbers (and headerified reg definitions)
 * split of as device-model-only patch
 * use bitops for 64 bit register access
 * Fixed auto increment mode to check condition properly
 * general cleanup (names/style etc).
]
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
[PMM:
 * minor typo fixes
 * added missing return after error_setg()
 * dropped setting dc->no_user = 1
]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 default-configs/arm-softmmu.mak |   1 +
 hw/timer/Makefile.objs          |   1 +
 hw/timer/a9gtimer.c             | 369 ++++++++++++++++++++++++++++++++++++++++
 include/hw/timer/a9gtimer.h     |  97 +++++++++++
 4 files changed, 468 insertions(+)
 create mode 100644 hw/timer/a9gtimer.c
 create mode 100644 include/hw/timer/a9gtimer.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index a555eef..e48f102 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -41,6 +41,7 @@ CONFIG_ARM_GIC=y
 CONFIG_ARM_GIC_KVM=$(CONFIG_KVM)
 CONFIG_ARM_TIMER=y
 CONFIG_ARM_MPTIMER=y
+CONFIG_A9_GTIMER=y
 CONFIG_PL011=y
 CONFIG_PL022=y
 CONFIG_PL031=y
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index eca5905..3ae091c 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -1,5 +1,6 @@
 common-obj-$(CONFIG_ARM_TIMER) += arm_timer.o
 common-obj-$(CONFIG_ARM_MPTIMER) += arm_mptimer.o
+common-obj-$(CONFIG_A9_GTIMER) += a9gtimer.o
 common-obj-$(CONFIG_CADENCE) += cadence_ttc.o
 common-obj-$(CONFIG_DS1338) += ds1338.o
 common-obj-$(CONFIG_HPET) += hpet.o
diff --git a/hw/timer/a9gtimer.c b/hw/timer/a9gtimer.c
new file mode 100644
index 0000000..a0656d5
--- /dev/null
+++ b/hw/timer/a9gtimer.c
@@ -0,0 +1,369 @@
+/*
+ * Global peripheral timer block for ARM A9MP
+ *
+ * (C) 2013 Xilinx Inc.
+ *
+ * Written by François LEGAL
+ * Written by Peter Crosthwaite <peter.crosthwaite@xilinx.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw/timer/a9gtimer.h"
+#include "qemu/timer.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+
+#ifndef A9_GTIMER_ERR_DEBUG
+#define A9_GTIMER_ERR_DEBUG 0
+#endif
+
+#define DB_PRINT_L(level, ...) do { \
+    if (A9_GTIMER_ERR_DEBUG > (level)) { \
+        fprintf(stderr,  ": %s: ", __func__); \
+        fprintf(stderr, ## __VA_ARGS__); \
+    } \
+} while (0);
+
+#define DB_PRINT(...) DB_PRINT_L(0, ## __VA_ARGS__)
+
+static inline int a9_gtimer_get_current_cpu(A9GTimerState *s)
+{
+    if (current_cpu->cpu_index >= s->num_cpu) {
+        hw_error("a9gtimer: num-cpu %d but this cpu is %d!\n",
+                 s->num_cpu, current_cpu->cpu_index);
+    }
+    return current_cpu->cpu_index;
+}
+
+static inline uint64_t a9_gtimer_get_conv(A9GTimerState *s)
+{
+    uint64_t prescale = extract32(s->control, R_CONTROL_PRESCALER_SHIFT,
+                                  R_CONTROL_PRESCALER_LEN);
+
+    return (prescale + 1) * 10;
+}
+
+static A9GTimerUpdate a9_gtimer_get_update(A9GTimerState *s)
+{
+    A9GTimerUpdate ret;
+
+    ret.now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    ret.new = s->ref_counter +
+              (ret.now - s->cpu_ref_time) / a9_gtimer_get_conv(s);
+    return ret;
+}
+
+static void a9_gtimer_update(A9GTimerState *s, bool sync)
+{
+
+    A9GTimerUpdate update = a9_gtimer_get_update(s);
+    int i;
+    int64_t next_cdiff = 0;
+
+    for (i = 0; i < s->num_cpu; ++i) {
+        A9GTimerPerCPU *gtb = &s->per_cpu[i];
+        int64_t cdiff = 0;
+
+        if ((s->control & R_CONTROL_TIMER_ENABLE) &&
+                (gtb->control & R_CONTROL_COMP_ENABLE)) {
+            /* R2p0+, where the compare function is >= */
+            while (gtb->compare < update.new) {
+                DB_PRINT("Compare event happened for CPU %d\n", i);
+                gtb->status = 1;
+                if (gtb->control & R_CONTROL_AUTO_INCREMENT) {
+                    DB_PRINT("Auto incrementing timer compare by %" PRId32 "\n",
+                             gtb->inc);
+                    gtb->compare += gtb->inc;
+                } else {
+                    break;
+                }
+            }
+            cdiff = (int64_t)gtb->compare - (int64_t)update.new + 1;
+            if (cdiff > 0 && (cdiff < next_cdiff || !next_cdiff)) {
+                next_cdiff = cdiff;
+            }
+        }
+
+        qemu_set_irq(gtb->irq,
+                     gtb->status && (gtb->control & R_CONTROL_IRQ_ENABLE));
+    }
+
+    timer_del(s->timer);
+    if (next_cdiff) {
+        DB_PRINT("scheduling qemu_timer to fire again in %"
+                 PRIx64 " cycles\n", next_cdiff);
+        timer_mod(s->timer, update.now + next_cdiff * a9_gtimer_get_conv(s));
+    }
+
+    if (s->control & R_CONTROL_TIMER_ENABLE) {
+        s->counter = update.new;
+    }
+
+    if (sync) {
+        s->cpu_ref_time = update.now;
+        s->ref_counter = s->counter;
+    }
+}
+
+static void a9_gtimer_update_no_sync(void *opaque)
+{
+    A9GTimerState *s = A9_GTIMER(opaque);
+
+    return a9_gtimer_update(s, false);
+}
+
+static uint64_t a9_gtimer_read(void *opaque, hwaddr addr, unsigned size)
+{
+    A9GTimerPerCPU *gtb = (A9GTimerPerCPU *)opaque;
+    A9GTimerState *s = gtb->parent;
+    A9GTimerUpdate update;
+    uint64_t ret = 0;
+    int shift = 0;
+
+    switch (addr) {
+    case R_COUNTER_HI:
+        shift = 32;
+        /* fallthrough */
+    case R_COUNTER_LO:
+        update = a9_gtimer_get_update(s);
+        ret = extract64(update.new, shift, 32);
+        break;
+    case R_CONTROL:
+        ret = s->control | gtb->control;
+        break;
+    case R_INTERRUPT_STATUS:
+        ret = gtb->status;
+        break;
+    case R_COMPARATOR_HI:
+        shift = 32;
+        /* fallthrough */
+    case R_COMPARATOR_LO:
+        ret = extract64(gtb->compare, shift, 32);
+        break;
+    case R_AUTO_INCREMENT:
+        ret =  gtb->inc;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "bad a9gtimer register: %x\n",
+                      (unsigned)addr);
+        return 0;
+    }
+
+    DB_PRINT("addr:%#x data:%#08" PRIx64 "\n", (unsigned)addr, ret);
+    return ret;
+}
+
+static void a9_gtimer_write(void *opaque, hwaddr addr, uint64_t value,
+                            unsigned size)
+{
+    A9GTimerPerCPU *gtb = (A9GTimerPerCPU *)opaque;
+    A9GTimerState *s = gtb->parent;
+    int shift = 0;
+
+    DB_PRINT("addr:%#x data:%#08" PRIx64 "\n", (unsigned)addr, value);
+
+    switch (addr) {
+    case R_COUNTER_HI:
+        shift = 32;
+        /* fallthrough */
+    case R_COUNTER_LO:
+        /*
+         * Keep it simple - ARM docco explicitly says to disable timer before
+         * modding it, so dont bother trying to do all the difficult on the fly
+         * timer modifications - (if they even work in real hardware??).
+         */
+        if (s->control & R_CONTROL_TIMER_ENABLE) {
+            qemu_log_mask(LOG_GUEST_ERROR, "Cannot mod running ARM gtimer\n");
+            return;
+        }
+        s->counter = deposit64(s->counter, shift, 32, value);
+        return;
+    case R_CONTROL:
+        a9_gtimer_update(s, (value ^ s->control) & R_CONTROL_NEEDS_SYNC);
+        gtb->control = value & R_CONTROL_BANKED;
+        s->control = value & ~R_CONTROL_BANKED;
+        break;
+    case R_INTERRUPT_STATUS:
+        a9_gtimer_update(s, false);
+        gtb->status &= ~value;
+        break;
+    case R_COMPARATOR_HI:
+        shift = 32;
+        /* fallthrough */
+    case R_COMPARATOR_LO:
+        a9_gtimer_update(s, false);
+        gtb->compare = deposit64(gtb->compare, shift, 32, value);
+        break;
+    case R_AUTO_INCREMENT:
+        gtb->inc = value;
+        return;
+    default:
+        return;
+    }
+
+    a9_gtimer_update(s, false);
+}
+
+/* Wrapper functions to implement the "read global timer for
+ * the current CPU" memory regions.
+ */
+static uint64_t a9_gtimer_this_read(void *opaque, hwaddr addr,
+                                    unsigned size)
+{
+    A9GTimerState *s = A9_GTIMER(opaque);
+    int id = a9_gtimer_get_current_cpu(s);
+
+    /* no \n so concatenates with message from read fn */
+    DB_PRINT("CPU:%d:", id);
+
+    return a9_gtimer_read(&s->per_cpu[id], addr, size);
+}
+
+static void a9_gtimer_this_write(void *opaque, hwaddr addr,
+                                 uint64_t value, unsigned size)
+{
+    A9GTimerState *s = A9_GTIMER(opaque);
+    int id = a9_gtimer_get_current_cpu(s);
+
+    /* no \n so concatenates with message from write fn */
+    DB_PRINT("CPU:%d:", id);
+
+    a9_gtimer_write(&s->per_cpu[id], addr, value, size);
+}
+
+static const MemoryRegionOps a9_gtimer_this_ops = {
+    .read = a9_gtimer_this_read,
+    .write = a9_gtimer_this_write,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const MemoryRegionOps a9_gtimer_ops = {
+    .read = a9_gtimer_read,
+    .write = a9_gtimer_write,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void a9_gtimer_reset(DeviceState *dev)
+{
+    A9GTimerState *s = A9_GTIMER(dev);
+    int i;
+
+    s->counter = 0;
+    s->control = 0;
+
+    for (i = 0; i < s->num_cpu; i++) {
+        A9GTimerPerCPU *gtb = &s->per_cpu[i];
+
+        gtb->control = 0;
+        gtb->status = 0;
+        gtb->compare = 0;
+        gtb->inc = 0;
+    }
+    a9_gtimer_update(s, false);
+}
+
+static void a9_gtimer_realize(DeviceState *dev, Error **errp)
+{
+    A9GTimerState *s = A9_GTIMER(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    int i;
+
+    if (s->num_cpu < 1 || s->num_cpu > A9_GTIMER_MAX_CPUS) {
+        error_setg(errp, "%s: num-cpu must be between 1 and %d\n",
+                   __func__, A9_GTIMER_MAX_CPUS);
+        return;
+    }
+
+    memory_region_init_io(&s->iomem, OBJECT(dev), &a9_gtimer_this_ops, s,
+                          "a9gtimer shared", 0x20);
+    sysbus_init_mmio(sbd, &s->iomem);
+    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, a9_gtimer_update_no_sync, s);
+
+    for (i = 0; i < s->num_cpu; i++) {
+        A9GTimerPerCPU *gtb = &s->per_cpu[i];
+
+        gtb->parent = s;
+        sysbus_init_irq(sbd, &gtb->irq);
+        memory_region_init_io(&gtb->iomem, OBJECT(dev), &a9_gtimer_ops, gtb,
+                              "a9gtimer per cpu", 0x20);
+        sysbus_init_mmio(sbd, &gtb->iomem);
+    }
+}
+
+static const VMStateDescription vmstate_a9_gtimer_per_cpu = {
+    .name = "arm.cortex-a9-global-timer.percpu",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(control, A9GTimerPerCPU),
+        VMSTATE_UINT64(compare, A9GTimerPerCPU),
+        VMSTATE_UINT32(status, A9GTimerPerCPU),
+        VMSTATE_UINT32(inc, A9GTimerPerCPU),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_a9_gtimer = {
+    .name = "arm.cortex-a9-global-timer",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_TIMER(timer, A9GTimerState),
+        VMSTATE_UINT64(counter, A9GTimerState),
+        VMSTATE_UINT64(ref_counter, A9GTimerState),
+        VMSTATE_UINT64(cpu_ref_time, A9GTimerState),
+        VMSTATE_STRUCT_VARRAY_UINT32(per_cpu, A9GTimerState, num_cpu,
+                                     1, vmstate_a9_gtimer_per_cpu,
+                                     A9GTimerPerCPU),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static Property a9_gtimer_properties[] = {
+    DEFINE_PROP_UINT32("num-cpu", A9GTimerState, num_cpu, 0),
+    DEFINE_PROP_END_OF_LIST()
+};
+
+static void a9_gtimer_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = a9_gtimer_realize;
+    dc->vmsd = &vmstate_a9_gtimer;
+    dc->reset = a9_gtimer_reset;
+    dc->props = a9_gtimer_properties;
+}
+
+static const TypeInfo a9_gtimer_info = {
+    .name          = TYPE_A9_GTIMER,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(A9GTimerState),
+    .class_init    = a9_gtimer_class_init,
+};
+
+static void a9_gtimer_register_types(void)
+{
+    type_register_static(&a9_gtimer_info);
+}
+
+type_init(a9_gtimer_register_types)
diff --git a/include/hw/timer/a9gtimer.h b/include/hw/timer/a9gtimer.h
new file mode 100644
index 0000000..b88c02a
--- /dev/null
+++ b/include/hw/timer/a9gtimer.h
@@ -0,0 +1,97 @@
+/*
+ * Global peripheral timer block for ARM A9MP
+ *
+ * (C) 2013 Xilinx Inc.
+ *
+ * Written by François LEGAL
+ * Written by Peter Crosthwaite <peter.crosthwaite@xilinx.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HW_TIMER_A9_GTIMER_H_H
+#define HW_TIMER_A9_GTIMER_H_H
+
+#include "hw/sysbus.h"
+
+#define A9_GTIMER_MAX_CPUS 4
+
+#define TYPE_A9_GTIMER "arm.cortex-a9-global-timer"
+#define A9_GTIMER(obj) OBJECT_CHECK(A9GTimerState, (obj), TYPE_A9_GTIMER)
+
+#define R_COUNTER_LO                0x00
+#define R_COUNTER_HI                0x04
+
+#define R_CONTROL                   0x08
+#define R_CONTROL_TIMER_ENABLE      (1 << 0)
+#define R_CONTROL_COMP_ENABLE       (1 << 1)
+#define R_CONTROL_IRQ_ENABLE        (1 << 2)
+#define R_CONTROL_AUTO_INCREMENT    (1 << 2)
+#define R_CONTROL_PRESCALER_SHIFT   8
+#define R_CONTROL_PRESCALER_LEN     8
+#define R_CONTROL_PRESCALER_MASK    (((1 << R_CONTROL_PRESCALER_LEN) - 1) << \
+                                     R_CONTROL_PRESCALER_SHIFT)
+
+#define R_CONTROL_BANKED            (R_CONTROL_COMP_ENABLE | \
+                                     R_CONTROL_IRQ_ENABLE | \
+                                     R_CONTROL_AUTO_INCREMENT)
+#define R_CONTROL_NEEDS_SYNC        (R_CONTROL_TIMER_ENABLE | \
+                                     R_CONTROL_PRESCALER_MASK)
+
+#define R_INTERRUPT_STATUS          0x0C
+#define R_COMPARATOR_LO             0x10
+#define R_COMPARATOR_HI             0x14
+#define R_AUTO_INCREMENT            0x18
+
+typedef struct A9GTimerPerCPU A9GTimerPerCPU;
+typedef struct A9GTimerState A9GTimerState;
+
+struct A9GTimerPerCPU {
+    A9GTimerState *parent;
+
+    uint32_t control; /* only per cpu banked bits valid */
+    uint64_t compare;
+    uint32_t status;
+    uint32_t inc;
+
+    MemoryRegion iomem;
+    qemu_irq irq; /* PPI interrupts */
+};
+
+struct A9GTimerState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    MemoryRegion iomem;
+    /* static props */
+    uint32_t num_cpu;
+
+    QEMUTimer *timer;
+
+    uint64_t counter; /* current timer value */
+
+    uint64_t ref_counter;
+    uint64_t cpu_ref_time; /* the cpu time as of last update of ref_counter */
+    uint32_t control; /* only non per cpu banked bits valid */
+
+    A9GTimerPerCPU per_cpu[A9_GTIMER_MAX_CPUS];
+};
+
+typedef struct A9GTimerUpdate {
+    uint64_t now;
+    uint64_t new;
+} A9GTimerUpdate;
+
+#endif /* #ifdef HW_TIMER_A9_GTIMER_H_H */
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 05/37] cpu/a9mpcore: Add Global Timer
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (3 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 04/37] hw/timer: Introduce ARM A9 Global Timer Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 06/37] target-arm: Provide mechanism for getting KVM constants even if not CONFIG_KVM Peter Maydell
                   ` (31 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: François LEGAL <devel@thom.fr.eu.org>

Add the global timer to A9 MPCore.

Signed-off-by: François LEGAL <devel@thom.fr.eu.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: ff92f35f438ac671b57d99d823723dd3e62d2c49.1385969450.git.peter.crosthwaite@xilinx.com
[PC Changes:
 * new commit message
 * split off original version as a separate patch
 * Rebased against new mpcore implementation (with struct embedding)
]
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/cpu/a9mpcore.c         | 26 +++++++++++++++++++++-----
 include/hw/cpu/a9mpcore.h |  2 ++
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c
index a38464b..c09358c 100644
--- a/hw/cpu/a9mpcore.c
+++ b/hw/cpu/a9mpcore.c
@@ -30,6 +30,9 @@ static void a9mp_priv_initfn(Object *obj)
     object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC);
     qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default());
 
+    object_initialize(&s->gtimer, sizeof(s->gtimer), TYPE_A9_GTIMER);
+    qdev_set_parent_bus(DEVICE(&s->gtimer), sysbus_get_default());
+
     object_initialize(&s->mptimer, sizeof(s->mptimer), TYPE_ARM_MPTIMER);
     qdev_set_parent_bus(DEVICE(&s->mptimer), sysbus_get_default());
 
@@ -41,8 +44,9 @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
 {
     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
     A9MPPrivState *s = A9MPCORE_PRIV(dev);
-    DeviceState *scudev, *gicdev, *mptimerdev, *wdtdev;
-    SysBusDevice *scubusdev, *gicbusdev, *mptimerbusdev, *wdtbusdev;
+    DeviceState *scudev, *gicdev, *gtimerdev, *mptimerdev, *wdtdev;
+    SysBusDevice *scubusdev, *gicbusdev, *gtimerbusdev, *mptimerbusdev,
+                 *wdtbusdev;
     Error *err = NULL;
     int i;
 
@@ -71,6 +75,15 @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
     /* Pass through inbound GPIO lines to the GIC */
     qdev_init_gpio_in(dev, a9mp_priv_set_irq, s->num_irq - 32);
 
+    gtimerdev = DEVICE(&s->gtimer);
+    qdev_prop_set_uint32(gtimerdev, "num-cpu", s->num_cpu);
+    object_property_set_bool(OBJECT(&s->gtimer), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+    gtimerbusdev = SYS_BUS_DEVICE(&s->gtimer);
+
     mptimerdev = DEVICE(&s->mptimer);
     qdev_prop_set_uint32(mptimerdev, "num-cpu", s->num_cpu);
     object_property_set_bool(OBJECT(&s->mptimer), true, "realized", &err);
@@ -97,14 +110,14 @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
      *  0x0600-0x06ff -- private timers and watchdogs
      *  0x0700-0x0fff -- nothing
      *  0x1000-0x1fff -- GIC Distributor
-     *
-     * We should implement the global timer but don't currently do so.
      */
     memory_region_add_subregion(&s->container, 0,
                                 sysbus_mmio_get_region(scubusdev, 0));
     /* GIC CPU interface */
     memory_region_add_subregion(&s->container, 0x100,
                                 sysbus_mmio_get_region(gicbusdev, 1));
+    memory_region_add_subregion(&s->container, 0x200,
+                                sysbus_mmio_get_region(gtimerbusdev, 0));
     /* Note that the A9 exposes only the "timer/watchdog for this core"
      * memory region, not the "timer/watchdog for core X" ones 11MPcore has.
      */
@@ -116,10 +129,13 @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
                                 sysbus_mmio_get_region(gicbusdev, 0));
 
     /* Wire up the interrupt from each watchdog and timer.
-     * For each core the timer is PPI 29 and the watchdog PPI 30.
+     * For each core the global timer is PPI 27, the private
+     * timer is PPI 29 and the watchdog PPI 30.
      */
     for (i = 0; i < s->num_cpu; i++) {
         int ppibase = (s->num_irq - 32) + i * 32;
+        sysbus_connect_irq(gtimerbusdev, i,
+                           qdev_get_gpio_in(gicdev, ppibase + 27));
         sysbus_connect_irq(mptimerbusdev, i,
                            qdev_get_gpio_in(gicdev, ppibase + 29));
         sysbus_connect_irq(wdtbusdev, i,
diff --git a/include/hw/cpu/a9mpcore.h b/include/hw/cpu/a9mpcore.h
index 8eece07..5d67ca2 100644
--- a/include/hw/cpu/a9mpcore.h
+++ b/include/hw/cpu/a9mpcore.h
@@ -14,6 +14,7 @@
 #include "hw/intc/arm_gic.h"
 #include "hw/misc/a9scu.h"
 #include "hw/timer/arm_mptimer.h"
+#include "hw/timer/a9gtimer.h"
 
 #define TYPE_A9MPCORE_PRIV "a9mpcore_priv"
 #define A9MPCORE_PRIV(obj) \
@@ -30,6 +31,7 @@ typedef struct A9MPPrivState {
 
     A9SCUState scu;
     GICState gic;
+    A9GTimerState gtimer;
     ARMMPTimerState mptimer;
     ARMMPTimerState wdt;
 } A9MPPrivState;
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 06/37] target-arm: Provide mechanism for getting KVM constants even if not CONFIG_KVM
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (4 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 05/37] cpu/a9mpcore: Add " Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 07/37] device_tree.c: Terminate the empty reservemap in create_device_tree() Peter Maydell
                   ` (30 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

There are a number of places where it would be convenient for ARM
code to have working definitions of KVM constants even in code
which is compiled with CONFIG_KVM not set. In this situation we
can't simply include the kernel KVM headers (which might conflict
with host header definitions or not even compile on the compiler
we're using) so we have to redefine equivalent constants.
Provide a mechanism for doing this and checking that the values
match, and use it for the constants we're currently exposing
via an ad-hoc mechanism.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1385140638-10444-2-git-send-email-peter.maydell@linaro.org
---
 target-arm/cpu.h        | 13 ++-----------
 target-arm/kvm-consts.h | 41 +++++++++++++++++++++++++++++++++++++++++
 target-arm/kvm.c        |  9 ---------
 3 files changed, 43 insertions(+), 20 deletions(-)
 create mode 100644 target-arm/kvm-consts.h

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 9f110f1..c3f007f 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -21,6 +21,8 @@
 
 #include "config.h"
 
+#include "kvm-consts.h"
+
 #if defined(TARGET_AARCH64)
   /* AArch64 definitions */
 #  define TARGET_LONG_BITS 64
@@ -497,17 +499,6 @@ void armv7m_nvic_complete_irq(void *opaque, int irq);
     (((cp) << 16) | ((is64) << 15) | ((crn) << 11) |    \
      ((crm) << 7) | ((opc1) << 3) | (opc2))
 
-/* Note that these must line up with the KVM/ARM register
- * ID field definitions (kvm.c will check this, but we
- * can't just use the KVM defines here as the kvm headers
- * are unavailable to non-KVM-specific files)
- */
-#define CP_REG_SIZE_SHIFT 52
-#define CP_REG_SIZE_MASK       0x00f0000000000000ULL
-#define CP_REG_SIZE_U32        0x0020000000000000ULL
-#define CP_REG_SIZE_U64        0x0030000000000000ULL
-#define CP_REG_ARM             0x4000000000000000ULL
-
 /* Convert a full 64 bit KVM register ID to the truncated 32 bit
  * version used as a key for the coprocessor register hashtable
  */
diff --git a/target-arm/kvm-consts.h b/target-arm/kvm-consts.h
new file mode 100644
index 0000000..6f56f72
--- /dev/null
+++ b/target-arm/kvm-consts.h
@@ -0,0 +1,41 @@
+/*
+ * KVM ARM ABI constant definitions
+ *
+ * Copyright (c) 2013 Linaro Limited
+ *
+ * Provide versions of KVM constant defines that can be used even
+ * when CONFIG_KVM is not set and we don't have access to the
+ * KVM headers. If CONFIG_KVM is set, we do a compile-time check
+ * that we haven't got out of sync somehow.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef ARM_KVM_CONSTS_H
+#define ARM_KVM_CONSTS_H
+
+#ifdef CONFIG_KVM
+#include "qemu/compiler.h"
+#include <linux/kvm.h>
+
+#define MISMATCH_CHECK(X, Y) QEMU_BUILD_BUG_ON(X != Y)
+
+#else
+#define MISMATCH_CHECK(X, Y)
+#endif
+
+#define CP_REG_SIZE_SHIFT 52
+#define CP_REG_SIZE_MASK       0x00f0000000000000ULL
+#define CP_REG_SIZE_U32        0x0020000000000000ULL
+#define CP_REG_SIZE_U64        0x0030000000000000ULL
+#define CP_REG_ARM             0x4000000000000000ULL
+
+MISMATCH_CHECK(CP_REG_SIZE_SHIFT, KVM_REG_SIZE_SHIFT)
+MISMATCH_CHECK(CP_REG_SIZE_MASK, KVM_REG_SIZE_MASK)
+MISMATCH_CHECK(CP_REG_SIZE_U32, KVM_REG_SIZE_U32)
+MISMATCH_CHECK(CP_REG_SIZE_U64, KVM_REG_SIZE_U64)
+MISMATCH_CHECK(CP_REG_ARM, KVM_REG_ARM)
+
+#undef MISMATCH_CHECK
+
+#endif
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 6e5cd36..3098456 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -23,15 +23,6 @@
 #include "cpu.h"
 #include "hw/arm/arm.h"
 
-/* Check that cpu.h's idea of coprocessor fields matches KVM's */
-#if (CP_REG_SIZE_SHIFT != KVM_REG_SIZE_SHIFT) || \
-    (CP_REG_SIZE_MASK != KVM_REG_SIZE_MASK) ||   \
-    (CP_REG_SIZE_U32 != KVM_REG_SIZE_U32) || \
-    (CP_REG_SIZE_U64 != KVM_REG_SIZE_U64) || \
-    (CP_REG_ARM != KVM_REG_ARM)
-#error mismatch between cpu.h and KVM header definitions
-#endif
-
 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
     KVM_CAP_LAST_INFO
 };
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 07/37] device_tree.c: Terminate the empty reservemap in create_device_tree()
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (5 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 06/37] target-arm: Provide mechanism for getting KVM constants even if not CONFIG_KVM Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 08/37] hw/arm/boot: Allow boards to provide an fdt blob Peter Maydell
                   ` (29 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

Device trees created with create_device_tree() may not have any
entries in their reservemap, because the FDT API requires that the
reservemap is completed before any FDT nodes are added, and
create_device_tree() itself creates a node.  However we were not
calling fdt_finish_reservemap(), which meant that there was no
terminator in the reservemap list and whatever happened to be at the
start of the FDT data section would end up being interpreted as
reservemap entries.  Avoid this by calling fdt_finish_reservemap()
to add the terminator.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Acked-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: 1385140638-10444-3-git-send-email-peter.maydell@linaro.org
---
 device_tree.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/device_tree.c b/device_tree.c
index ffec99a..391da8c 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -41,6 +41,10 @@ void *create_device_tree(int *sizep)
     if (ret < 0) {
         goto fail;
     }
+    ret = fdt_finish_reservemap(fdt);
+    if (ret < 0) {
+        goto fail;
+    }
     ret = fdt_begin_node(fdt, "");
     if (ret < 0) {
         goto fail;
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 08/37] hw/arm/boot: Allow boards to provide an fdt blob
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (6 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 07/37] device_tree.c: Terminate the empty reservemap in create_device_tree() Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 09/37] target-arm: Provide PSCI constants to generic QEMU code Peter Maydell
                   ` (28 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: John Rigby <john.rigby@linaro.org>

If no fdt is provided on command line and the new field
get_dtb in struct arm_boot_info is set then call it to
get a device tree blob.

Signed-off-by: John Rigby <john.rigby@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1385140638-10444-4-git-send-email-peter.maydell@linaro.org
[PMM: minor tweaks and cleanup]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/boot.c        | 32 ++++++++++++++++++++------------
 include/hw/arm/arm.h |  7 +++++++
 2 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 583ec79..55d552f 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -228,23 +228,31 @@ static void set_kernel_args_old(const struct arm_boot_info *info)
 static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
 {
     void *fdt = NULL;
-    char *filename;
     int size, rc;
     uint32_t acells, scells;
 
-    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, binfo->dtb_filename);
-    if (!filename) {
-        fprintf(stderr, "Couldn't open dtb file %s\n", binfo->dtb_filename);
-        goto fail;
-    }
+    if (binfo->dtb_filename) {
+        char *filename;
+        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, binfo->dtb_filename);
+        if (!filename) {
+            fprintf(stderr, "Couldn't open dtb file %s\n", binfo->dtb_filename);
+            goto fail;
+        }
 
-    fdt = load_device_tree(filename, &size);
-    if (!fdt) {
-        fprintf(stderr, "Couldn't open dtb file %s\n", filename);
+        fdt = load_device_tree(filename, &size);
+        if (!fdt) {
+            fprintf(stderr, "Couldn't open dtb file %s\n", filename);
+            g_free(filename);
+            goto fail;
+        }
         g_free(filename);
-        goto fail;
+    } else if (binfo->get_dtb) {
+        fdt = binfo->get_dtb(binfo, &size);
+        if (!fdt) {
+            fprintf(stderr, "Board was unable to create a dtb blob\n");
+            goto fail;
+        }
     }
-    g_free(filename);
 
     acells = qemu_devtree_getprop_cell(fdt, "/", "#address-cells");
     scells = qemu_devtree_getprop_cell(fdt, "/", "#size-cells");
@@ -438,7 +446,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
         /* for device tree boot, we pass the DTB directly in r2. Otherwise
          * we point to the kernel args.
          */
-        if (info->dtb_filename) {
+        if (info->dtb_filename || info->get_dtb) {
             /* Place the DTB after the initrd in memory. Note that some
              * kernels will trash anything in the 4K page the initrd
              * ends in, so make sure the DTB isn't caught up in that.
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index ecbbba8..cbbf4ca 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -50,6 +50,13 @@ struct arm_boot_info {
                                  const struct arm_boot_info *info);
     void (*secondary_cpu_reset_hook)(ARMCPU *cpu,
                                      const struct arm_boot_info *info);
+    /* if a board is able to create a dtb without a dtb file then it
+     * sets get_dtb. This will only be used if no dtb file is provided
+     * by the user. On success, sets *size to the length of the created
+     * dtb, and returns a pointer to it. (The caller must free this memory
+     * with g_free() when it has finished with it.) On failure, returns NULL.
+     */
+    void *(*get_dtb)(const struct arm_boot_info *info, int *size);
     /* if a board needs to be able to modify a device tree provided by
      * the user it should implement this hook.
      */
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 09/37] target-arm: Provide PSCI constants to generic QEMU code
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (7 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 08/37] hw/arm/boot: Allow boards to provide an fdt blob Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 10/37] target-arm: Add ARMCPU field for Linux device-tree 'compatible' string Peter Maydell
                   ` (27 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

Provide versions of the KVM PSCI constants to non-KVM code;
this will allow us to avoid an ifdef in boards which set up
a PSCI node in the device tree.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1385140638-10444-5-git-send-email-peter.maydell@linaro.org
---
 target-arm/kvm-consts.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/target-arm/kvm-consts.h b/target-arm/kvm-consts.h
index 6f56f72..4062f11 100644
--- a/target-arm/kvm-consts.h
+++ b/target-arm/kvm-consts.h
@@ -36,6 +36,18 @@ MISMATCH_CHECK(CP_REG_SIZE_U32, KVM_REG_SIZE_U32)
 MISMATCH_CHECK(CP_REG_SIZE_U64, KVM_REG_SIZE_U64)
 MISMATCH_CHECK(CP_REG_ARM, KVM_REG_ARM)
 
+#define PSCI_FN_BASE 0x95c1ba5e
+#define PSCI_FN(n) (PSCI_FN_BASE + (n))
+#define PSCI_FN_CPU_SUSPEND PSCI_FN(0)
+#define PSCI_FN_CPU_OFF PSCI_FN(1)
+#define PSCI_FN_CPU_ON PSCI_FN(2)
+#define PSCI_FN_MIGRATE PSCI_FN(3)
+
+MISMATCH_CHECK(PSCI_FN_CPU_SUSPEND, KVM_PSCI_FN_CPU_SUSPEND)
+MISMATCH_CHECK(PSCI_FN_CPU_OFF, KVM_PSCI_FN_CPU_OFF)
+MISMATCH_CHECK(PSCI_FN_CPU_ON, KVM_PSCI_FN_CPU_ON)
+MISMATCH_CHECK(PSCI_FN_MIGRATE, KVM_PSCI_FN_MIGRATE)
+
 #undef MISMATCH_CHECK
 
 #endif
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 10/37] target-arm: Add ARMCPU field for Linux device-tree 'compatible' string
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (8 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 09/37] target-arm: Provide PSCI constants to generic QEMU code Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 11/37] target-arm: Allow secondary KVM CPUs to be booted via PSCI Peter Maydell
                   ` (26 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

Linux requires device tree CPU nodes to include a 'compatible'
string describing the CPU. Add a field in the ARMCPU struct for
this so that boards which construct a device tree can insert
the correct CPU nodes.

Note that there is currently no officially specified 'compatible'
string for the TI925T, Cortex-M3 or SA1110 CPUs.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1385140638-10444-6-git-send-email-peter.maydell@linaro.org
---
 target-arm/cpu-qom.h |  3 +++
 target-arm/cpu.c     | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index b55306a..cbb9eec 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -91,6 +91,9 @@ typedef struct ARMCPU {
     /* GPIO outputs for generic timer */
     qemu_irq gt_timer_outputs[NUM_GTIMERS];
 
+    /* 'compatible' string for this CPU for Linux device trees */
+    const char *dtb_compatible;
+
     /* The instance init functions for implementation-specific subclasses
      * set these fields to specify the implementation-dependent values of
      * various constant registers and reset values of non-constant
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index d40f2a7..4c8d9c7 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -217,6 +217,12 @@ static void arm_cpu_initfn(Object *obj)
                        ARRAY_SIZE(cpu->gt_timer_outputs));
 #endif
 
+    /* DTB consumers generally don't in fact care what the 'compatible'
+     * string is, so always provide some string and trust that a hypothetical
+     * picky DTB consumer will also provide a helpful error message.
+     */
+    cpu->dtb_compatible = "qemu,unknown";
+
     if (tcg_enabled() && !inited) {
         inited = true;
         arm_translate_init();
@@ -318,6 +324,8 @@ static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
 static void arm926_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "arm,arm926";
     set_feature(&cpu->env, ARM_FEATURE_V5);
     set_feature(&cpu->env, ARM_FEATURE_VFP);
     set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
@@ -331,6 +339,8 @@ static void arm926_initfn(Object *obj)
 static void arm946_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "arm,arm946";
     set_feature(&cpu->env, ARM_FEATURE_V5);
     set_feature(&cpu->env, ARM_FEATURE_MPU);
     set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
@@ -342,6 +352,8 @@ static void arm946_initfn(Object *obj)
 static void arm1026_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "arm,arm1026";
     set_feature(&cpu->env, ARM_FEATURE_V5);
     set_feature(&cpu->env, ARM_FEATURE_VFP);
     set_feature(&cpu->env, ARM_FEATURE_AUXCR);
@@ -374,6 +386,8 @@ static void arm1136_r2_initfn(Object *obj)
      * for 1136_r2 (in particular r0p2 does not actually implement most
      * of the ID registers).
      */
+
+    cpu->dtb_compatible = "arm,arm1136";
     set_feature(&cpu->env, ARM_FEATURE_V6);
     set_feature(&cpu->env, ARM_FEATURE_VFP);
     set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
@@ -403,6 +417,8 @@ static void arm1136_r2_initfn(Object *obj)
 static void arm1136_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "arm,arm1136";
     set_feature(&cpu->env, ARM_FEATURE_V6K);
     set_feature(&cpu->env, ARM_FEATURE_V6);
     set_feature(&cpu->env, ARM_FEATURE_VFP);
@@ -433,6 +449,8 @@ static void arm1136_initfn(Object *obj)
 static void arm1176_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "arm,arm1176";
     set_feature(&cpu->env, ARM_FEATURE_V6K);
     set_feature(&cpu->env, ARM_FEATURE_VFP);
     set_feature(&cpu->env, ARM_FEATURE_VAPA);
@@ -463,6 +481,8 @@ static void arm1176_initfn(Object *obj)
 static void arm11mpcore_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "arm,arm11mpcore";
     set_feature(&cpu->env, ARM_FEATURE_V6K);
     set_feature(&cpu->env, ARM_FEATURE_VFP);
     set_feature(&cpu->env, ARM_FEATURE_VAPA);
@@ -516,6 +536,8 @@ static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
 static void cortex_a8_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "arm,cortex-a8";
     set_feature(&cpu->env, ARM_FEATURE_V7);
     set_feature(&cpu->env, ARM_FEATURE_VFP3);
     set_feature(&cpu->env, ARM_FEATURE_NEON);
@@ -580,6 +602,8 @@ static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
 static void cortex_a9_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "arm,cortex-a9";
     set_feature(&cpu->env, ARM_FEATURE_V7);
     set_feature(&cpu->env, ARM_FEATURE_VFP3);
     set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
@@ -649,6 +673,8 @@ static const ARMCPRegInfo cortexa15_cp_reginfo[] = {
 static void cortex_a15_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "arm,cortex-a15";
     set_feature(&cpu->env, ARM_FEATURE_V7);
     set_feature(&cpu->env, ARM_FEATURE_VFP4);
     set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
@@ -697,6 +723,8 @@ static void ti925t_initfn(Object *obj)
 static void sa1100_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "intel,sa1100";
     set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
     set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
     cpu->midr = 0x4401A11B;
@@ -715,6 +743,8 @@ static void sa1110_initfn(Object *obj)
 static void pxa250_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "marvell,xscale";
     set_feature(&cpu->env, ARM_FEATURE_V5);
     set_feature(&cpu->env, ARM_FEATURE_XSCALE);
     cpu->midr = 0x69052100;
@@ -725,6 +755,8 @@ static void pxa250_initfn(Object *obj)
 static void pxa255_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "marvell,xscale";
     set_feature(&cpu->env, ARM_FEATURE_V5);
     set_feature(&cpu->env, ARM_FEATURE_XSCALE);
     cpu->midr = 0x69052d00;
@@ -735,6 +767,8 @@ static void pxa255_initfn(Object *obj)
 static void pxa260_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "marvell,xscale";
     set_feature(&cpu->env, ARM_FEATURE_V5);
     set_feature(&cpu->env, ARM_FEATURE_XSCALE);
     cpu->midr = 0x69052903;
@@ -745,6 +779,8 @@ static void pxa260_initfn(Object *obj)
 static void pxa261_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "marvell,xscale";
     set_feature(&cpu->env, ARM_FEATURE_V5);
     set_feature(&cpu->env, ARM_FEATURE_XSCALE);
     cpu->midr = 0x69052d05;
@@ -755,6 +791,8 @@ static void pxa261_initfn(Object *obj)
 static void pxa262_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "marvell,xscale";
     set_feature(&cpu->env, ARM_FEATURE_V5);
     set_feature(&cpu->env, ARM_FEATURE_XSCALE);
     cpu->midr = 0x69052d06;
@@ -765,6 +803,8 @@ static void pxa262_initfn(Object *obj)
 static void pxa270a0_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "marvell,xscale";
     set_feature(&cpu->env, ARM_FEATURE_V5);
     set_feature(&cpu->env, ARM_FEATURE_XSCALE);
     set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
@@ -776,6 +816,8 @@ static void pxa270a0_initfn(Object *obj)
 static void pxa270a1_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "marvell,xscale";
     set_feature(&cpu->env, ARM_FEATURE_V5);
     set_feature(&cpu->env, ARM_FEATURE_XSCALE);
     set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
@@ -787,6 +829,8 @@ static void pxa270a1_initfn(Object *obj)
 static void pxa270b0_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "marvell,xscale";
     set_feature(&cpu->env, ARM_FEATURE_V5);
     set_feature(&cpu->env, ARM_FEATURE_XSCALE);
     set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
@@ -798,6 +842,8 @@ static void pxa270b0_initfn(Object *obj)
 static void pxa270b1_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "marvell,xscale";
     set_feature(&cpu->env, ARM_FEATURE_V5);
     set_feature(&cpu->env, ARM_FEATURE_XSCALE);
     set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
@@ -809,6 +855,8 @@ static void pxa270b1_initfn(Object *obj)
 static void pxa270c0_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "marvell,xscale";
     set_feature(&cpu->env, ARM_FEATURE_V5);
     set_feature(&cpu->env, ARM_FEATURE_XSCALE);
     set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
@@ -820,6 +868,8 @@ static void pxa270c0_initfn(Object *obj)
 static void pxa270c5_initfn(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
+
+    cpu->dtb_compatible = "marvell,xscale";
     set_feature(&cpu->env, ARM_FEATURE_V5);
     set_feature(&cpu->env, ARM_FEATURE_XSCALE);
     set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 11/37] target-arm: Allow secondary KVM CPUs to be booted via PSCI
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (9 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 10/37] target-arm: Add ARMCPU field for Linux device-tree 'compatible' string Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 12/37] hw/arm: Add 'virt' platform Peter Maydell
                   ` (25 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

New ARM boards are generally expected to boot their secondary CPUs
via the PSCI interface, rather than ad-hoc "loop around in holding
pen code" as hw/arm/boot.c implements. In particular this is
necessary for mach-virt kernels. For KVM we achieve this by creating
the VCPUs with a feature flag marking them as starting in PSCI
powered-down state; the guest kernel will then make a PSCI call
(implemented in the host kernel) to start the secondaries at
an address of its choosing once it has got the primary CPU up.

Implement this setting of the feature flag, controlled by a
qdev property for ARMCPU, which board code can set if it is a
PSCI system.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1385140638-10444-7-git-send-email-peter.maydell@linaro.org
---
 target-arm/cpu-qom.h | 3 +++
 target-arm/cpu.c     | 7 +++++++
 target-arm/kvm.c     | 3 +++
 3 files changed, 13 insertions(+)

diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index cbb9eec..8bd3e36 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -94,6 +94,9 @@ typedef struct ARMCPU {
     /* 'compatible' string for this CPU for Linux device trees */
     const char *dtb_compatible;
 
+    /* Should CPU start in PSCI powered-off state? */
+    bool start_powered_off;
+
     /* The instance init functions for implementation-specific subclasses
      * set these fields to specify the implementation-dependent values of
      * various constant registers and reset values of non-constant
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 4c8d9c7..0325815 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -20,6 +20,7 @@
 
 #include "cpu.h"
 #include "qemu-common.h"
+#include "hw/qdev-properties.h"
 #if !defined(CONFIG_USER_ONLY)
 #include "hw/loader.h"
 #endif
@@ -944,6 +945,11 @@ static const ARMCPUInfo arm_cpus[] = {
 #endif
 };
 
+static Property arm_cpu_properties[] = {
+    DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
+    DEFINE_PROP_END_OF_LIST()
+};
+
 static void arm_cpu_class_init(ObjectClass *oc, void *data)
 {
     ARMCPUClass *acc = ARM_CPU_CLASS(oc);
@@ -952,6 +958,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
 
     acc->parent_realize = dc->realize;
     dc->realize = arm_cpu_realizefn;
+    dc->props = arm_cpu_properties;
 
     acc->parent_reset = cc->reset;
     cc->reset = arm_cpu_reset;
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 3098456..80c58c5 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -79,6 +79,9 @@ int kvm_arch_init_vcpu(CPUState *cs)
 
     init.target = KVM_ARM_TARGET_CORTEX_A15;
     memset(init.features, 0, sizeof(init.features));
+    if (cpu->start_powered_off) {
+        init.features[0] = 1 << KVM_ARM_VCPU_POWER_OFF;
+    }
     ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
     if (ret) {
         return ret;
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 12/37] hw/arm: Add 'virt' platform
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (10 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 11/37] target-arm: Allow secondary KVM CPUs to be booted via PSCI Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 13/37] target-arm: Don't hardcode KVM target CPU to be A15 Peter Maydell
                   ` (24 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

Add 'virt' platform support corresponding to arch/arm/mach-virt
in the Linux kernel tree. This has no platform-specific code but
can use any device whose kernel driver is is able to work purely
from a device tree node. We use this to instantiate a minimal
set of devices: a GIC and some virtio-mmio transports.

Signed-off-by: John Rigby <john.rigby@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1385140638-10444-8-git-send-email-peter.maydell@linaro.org
[PMM:
 Significantly overhauled:
 * renamed user-facing machine to just "virt"
 * removed the A9 support (it can't work since the A9 has no
   generic timers)
 * added virtio-mmio transports instead of random set of 'soc' devices
   (though we retain a pl011 UART)
 * instead of updating io_base as we step through adding devices,
   define a memory map with an array (similar to vexpress)
 * similarly, define irqmap with an array
 * folded in some minor fixes from John's aarch64-support patch
 * rather than explicitly doing endian-swapping on FDT cells,
   use fdt APIs that let us just pass in host-endian values
   and let the fdt layer take care of the swapping
 * miscellaneous minor code cleanups and style fixes
]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/Makefile.objs |   2 +-
 hw/arm/virt.c        | 444 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 445 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/virt.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 3671b42..78b5614 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -1,7 +1,7 @@
 obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
 obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
 obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
-obj-y += tosa.o versatilepb.o vexpress.o xilinx_zynq.o z2.o
+obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
 obj-y += omap1.o omap2.o strongarm.o
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
new file mode 100644
index 0000000..1e42cc2
--- /dev/null
+++ b/hw/arm/virt.c
@@ -0,0 +1,444 @@
+/*
+ * ARM mach-virt emulation
+ *
+ * Copyright (c) 2013 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Emulate a virtual board which works by passing Linux all the information
+ * it needs about what devices are present via the device tree.
+ * There are some restrictions about what we can do here:
+ *  + we can only present devices whose Linux drivers will work based
+ *    purely on the device tree with no platform data at all
+ *  + we want to present a very stripped-down minimalist platform,
+ *    both because this reduces the security attack surface from the guest
+ *    and also because it reduces our exposure to being broken when
+ *    the kernel updates its device tree bindings and requires further
+ *    information in a device binding that we aren't providing.
+ * This is essentially the same approach kvmtool uses.
+ */
+
+#include "hw/sysbus.h"
+#include "hw/arm/arm.h"
+#include "hw/arm/primecell.h"
+#include "hw/devices.h"
+#include "net/net.h"
+#include "sysemu/device_tree.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/kvm.h"
+#include "hw/boards.h"
+#include "exec/address-spaces.h"
+#include "qemu/bitops.h"
+#include "qemu/error-report.h"
+
+#define NUM_VIRTIO_TRANSPORTS 32
+
+/* Number of external interrupt lines to configure the GIC with */
+#define NUM_IRQS 128
+
+#define GIC_FDT_IRQ_TYPE_SPI 0
+#define GIC_FDT_IRQ_TYPE_PPI 1
+
+#define GIC_FDT_IRQ_FLAGS_EDGE_LO_HI 1
+#define GIC_FDT_IRQ_FLAGS_EDGE_HI_LO 2
+#define GIC_FDT_IRQ_FLAGS_LEVEL_HI 4
+#define GIC_FDT_IRQ_FLAGS_LEVEL_LO 8
+
+#define GIC_FDT_IRQ_PPI_CPU_START 8
+#define GIC_FDT_IRQ_PPI_CPU_WIDTH 8
+
+enum {
+    VIRT_FLASH,
+    VIRT_MEM,
+    VIRT_CPUPERIPHS,
+    VIRT_GIC_DIST,
+    VIRT_GIC_CPU,
+    VIRT_UART,
+    VIRT_MMIO,
+};
+
+typedef struct MemMapEntry {
+    hwaddr base;
+    hwaddr size;
+} MemMapEntry;
+
+typedef struct VirtBoardInfo {
+    struct arm_boot_info bootinfo;
+    const char *cpu_model;
+    const char *qdevname;
+    const char *gic_compatible;
+    const MemMapEntry *memmap;
+    const int *irqmap;
+    int smp_cpus;
+    void *fdt;
+    int fdt_size;
+    uint32_t clock_phandle;
+} VirtBoardInfo;
+
+/* Addresses and sizes of our components.
+ * 0..128MB is space for a flash device so we can run bootrom code such as UEFI.
+ * 128MB..256MB is used for miscellaneous device I/O.
+ * 256MB..1GB is reserved for possible future PCI support (ie where the
+ * PCI memory window will go if we add a PCI host controller).
+ * 1GB and up is RAM (which may happily spill over into the
+ * high memory region beyond 4GB).
+ * This represents a compromise between how much RAM can be given to
+ * a 32 bit VM and leaving space for expansion and in particular for PCI.
+ */
+static const MemMapEntry a15memmap[] = {
+    /* Space up to 0x8000000 is reserved for a boot ROM */
+    [VIRT_FLASH] = { 0, 0x8000000 },
+    [VIRT_CPUPERIPHS] = { 0x8000000, 0x8000 },
+    /* GIC distributor and CPU interfaces sit inside the CPU peripheral space */
+    [VIRT_GIC_DIST] = { 0x8001000, 0x1000 },
+    [VIRT_GIC_CPU] = { 0x8002000, 0x1000 },
+    [VIRT_UART] = { 0x9000000, 0x1000 },
+    [VIRT_MMIO] = { 0xa000000, 0x200 },
+    /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
+    /* 0x10000000 .. 0x40000000 reserved for PCI */
+    [VIRT_MEM] = { 0x40000000, 30ULL * 1024 * 1024 * 1024 },
+};
+
+static const int a15irqmap[] = {
+    [VIRT_UART] = 1,
+    [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
+};
+
+static VirtBoardInfo machines[] = {
+    {
+        .cpu_model = "cortex-a15",
+        .qdevname = "a15mpcore_priv",
+        .gic_compatible = "arm,cortex-a15-gic",
+        .memmap = a15memmap,
+        .irqmap = a15irqmap,
+    },
+};
+
+static VirtBoardInfo *find_machine_info(const char *cpu)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(machines); i++) {
+        if (strcmp(cpu, machines[i].cpu_model) == 0) {
+            return &machines[i];
+        }
+    }
+    return NULL;
+}
+
+static void create_fdt(VirtBoardInfo *vbi)
+{
+    void *fdt = create_device_tree(&vbi->fdt_size);
+
+    if (!fdt) {
+        error_report("create_device_tree() failed");
+        exit(1);
+    }
+
+    vbi->fdt = fdt;
+
+    /* Header */
+    qemu_devtree_setprop_string(fdt, "/", "compatible", "linux,dummy-virt");
+    qemu_devtree_setprop_cell(fdt, "/", "#address-cells", 0x2);
+    qemu_devtree_setprop_cell(fdt, "/", "#size-cells", 0x2);
+
+    /*
+     * /chosen and /memory nodes must exist for load_dtb
+     * to fill in necessary properties later
+     */
+    qemu_devtree_add_subnode(fdt, "/chosen");
+    qemu_devtree_add_subnode(fdt, "/memory");
+    qemu_devtree_setprop_string(fdt, "/memory", "device_type", "memory");
+
+    /* Clock node, for the benefit of the UART. The kernel device tree
+     * binding documentation claims the PL011 node clock properties are
+     * optional but in practice if you omit them the kernel refuses to
+     * probe for the device.
+     */
+    vbi->clock_phandle = qemu_devtree_alloc_phandle(fdt);
+    qemu_devtree_add_subnode(fdt, "/apb-pclk");
+    qemu_devtree_setprop_string(fdt, "/apb-pclk", "compatible", "fixed-clock");
+    qemu_devtree_setprop_cell(fdt, "/apb-pclk", "#clock-cells", 0x0);
+    qemu_devtree_setprop_cell(fdt, "/apb-pclk", "clock-frequency", 24000000);
+    qemu_devtree_setprop_string(fdt, "/apb-pclk", "clock-output-names",
+                                "clk24mhz");
+    qemu_devtree_setprop_cell(fdt, "/apb-pclk", "phandle", vbi->clock_phandle);
+
+    /* No PSCI for TCG yet */
+    if (kvm_enabled()) {
+        qemu_devtree_add_subnode(fdt, "/psci");
+        qemu_devtree_setprop_string(fdt, "/psci", "compatible", "arm,psci");
+        qemu_devtree_setprop_string(fdt, "/psci", "method", "hvc");
+        qemu_devtree_setprop_cell(fdt, "/psci", "cpu_suspend",
+                                  PSCI_FN_CPU_SUSPEND);
+        qemu_devtree_setprop_cell(fdt, "/psci", "cpu_off", PSCI_FN_CPU_OFF);
+        qemu_devtree_setprop_cell(fdt, "/psci", "cpu_on", PSCI_FN_CPU_ON);
+        qemu_devtree_setprop_cell(fdt, "/psci", "migrate", PSCI_FN_MIGRATE);
+    }
+}
+
+static void fdt_add_timer_nodes(const VirtBoardInfo *vbi)
+{
+    /* Note that on A15 h/w these interrupts are level-triggered,
+     * but for the GIC implementation provided by both QEMU and KVM
+     * they are edge-triggered.
+     */
+    uint32_t irqflags = GIC_FDT_IRQ_FLAGS_EDGE_LO_HI;
+
+    irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
+                         GIC_FDT_IRQ_PPI_CPU_WIDTH, (1 << vbi->smp_cpus) - 1);
+
+    qemu_devtree_add_subnode(vbi->fdt, "/timer");
+    qemu_devtree_setprop_string(vbi->fdt, "/timer",
+                                "compatible", "arm,armv7-timer");
+    qemu_devtree_setprop_cells(vbi->fdt, "/timer", "interrupts",
+                               GIC_FDT_IRQ_TYPE_PPI, 13, irqflags,
+                               GIC_FDT_IRQ_TYPE_PPI, 14, irqflags,
+                               GIC_FDT_IRQ_TYPE_PPI, 11, irqflags,
+                               GIC_FDT_IRQ_TYPE_PPI, 10, irqflags);
+}
+
+static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
+{
+    int cpu;
+
+    qemu_devtree_add_subnode(vbi->fdt, "/cpus");
+    qemu_devtree_setprop_cell(vbi->fdt, "/cpus", "#address-cells", 0x1);
+    qemu_devtree_setprop_cell(vbi->fdt, "/cpus", "#size-cells", 0x0);
+
+    for (cpu = vbi->smp_cpus - 1; cpu >= 0; cpu--) {
+        char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
+        ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
+
+        qemu_devtree_add_subnode(vbi->fdt, nodename);
+        qemu_devtree_setprop_string(vbi->fdt, nodename, "device_type", "cpu");
+        qemu_devtree_setprop_string(vbi->fdt, nodename, "compatible",
+                                    armcpu->dtb_compatible);
+
+        if (vbi->smp_cpus > 1) {
+            qemu_devtree_setprop_string(vbi->fdt, nodename,
+                                        "enable-method", "psci");
+        }
+
+        qemu_devtree_setprop_cell(vbi->fdt, nodename, "reg", cpu);
+        g_free(nodename);
+    }
+}
+
+static void fdt_add_gic_node(const VirtBoardInfo *vbi)
+{
+    uint32_t gic_phandle;
+
+    gic_phandle = qemu_devtree_alloc_phandle(vbi->fdt);
+    qemu_devtree_setprop_cell(vbi->fdt, "/", "interrupt-parent", gic_phandle);
+
+    qemu_devtree_add_subnode(vbi->fdt, "/intc");
+    qemu_devtree_setprop_string(vbi->fdt, "/intc", "compatible",
+                                vbi->gic_compatible);
+    qemu_devtree_setprop_cell(vbi->fdt, "/intc", "#interrupt-cells", 3);
+    qemu_devtree_setprop(vbi->fdt, "/intc", "interrupt-controller", NULL, 0);
+    qemu_devtree_setprop_sized_cells(vbi->fdt, "/intc", "reg",
+                                     2, vbi->memmap[VIRT_GIC_DIST].base,
+                                     2, vbi->memmap[VIRT_GIC_DIST].size,
+                                     2, vbi->memmap[VIRT_GIC_CPU].base,
+                                     2, vbi->memmap[VIRT_GIC_CPU].size);
+    qemu_devtree_setprop_cell(vbi->fdt, "/intc", "phandle", gic_phandle);
+}
+
+static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic)
+{
+    char *nodename;
+    hwaddr base = vbi->memmap[VIRT_UART].base;
+    hwaddr size = vbi->memmap[VIRT_UART].size;
+    int irq = vbi->irqmap[VIRT_UART];
+    const char compat[] = "arm,pl011\0arm,primecell";
+    const char clocknames[] = "uartclk\0apb_pclk";
+
+    sysbus_create_simple("pl011", base, pic[irq]);
+
+    nodename = g_strdup_printf("/pl011@%" PRIx64, base);
+    qemu_devtree_add_subnode(vbi->fdt, nodename);
+    /* Note that we can't use setprop_string because of the embedded NUL */
+    qemu_devtree_setprop(vbi->fdt, nodename, "compatible",
+                         compat, sizeof(compat));
+    qemu_devtree_setprop_sized_cells(vbi->fdt, nodename, "reg",
+                                     2, base, 2, size);
+    qemu_devtree_setprop_cells(vbi->fdt, nodename, "interrupts",
+                               GIC_FDT_IRQ_TYPE_SPI, irq,
+                               GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
+    qemu_devtree_setprop_cells(vbi->fdt, nodename, "clocks",
+                               vbi->clock_phandle, vbi->clock_phandle);
+    qemu_devtree_setprop(vbi->fdt, nodename, "clock-names",
+                         clocknames, sizeof(clocknames));
+    g_free(nodename);
+}
+
+static void create_virtio_devices(const VirtBoardInfo *vbi, qemu_irq *pic)
+{
+    int i;
+    hwaddr size = vbi->memmap[VIRT_MMIO].size;
+
+    /* Note that we have to create the transports in forwards order
+     * so that command line devices are inserted lowest address first,
+     * and then add dtb nodes in reverse order so that they appear in
+     * the finished device tree lowest address first.
+     */
+    for (i = 0; i < NUM_VIRTIO_TRANSPORTS; i++) {
+        int irq = vbi->irqmap[VIRT_MMIO] + i;
+        hwaddr base = vbi->memmap[VIRT_MMIO].base + i * size;
+
+        sysbus_create_simple("virtio-mmio", base, pic[irq]);
+    }
+
+    for (i = NUM_VIRTIO_TRANSPORTS - 1; i >= 0; i--) {
+        char *nodename;
+        int irq = vbi->irqmap[VIRT_MMIO] + i;
+        hwaddr base = vbi->memmap[VIRT_MMIO].base + i * size;
+
+        nodename = g_strdup_printf("/virtio_mmio@%" PRIx64, base);
+        qemu_devtree_add_subnode(vbi->fdt, nodename);
+        qemu_devtree_setprop_string(vbi->fdt, nodename,
+                                    "compatible", "virtio,mmio");
+        qemu_devtree_setprop_sized_cells(vbi->fdt, nodename, "reg",
+                                         2, base, 2, size);
+        qemu_devtree_setprop_cells(vbi->fdt, nodename, "interrupts",
+                                   GIC_FDT_IRQ_TYPE_SPI, irq,
+                                   GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
+        g_free(nodename);
+    }
+}
+
+static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
+{
+    const VirtBoardInfo *board = (const VirtBoardInfo *)binfo;
+
+    *fdt_size = board->fdt_size;
+    return board->fdt;
+}
+
+static void machvirt_init(QEMUMachineInitArgs *args)
+{
+    qemu_irq pic[NUM_IRQS];
+    MemoryRegion *sysmem = get_system_memory();
+    int n;
+    MemoryRegion *ram = g_new(MemoryRegion, 1);
+    DeviceState *dev;
+    SysBusDevice *busdev;
+    const char *cpu_model = args->cpu_model;
+    VirtBoardInfo *vbi;
+
+    if (!cpu_model) {
+        cpu_model = "cortex-a15";
+    }
+
+    vbi = find_machine_info(cpu_model);
+
+    if (!vbi) {
+        error_report("mach-virt: CPU %s not supported", cpu_model);
+        exit(1);
+    }
+
+    vbi->smp_cpus = smp_cpus;
+
+    /*
+     * Only supported method of starting secondary CPUs is PSCI and
+     * PSCI is not yet supported with TCG, so limit smp_cpus to 1
+     * if we're not using KVM.
+     */
+    if (!kvm_enabled() && smp_cpus > 1) {
+        error_report("mach-virt: must enable KVM to use multiple CPUs");
+        exit(1);
+    }
+
+    if (args->ram_size > vbi->memmap[VIRT_MEM].size) {
+        error_report("mach-virt: cannot model more than 30GB RAM");
+        exit(1);
+    }
+
+    create_fdt(vbi);
+    fdt_add_timer_nodes(vbi);
+
+    for (n = 0; n < smp_cpus; n++) {
+        ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
+        Object *cpuobj;
+
+        if (!oc) {
+            fprintf(stderr, "Unable to find CPU definition\n");
+            exit(1);
+        }
+        cpuobj = object_new(object_class_get_name(oc));
+
+        /* Secondary CPUs start in PSCI powered-down state */
+        if (n > 0) {
+            object_property_set_bool(cpuobj, true, "start-powered-off", NULL);
+        }
+        object_property_set_bool(cpuobj, true, "realized", NULL);
+    }
+    fdt_add_cpu_nodes(vbi);
+
+    memory_region_init_ram(ram, NULL, "mach-virt.ram", args->ram_size);
+    vmstate_register_ram_global(ram);
+    memory_region_add_subregion(sysmem, vbi->memmap[VIRT_MEM].base, ram);
+
+    dev = qdev_create(NULL, vbi->qdevname);
+    qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
+    /* Note that the num-irq property counts both internal and external
+     * interrupts; there are always 32 of the former (mandated by GIC spec).
+     */
+    qdev_prop_set_uint32(dev, "num-irq", NUM_IRQS + 32);
+    qdev_init_nofail(dev);
+    busdev = SYS_BUS_DEVICE(dev);
+    sysbus_mmio_map(busdev, 0, vbi->memmap[VIRT_CPUPERIPHS].base);
+    fdt_add_gic_node(vbi);
+    for (n = 0; n < smp_cpus; n++) {
+        DeviceState *cpudev = DEVICE(qemu_get_cpu(n));
+
+        sysbus_connect_irq(busdev, n, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
+    }
+
+    for (n = 0; n < NUM_IRQS; n++) {
+        pic[n] = qdev_get_gpio_in(dev, n);
+    }
+
+    create_uart(vbi, pic);
+
+    /* Create mmio transports, so the user can create virtio backends
+     * (which will be automatically plugged in to the transports). If
+     * no backend is created the transport will just sit harmlessly idle.
+     */
+    create_virtio_devices(vbi, pic);
+
+    vbi->bootinfo.ram_size = args->ram_size;
+    vbi->bootinfo.kernel_filename = args->kernel_filename;
+    vbi->bootinfo.kernel_cmdline = args->kernel_cmdline;
+    vbi->bootinfo.initrd_filename = args->initrd_filename;
+    vbi->bootinfo.nb_cpus = smp_cpus;
+    vbi->bootinfo.board_id = -1;
+    vbi->bootinfo.loader_start = vbi->memmap[VIRT_MEM].base;
+    vbi->bootinfo.get_dtb = machvirt_dtb;
+    arm_load_kernel(ARM_CPU(first_cpu), &vbi->bootinfo);
+}
+
+static QEMUMachine machvirt_a15_machine = {
+    .name = "virt",
+    .desc = "ARM Virtual Machine",
+    .init = machvirt_init,
+    .max_cpus = 4,
+};
+
+static void machvirt_machine_init(void)
+{
+    qemu_register_machine(&machvirt_a15_machine);
+}
+
+machine_init(machvirt_machine_init);
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 13/37] target-arm: Don't hardcode KVM target CPU to be A15
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (11 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 12/37] hw/arm: Add 'virt' platform Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 14/37] target-arm: Provide '-cpu host' when running KVM Peter Maydell
                   ` (23 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

Instead of assuming that a KVM target CPU must always be a
Cortex-A15 and hardcoding this in kvm_arch_init_vcpu(),
store the KVM_ARM_TARGET_* value in the ARMCPU class,
and use that.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1385140638-10444-10-git-send-email-peter.maydell@linaro.org
---
 target-arm/cpu-qom.h    |  5 +++++
 target-arm/cpu.c        |  2 ++
 target-arm/kvm-consts.h | 11 +++++++++++
 target-arm/kvm.c        |  7 ++++++-
 4 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index 8bd3e36..f32178a 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -97,6 +97,11 @@ typedef struct ARMCPU {
     /* Should CPU start in PSCI powered-off state? */
     bool start_powered_off;
 
+    /* [QEMU_]KVM_ARM_TARGET_* constant for this CPU, or
+     * QEMU_KVM_ARM_TARGET_NONE if the kernel doesn't support this CPU type.
+     */
+    uint32_t kvm_target;
+
     /* The instance init functions for implementation-specific subclasses
      * set these fields to specify the implementation-dependent values of
      * various constant registers and reset values of non-constant
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 0325815..0635e78 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -223,6 +223,7 @@ static void arm_cpu_initfn(Object *obj)
      * picky DTB consumer will also provide a helpful error message.
      */
     cpu->dtb_compatible = "qemu,unknown";
+    cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
 
     if (tcg_enabled() && !inited) {
         inited = true;
@@ -685,6 +686,7 @@ static void cortex_a15_initfn(Object *obj)
     set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
     set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
     set_feature(&cpu->env, ARM_FEATURE_LPAE);
+    cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
     cpu->midr = 0x412fc0f1;
     cpu->reset_fpsid = 0x410430f0;
     cpu->mvfr0 = 0x10110222;
diff --git a/target-arm/kvm-consts.h b/target-arm/kvm-consts.h
index 4062f11..2bba0bd 100644
--- a/target-arm/kvm-consts.h
+++ b/target-arm/kvm-consts.h
@@ -48,6 +48,17 @@ MISMATCH_CHECK(PSCI_FN_CPU_OFF, KVM_PSCI_FN_CPU_OFF)
 MISMATCH_CHECK(PSCI_FN_CPU_ON, KVM_PSCI_FN_CPU_ON)
 MISMATCH_CHECK(PSCI_FN_MIGRATE, KVM_PSCI_FN_MIGRATE)
 
+#define QEMU_KVM_ARM_TARGET_CORTEX_A15 0
+
+/* There's no kernel define for this: sentinel value which
+ * matches no KVM target value for either 64 or 32 bit
+ */
+#define QEMU_KVM_ARM_TARGET_NONE UINT_MAX
+
+#ifndef TARGET_AARCH64
+MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A15, KVM_ARM_TARGET_CORTEX_A15)
+#endif
+
 #undef MISMATCH_CHECK
 
 #endif
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 80c58c5..182db85 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -77,7 +77,12 @@ int kvm_arch_init_vcpu(CPUState *cs)
     struct kvm_reg_list *rlp;
     ARMCPU *cpu = ARM_CPU(cs);
 
-    init.target = KVM_ARM_TARGET_CORTEX_A15;
+    if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) {
+        fprintf(stderr, "KVM is not supported for this guest CPU type\n");
+        return -EINVAL;
+    }
+
+    init.target = cpu->kvm_target;
     memset(init.features, 0, sizeof(init.features));
     if (cpu->start_powered_off) {
         init.features[0] = 1 << KVM_ARM_VCPU_POWER_OFF;
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 14/37] target-arm: Provide '-cpu host' when running KVM
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (12 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 13/37] target-arm: Don't hardcode KVM target CPU to be A15 Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 15/37] hw/arm/virt: Support -cpu host Peter Maydell
                   ` (22 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

Implement '-cpu host' for ARM when we're using KVM, broadly
in line with other KVM-supporting architectures.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1385140638-10444-11-git-send-email-peter.maydell@linaro.org
---
 target-arm/helper.c  |   6 ++
 target-arm/kvm.c     | 224 +++++++++++++++++++++++++++++++++++++++++++++++++++
 target-arm/kvm_arm.h |  55 +++++++++++++
 3 files changed, 285 insertions(+)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 3445813..263dbbf 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1842,6 +1842,12 @@ void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf)
     (*cpu_fprintf)(f, "Available CPUs:\n");
     g_slist_foreach(list, arm_cpu_list_entry, &s);
     g_slist_free(list);
+#ifdef CONFIG_KVM
+    /* The 'host' CPU type is dynamically registered only if KVM is
+     * enabled, so we have to special-case it here:
+     */
+    (*cpu_fprintf)(f, "  host (only available in KVM mode)\n");
+#endif
 }
 
 static void arm_cpu_add_definition(gpointer data, gpointer user_data)
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 182db85..f865dac 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -27,12 +27,236 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
     KVM_CAP_LAST_INFO
 };
 
+bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
+                                      int *fdarray,
+                                      struct kvm_vcpu_init *init)
+{
+    int ret, kvmfd = -1, vmfd = -1, cpufd = -1;
+
+    kvmfd = qemu_open("/dev/kvm", O_RDWR);
+    if (kvmfd < 0) {
+        goto err;
+    }
+    vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0);
+    if (vmfd < 0) {
+        goto err;
+    }
+    cpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0);
+    if (cpufd < 0) {
+        goto err;
+    }
+
+    ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, init);
+    if (ret >= 0) {
+        ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init);
+        if (ret < 0) {
+            goto err;
+        }
+    } else {
+        /* Old kernel which doesn't know about the
+         * PREFERRED_TARGET ioctl: we know it will only support
+         * creating one kind of guest CPU which is its preferred
+         * CPU type.
+         */
+        while (*cpus_to_try != QEMU_KVM_ARM_TARGET_NONE) {
+            init->target = *cpus_to_try++;
+            memset(init->features, 0, sizeof(init->features));
+            ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init);
+            if (ret >= 0) {
+                break;
+            }
+        }
+        if (ret < 0) {
+            goto err;
+        }
+    }
+
+    fdarray[0] = kvmfd;
+    fdarray[1] = vmfd;
+    fdarray[2] = cpufd;
+
+    return true;
+
+err:
+    if (cpufd >= 0) {
+        close(cpufd);
+    }
+    if (vmfd >= 0) {
+        close(vmfd);
+    }
+    if (kvmfd >= 0) {
+        close(kvmfd);
+    }
+
+    return false;
+}
+
+void kvm_arm_destroy_scratch_host_vcpu(int *fdarray)
+{
+    int i;
+
+    for (i = 2; i >= 0; i--) {
+        close(fdarray[i]);
+    }
+}
+
+static inline void set_feature(uint64_t *features, int feature)
+{
+    *features |= 1ULL << feature;
+}
+
+bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
+{
+    /* Identify the feature bits corresponding to the host CPU, and
+     * fill out the ARMHostCPUClass fields accordingly. To do this
+     * we have to create a scratch VM, create a single CPU inside it,
+     * and then query that CPU for the relevant ID registers.
+     */
+    int i, ret, fdarray[3];
+    uint32_t midr, id_pfr0, id_isar0, mvfr1;
+    uint64_t features = 0;
+    /* Old kernels may not know about the PREFERRED_TARGET ioctl: however
+     * we know these will only support creating one kind of guest CPU,
+     * which is its preferred CPU type.
+     */
+    static const uint32_t cpus_to_try[] = {
+        QEMU_KVM_ARM_TARGET_CORTEX_A15,
+        QEMU_KVM_ARM_TARGET_NONE
+    };
+    struct kvm_vcpu_init init;
+    struct kvm_one_reg idregs[] = {
+        {
+            .id = KVM_REG_ARM | KVM_REG_SIZE_U32
+            | ENCODE_CP_REG(15, 0, 0, 0, 0, 0),
+            .addr = (uintptr_t)&midr,
+        },
+        {
+            .id = KVM_REG_ARM | KVM_REG_SIZE_U32
+            | ENCODE_CP_REG(15, 0, 0, 1, 0, 0),
+            .addr = (uintptr_t)&id_pfr0,
+        },
+        {
+            .id = KVM_REG_ARM | KVM_REG_SIZE_U32
+            | ENCODE_CP_REG(15, 0, 0, 2, 0, 0),
+            .addr = (uintptr_t)&id_isar0,
+        },
+        {
+            .id = KVM_REG_ARM | KVM_REG_SIZE_U32
+            | KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR1,
+            .addr = (uintptr_t)&mvfr1,
+        },
+    };
+
+    if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
+        return false;
+    }
+
+    ahcc->target = init.target;
+
+    /* This is not strictly blessed by the device tree binding docs yet,
+     * but in practice the kernel does not care about this string so
+     * there is no point maintaining an KVM_ARM_TARGET_* -> string table.
+     */
+    ahcc->dtb_compatible = "arm,arm-v7";
+
+    for (i = 0; i < ARRAY_SIZE(idregs); i++) {
+        ret = ioctl(fdarray[2], KVM_GET_ONE_REG, &idregs[i]);
+        if (ret) {
+            break;
+        }
+    }
+
+    kvm_arm_destroy_scratch_host_vcpu(fdarray);
+
+    if (ret) {
+        return false;
+    }
+
+    /* Now we've retrieved all the register information we can
+     * set the feature bits based on the ID register fields.
+     * We can assume any KVM supporting CPU is at least a v7
+     * with VFPv3, LPAE and the generic timers; this in turn implies
+     * most of the other feature bits, but a few must be tested.
+     */
+    set_feature(&features, ARM_FEATURE_V7);
+    set_feature(&features, ARM_FEATURE_VFP3);
+    set_feature(&features, ARM_FEATURE_LPAE);
+    set_feature(&features, ARM_FEATURE_GENERIC_TIMER);
+
+    switch (extract32(id_isar0, 24, 4)) {
+    case 1:
+        set_feature(&features, ARM_FEATURE_THUMB_DIV);
+        break;
+    case 2:
+        set_feature(&features, ARM_FEATURE_ARM_DIV);
+        set_feature(&features, ARM_FEATURE_THUMB_DIV);
+        break;
+    default:
+        break;
+    }
+
+    if (extract32(id_pfr0, 12, 4) == 1) {
+        set_feature(&features, ARM_FEATURE_THUMB2EE);
+    }
+    if (extract32(mvfr1, 20, 4) == 1) {
+        set_feature(&features, ARM_FEATURE_VFP_FP16);
+    }
+    if (extract32(mvfr1, 12, 4) == 1) {
+        set_feature(&features, ARM_FEATURE_NEON);
+    }
+    if (extract32(mvfr1, 28, 4) == 1) {
+        /* FMAC support implies VFPv4 */
+        set_feature(&features, ARM_FEATURE_VFP4);
+    }
+
+    ahcc->features = features;
+
+    return true;
+}
+
+static void kvm_arm_host_cpu_class_init(ObjectClass *oc, void *data)
+{
+    ARMHostCPUClass *ahcc = ARM_HOST_CPU_CLASS(oc);
+
+    /* All we really need to set up for the 'host' CPU
+     * is the feature bits -- we rely on the fact that the
+     * various ID register values in ARMCPU are only used for
+     * TCG CPUs.
+     */
+    if (!kvm_arm_get_host_cpu_features(ahcc)) {
+        fprintf(stderr, "Failed to retrieve host CPU features!\n");
+        abort();
+    }
+}
+
+static void kvm_arm_host_cpu_initfn(Object *obj)
+{
+    ARMHostCPUClass *ahcc = ARM_HOST_CPU_GET_CLASS(obj);
+    ARMCPU *cpu = ARM_CPU(obj);
+    CPUARMState *env = &cpu->env;
+
+    cpu->kvm_target = ahcc->target;
+    cpu->dtb_compatible = ahcc->dtb_compatible;
+    env->features = ahcc->features;
+}
+
+static const TypeInfo host_arm_cpu_type_info = {
+    .name = TYPE_ARM_HOST_CPU,
+    .parent = TYPE_ARM_CPU,
+    .instance_init = kvm_arm_host_cpu_initfn,
+    .class_init = kvm_arm_host_cpu_class_init,
+    .class_size = sizeof(ARMHostCPUClass),
+};
+
 int kvm_arch_init(KVMState *s)
 {
     /* For ARM interrupt delivery is always asynchronous,
      * whether we are using an in-kernel VGIC or not.
      */
     kvm_async_interrupts_allowed = true;
+
+    type_register_static(&host_arm_cpu_type_info);
+
     return 0;
 }
 
diff --git a/target-arm/kvm_arm.h b/target-arm/kvm_arm.h
index 5d14887..cd3d13c 100644
--- a/target-arm/kvm_arm.h
+++ b/target-arm/kvm_arm.h
@@ -62,4 +62,59 @@ bool write_list_to_kvmstate(ARMCPU *cpu);
  */
 bool write_kvmstate_to_list(ARMCPU *cpu);
 
+#ifdef CONFIG_KVM
+/**
+ * kvm_arm_create_scratch_host_vcpu:
+ * @cpus_to_try: array of QEMU_KVM_ARM_TARGET_* values (terminated with
+ * QEMU_KVM_ARM_TARGET_NONE) to try as fallback if the kernel does not
+ * know the PREFERRED_TARGET ioctl
+ * @fdarray: filled in with kvmfd, vmfd, cpufd file descriptors in that order
+ * @init: filled in with the necessary values for creating a host vcpu
+ *
+ * Create a scratch vcpu in its own VM of the type preferred by the host
+ * kernel (as would be used for '-cpu host'), for purposes of probing it
+ * for capabilities.
+ *
+ * Returns: true on success (and fdarray and init are filled in),
+ * false on failure (and fdarray and init are not valid).
+ */
+bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
+                                      int *fdarray,
+                                      struct kvm_vcpu_init *init);
+
+/**
+ * kvm_arm_destroy_scratch_host_vcpu:
+ * @fdarray: array of fds as set up by kvm_arm_create_scratch_host_vcpu
+ *
+ * Tear down the scratch vcpu created by kvm_arm_create_scratch_host_vcpu.
+ */
+void kvm_arm_destroy_scratch_host_vcpu(int *fdarray);
+
+#define TYPE_ARM_HOST_CPU "host-" TYPE_ARM_CPU
+#define ARM_HOST_CPU_CLASS(klass) \
+    OBJECT_CLASS_CHECK(ARMHostCPUClass, (klass), TYPE_ARM_HOST_CPU)
+#define ARM_HOST_CPU_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(ARMHostCPUClass, (obj), TYPE_ARM_HOST_CPU)
+
+typedef struct ARMHostCPUClass {
+    /*< private >*/
+    ARMCPUClass parent_class;
+    /*< public >*/
+
+    uint64_t features;
+    uint32_t target;
+    const char *dtb_compatible;
+} ARMHostCPUClass;
+
+/**
+ * kvm_arm_get_host_cpu_features:
+ * @ahcc: ARMHostCPUClass to fill in
+ *
+ * Probe the capabilities of the host kernel's preferred CPU and fill
+ * in the ARMHostCPUClass struct accordingly.
+ */
+bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc);
+
+#endif
+
 #endif
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 15/37] hw/arm/virt: Support -cpu host
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (13 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 14/37] target-arm: Provide '-cpu host' when running KVM Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 16/37] net/cadence_gem: Implement mac level loopback mode Peter Maydell
                   ` (21 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

Support -cpu host in virt machine (treating it like an A15, ie
with a GIC v2 and the A15's private peripherals.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1385140638-10444-12-git-send-email-peter.maydell@linaro.org
---
 hw/arm/virt.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 1e42cc2..9531b5a 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -122,6 +122,14 @@ static VirtBoardInfo machines[] = {
         .memmap = a15memmap,
         .irqmap = a15irqmap,
     },
+    {
+        .cpu_model = "host",
+        /* We use the A15 private peripheral model to get a V2 GIC */
+        .qdevname = "a15mpcore_priv",
+        .gic_compatible = "arm,cortex-a15-gic",
+        .memmap = a15memmap,
+        .irqmap = a15irqmap,
+    },
 };
 
 static VirtBoardInfo *find_machine_info(const char *cpu)
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 16/37] net/cadence_gem: Implement mac level loopback mode
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (14 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 15/37] hw/arm/virt: Support -cpu host Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 17/37] net/cadence_gem: Update DMA rx descriptors as we process them Peter Maydell
                   ` (20 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

Cadence GEM has a MAC level loopback mode. Implement. Use the same basic
operation as the already implemented PHY loopback.

Reported-by: Deepika Dhamija <deepika@xilinx.com>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 3a0baf1b6b2fc1be638bdf1a37408ec38988e970.1386136219.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/net/cadence_gem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 4a355bb..a31801d 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -893,7 +893,7 @@ static void gem_transmit(GemState *s)
             gem_transmit_updatestats(s, tx_packet, total_bytes);
 
             /* Send the packet somewhere */
-            if (s->phy_loop) {
+            if (s->phy_loop || (s->regs[GEM_NWCTRL] & GEM_NWCTRL_LOCALLOOP)) {
                 gem_receive(qemu_get_queue(s->nic), tx_packet, total_bytes);
             } else {
                 qemu_send_packet(qemu_get_queue(s->nic), tx_packet,
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 17/37] net/cadence_gem: Update DMA rx descriptors as we process them
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (15 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 16/37] net/cadence_gem: Implement mac level loopback mode Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 18/37] net/cadence_gem: Don't assert against 0 buffer address Peter Maydell
                   ` (19 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>

We were updating the ownership bit of all descriptors if packets
get split and written through several descriptors.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: d61b7847b51487118783c93765a485bc5c66d272.1386136219.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/net/cadence_gem.c | 33 ++++++++++++++++-----------------
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index a31801d..b84ee60 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -592,6 +592,7 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
     unsigned   rxbuf_offset;
     uint8_t    rxbuf[2048];
     uint8_t   *rxbuf_ptr;
+    bool first_desc = true;
 
     s = qemu_get_nic_opaque(nc);
 
@@ -701,6 +702,21 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
                                   rxbuf_ptr, MIN(bytes_to_copy, rxbufsize));
         bytes_to_copy -= MIN(bytes_to_copy, rxbufsize);
         rxbuf_ptr += MIN(bytes_to_copy, rxbufsize);
+
+        /* Update the descriptor.  */
+        if (first_desc) {
+            rx_desc_set_sof(desc);
+            first_desc = false;
+        }
+        if (bytes_to_copy == 0) {
+            rx_desc_set_eof(desc);
+            rx_desc_set_length(desc, size);
+        }
+        rx_desc_set_ownership(desc);
+        /* Descriptor write-back.  */
+        cpu_physical_memory_write(packet_desc_addr,
+                                  (uint8_t *)&desc[0], sizeof(desc));
+
         if (bytes_to_copy == 0) {
             break;
         }
@@ -716,12 +732,6 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
     DB_PRINT("set length: %ld, EOF on descriptor 0x%x\n", size,
             (unsigned)packet_desc_addr);
 
-    /* Update last descriptor with EOF and total length */
-    rx_desc_set_eof(desc);
-    rx_desc_set_length(desc, size);
-    cpu_physical_memory_write(packet_desc_addr,
-                              (uint8_t *)&desc[0], sizeof(desc));
-
     /* Advance RX packet descriptor Q */
     last_desc_addr = packet_desc_addr;
     packet_desc_addr = s->rx_desc_addr;
@@ -734,20 +744,9 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
         s->rx_desc_addr += 8;
     }
 
-    DB_PRINT("set SOF, OWN on descriptor 0x%08x\n", (unsigned)packet_desc_addr);
-
     /* Count it */
     gem_receive_updatestats(s, buf, size);
 
-    /* Update first descriptor (which could also be the last) */
-    /* read descriptor */
-    cpu_physical_memory_read(packet_desc_addr,
-                             (uint8_t *)&desc[0], sizeof(desc));
-    rx_desc_set_sof(desc);
-    rx_desc_set_ownership(desc);
-    cpu_physical_memory_write(packet_desc_addr,
-                              (uint8_t *)&desc[0], sizeof(desc));
-
     s->regs[GEM_RXSTATUS] |= GEM_RXSTATUS_FRMRCVD;
     s->regs[GEM_ISR] |= GEM_INT_RXCMPL & ~(s->regs[GEM_IMR]);
 
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 18/37] net/cadence_gem: Don't assert against 0 buffer address
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (16 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 17/37] net/cadence_gem: Update DMA rx descriptors as we process them Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 19/37] net/cadence_gem: simplify rx buf descriptor walking Peter Maydell
                   ` (18 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

This has no real hardware analog and asserting correctness of DMA
addresses is not a perhiperal level problem. Delete.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: fc02417eb1874cb05e4f20531c6203c5a00110f1.1386136219.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/net/cadence_gem.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index b84ee60..b0f3dba 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -688,15 +688,6 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
         DB_PRINT("copy %d bytes to 0x%x\n", MIN(bytes_to_copy, rxbufsize),
                 rx_desc_get_buffer(desc));
 
-        /*
-         * Let's have QEMU lend a helping hand.
-         */
-        if (rx_desc_get_buffer(desc) == 0) {
-            DB_PRINT("Invalid RX buffer (NULL) for descriptor 0x%x\n",
-                     (unsigned)packet_desc_addr);
-            break;
-        }
-
         /* Copy packet data to emulated DMA buffer */
         cpu_physical_memory_write(rx_desc_get_buffer(desc) + rxbuf_offset,
                                   rxbuf_ptr, MIN(bytes_to_copy, rxbufsize));
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 19/37] net/cadence_gem: simplify rx buf descriptor walking
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (17 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 18/37] net/cadence_gem: Don't assert against 0 buffer address Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 20/37] net/cadence_gem: Prefetch rx descriptors ASAP Peter Maydell
                   ` (17 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

There was a replication of the rx descriptor address walking logic.
Reorder the flow control to remove. This refactoring also obsoletes
the local variables packet_desc_addr and last_desc_addr.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: 2a425b457ff0b57274bf206ad2236690cd7f5909.1386136219.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/net/cadence_gem.c | 37 +++++++++----------------------------
 1 file changed, 9 insertions(+), 28 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index b0f3dba..69ad87e 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -586,7 +586,6 @@ static int gem_mac_address_filter(GemState *s, const uint8_t *packet)
 static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
 {
     unsigned    desc[2];
-    hwaddr packet_desc_addr, last_desc_addr;
     GemState *s;
     unsigned   rxbufsize, bytes_to_copy;
     unsigned   rxbuf_offset;
@@ -667,17 +666,16 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
 
     DB_PRINT("config bufsize: %d packet size: %ld\n", rxbufsize, size);
 
-    packet_desc_addr = s->rx_desc_addr;
-    while (1) {
-        DB_PRINT("read descriptor 0x%x\n", (unsigned)packet_desc_addr);
+    while (bytes_to_copy) {
+        DB_PRINT("read descriptor 0x%x\n", (unsigned)s->rx_desc_addr);
         /* read current descriptor */
-        cpu_physical_memory_read(packet_desc_addr,
+        cpu_physical_memory_read(s->rx_desc_addr,
                                  (uint8_t *)&desc[0], sizeof(desc));
 
         /* Descriptor owned by software ? */
         if (rx_desc_get_ownership(desc) == 1) {
             DB_PRINT("descriptor 0x%x owned by sw.\n",
-                     (unsigned)packet_desc_addr);
+                     (unsigned)s->rx_desc_addr);
             s->regs[GEM_RXSTATUS] |= GEM_RXSTATUS_NOBUF;
             s->regs[GEM_ISR] |= GEM_INT_RXUSED & ~(s->regs[GEM_IMR]);
             /* Handle interrupt consequences */
@@ -705,36 +703,19 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
         }
         rx_desc_set_ownership(desc);
         /* Descriptor write-back.  */
-        cpu_physical_memory_write(packet_desc_addr,
+        cpu_physical_memory_write(s->rx_desc_addr,
                                   (uint8_t *)&desc[0], sizeof(desc));
 
-        if (bytes_to_copy == 0) {
-            break;
-        }
-
         /* Next descriptor */
         if (rx_desc_get_wrap(desc)) {
-            packet_desc_addr = s->regs[GEM_RXQBASE];
+            DB_PRINT("wrapping RX descriptor list\n");
+            s->rx_desc_addr = s->regs[GEM_RXQBASE];
         } else {
-            packet_desc_addr += 8;
+            DB_PRINT("incrementing RX descriptor list\n");
+            s->rx_desc_addr += 8;
         }
     }
 
-    DB_PRINT("set length: %ld, EOF on descriptor 0x%x\n", size,
-            (unsigned)packet_desc_addr);
-
-    /* Advance RX packet descriptor Q */
-    last_desc_addr = packet_desc_addr;
-    packet_desc_addr = s->rx_desc_addr;
-    s->rx_desc_addr = last_desc_addr;
-    if (rx_desc_get_wrap(desc)) {
-        s->rx_desc_addr = s->regs[GEM_RXQBASE];
-        DB_PRINT("wrapping RX descriptor list\n");
-    } else {
-        DB_PRINT("incrementing RX descriptor list\n");
-        s->rx_desc_addr += 8;
-    }
-
     /* Count it */
     gem_receive_updatestats(s, buf, size);
 
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 20/37] net/cadence_gem: Prefetch rx descriptors ASAP
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (18 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 19/37] net/cadence_gem: simplify rx buf descriptor walking Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 21/37] net/cadence_gem: Implement RX descriptor match mode flags Peter Maydell
                   ` (16 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

The real hardware prefetches rx buffer descriptors ASAP and
potentially throws relevant interrupts following the fetch
even in the absence of a received packet.

Reported-by: Deepika Dhamija <deepika@xilinx.com>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: 41629e35edfdb1f02f1e401f2c3d0e2e4c9e44b3.1386136219.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/net/cadence_gem.c | 62 +++++++++++++++++++++++++++++-----------------------
 1 file changed, 35 insertions(+), 27 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 69ad87e..6734a9d 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -346,6 +346,8 @@ typedef struct GemState {
     uint32_t rx_desc_addr;
     uint32_t tx_desc_addr;
 
+    unsigned rx_desc[2];
+
 } GemState;
 
 /* The broadcast MAC address: 0xFFFFFFFFFFFF */
@@ -579,13 +581,30 @@ static int gem_mac_address_filter(GemState *s, const uint8_t *packet)
     return GEM_RX_REJECT;
 }
 
+static void gem_get_rx_desc(GemState *s)
+{
+    DB_PRINT("read descriptor 0x%x\n", (unsigned)s->rx_desc_addr);
+    /* read current descriptor */
+    cpu_physical_memory_read(s->rx_desc_addr,
+                             (uint8_t *)s->rx_desc, sizeof(s->rx_desc));
+
+    /* Descriptor owned by software ? */
+    if (rx_desc_get_ownership(s->rx_desc) == 1) {
+        DB_PRINT("descriptor 0x%x owned by sw.\n",
+                 (unsigned)s->rx_desc_addr);
+        s->regs[GEM_RXSTATUS] |= GEM_RXSTATUS_NOBUF;
+        s->regs[GEM_ISR] |= GEM_INT_RXUSED & ~(s->regs[GEM_IMR]);
+        /* Handle interrupt consequences */
+        gem_update_int_status(s);
+    }
+}
+
 /*
  * gem_receive:
  * Fit a packet handed to us by QEMU into the receive descriptor ring.
  */
 static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
 {
-    unsigned    desc[2];
     GemState *s;
     unsigned   rxbufsize, bytes_to_copy;
     unsigned   rxbuf_offset;
@@ -595,11 +614,6 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
 
     s = qemu_get_nic_opaque(nc);
 
-    /* Do nothing if receive is not enabled. */
-    if (!gem_can_receive(nc)) {
-        return -1;
-    }
-
     /* Is this destination MAC address "for us" ? */
     if (gem_mac_address_filter(s, buf) == GEM_RX_REJECT) {
         return -1;
@@ -667,53 +681,44 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
     DB_PRINT("config bufsize: %d packet size: %ld\n", rxbufsize, size);
 
     while (bytes_to_copy) {
-        DB_PRINT("read descriptor 0x%x\n", (unsigned)s->rx_desc_addr);
-        /* read current descriptor */
-        cpu_physical_memory_read(s->rx_desc_addr,
-                                 (uint8_t *)&desc[0], sizeof(desc));
-
-        /* Descriptor owned by software ? */
-        if (rx_desc_get_ownership(desc) == 1) {
-            DB_PRINT("descriptor 0x%x owned by sw.\n",
-                     (unsigned)s->rx_desc_addr);
-            s->regs[GEM_RXSTATUS] |= GEM_RXSTATUS_NOBUF;
-            s->regs[GEM_ISR] |= GEM_INT_RXUSED & ~(s->regs[GEM_IMR]);
-            /* Handle interrupt consequences */
-            gem_update_int_status(s);
+        /* Do nothing if receive is not enabled. */
+        if (!gem_can_receive(nc)) {
+            assert(!first_desc);
             return -1;
         }
 
         DB_PRINT("copy %d bytes to 0x%x\n", MIN(bytes_to_copy, rxbufsize),
-                rx_desc_get_buffer(desc));
+                rx_desc_get_buffer(s->rx_desc));
 
         /* Copy packet data to emulated DMA buffer */
-        cpu_physical_memory_write(rx_desc_get_buffer(desc) + rxbuf_offset,
+        cpu_physical_memory_write(rx_desc_get_buffer(s->rx_desc) + rxbuf_offset,
                                   rxbuf_ptr, MIN(bytes_to_copy, rxbufsize));
         bytes_to_copy -= MIN(bytes_to_copy, rxbufsize);
         rxbuf_ptr += MIN(bytes_to_copy, rxbufsize);
 
         /* Update the descriptor.  */
         if (first_desc) {
-            rx_desc_set_sof(desc);
+            rx_desc_set_sof(s->rx_desc);
             first_desc = false;
         }
         if (bytes_to_copy == 0) {
-            rx_desc_set_eof(desc);
-            rx_desc_set_length(desc, size);
+            rx_desc_set_eof(s->rx_desc);
+            rx_desc_set_length(s->rx_desc, size);
         }
-        rx_desc_set_ownership(desc);
+        rx_desc_set_ownership(s->rx_desc);
         /* Descriptor write-back.  */
         cpu_physical_memory_write(s->rx_desc_addr,
-                                  (uint8_t *)&desc[0], sizeof(desc));
+                                  (uint8_t *)s->rx_desc, sizeof(s->rx_desc));
 
         /* Next descriptor */
-        if (rx_desc_get_wrap(desc)) {
+        if (rx_desc_get_wrap(s->rx_desc)) {
             DB_PRINT("wrapping RX descriptor list\n");
             s->rx_desc_addr = s->regs[GEM_RXQBASE];
         } else {
             DB_PRINT("incrementing RX descriptor list\n");
             s->rx_desc_addr += 8;
         }
+        gem_get_rx_desc(s);
     }
 
     /* Count it */
@@ -1053,6 +1058,9 @@ static void gem_write(void *opaque, hwaddr offset, uint64_t val,
     /* Handle register write side effects */
     switch (offset) {
     case GEM_NWCTRL:
+        if (val & GEM_NWCTRL_RXENA) {
+            gem_get_rx_desc(s);
+        }
         if (val & GEM_NWCTRL_TXSTART) {
             gem_transmit(s);
         }
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 21/37] net/cadence_gem: Implement RX descriptor match mode flags
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (19 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 20/37] net/cadence_gem: Prefetch rx descriptors ASAP Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 22/37] net/cadence_gem: Implement SAR match bit in rx desc Peter Maydell
                   ` (15 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

The various Rx packet address matching mode flags were not being set in
the rx descriptor. Implement.

Reported-by: Deepika Dhamija <deepika@xilinx.com>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: 6002a24a6a8ceaa11d3009ab5392840d1c084b28.1386136219.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/net/cadence_gem.c | 82 +++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 69 insertions(+), 13 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 6734a9d..dceafb5 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -222,8 +222,13 @@
 #define PHY_REG_INT_ST_ENERGY   0x0010
 
 /***********************************************************************/
-#define GEM_RX_REJECT  1
-#define GEM_RX_ACCEPT  0
+#define GEM_RX_REJECT                   (-1)
+#define GEM_RX_PROMISCUOUS_ACCEPT       (-2)
+#define GEM_RX_BROADCAST_ACCEPT         (-3)
+#define GEM_RX_MULTICAST_HASH_ACCEPT    (-4)
+#define GEM_RX_UNICAST_HASH_ACCEPT      (-5)
+
+#define GEM_RX_SAR_ACCEPT               0
 
 /***********************************************************************/
 
@@ -236,6 +241,12 @@
 #define DESC_0_RX_WRAP 0x00000002
 #define DESC_0_RX_OWNERSHIP 0x00000001
 
+#define R_DESC_1_RX_SAR_SHIFT           25
+#define R_DESC_1_RX_SAR_LENGTH          2
+#define R_DESC_1_RX_UNICAST_HASH        (1 << 29)
+#define R_DESC_1_RX_MULTICAST_HASH      (1 << 30)
+#define R_DESC_1_RX_BROADCAST           (1 << 31)
+
 #define DESC_1_RX_SOF 0x00004000
 #define DESC_1_RX_EOF 0x00008000
 
@@ -315,6 +326,27 @@ static inline void rx_desc_set_length(unsigned *desc, unsigned len)
     desc[1] |= len;
 }
 
+static inline void rx_desc_set_broadcast(unsigned *desc)
+{
+    desc[1] |= R_DESC_1_RX_BROADCAST;
+}
+
+static inline void rx_desc_set_unicast_hash(unsigned *desc)
+{
+    desc[1] |= R_DESC_1_RX_UNICAST_HASH;
+}
+
+static inline void rx_desc_set_multicast_hash(unsigned *desc)
+{
+    desc[1] |= R_DESC_1_RX_MULTICAST_HASH;
+}
+
+static inline void rx_desc_set_sar(unsigned *desc, int sar_idx)
+{
+    desc[1] = deposit32(desc[1], R_DESC_1_RX_SAR_SHIFT, R_DESC_1_RX_SAR_LENGTH,
+                        sar_idx);
+}
+
 #define TYPE_CADENCE_GEM "cadence_gem"
 #define GEM(obj) OBJECT_CHECK(GemState, (obj), TYPE_CADENCE_GEM)
 
@@ -529,7 +561,10 @@ static unsigned calc_mac_hash(const uint8_t *mac)
  * Accept or reject this destination address?
  * Returns:
  * GEM_RX_REJECT: reject
- * GEM_RX_ACCEPT: accept
+ * >= 0: Specific address accept (which matched SAR is returned)
+ * others for various other modes of accept:
+ * GEM_RM_PROMISCUOUS_ACCEPT, GEM_RX_BROADCAST_ACCEPT,
+ * GEM_RX_MULTICAST_HASH_ACCEPT or GEM_RX_UNICAST_HASH_ACCEPT
  */
 static int gem_mac_address_filter(GemState *s, const uint8_t *packet)
 {
@@ -538,7 +573,7 @@ static int gem_mac_address_filter(GemState *s, const uint8_t *packet)
 
     /* Promiscuous mode? */
     if (s->regs[GEM_NWCFG] & GEM_NWCFG_PROMISC) {
-        return GEM_RX_ACCEPT;
+        return GEM_RX_PROMISCUOUS_ACCEPT;
     }
 
     if (!memcmp(packet, broadcast_addr, 6)) {
@@ -546,7 +581,7 @@ static int gem_mac_address_filter(GemState *s, const uint8_t *packet)
         if (s->regs[GEM_NWCFG] & GEM_NWCFG_BCAST_REJ) {
             return GEM_RX_REJECT;
         }
-        return GEM_RX_ACCEPT;
+        return GEM_RX_BROADCAST_ACCEPT;
     }
 
     /* Accept packets -w- hash match? */
@@ -557,24 +592,24 @@ static int gem_mac_address_filter(GemState *s, const uint8_t *packet)
         hash_index = calc_mac_hash(packet);
         if (hash_index < 32) {
             if (s->regs[GEM_HASHLO] & (1<<hash_index)) {
-                return GEM_RX_ACCEPT;
+                return packet[0] == 0x01 ? GEM_RX_MULTICAST_HASH_ACCEPT :
+                                           GEM_RX_UNICAST_HASH_ACCEPT;
             }
         } else {
             hash_index -= 32;
             if (s->regs[GEM_HASHHI] & (1<<hash_index)) {
-                return GEM_RX_ACCEPT;
+                return packet[0] == 0x01 ? GEM_RX_MULTICAST_HASH_ACCEPT :
+                                           GEM_RX_UNICAST_HASH_ACCEPT;
             }
         }
     }
 
     /* Check all 4 specific addresses */
     gem_spaddr = (uint8_t *)&(s->regs[GEM_SPADDR1LO]);
-    for (i = 0; i < 4; i++) {
-        if (!memcmp(packet, gem_spaddr, 6)) {
-            return GEM_RX_ACCEPT;
+    for (i = 3; i >= 0; i--) {
+        if (!memcmp(packet, gem_spaddr + 8 * i, 6)) {
+            return GEM_RX_SAR_ACCEPT + i;
         }
-
-        gem_spaddr += 8;
     }
 
     /* No address match; reject the packet */
@@ -611,11 +646,13 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
     uint8_t    rxbuf[2048];
     uint8_t   *rxbuf_ptr;
     bool first_desc = true;
+    int maf;
 
     s = qemu_get_nic_opaque(nc);
 
     /* Is this destination MAC address "for us" ? */
-    if (gem_mac_address_filter(s, buf) == GEM_RX_REJECT) {
+    maf = gem_mac_address_filter(s, buf);
+    if (maf == GEM_RX_REJECT) {
         return -1;
     }
 
@@ -706,6 +743,25 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
             rx_desc_set_length(s->rx_desc, size);
         }
         rx_desc_set_ownership(s->rx_desc);
+
+        switch (maf) {
+        case GEM_RX_PROMISCUOUS_ACCEPT:
+            break;
+        case GEM_RX_BROADCAST_ACCEPT:
+            rx_desc_set_broadcast(s->rx_desc);
+            break;
+        case GEM_RX_UNICAST_HASH_ACCEPT:
+            rx_desc_set_unicast_hash(s->rx_desc);
+            break;
+        case GEM_RX_MULTICAST_HASH_ACCEPT:
+            rx_desc_set_multicast_hash(s->rx_desc);
+            break;
+        case GEM_RX_REJECT:
+            abort();
+        default: /* SAR */
+            rx_desc_set_sar(s->rx_desc, maf);
+        }
+
         /* Descriptor write-back.  */
         cpu_physical_memory_write(s->rx_desc_addr,
                                   (uint8_t *)s->rx_desc, sizeof(s->rx_desc));
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 22/37] net/cadence_gem: Implement SAR match bit in rx desc
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (20 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 21/37] net/cadence_gem: Implement RX descriptor match mode flags Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 23/37] net/cadence_gem: Implement SAR (de)activation Peter Maydell
                   ` (14 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

Bit 27 of the RX buffer desc word 1 should be set when the packet was
accepted due to specific address register match. Implement.

This feature is absent from the Xilinx documentation (UG585) but the
behaviour is tested as accurate on real hardware.

Reported-by: Deepika Dhamija <deepika@xilinx.com>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 7e3f26fc4ab244e8123efc12723e7164730abdcb.1386136219.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/net/cadence_gem.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index dceafb5..58d9b63 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -243,6 +243,7 @@
 
 #define R_DESC_1_RX_SAR_SHIFT           25
 #define R_DESC_1_RX_SAR_LENGTH          2
+#define R_DESC_1_RX_SAR_MATCH           (1 << 27)
 #define R_DESC_1_RX_UNICAST_HASH        (1 << 29)
 #define R_DESC_1_RX_MULTICAST_HASH      (1 << 30)
 #define R_DESC_1_RX_BROADCAST           (1 << 31)
@@ -345,6 +346,7 @@ static inline void rx_desc_set_sar(unsigned *desc, int sar_idx)
 {
     desc[1] = deposit32(desc[1], R_DESC_1_RX_SAR_SHIFT, R_DESC_1_RX_SAR_LENGTH,
                         sar_idx);
+    desc[1] |= R_DESC_1_RX_SAR_MATCH;
 }
 
 #define TYPE_CADENCE_GEM "cadence_gem"
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 23/37] net/cadence_gem: Implement SAR (de)activation
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (21 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 22/37] net/cadence_gem: Implement SAR match bit in rx desc Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 24/37] net/cadence_gem: Add missing VMSTATE_END_OF_LIST Peter Maydell
                   ` (13 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

The Specific address registers can be enabled or disabled by software.
QEMU was assuming they were always enabled. Implement the
disable/enable feature. SARs are disabled by writing to the lower half
register. They are re-enabled by then writing the upper half.

Reported-by: Deepika Dhamija <deepika@xilinx.com>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: 49efd1f7450af8f980b967d3054245bae137866c.1386136219.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/net/cadence_gem.c | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 58d9b63..07e6fe7 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -382,6 +382,7 @@ typedef struct GemState {
 
     unsigned rx_desc[2];
 
+    bool sar_active[4];
 } GemState;
 
 /* The broadcast MAC address: 0xFFFFFFFFFFFF */
@@ -609,7 +610,7 @@ static int gem_mac_address_filter(GemState *s, const uint8_t *packet)
     /* Check all 4 specific addresses */
     gem_spaddr = (uint8_t *)&(s->regs[GEM_SPADDR1LO]);
     for (i = 3; i >= 0; i--) {
-        if (!memcmp(packet, gem_spaddr + 8 * i, 6)) {
+        if (s->sar_active[i] && !memcmp(packet, gem_spaddr + 8 * i, 6)) {
             return GEM_RX_SAR_ACCEPT + i;
         }
     }
@@ -983,6 +984,7 @@ static void gem_phy_reset(GemState *s)
 
 static void gem_reset(DeviceState *d)
 {
+    int i;
     GemState *s = GEM(d);
 
     DB_PRINT("\n");
@@ -1002,6 +1004,10 @@ static void gem_reset(DeviceState *d)
     s->regs[GEM_DESCONF5] = 0x002f2145;
     s->regs[GEM_DESCONF6] = 0x00000200;
 
+    for (i = 0; i < 4; i++) {
+        s->sar_active[i] = false;
+    }
+
     gem_phy_reset(s);
 
     gem_update_int_status(s);
@@ -1151,6 +1157,18 @@ static void gem_write(void *opaque, hwaddr offset, uint64_t val,
         s->regs[GEM_IMR] |= val;
         gem_update_int_status(s);
         break;
+    case GEM_SPADDR1LO:
+    case GEM_SPADDR2LO:
+    case GEM_SPADDR3LO:
+    case GEM_SPADDR4LO:
+        s->sar_active[(offset - GEM_SPADDR1LO) / 2] = false;
+        break;
+    case GEM_SPADDR1HI:
+    case GEM_SPADDR2HI:
+    case GEM_SPADDR3HI:
+    case GEM_SPADDR4HI:
+        s->sar_active[(offset - GEM_SPADDR1HI) / 2] = true;
+        break;
     case GEM_PHYMNTNC:
         if (val & GEM_PHYMNTNC_OP_W) {
             uint32_t phy_addr, reg_num;
@@ -1218,15 +1236,16 @@ static int gem_init(SysBusDevice *sbd)
 
 static const VMStateDescription vmstate_cadence_gem = {
     .name = "cadence_gem",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .minimum_version_id_old = 1,
+    .version_id = 2,
+    .minimum_version_id = 2,
+    .minimum_version_id_old = 2,
     .fields      = (VMStateField[]) {
         VMSTATE_UINT32_ARRAY(regs, GemState, GEM_MAXREG),
         VMSTATE_UINT16_ARRAY(phy_regs, GemState, 32),
         VMSTATE_UINT8(phy_loop, GemState),
         VMSTATE_UINT32(rx_desc_addr, GemState),
         VMSTATE_UINT32(tx_desc_addr, GemState),
+        VMSTATE_BOOL_ARRAY(sar_active, GemState, 4),
     }
 };
 
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 24/37] net/cadence_gem: Add missing VMSTATE_END_OF_LIST
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (22 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 23/37] net/cadence_gem: Implement SAR (de)activation Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 25/37] net/cadence_gem: Fix rx multi-fragment packets Peter Maydell
                   ` (12 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: 8f8c2bfb15f40fb5f0d5766aa4cd3d54c596de6a.1386136219.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/net/cadence_gem.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 07e6fe7..8cfad04 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -1246,6 +1246,7 @@ static const VMStateDescription vmstate_cadence_gem = {
         VMSTATE_UINT32(rx_desc_addr, GemState),
         VMSTATE_UINT32(tx_desc_addr, GemState),
         VMSTATE_BOOL_ARRAY(sar_active, GemState, 4),
+        VMSTATE_END_OF_LIST(),
     }
 };
 
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 25/37] net/cadence_gem: Fix rx multi-fragment packets
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (23 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 24/37] net/cadence_gem: Add missing VMSTATE_END_OF_LIST Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 26/37] net/cadence_gem: Fix small packet FCS stripping Peter Maydell
                   ` (11 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

Bytes_to_copy was being updated before its final use where it
advances the rx buffer pointer. This was causing total mayhem,
where packet data for any subsequent fragments was being fetched
from the wrong place.

Reported-by: Deepika Dhamija <deepika@xilinx.com>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: c2a1c65c1fd06eb274442a0fa4a6839d940e145e.1386136219.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/net/cadence_gem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 8cfad04..2afafdf 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -733,8 +733,8 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
         /* Copy packet data to emulated DMA buffer */
         cpu_physical_memory_write(rx_desc_get_buffer(s->rx_desc) + rxbuf_offset,
                                   rxbuf_ptr, MIN(bytes_to_copy, rxbufsize));
-        bytes_to_copy -= MIN(bytes_to_copy, rxbufsize);
         rxbuf_ptr += MIN(bytes_to_copy, rxbufsize);
+        bytes_to_copy -= MIN(bytes_to_copy, rxbufsize);
 
         /* Update the descriptor.  */
         if (first_desc) {
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 26/37] net/cadence_gem: Fix small packet FCS stripping
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (24 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 25/37] net/cadence_gem: Fix rx multi-fragment packets Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 27/37] net/cadence_gem: Fix register w1c logic Peter Maydell
                   ` (10 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

The minimum packet size is 64, however this is before FCS stripping
occurs. So when FCS stripping the minimum packet size is 60. Fix.

Reported-by: Deepika Dhamija <deepika@xilinx.com>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: 8aac5bd737f9cf48b87f32943d7eb5939061e546.1386136219.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/net/cadence_gem.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 2afafdf..1619507 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -687,6 +687,14 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
                  GEM_DMACFG_RBUFSZ_S) * GEM_DMACFG_RBUFSZ_MUL;
     bytes_to_copy = size;
 
+    /* Pad to minimum length. Assume FCS field is stripped, logic
+     * below will increment it to the real minimum of 64 when
+     * not FCS stripping
+     */
+    if (size < 60) {
+        size = 60;
+    }
+
     /* Strip of FCS field ? (usually yes) */
     if (s->regs[GEM_NWCFG] & GEM_NWCFG_STRIP_FCS) {
         rxbuf_ptr = (void *)buf;
@@ -713,11 +721,6 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
         size += 4;
     }
 
-    /* Pad to minimum length */
-    if (size < 64) {
-        size = 64;
-    }
-
     DB_PRINT("config bufsize: %d packet size: %ld\n", rxbufsize, size);
 
     while (bytes_to_copy) {
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 27/37] net/cadence_gem: Fix register w1c logic
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (25 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 26/37] net/cadence_gem: Fix small packet FCS stripping Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 28/37] net/cadence_gem: Improve can_receive debug printfery Peter Maydell
                   ` (9 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

This write-1-clear logic was incorrect. It was always clearing w1c
bits regardless of whether the written value was 1 or not. i.e. it
was implementing a write-anything-to-clear strategy.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: ed905b04d3343966ded425f06aa2224bc7a35b59.1386136219.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/net/cadence_gem.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 1619507..f2c734e 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -1112,15 +1112,14 @@ static void gem_write(void *opaque, hwaddr offset, uint64_t val,
 
     /* Squash bits which are read only in write value */
     val &= ~(s->regs_ro[offset]);
-    /* Preserve (only) bits which are read only in register */
-    readonly = s->regs[offset];
-    readonly &= s->regs_ro[offset];
-
-    /* Squash bits which are write 1 to clear */
-    val &= ~(s->regs_w1c[offset] & val);
+    /* Preserve (only) bits which are read only and wtc in register */
+    readonly = s->regs[offset] & (s->regs_ro[offset] | s->regs_w1c[offset]);
 
     /* Copy register write to backing store */
-    s->regs[offset] = val | readonly;
+    s->regs[offset] = (val & ~s->regs_w1c[offset]) | readonly;
+
+    /* do w1c */
+    s->regs[offset] &= ~(s->regs_w1c[offset] & val);
 
     /* Handle register write side effects */
     switch (offset) {
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 28/37] net/cadence_gem: Improve can_receive debug printfery
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (26 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 27/37] net/cadence_gem: Fix register w1c logic Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 29/37] net/cadence_gem: Don't rx packets when no rx buffer available Peter Maydell
                   ` (8 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

Currently this just floods indicating that can_receive has been called
by the net framework. Instead, save the result of the most recent
can_receive callback as state and only print a message if the result
changes (indicating some sort of actual state change in GEM). Make said
debug message more meaningful as well.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: 2eb74ca6a5756aea242d9f525961db95d6cfcf2c.1386136219.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/net/cadence_gem.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index f2c734e..f6e38ca 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -380,6 +380,8 @@ typedef struct GemState {
     uint32_t rx_desc_addr;
     uint32_t tx_desc_addr;
 
+    uint8_t can_rx_state; /* Debug only */
+
     unsigned rx_desc[2];
 
     bool sar_active[4];
@@ -452,13 +454,19 @@ static int gem_can_receive(NetClientState *nc)
 
     s = qemu_get_nic_opaque(nc);
 
-    DB_PRINT("\n");
-
     /* Do nothing if receive is not enabled. */
     if (!(s->regs[GEM_NWCTRL] & GEM_NWCTRL_RXENA)) {
+        if (s->can_rx_state != 1) {
+            s->can_rx_state = 1;
+            DB_PRINT("can't receive - no enable\n");
+        }
         return 0;
     }
 
+    if (s->can_rx_state != 0) {
+        s->can_rx_state = 0;
+        DB_PRINT("can receive 0x%x\n", s->rx_desc_addr);
+    }
     return 1;
 }
 
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 29/37] net/cadence_gem: Don't rx packets when no rx buffer available
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (27 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 28/37] net/cadence_gem: Improve can_receive debug printfery Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 30/37] target-arm: Move call to disas_vfp_insn out of disas_coproc_insn Peter Maydell
                   ` (7 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

Return false from can_receive() when no valid buffer descriptor is
available. Ensures against mass packet droppage in some applications.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: cde00ef774e84e2586bf10fd37b542f75bf36cfb.1386136219.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/net/cadence_gem.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index f6e38ca..92dc2f2 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -463,6 +463,15 @@ static int gem_can_receive(NetClientState *nc)
         return 0;
     }
 
+    if (rx_desc_get_ownership(s->rx_desc) == 1) {
+        if (s->can_rx_state != 2) {
+            s->can_rx_state = 2;
+            DB_PRINT("can't receive - busy buffer descriptor 0x%x\n",
+                     s->rx_desc_addr);
+        }
+        return 0;
+    }
+
     if (s->can_rx_state != 0) {
         s->can_rx_state = 0;
         DB_PRINT("can receive 0x%x\n", s->rx_desc_addr);
@@ -1142,7 +1151,7 @@ static void gem_write(void *opaque, hwaddr offset, uint64_t val,
             /* Reset to start of Q when transmit disabled. */
             s->tx_desc_addr = s->regs[GEM_TXQBASE];
         }
-        if (val & GEM_NWCTRL_RXENA) {
+        if (gem_can_receive(qemu_get_queue(s->nic))) {
             qemu_flush_queued_packets(qemu_get_queue(s->nic));
         }
         break;
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 30/37] target-arm: Move call to disas_vfp_insn out of disas_coproc_insn.
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (28 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 29/37] net/cadence_gem: Don't rx packets when no rx buffer available Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 31/37] target-arm: Implement ARMv8 VSEL instruction Peter Maydell
                   ` (6 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Will Newton <will.newton@linaro.org>

Floating point is an extension to the instruction set rather than
a coprocessor, so call it directly from the ARM and Thumb decode
functions.

Signed-off-by: Will Newton <will.newton@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1386158099-9239-2-git-send-email-will.newton@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/translate.c | 32 +++++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 5f003e7..f63e89d 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -2636,6 +2636,14 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
             && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
             return 1;
     }
+
+    if (extract32(insn, 28, 4) == 0xf) {
+        /* Encodings with T=1 (Thumb) or unconditional (ARM):
+         * only used in v8 and above.
+         */
+        return 1;
+    }
+
     dp = ((insn & 0xf00) == 0xb00);
     switch ((insn >> 24) & 0xf) {
     case 0xe:
@@ -6296,9 +6304,6 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
 	    return disas_dsp_insn(env, s, insn);
 	}
 	return 1;
-    case 10:
-    case 11:
-	return disas_vfp_insn (env, s, insn);
     default:
         break;
     }
@@ -6753,6 +6758,13 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
                 goto illegal_op;
             return;
         }
+        if ((insn & 0x0f000e10) == 0x0e000a00) {
+            /* VFP.  */
+            if (disas_vfp_insn(env, s, insn)) {
+                goto illegal_op;
+            }
+            return;
+        }
         if (((insn & 0x0f30f000) == 0x0510f000) ||
             ((insn & 0x0f30f010) == 0x0710f000)) {
             if ((insn & (1 << 22)) == 0) {
@@ -8033,9 +8045,15 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
         case 0xc:
         case 0xd:
         case 0xe:
-            /* Coprocessor.  */
-            if (disas_coproc_insn(env, s, insn))
+            if (((insn >> 8) & 0xe) == 10) {
+                /* VFP.  */
+                if (disas_vfp_insn(env, s, insn)) {
+                    goto illegal_op;
+                }
+            } else if (disas_coproc_insn(env, s, insn)) {
+                /* Coprocessor.  */
                 goto illegal_op;
+            }
             break;
         case 0xf:
             /* swi */
@@ -8765,6 +8783,10 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
             insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
             if (disas_neon_data_insn(env, s, insn))
                 goto illegal_op;
+        } else if (((insn >> 8) & 0xe) == 10) {
+            if (disas_vfp_insn(env, s, insn)) {
+                goto illegal_op;
+            }
         } else {
             if (insn & (1 << 28))
                 goto illegal_op;
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 31/37] target-arm: Implement ARMv8 VSEL instruction.
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (29 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 30/37] target-arm: Move call to disas_vfp_insn out of disas_coproc_insn Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 32/37] softfloat: Remove unused argument from MINMAX macro Peter Maydell
                   ` (5 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Will Newton <will.newton@linaro.org>

This adds support for the VSEL floating point selection instruction
which was added in ARMv8.

Signed-off-by: Will Newton <will.newton@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1386158099-9239-3-git-send-email-will.newton@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/translate.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 134 insertions(+), 1 deletion(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index f63e89d..0a22ad8 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -2614,6 +2614,139 @@ static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
     return tmp;
 }
 
+static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
+                       uint32_t dp)
+{
+    uint32_t cc = extract32(insn, 20, 2);
+
+    if (dp) {
+        TCGv_i64 frn, frm, dest;
+        TCGv_i64 tmp, zero, zf, nf, vf;
+
+        zero = tcg_const_i64(0);
+
+        frn = tcg_temp_new_i64();
+        frm = tcg_temp_new_i64();
+        dest = tcg_temp_new_i64();
+
+        zf = tcg_temp_new_i64();
+        nf = tcg_temp_new_i64();
+        vf = tcg_temp_new_i64();
+
+        tcg_gen_extu_i32_i64(zf, cpu_ZF);
+        tcg_gen_ext_i32_i64(nf, cpu_NF);
+        tcg_gen_ext_i32_i64(vf, cpu_VF);
+
+        tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
+        tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
+        switch (cc) {
+        case 0: /* eq: Z */
+            tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
+                                frn, frm);
+            break;
+        case 1: /* vs: V */
+            tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
+                                frn, frm);
+            break;
+        case 2: /* ge: N == V -> N ^ V == 0 */
+            tmp = tcg_temp_new_i64();
+            tcg_gen_xor_i64(tmp, vf, nf);
+            tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
+                                frn, frm);
+            tcg_temp_free_i64(tmp);
+            break;
+        case 3: /* gt: !Z && N == V */
+            tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
+                                frn, frm);
+            tmp = tcg_temp_new_i64();
+            tcg_gen_xor_i64(tmp, vf, nf);
+            tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
+                                dest, frm);
+            tcg_temp_free_i64(tmp);
+            break;
+        }
+        tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
+        tcg_temp_free_i64(frn);
+        tcg_temp_free_i64(frm);
+        tcg_temp_free_i64(dest);
+
+        tcg_temp_free_i64(zf);
+        tcg_temp_free_i64(nf);
+        tcg_temp_free_i64(vf);
+
+        tcg_temp_free_i64(zero);
+    } else {
+        TCGv_i32 frn, frm, dest;
+        TCGv_i32 tmp, zero;
+
+        zero = tcg_const_i32(0);
+
+        frn = tcg_temp_new_i32();
+        frm = tcg_temp_new_i32();
+        dest = tcg_temp_new_i32();
+        tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
+        tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
+        switch (cc) {
+        case 0: /* eq: Z */
+            tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
+                                frn, frm);
+            break;
+        case 1: /* vs: V */
+            tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
+                                frn, frm);
+            break;
+        case 2: /* ge: N == V -> N ^ V == 0 */
+            tmp = tcg_temp_new_i32();
+            tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
+            tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
+                                frn, frm);
+            tcg_temp_free_i32(tmp);
+            break;
+        case 3: /* gt: !Z && N == V */
+            tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
+                                frn, frm);
+            tmp = tcg_temp_new_i32();
+            tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
+            tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
+                                dest, frm);
+            tcg_temp_free_i32(tmp);
+            break;
+        }
+        tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
+        tcg_temp_free_i32(frn);
+        tcg_temp_free_i32(frm);
+        tcg_temp_free_i32(dest);
+
+        tcg_temp_free_i32(zero);
+    }
+
+    return 0;
+}
+
+static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
+{
+    uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
+
+    if (!arm_feature(env, ARM_FEATURE_V8)) {
+        return 1;
+    }
+
+    if (dp) {
+        VFP_DREG_D(rd, insn);
+        VFP_DREG_N(rn, insn);
+        VFP_DREG_M(rm, insn);
+    } else {
+        rd = VFP_SREG_D(insn);
+        rn = VFP_SREG_N(insn);
+        rm = VFP_SREG_M(insn);
+    }
+
+    if ((insn & 0x0f800e50) == 0x0e000a00) {
+        return handle_vsel(insn, rd, rn, rm, dp);
+    }
+    return 1;
+}
+
 /* Disassemble a VFP instruction.  Returns nonzero if an error occurred
    (ie. an undefined instruction).  */
 static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
@@ -2641,7 +2774,7 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
         /* Encodings with T=1 (Thumb) or unconditional (ARM):
          * only used in v8 and above.
          */
-        return 1;
+        return disas_vfp_v8_insn(env, s, insn);
     }
 
     dp = ((insn & 0xf00) == 0xb00);
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 32/37] softfloat: Remove unused argument from MINMAX macro.
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (30 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 31/37] target-arm: Implement ARMv8 VSEL instruction Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 33/37] softfloat: Add minNum() and maxNum() functions to softfloat Peter Maydell
                   ` (4 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Will Newton <will.newton@linaro.org>

The nan_exp argument is not used, so remove it.

Signed-off-by: Will Newton <will.newton@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1386158099-9239-4-git-send-email-will.newton@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 fpu/softfloat.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 7ba51b6..97bf627 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6706,7 +6706,7 @@ int float128_compare_quiet( float128 a, float128 b STATUS_PARAM )
  * 'compare and pick one input' because that would mishandle
  * NaNs and +0 vs -0.
  */
-#define MINMAX(s, nan_exp)                                              \
+#define MINMAX(s)                                                       \
 INLINE float ## s float ## s ## _minmax(float ## s a, float ## s b,     \
                                         int ismin STATUS_PARAM )        \
 {                                                                       \
@@ -6747,8 +6747,8 @@ float ## s float ## s ## _max(float ## s a, float ## s b STATUS_PARAM)  \
     return float ## s ## _minmax(a, b, 0 STATUS_VAR);                   \
 }
 
-MINMAX(32, 0xff)
-MINMAX(64, 0x7ff)
+MINMAX(32)
+MINMAX(64)
 
 
 /* Multiply A by 2 raised to the power N.  */
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 33/37] softfloat: Add minNum() and maxNum() functions to softfloat.
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (31 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 32/37] softfloat: Remove unused argument from MINMAX macro Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 34/37] target-arm: Implement ARMv8 FP VMAXNM and VMINNM instructions Peter Maydell
                   ` (3 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Will Newton <will.newton@linaro.org>

Add floatnn_minnum() and floatnn_maxnum() functions which are equivalent
to the minNum() and maxNum() functions from IEEE 754-2008. They are
similar to min() and max() but differ in the handling of QNaN arguments.

Signed-off-by: Will Newton <will.newton@linaro.org>
Message-id: 1386158099-9239-5-git-send-email-will.newton@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 fpu/softfloat.c         | 32 +++++++++++++++++++++++++++++---
 include/fpu/softfloat.h |  4 ++++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 97bf627..dbda61b 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6705,10 +6705,17 @@ int float128_compare_quiet( float128 a, float128 b STATUS_PARAM )
 /* min() and max() functions. These can't be implemented as
  * 'compare and pick one input' because that would mishandle
  * NaNs and +0 vs -0.
+ *
+ * minnum() and maxnum() functions. These are similar to the min()
+ * and max() functions but if one of the arguments is a QNaN and
+ * the other is numerical then the numerical argument is returned.
+ * minnum() and maxnum correspond to the IEEE 754-2008 minNum()
+ * and maxNum() operations. min() and max() are the typical min/max
+ * semantics provided by many CPUs which predate that specification.
  */
 #define MINMAX(s)                                                       \
 INLINE float ## s float ## s ## _minmax(float ## s a, float ## s b,     \
-                                        int ismin STATUS_PARAM )        \
+                                        int ismin, int isieee STATUS_PARAM) \
 {                                                                       \
     flag aSign, bSign;                                                  \
     uint ## s ## _t av, bv;                                             \
@@ -6716,6 +6723,15 @@ INLINE float ## s float ## s ## _minmax(float ## s a, float ## s b,     \
     b = float ## s ## _squash_input_denormal(b STATUS_VAR);             \
     if (float ## s ## _is_any_nan(a) ||                                 \
         float ## s ## _is_any_nan(b)) {                                 \
+        if (isieee) {                                                   \
+            if (float ## s ## _is_quiet_nan(a) &&                       \
+                !float ## s ##_is_any_nan(b)) {                         \
+                return b;                                               \
+            } else if (float ## s ## _is_quiet_nan(b) &&                \
+                       !float ## s ## _is_any_nan(a)) {                 \
+                return a;                                               \
+            }                                                           \
+        }                                                               \
         return propagateFloat ## s ## NaN(a, b STATUS_VAR);             \
     }                                                                   \
     aSign = extractFloat ## s ## Sign(a);                               \
@@ -6739,12 +6755,22 @@ INLINE float ## s float ## s ## _minmax(float ## s a, float ## s b,     \
                                                                         \
 float ## s float ## s ## _min(float ## s a, float ## s b STATUS_PARAM)  \
 {                                                                       \
-    return float ## s ## _minmax(a, b, 1 STATUS_VAR);                   \
+    return float ## s ## _minmax(a, b, 1, 0 STATUS_VAR);                \
 }                                                                       \
                                                                         \
 float ## s float ## s ## _max(float ## s a, float ## s b STATUS_PARAM)  \
 {                                                                       \
-    return float ## s ## _minmax(a, b, 0 STATUS_VAR);                   \
+    return float ## s ## _minmax(a, b, 0, 0 STATUS_VAR);                \
+}                                                                       \
+                                                                        \
+float ## s float ## s ## _minnum(float ## s a, float ## s b STATUS_PARAM) \
+{                                                                       \
+    return float ## s ## _minmax(a, b, 1, 1 STATUS_VAR);                \
+}                                                                       \
+                                                                        \
+float ## s float ## s ## _maxnum(float ## s a, float ## s b STATUS_PARAM) \
+{                                                                       \
+    return float ## s ## _minmax(a, b, 0, 1 STATUS_VAR);                \
 }
 
 MINMAX(32)
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index f3927e2..2365274 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -302,6 +302,8 @@ int float32_compare( float32, float32 STATUS_PARAM );
 int float32_compare_quiet( float32, float32 STATUS_PARAM );
 float32 float32_min(float32, float32 STATUS_PARAM);
 float32 float32_max(float32, float32 STATUS_PARAM);
+float32 float32_minnum(float32, float32 STATUS_PARAM);
+float32 float32_maxnum(float32, float32 STATUS_PARAM);
 int float32_is_quiet_nan( float32 );
 int float32_is_signaling_nan( float32 );
 float32 float32_maybe_silence_nan( float32 );
@@ -408,6 +410,8 @@ int float64_compare( float64, float64 STATUS_PARAM );
 int float64_compare_quiet( float64, float64 STATUS_PARAM );
 float64 float64_min(float64, float64 STATUS_PARAM);
 float64 float64_max(float64, float64 STATUS_PARAM);
+float64 float64_minnum(float64, float64 STATUS_PARAM);
+float64 float64_maxnum(float64, float64 STATUS_PARAM);
 int float64_is_quiet_nan( float64 a );
 int float64_is_signaling_nan( float64 );
 float64 float64_maybe_silence_nan( float64 );
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 34/37] target-arm: Implement ARMv8 FP VMAXNM and VMINNM instructions.
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (32 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 33/37] softfloat: Add minNum() and maxNum() functions to softfloat Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 35/37] target-arm: Implement ARMv8 SIMD " Peter Maydell
                   ` (2 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Will Newton <will.newton@linaro.org>

This adds support for the ARMv8 floating point VMAXNM and VMINNM
instructions.

Signed-off-by: Will Newton <will.newton@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1386158099-9239-6-git-send-email-will.newton@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/helper.c    | 25 +++++++++++++++++++++++++
 target-arm/helper.h    |  5 +++++
 target-arm/translate.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 263dbbf..8ec4cb1 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -4085,3 +4085,28 @@ float64 VFP_HELPER(muladd, d)(float64 a, float64 b, float64 c, void *fpstp)
     float_status *fpst = fpstp;
     return float64_muladd(a, b, c, 0, fpst);
 }
+
+/* ARMv8 VMAXNM/VMINNM */
+float32 VFP_HELPER(maxnm, s)(float32 a, float32 b, void *fpstp)
+{
+    float_status *fpst = fpstp;
+    return float32_maxnum(a, b, fpst);
+}
+
+float64 VFP_HELPER(maxnm, d)(float64 a, float64 b, void *fpstp)
+{
+    float_status *fpst = fpstp;
+    return float64_maxnum(a, b, fpst);
+}
+
+float32 VFP_HELPER(minnm, s)(float32 a, float32 b, void *fpstp)
+{
+    float_status *fpst = fpstp;
+    return float32_minnum(a, b, fpst);
+}
+
+float64 VFP_HELPER(minnm, d)(float64 a, float64 b, void *fpstp)
+{
+    float_status *fpst = fpstp;
+    return float64_minnum(a, b, fpst);
+}
diff --git a/target-arm/helper.h b/target-arm/helper.h
index cac9564..d459a39 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -132,6 +132,11 @@ DEF_HELPER_2(neon_fcvt_f32_to_f16, i32, f32, env)
 DEF_HELPER_4(vfp_muladdd, f64, f64, f64, f64, ptr)
 DEF_HELPER_4(vfp_muladds, f32, f32, f32, f32, ptr)
 
+DEF_HELPER_3(vfp_maxnmd, f64, f64, f64, ptr)
+DEF_HELPER_3(vfp_maxnms, f32, f32, f32, ptr)
+DEF_HELPER_3(vfp_minnmd, f64, f64, f64, ptr)
+DEF_HELPER_3(vfp_minnms, f32, f32, f32, ptr)
+
 DEF_HELPER_3(recps_f32, f32, f32, f32, env)
 DEF_HELPER_3(rsqrts_f32, f32, f32, f32, env)
 DEF_HELPER_2(recpe_f32, f32, f32, env)
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 0a22ad8..9a8069e 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -2723,6 +2723,54 @@ static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
     return 0;
 }
 
+static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
+                            uint32_t rm, uint32_t dp)
+{
+    uint32_t vmin = extract32(insn, 6, 1);
+    TCGv_ptr fpst = get_fpstatus_ptr(0);
+
+    if (dp) {
+        TCGv_i64 frn, frm, dest;
+
+        frn = tcg_temp_new_i64();
+        frm = tcg_temp_new_i64();
+        dest = tcg_temp_new_i64();
+
+        tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
+        tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
+        if (vmin) {
+            gen_helper_vfp_minnmd(dest, frn, frm, fpst);
+        } else {
+            gen_helper_vfp_maxnmd(dest, frn, frm, fpst);
+        }
+        tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
+        tcg_temp_free_i64(frn);
+        tcg_temp_free_i64(frm);
+        tcg_temp_free_i64(dest);
+    } else {
+        TCGv_i32 frn, frm, dest;
+
+        frn = tcg_temp_new_i32();
+        frm = tcg_temp_new_i32();
+        dest = tcg_temp_new_i32();
+
+        tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
+        tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
+        if (vmin) {
+            gen_helper_vfp_minnms(dest, frn, frm, fpst);
+        } else {
+            gen_helper_vfp_maxnms(dest, frn, frm, fpst);
+        }
+        tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
+        tcg_temp_free_i32(frn);
+        tcg_temp_free_i32(frm);
+        tcg_temp_free_i32(dest);
+    }
+
+    tcg_temp_free_ptr(fpst);
+    return 0;
+}
+
 static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
 {
     uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
@@ -2743,6 +2791,8 @@ static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
 
     if ((insn & 0x0f800e50) == 0x0e000a00) {
         return handle_vsel(insn, rd, rn, rm, dp);
+    } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
+        return handle_vminmaxnm(insn, rd, rn, rm, dp);
     }
     return 1;
 }
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 35/37] target-arm: Implement ARMv8 SIMD VMAXNM and VMINNM instructions.
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (33 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 34/37] target-arm: Implement ARMv8 FP VMAXNM and VMINNM instructions Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 36/37] target-arm: Use new qemu_ld/st opcodes Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 37/37] target-arm: fix TTBCR write masking Peter Maydell
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Will Newton <will.newton@linaro.org>

This adds support for the ARMv8 Advanced SIMD VMAXNM and VMINNM
instructions.

Signed-off-by: Will Newton <will.newton@linaro.org>
Message-id: 1386158099-9239-7-git-send-email-will.newton@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/translate.c | 31 ++++++++++++++++++++++---------
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 9a8069e..73ed266 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4553,7 +4553,7 @@ static void gen_neon_narrow_op(int op, int u, int size,
 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
-#define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
+#define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
 
 static const uint8_t neon_3r_sizes[] = {
     [NEON_3R_VHADD] = 0x7,
@@ -4586,7 +4586,7 @@ static const uint8_t neon_3r_sizes[] = {
     [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
     [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
     [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
-    [NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */
+    [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
 };
 
 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
@@ -4847,8 +4847,9 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
                 return 1;
             }
             break;
-        case NEON_3R_VRECPS_VRSQRTS:
-            if (u) {
+        case NEON_3R_FLOAT_MISC:
+            /* VMAXNM/VMINNM in ARMv8 */
+            if (u && !arm_feature(env, ARM_FEATURE_V8)) {
                 return 1;
             }
             break;
@@ -5137,11 +5138,23 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
             tcg_temp_free_ptr(fpstatus);
             break;
         }
-        case NEON_3R_VRECPS_VRSQRTS:
-            if (size == 0)
-                gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
-            else
-                gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
+        case NEON_3R_FLOAT_MISC:
+            if (u) {
+                /* VMAXNM/VMINNM */
+                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
+                if (size == 0) {
+                    gen_helper_vfp_maxnms(tmp, tmp, tmp2, fpstatus);
+                } else {
+                    gen_helper_vfp_minnms(tmp, tmp, tmp2, fpstatus);
+                }
+                tcg_temp_free_ptr(fpstatus);
+            } else {
+                if (size == 0) {
+                    gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
+                } else {
+                    gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
+              }
+            }
             break;
         case NEON_3R_VFM:
         {
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 36/37] target-arm: Use new qemu_ld/st opcodes
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (34 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 35/37] target-arm: Implement ARMv8 SIMD " Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  2013-12-10 14:43 ` [Qemu-devel] [PULL 37/37] target-arm: fix TTBCR write masking Peter Maydell
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Richard Henderson <rth@twiddle.net>

Retain the existing gen_aa32_* inlines, to aid compilation for A64.

Cc: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Message-id: 1386628626-21627-1-git-send-email-rth@twiddle.net
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/translate.c | 56 ++++++++++++++++++++++----------------------------
 1 file changed, 25 insertions(+), 31 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 73ed266..8c479ff 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -825,63 +825,57 @@ static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
  * extended if we're a 64 bit core) and  data is also
  * 32 bits unless specifically doing a 64 bit access.
  * These functions work like tcg_gen_qemu_{ld,st}* except
- * that their arguments are TCGv_i32 rather than TCGv.
+ * that the address argument is TCGv_i32 rather than TCGv.
  */
 #if TARGET_LONG_BITS == 32
 
-#define DO_GEN_LD(OP)                                                    \
-static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
+#define DO_GEN_LD(SUFF, OPC)                                             \
+static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
 {                                                                        \
-    tcg_gen_qemu_##OP(val, addr, index);                                 \
+    tcg_gen_qemu_ld_i32(val, addr, index, OPC);                          \
 }
 
-#define DO_GEN_ST(OP)                                                    \
-static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
+#define DO_GEN_ST(SUFF, OPC)                                             \
+static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
 {                                                                        \
-    tcg_gen_qemu_##OP(val, addr, index);                                 \
+    tcg_gen_qemu_st_i32(val, addr, index, OPC);                          \
 }
 
 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
 {
-    tcg_gen_qemu_ld64(val, addr, index);
+    tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ);
 }
 
 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
 {
-    tcg_gen_qemu_st64(val, addr, index);
+    tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ);
 }
 
 #else
 
-#define DO_GEN_LD(OP)                                                    \
-static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
+#define DO_GEN_LD(SUFF, OPC)                                             \
+static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
 {                                                                        \
     TCGv addr64 = tcg_temp_new();                                        \
-    TCGv val64 = tcg_temp_new();                                         \
     tcg_gen_extu_i32_i64(addr64, addr);                                  \
-    tcg_gen_qemu_##OP(val64, addr64, index);                             \
+    tcg_gen_qemu_ld_i32(val, addr64, index, OPC);                        \
     tcg_temp_free(addr64);                                               \
-    tcg_gen_trunc_i64_i32(val, val64);                                   \
-    tcg_temp_free(val64);                                                \
 }
 
-#define DO_GEN_ST(OP)                                                    \
-static inline void gen_aa32_##OP(TCGv_i32 val, TCGv_i32 addr, int index) \
+#define DO_GEN_ST(SUFF, OPC)                                             \
+static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
 {                                                                        \
     TCGv addr64 = tcg_temp_new();                                        \
-    TCGv val64 = tcg_temp_new();                                         \
     tcg_gen_extu_i32_i64(addr64, addr);                                  \
-    tcg_gen_extu_i32_i64(val64, val);                                    \
-    tcg_gen_qemu_##OP(val64, addr64, index);                             \
+    tcg_gen_qemu_st_i32(val, addr64, index, OPC);                        \
     tcg_temp_free(addr64);                                               \
-    tcg_temp_free(val64);                                                \
 }
 
 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
 {
     TCGv addr64 = tcg_temp_new();
     tcg_gen_extu_i32_i64(addr64, addr);
-    tcg_gen_qemu_ld64(val, addr64, index);
+    tcg_gen_qemu_ld_i64(val, addr64, index, MO_TEQ);
     tcg_temp_free(addr64);
 }
 
@@ -889,20 +883,20 @@ static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
 {
     TCGv addr64 = tcg_temp_new();
     tcg_gen_extu_i32_i64(addr64, addr);
-    tcg_gen_qemu_st64(val, addr64, index);
+    tcg_gen_qemu_st_i64(val, addr64, index, MO_TEQ);
     tcg_temp_free(addr64);
 }
 
 #endif
 
-DO_GEN_LD(ld8s)
-DO_GEN_LD(ld8u)
-DO_GEN_LD(ld16s)
-DO_GEN_LD(ld16u)
-DO_GEN_LD(ld32u)
-DO_GEN_ST(st8)
-DO_GEN_ST(st16)
-DO_GEN_ST(st32)
+DO_GEN_LD(8s, MO_SB)
+DO_GEN_LD(8u, MO_UB)
+DO_GEN_LD(16s, MO_TESW)
+DO_GEN_LD(16u, MO_TEUW)
+DO_GEN_LD(32u, MO_TEUL)
+DO_GEN_ST(8, MO_UB)
+DO_GEN_ST(16, MO_TEUW)
+DO_GEN_ST(32, MO_TEUL)
 
 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
 {
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 37/37] target-arm: fix TTBCR write masking
  2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (35 preceding siblings ...)
  2013-12-10 14:43 ` [Qemu-devel] [PULL 36/37] target-arm: Use new qemu_ld/st opcodes Peter Maydell
@ 2013-12-10 14:43 ` Peter Maydell
  36 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-12-10 14:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, qemu-devel, Aurelien Jarno

From: Sergey Fedorov <s.fedorov@samsung.com>

Current implementation is not accurate according to ARMv7-AR reference
manual. See "B4.1.153 TTBCR, Translation Table Base Control Register,
VMSA | TTBCR format when using the Long-descriptor translation table
format". When LPAE feature is supported, EAE, bit[31] selects
translation descriptor format and, therefore, TTBCR format.

Signed-off-by: Sergey Fedorov <s.fedorov@samsung.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1386657709-23399-1-git-send-email-s.fedorov@samsung.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 8ec4cb1..5e5e5aa 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1173,7 +1173,7 @@ static int vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
 {
     int maskshift = extract32(value, 0, 3);
 
-    if (arm_feature(env, ARM_FEATURE_LPAE)) {
+    if (arm_feature(env, ARM_FEATURE_LPAE) && (value & (1 << 31))) {
         value &= ~((7 << 19) | (3 << 14) | (0xf << 3));
     } else {
         value &= 7;
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 00/37] target-arm queue
@ 2018-12-13 14:54 Peter Maydell
  2018-12-14 16:43 ` Peter Maydell
  0 siblings, 1 reply; 43+ messages in thread
From: Peter Maydell @ 2018-12-13 14:54 UTC (permalink / raw)
  To: qemu-devel

First target-arm pullreq of the 4.0 series; most of this
is Mao's cleanups that finally let us drop sysbus::init;
the most interesting user-visible feature is RTH's patches
adding some v8.1 and v8.2 architecture features.

thanks
-- PMM

The following changes since commit 6145a6d84b3bf0f25935b88543febe076c61b0f4:

  Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20181212' into staging (2018-12-13 13:06:09 +0000)

are available in the Git repository at:

  https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20181213

for you to fetch changes up to 2d7137c10fafefe40a0a049ff8a7bd78b66e661f:

  target/arm: Implement the ARMv8.1-LOR extension (2018-12-13 14:41:24 +0000)

----------------------------------------------------------------
target-arm queue:
 * Convert various devices from sysbus init to instance_init
 * Remove the now unused sysbus init support entirely
 * Allow AArch64 processors to boot from a kernel placed over 4GB
 * hw: arm: musicpal: drop TYPE_WM8750 in object_property_set_link()
 * versal: minor fixes to virtio-mmio instantation
 * arm: Implement the ARMv8.1-HPD extension
 * arm: Implement the ARMv8.2-AA32HPD extension
 * arm: Implement the ARMv8.1-LOR extension (as the trivial
   "no limited ordering regions provided" minimum)

----------------------------------------------------------------
Edgar E. Iglesias (4):
      hw/arm: versal: Remove bogus virtio-mmio creation
      hw/arm: versal: Reduce number of virtio-mmio instances
      hw/arm: versal: Use IRQs 111 - 118 for virtio-mmio
      hw/arm: versal: Correct the nr of IRQs to 192

Li Qiang (1):
      hw: arm: musicpal: drop TYPE_WM8750 in object_property_set_link()

Mao Zhongyi (21):
      musicpal: Convert sysbus init function to realize function
      block/noenand: Convert sysbus init function to realize function
      char/grlib_apbuart: Convert sysbus init function to realize function
      core/empty_slot: Convert sysbus init function to realize function
      display/g364fb: Convert sysbus init function to realize function
      dma/puv3_dma: Convert sysbus init function to realize function
      gpio/puv3_gpio: Convert sysbus init function to realize function
      milkymist-softusb: Convert sysbus init function to realize function
      input/pl050: Convert sysbus init function to realize function
      intc/puv3_intc: Convert sysbus init function to realize function
      milkymist-hpdmc: Convert sysbus init function to realize function
      milkymist-pfpu: Convert sysbus init function to realize function
      puv3_pm.c: Convert sysbus init function to realize function
      nvram/ds1225y: Convert sysbus init function to realize function
      pci-bridge/dec: Convert sysbus init function to realize function
      timer/etraxfs_timer: Convert sysbus init function to realize function
      timer/grlib_gptimer: Convert sysbus init function to realize function
      timer/puv3_ost: Convert sysbus init function to realize function
      usb/tusb6010: Convert sysbus init function to realize function
      xen_backend: remove xen_sysdev_init() function
      core/sysbus: remove the SysBusDeviceClass::init path

Peter Maydell (1):
      target/arm: Move id_aa64mmfr* to ARMISARegisters

Ricardo Perez Blanco (1):
      Allow AArch64 processors to boot from a kernel placed over 4GB

Richard Henderson (9):
      target/arm: Add HCR_EL2 bits up to ARMv8.5
      target/arm: Add SCR_EL3 bits up to ARMv8.5
      target/arm: Fix HCR_EL2.TGE check in arm_phys_excp_target_el
      target/arm: Tidy scr_write
      target/arm: Implement the ARMv8.1-HPD extension
      target/arm: Implement the ARMv8.2-AA32HPD extension
      target/arm: Introduce arm_hcr_el2_eff
      target/arm: Use arm_hcr_el2_eff more places
      target/arm: Implement the ARMv8.1-LOR extension

 include/hw/arm/xlnx-versal.h |   8 +-
 include/hw/sysbus.h          |   3 -
 target/arm/cpu.h             | 141 ++++++++++++++++-----------
 target/arm/internals.h       |   3 +-
 hw/arm/boot.c                |  35 ++++---
 hw/arm/musicpal.c            |  11 +--
 hw/arm/xlnx-versal-virt.c    |   7 +-
 hw/block/onenand.c           |  16 ++--
 hw/char/grlib_apbuart.c      |  12 +--
 hw/core/empty_slot.c         |   9 +-
 hw/core/sysbus.c             |  15 +--
 hw/display/g364fb.c          |   9 +-
 hw/dma/puv3_dma.c            |  10 +-
 hw/gpio/puv3_gpio.c          |  29 +++---
 hw/input/milkymist-softusb.c |  16 ++--
 hw/input/pl050.c             |  11 +--
 hw/intc/arm_gicv3_cpuif.c    |  21 ++--
 hw/intc/puv3_intc.c          |  11 +--
 hw/misc/milkymist-hpdmc.c    |   9 +-
 hw/misc/milkymist-pfpu.c     |  12 +--
 hw/misc/puv3_pm.c            |  10 +-
 hw/nvram/ds1225y.c           |  12 +--
 hw/pci-bridge/dec.c          |  12 +--
 hw/timer/etraxfs_timer.c     |  14 +--
 hw/timer/grlib_gptimer.c     |  11 +--
 hw/timer/puv3_ost.c          |  13 ++-
 hw/usb/tusb6010.c            |   8 +-
 hw/xen/xen_backend.c         |   7 --
 target/arm/cpu.c             |   4 +
 target/arm/cpu64.c           |  11 ++-
 target/arm/helper.c          | 222 ++++++++++++++++++++++++++++++++++++-------
 target/arm/kvm64.c           |   4 +
 target/arm/op_helper.c       |  14 ++-
 target/arm/translate-a64.c   |  12 +++
 34 files changed, 456 insertions(+), 286 deletions(-)

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [Qemu-devel] [PULL 00/37] target-arm queue
  2018-12-13 14:54 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
@ 2018-12-14 16:43 ` Peter Maydell
  0 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2018-12-14 16:43 UTC (permalink / raw)
  To: QEMU Developers

On Thu, 13 Dec 2018 at 14:56, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> First target-arm pullreq of the 4.0 series; most of this
> is Mao's cleanups that finally let us drop sysbus::init;
> the most interesting user-visible feature is RTH's patches
> adding some v8.1 and v8.2 architecture features.
>
> thanks
> -- PMM
>
> The following changes since commit 6145a6d84b3bf0f25935b88543febe076c61b0f4:
>
>   Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20181212' into staging (2018-12-13 13:06:09 +0000)
>
> are available in the Git repository at:
>
>   https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20181213
>
> for you to fetch changes up to 2d7137c10fafefe40a0a049ff8a7bd78b66e661f:
>
>   target/arm: Implement the ARMv8.1-LOR extension (2018-12-13 14:41:24 +0000)
>
> ----------------------------------------------------------------
> target-arm queue:
>  * Convert various devices from sysbus init to instance_init
>  * Remove the now unused sysbus init support entirely
>  * Allow AArch64 processors to boot from a kernel placed over 4GB
>  * hw: arm: musicpal: drop TYPE_WM8750 in object_property_set_link()
>  * versal: minor fixes to virtio-mmio instantation
>  * arm: Implement the ARMv8.1-HPD extension
>  * arm: Implement the ARMv8.2-AA32HPD extension
>  * arm: Implement the ARMv8.1-LOR extension (as the trivial
>    "no limited ordering regions provided" minimum)
>
Applied, thanks.

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

-- PMM

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [Qemu-devel] [PULL 00/37] target-arm queue
@ 2019-01-07 16:30 Peter Maydell
  2019-01-07 18:24 ` Peter Maydell
  2019-01-07 20:29 ` no-reply
  0 siblings, 2 replies; 43+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

target-arm queue: the big things here are the new nRF51
(microbit) devices and Luc's gdbstub multiprocess work.

thanks
-- PMM

The following changes since commit a29644590f95166c8a13e5797f8e7701134b31d0:

  Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2019-01-05' into staging (2019-01-07 11:55:52 +0000)

are available in the Git repository at:

  https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190107

for you to fetch changes up to f831f955d420966471f5f8b316ba50d2523b1ff0:

  Support u-boot noload images for arm as used by, NetBSD/evbarm GENERIC kernel. (2019-01-07 15:46:20 +0000)

----------------------------------------------------------------
target-arm queue:
 * Support u-boot 'noload' images for Arm (as used by NetBSD/evbarm GENERIC kernel)
 * hw/misc/tz-mpc: Fix value of BLK_MAX register
 * target/arm: Emit barriers for A32/T32 load-acquire/store-release insns
 * nRF51 SoC: add timer, GPIO, RNG peripherals
 * hw/arm/allwinner-a10: Add the 'A' SRAM and the SRAM controller
 * cpus.c: Fix race condition in cpu_stop_current()
 * hw/arm: versal: Plug memory leaks
 * Allow M profile boards to run even if -kernel not specified
 * gdbstub: Add multiprocess extension support for use when the
   board has multiple CPUs of different types (like the Xilinx Zynq boards)
 * target/arm: Don't decode S bit in SVE brk[ab] merging insns
 * target/arm: Convert ARM_TBFLAG_* to FIELDs

----------------------------------------------------------------
Edgar E. Iglesias (1):
      hw/arm: versal: Plug memory leaks

Luc Michel (16):
      hw/cpu: introduce CPU clusters
      gdbstub: introduce GDB processes
      gdbstub: add multiprocess support to '?' packets
      gdbstub: add multiprocess support to 'H' and 'T' packets
      gdbstub: add multiprocess support to vCont packets
      gdbstub: add multiprocess support to 'sC' packets
      gdbstub: add multiprocess support to (f|s)ThreadInfo and ThreadExtraInfo
      gdbstub: add multiprocess support to Xfer:features:read:
      gdbstub: add multiprocess support to gdb_vm_state_change()
      gdbstub: add multiprocess support to 'D' packets
      gdbstub: add support for extended mode packet
      gdbstub: add support for vAttach packets
      gdbstub: processes initialization on new peer connection
      gdbstub: gdb_set_stop_cpu: ignore request when process is not attached
      gdbstub: add multiprocess extension support
      arm/xlnx-zynqmp: put APUs and RPUs in separate CPU clusters

Nick Hudson (1):
      Support u-boot noload images for arm as used by, NetBSD/evbarm GENERIC kernel.

Peter Maydell (3):
      cpus.c: Fix race condition in cpu_stop_current()
      target/arm: Emit barriers for A32/T32 load-acquire/store-release insns
      hw/misc/tz-mpc: Fix value of BLK_MAX register

Philippe Mathieu-Daudé (1):
      hw/arm/allwinner-a10: Add the 'A' SRAM and the SRAM controller

Richard Henderson (2):
      target/arm: Convert ARM_TBFLAG_* to FIELDs
      target/arm: SVE brk[ab] merging does not have s bit

Stefan Hajnoczi (1):
      Revert "armv7m: Guard against no -kernel argument"

Steffen Görtz (11):
      qtest: Add set_irq_in command to set IRQ/GPIO level
      arm: Add header to host common definition for nRF51 SOC peripherals
      hw/misc/nrf51_rng: Add NRF51 random number generator peripheral
      arm: Instantiate NRF51 random number generator
      hw/gpio/nrf51_gpio: Add nRF51 GPIO peripheral
      arm: Instantiate NRF51 general purpose I/O
      tests/microbit-test: Add Tests for nRF51 GPIO
      hw/timer/nrf51_timer: Add nRF51 Timer peripheral
      arm: Instantiate NRF51 Timers
      tests/microbit-test: Add Tests for nRF51 Timer
      arm: Add Clock peripheral stub to NRF51 SOC

Thomas Huth (1):
      MAINTAINERS: Add ARM-related files for hw/[misc|input|timer]/

 Makefile.objs                  |   1 +
 hw/cpu/Makefile.objs           |   2 +-
 hw/gpio/Makefile.objs          |   1 +
 hw/misc/Makefile.objs          |   1 +
 hw/timer/Makefile.objs         |   1 +
 tests/Makefile.include         |   2 +
 hw/core/uboot_image.h          |   1 +
 include/hw/arm/allwinner-a10.h |   1 +
 include/hw/arm/nrf51.h         |  45 +++
 include/hw/arm/nrf51_soc.h     |   9 +
 include/hw/arm/xlnx-zynqmp.h   |   3 +
 include/hw/char/nrf51_uart.h   |   1 -
 include/hw/cpu/cluster.h       |  58 ++++
 include/hw/gpio/nrf51_gpio.h   |  69 +++++
 include/hw/loader.h            |   7 +-
 include/hw/misc/nrf51_rng.h    |  83 +++++
 include/hw/timer/nrf51_timer.h |  80 +++++
 target/arm/cpu.h               | 102 ++-----
 tests/libqtest.h               |  13 +
 cpus.c                         |   3 +-
 gdbstub.c                      | 672 ++++++++++++++++++++++++++++++++++++-----
 hw/arm/allwinner-a10.c         |   6 +
 hw/arm/armv7m.c                |   5 -
 hw/arm/boot.c                  |   8 +-
 hw/arm/nrf51_soc.c             | 117 +++++--
 hw/arm/xlnx-versal-virt.c      |   2 +
 hw/arm/xlnx-zynqmp.c           |  23 +-
 hw/core/loader.c               |  19 +-
 hw/cpu/cluster.c               |  50 +++
 hw/gpio/nrf51_gpio.c           | 300 ++++++++++++++++++
 hw/microblaze/boot.c           |   2 +-
 hw/misc/nrf51_rng.c            | 262 ++++++++++++++++
 hw/misc/tz-mpc.c               |   2 +-
 hw/nios2/boot.c                |   2 +-
 hw/ppc/e500.c                  |   1 +
 hw/ppc/ppc440_bamboo.c         |   2 +-
 hw/ppc/sam460ex.c              |   2 +-
 hw/timer/nrf51_timer.c         | 393 ++++++++++++++++++++++++
 qtest.c                        |  43 +++
 target/arm/helper.c            |  49 ++-
 target/arm/translate-a64.c     |  22 +-
 target/arm/translate.c         |  73 +++--
 tests/libqtest.c               |  10 +
 tests/microbit-test.c          | 255 ++++++++++++++++
 MAINTAINERS                    |  18 +-
 hw/gpio/trace-events           |   7 +
 hw/timer/trace-events          |   5 +
 target/arm/sve.decode          |   5 +-
 48 files changed, 2567 insertions(+), 271 deletions(-)
 create mode 100644 include/hw/arm/nrf51.h
 create mode 100644 include/hw/cpu/cluster.h
 create mode 100644 include/hw/gpio/nrf51_gpio.h
 create mode 100644 include/hw/misc/nrf51_rng.h
 create mode 100644 include/hw/timer/nrf51_timer.h
 create mode 100644 hw/cpu/cluster.c
 create mode 100644 hw/gpio/nrf51_gpio.c
 create mode 100644 hw/misc/nrf51_rng.c
 create mode 100644 hw/timer/nrf51_timer.c
 create mode 100644 tests/microbit-test.c
 create mode 100644 hw/gpio/trace-events

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [Qemu-devel] [PULL 00/37] target-arm queue
  2019-01-07 16:30 Peter Maydell
@ 2019-01-07 18:24 ` Peter Maydell
  2019-01-07 20:29 ` no-reply
  1 sibling, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2019-01-07 18:24 UTC (permalink / raw)
  To: QEMU Developers

On Mon, 7 Jan 2019 at 16:31, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> target-arm queue: the big things here are the new nRF51
> (microbit) devices and Luc's gdbstub multiprocess work.
>
> thanks
> -- PMM
>
> The following changes since commit a29644590f95166c8a13e5797f8e7701134b31d0:
>
>   Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2019-01-05' into staging (2019-01-07 11:55:52 +0000)
>
> are available in the Git repository at:
>
>   https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190107
>
> for you to fetch changes up to f831f955d420966471f5f8b316ba50d2523b1ff0:
>
>   Support u-boot noload images for arm as used by, NetBSD/evbarm GENERIC kernel. (2019-01-07 15:46:20 +0000)
>
> ----------------------------------------------------------------
> target-arm queue:
>  * Support u-boot 'noload' images for Arm (as used by NetBSD/evbarm GENERIC kernel)
>  * hw/misc/tz-mpc: Fix value of BLK_MAX register
>  * target/arm: Emit barriers for A32/T32 load-acquire/store-release insns
>  * nRF51 SoC: add timer, GPIO, RNG peripherals
>  * hw/arm/allwinner-a10: Add the 'A' SRAM and the SRAM controller
>  * cpus.c: Fix race condition in cpu_stop_current()
>  * hw/arm: versal: Plug memory leaks
>  * Allow M profile boards to run even if -kernel not specified
>  * gdbstub: Add multiprocess extension support for use when the
>    board has multiple CPUs of different types (like the Xilinx Zynq boards)
>  * target/arm: Don't decode S bit in SVE brk[ab] merging insns
>  * target/arm: Convert ARM_TBFLAG_* to FIELDs


Applied, thanks.

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

-- PMM

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [Qemu-devel] [PULL 00/37] target-arm queue
  2019-01-07 16:30 Peter Maydell
  2019-01-07 18:24 ` Peter Maydell
@ 2019-01-07 20:29 ` no-reply
  1 sibling, 0 replies; 43+ messages in thread
From: no-reply @ 2019-01-07 20:29 UTC (permalink / raw)
  To: peter.maydell; +Cc: fam, qemu-devel

Patchew URL: https://patchew.org/QEMU/20190107163117.16269-1-peter.maydell@linaro.org/



Hi,

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

Subject: [Qemu-devel] [PULL 00/37] target-arm queue
Message-id: 20190107163117.16269-1-peter.maydell@linaro.org
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
b2409c8 Support u-boot noload images for arm as used by, NetBSD/evbarm GENERIC kernel.
a212ed8 hw/misc/tz-mpc: Fix value of BLK_MAX register
d3d8681 target/arm: Emit barriers for A32/T32 load-acquire/store-release insns
95dc9ac arm: Add Clock peripheral stub to NRF51 SOC
814a757 tests/microbit-test: Add Tests for nRF51 Timer
31d3967 arm: Instantiate NRF51 Timers
a07deaf hw/timer/nrf51_timer: Add nRF51 Timer peripheral
1659930 tests/microbit-test: Add Tests for nRF51 GPIO
a0f346b arm: Instantiate NRF51 general purpose I/O
51dadd5 hw/gpio/nrf51_gpio: Add nRF51 GPIO peripheral
f5e930f arm: Instantiate NRF51 random number generator
10a0ea4 hw/misc/nrf51_rng: Add NRF51 random number generator peripheral
27b50a5 arm: Add header to host common definition for nRF51 SOC peripherals
328b5be qtest: Add set_irq_in command to set IRQ/GPIO level
04a8786 hw/arm/allwinner-a10: Add the 'A' SRAM and the SRAM controller
9ed39b1 cpus.c: Fix race condition in cpu_stop_current()
5f802b8 MAINTAINERS: Add ARM-related files for hw/[misc|input|timer]/
9731ced hw/arm: versal: Plug memory leaks
d60bc50 Revert "armv7m: Guard against no -kernel argument"
5ad714f arm/xlnx-zynqmp: put APUs and RPUs in separate CPU clusters
1df1cea gdbstub: add multiprocess extension support
531013e gdbstub: gdb_set_stop_cpu: ignore request when process is not attached
fbbf155 gdbstub: processes initialization on new peer connection
6bfe258 gdbstub: add support for vAttach packets
6deda56 gdbstub: add support for extended mode packet
b680a90 gdbstub: add multiprocess support to 'D' packets
f57d087 gdbstub: add multiprocess support to gdb_vm_state_change()
e9badd6 gdbstub: add multiprocess support to Xfer:features:read:
34b351b gdbstub: add multiprocess support to (f|s)ThreadInfo and ThreadExtraInfo
c1bf225 gdbstub: add multiprocess support to 'sC' packets
a5c8ccd gdbstub: add multiprocess support to vCont packets
f90eb5e gdbstub: add multiprocess support to 'H' and 'T' packets
01bf3a9 gdbstub: add multiprocess support to '?' packets
182cc17 gdbstub: introduce GDB processes
e54216e hw/cpu: introduce CPU clusters
029c2eb target/arm: SVE brk[ab] merging does not have s bit
cdbc6a8 target/arm: Convert ARM_TBFLAG_* to FIELDs

=== OUTPUT BEGIN ===
Checking PATCH 1/37: target/arm: Convert ARM_TBFLAG_* to FIELDs...
Checking PATCH 2/37: target/arm: SVE brk[ab] merging does not have s bit...
Checking PATCH 3/37: hw/cpu: introduce CPU clusters...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#50: 
new file mode 100644

WARNING: Block comments use a leading /* on a separate line
#153: FILE: include/hw/cpu/cluster.h:43:
+/**

total: 0 errors, 2 warnings, 122 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 4/37: gdbstub: introduce GDB processes...
Checking PATCH 5/37: gdbstub: add multiprocess support to '?' packets...
Checking PATCH 6/37: gdbstub: add multiprocess support to 'H' and 'T' packets...
Checking PATCH 7/37: gdbstub: add multiprocess support to vCont packets...
Checking PATCH 8/37: gdbstub: add multiprocess support to 'sC' packets...
Checking PATCH 9/37: gdbstub: add multiprocess support to (f|s)ThreadInfo and ThreadExtraInfo...
Checking PATCH 10/37: gdbstub: add multiprocess support to Xfer:features:read:...
Checking PATCH 11/37: gdbstub: add multiprocess support to gdb_vm_state_change()...
Checking PATCH 12/37: gdbstub: add multiprocess support to 'D' packets...
Checking PATCH 13/37: gdbstub: add support for extended mode packet...
Checking PATCH 14/37: gdbstub: add support for vAttach packets...
Checking PATCH 15/37: gdbstub: processes initialization on new peer connection...
Checking PATCH 16/37: gdbstub: gdb_set_stop_cpu: ignore request when process is not attached...
Checking PATCH 17/37: gdbstub: add multiprocess extension support...
Checking PATCH 18/37: arm/xlnx-zynqmp: put APUs and RPUs in separate CPU clusters...
Checking PATCH 19/37: Revert "armv7m: Guard against no -kernel argument"...
Checking PATCH 20/37: hw/arm: versal: Plug memory leaks...
Checking PATCH 21/37: MAINTAINERS: Add ARM-related files for hw/[misc|input|timer]/...
Checking PATCH 22/37: cpus.c: Fix race condition in cpu_stop_current()...
Checking PATCH 23/37: hw/arm/allwinner-a10: Add the 'A' SRAM and the SRAM controller...
Checking PATCH 24/37: qtest: Add set_irq_in command to set IRQ/GPIO level...
WARNING: Block comments use a leading /* on a separate line
#132: FILE: tests/libqtest.h:246:
+/**

total: 0 errors, 1 warnings, 91 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 25/37: arm: Add header to host common definition for nRF51 SOC peripherals...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#97: 
new file mode 100644

total: 0 errors, 1 warnings, 120 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 26/37: hw/misc/nrf51_rng: Add NRF51 random number generator peripheral...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#34: 
new file mode 100644

total: 0 errors, 1 warnings, 349 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 27/37: arm: Instantiate NRF51 random number generator...
Checking PATCH 28/37: hw/gpio/nrf51_gpio: Add nRF51 GPIO peripheral...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#51: 
new file mode 100644

total: 0 errors, 1 warnings, 387 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 29/37: arm: Instantiate NRF51 general purpose I/O...
Checking PATCH 30/37: tests/microbit-test: Add Tests for nRF51 GPIO...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#43: 
new file mode 100644

total: 0 errors, 1 warnings, 174 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 31/37: hw/timer/nrf51_timer: Add nRF51 Timer peripheral...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#32: 
new file mode 100644

total: 0 errors, 1 warnings, 488 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 32/37: arm: Instantiate NRF51 Timers...
Checking PATCH 33/37: tests/microbit-test: Add Tests for nRF51 Timer...
Checking PATCH 34/37: arm: Add Clock peripheral stub to NRF51 SOC...
Checking PATCH 35/37: target/arm: Emit barriers for A32/T32 load-acquire/store-release insns...
Checking PATCH 36/37: hw/misc/tz-mpc: Fix value of BLK_MAX register...
Checking PATCH 37/37: Support u-boot noload images for arm as used by, NetBSD/evbarm GENERIC kernel....
ERROR: code indent should never use tabs
#94: FILE: hw/core/uboot_image.h:127:
+#define IH_TYPE_KERNEL_NOLOAD  14^I/* OS Kernel Image (noload)^I*/$

total: 1 errors, 0 warnings, 111 lines checked

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

=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20190107163117.16269-1-peter.maydell@linaro.org/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

^ permalink raw reply	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2019-01-07 22:15 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
2013-12-10 14:42 ` [Qemu-devel] [PULL 01/37] integrator/cp: add support for REFCNT register Peter Maydell
2013-12-10 14:42 ` [Qemu-devel] [PULL 02/37] cpu/a9mpcore: rename timerbusdev variable Peter Maydell
2013-12-10 14:42 ` [Qemu-devel] [PULL 03/37] cpu/a9mpcore: reorder operations/declarations Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 04/37] hw/timer: Introduce ARM A9 Global Timer Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 05/37] cpu/a9mpcore: Add " Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 06/37] target-arm: Provide mechanism for getting KVM constants even if not CONFIG_KVM Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 07/37] device_tree.c: Terminate the empty reservemap in create_device_tree() Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 08/37] hw/arm/boot: Allow boards to provide an fdt blob Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 09/37] target-arm: Provide PSCI constants to generic QEMU code Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 10/37] target-arm: Add ARMCPU field for Linux device-tree 'compatible' string Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 11/37] target-arm: Allow secondary KVM CPUs to be booted via PSCI Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 12/37] hw/arm: Add 'virt' platform Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 13/37] target-arm: Don't hardcode KVM target CPU to be A15 Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 14/37] target-arm: Provide '-cpu host' when running KVM Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 15/37] hw/arm/virt: Support -cpu host Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 16/37] net/cadence_gem: Implement mac level loopback mode Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 17/37] net/cadence_gem: Update DMA rx descriptors as we process them Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 18/37] net/cadence_gem: Don't assert against 0 buffer address Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 19/37] net/cadence_gem: simplify rx buf descriptor walking Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 20/37] net/cadence_gem: Prefetch rx descriptors ASAP Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 21/37] net/cadence_gem: Implement RX descriptor match mode flags Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 22/37] net/cadence_gem: Implement SAR match bit in rx desc Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 23/37] net/cadence_gem: Implement SAR (de)activation Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 24/37] net/cadence_gem: Add missing VMSTATE_END_OF_LIST Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 25/37] net/cadence_gem: Fix rx multi-fragment packets Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 26/37] net/cadence_gem: Fix small packet FCS stripping Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 27/37] net/cadence_gem: Fix register w1c logic Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 28/37] net/cadence_gem: Improve can_receive debug printfery Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 29/37] net/cadence_gem: Don't rx packets when no rx buffer available Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 30/37] target-arm: Move call to disas_vfp_insn out of disas_coproc_insn Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 31/37] target-arm: Implement ARMv8 VSEL instruction Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 32/37] softfloat: Remove unused argument from MINMAX macro Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 33/37] softfloat: Add minNum() and maxNum() functions to softfloat Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 34/37] target-arm: Implement ARMv8 FP VMAXNM and VMINNM instructions Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 35/37] target-arm: Implement ARMv8 SIMD " Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 36/37] target-arm: Use new qemu_ld/st opcodes Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 37/37] target-arm: fix TTBCR write masking Peter Maydell
  -- strict thread matches above, loose matches on Subject: below --
2018-12-13 14:54 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
2018-12-14 16:43 ` Peter Maydell
2019-01-07 16:30 Peter Maydell
2019-01-07 18:24 ` Peter Maydell
2019-01-07 20:29 ` no-reply

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).