All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/37] target-arm queue
@ 2019-01-07 16:30 Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 01/37] target/arm: Convert ARM_TBFLAG_* to FIELDs Peter Maydell
                   ` (38 more replies)
  0 siblings, 39 replies; 49+ 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] 49+ messages in thread

* [Qemu-devel] [PULL 01/37] target/arm: Convert ARM_TBFLAG_* to FIELDs
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 02/37] target/arm: SVE brk[ab] merging does not have s bit Peter Maydell
                   ` (37 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Richard Henderson <richard.henderson@linaro.org>

Use "register" TBFLAG_ANY to indicate shared state between
A32 and A64, and "registers" TBFLAG_A32 & TBFLAG_A64 for
fields that are specific to the given cpu state.

Move ARM_TBFLAG_BE_DATA to shared state, instead of its current
placement within "Bit usage when in AArch32 state".

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20181218164348.7127-1-richard.henderson@linaro.org
[PMM: removed the renaming of BE_DATA flag to BE]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h           | 102 ++++++++-----------------------------
 target/arm/helper.c        |  49 +++++++++---------
 target/arm/translate-a64.c |  22 ++++----
 target/arm/translate.c     |  40 ++++++++-------
 4 files changed, 78 insertions(+), 135 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index c943f35dd92..fba1c578d30 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2944,102 +2944,40 @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
  * We put flags which are shared between 32 and 64 bit mode at the top
  * of the word, and flags which apply to only one mode at the bottom.
  */
-#define ARM_TBFLAG_AARCH64_STATE_SHIFT 31
-#define ARM_TBFLAG_AARCH64_STATE_MASK  (1U << ARM_TBFLAG_AARCH64_STATE_SHIFT)
-#define ARM_TBFLAG_MMUIDX_SHIFT 28
-#define ARM_TBFLAG_MMUIDX_MASK (0x7 << ARM_TBFLAG_MMUIDX_SHIFT)
-#define ARM_TBFLAG_SS_ACTIVE_SHIFT 27
-#define ARM_TBFLAG_SS_ACTIVE_MASK (1 << ARM_TBFLAG_SS_ACTIVE_SHIFT)
-#define ARM_TBFLAG_PSTATE_SS_SHIFT 26
-#define ARM_TBFLAG_PSTATE_SS_MASK (1 << ARM_TBFLAG_PSTATE_SS_SHIFT)
+FIELD(TBFLAG_ANY, AARCH64_STATE, 31, 1)
+FIELD(TBFLAG_ANY, MMUIDX, 28, 3)
+FIELD(TBFLAG_ANY, SS_ACTIVE, 27, 1)
+FIELD(TBFLAG_ANY, PSTATE_SS, 26, 1)
 /* Target EL if we take a floating-point-disabled exception */
-#define ARM_TBFLAG_FPEXC_EL_SHIFT 24
-#define ARM_TBFLAG_FPEXC_EL_MASK (0x3 << ARM_TBFLAG_FPEXC_EL_SHIFT)
+FIELD(TBFLAG_ANY, FPEXC_EL, 24, 2)
+FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
 
 /* Bit usage when in AArch32 state: */
-#define ARM_TBFLAG_THUMB_SHIFT      0
-#define ARM_TBFLAG_THUMB_MASK       (1 << ARM_TBFLAG_THUMB_SHIFT)
-#define ARM_TBFLAG_VECLEN_SHIFT     1
-#define ARM_TBFLAG_VECLEN_MASK      (0x7 << ARM_TBFLAG_VECLEN_SHIFT)
-#define ARM_TBFLAG_VECSTRIDE_SHIFT  4
-#define ARM_TBFLAG_VECSTRIDE_MASK   (0x3 << ARM_TBFLAG_VECSTRIDE_SHIFT)
-#define ARM_TBFLAG_VFPEN_SHIFT      7
-#define ARM_TBFLAG_VFPEN_MASK       (1 << ARM_TBFLAG_VFPEN_SHIFT)
-#define ARM_TBFLAG_CONDEXEC_SHIFT   8
-#define ARM_TBFLAG_CONDEXEC_MASK    (0xff << ARM_TBFLAG_CONDEXEC_SHIFT)
-#define ARM_TBFLAG_SCTLR_B_SHIFT    16
-#define ARM_TBFLAG_SCTLR_B_MASK     (1 << ARM_TBFLAG_SCTLR_B_SHIFT)
+FIELD(TBFLAG_A32, THUMB, 0, 1)
+FIELD(TBFLAG_A32, VECLEN, 1, 3)
+FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
+FIELD(TBFLAG_A32, VFPEN, 7, 1)
+FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
+FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
 /* We store the bottom two bits of the CPAR as TB flags and handle
  * checks on the other bits at runtime
  */
-#define ARM_TBFLAG_XSCALE_CPAR_SHIFT 17
-#define ARM_TBFLAG_XSCALE_CPAR_MASK (3 << ARM_TBFLAG_XSCALE_CPAR_SHIFT)
+FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
 /* Indicates whether cp register reads and writes by guest code should access
  * the secure or nonsecure bank of banked registers; note that this is not
  * the same thing as the current security state of the processor!
  */
-#define ARM_TBFLAG_NS_SHIFT         19
-#define ARM_TBFLAG_NS_MASK          (1 << ARM_TBFLAG_NS_SHIFT)
-#define ARM_TBFLAG_BE_DATA_SHIFT    20
-#define ARM_TBFLAG_BE_DATA_MASK     (1 << ARM_TBFLAG_BE_DATA_SHIFT)
+FIELD(TBFLAG_A32, NS, 19, 1)
 /* For M profile only, Handler (ie not Thread) mode */
-#define ARM_TBFLAG_HANDLER_SHIFT    21
-#define ARM_TBFLAG_HANDLER_MASK     (1 << ARM_TBFLAG_HANDLER_SHIFT)
+FIELD(TBFLAG_A32, HANDLER, 21, 1)
 /* For M profile only, whether we should generate stack-limit checks */
-#define ARM_TBFLAG_STACKCHECK_SHIFT 22
-#define ARM_TBFLAG_STACKCHECK_MASK  (1 << ARM_TBFLAG_STACKCHECK_SHIFT)
+FIELD(TBFLAG_A32, STACKCHECK, 22, 1)
 
 /* Bit usage when in AArch64 state */
-#define ARM_TBFLAG_TBI0_SHIFT 0        /* TBI0 for EL0/1 or TBI for EL2/3 */
-#define ARM_TBFLAG_TBI0_MASK (0x1ull << ARM_TBFLAG_TBI0_SHIFT)
-#define ARM_TBFLAG_TBI1_SHIFT 1        /* TBI1 for EL0/1  */
-#define ARM_TBFLAG_TBI1_MASK (0x1ull << ARM_TBFLAG_TBI1_SHIFT)
-#define ARM_TBFLAG_SVEEXC_EL_SHIFT  2
-#define ARM_TBFLAG_SVEEXC_EL_MASK   (0x3 << ARM_TBFLAG_SVEEXC_EL_SHIFT)
-#define ARM_TBFLAG_ZCR_LEN_SHIFT    4
-#define ARM_TBFLAG_ZCR_LEN_MASK     (0xf << ARM_TBFLAG_ZCR_LEN_SHIFT)
-
-/* some convenience accessor macros */
-#define ARM_TBFLAG_AARCH64_STATE(F) \
-    (((F) & ARM_TBFLAG_AARCH64_STATE_MASK) >> ARM_TBFLAG_AARCH64_STATE_SHIFT)
-#define ARM_TBFLAG_MMUIDX(F) \
-    (((F) & ARM_TBFLAG_MMUIDX_MASK) >> ARM_TBFLAG_MMUIDX_SHIFT)
-#define ARM_TBFLAG_SS_ACTIVE(F) \
-    (((F) & ARM_TBFLAG_SS_ACTIVE_MASK) >> ARM_TBFLAG_SS_ACTIVE_SHIFT)
-#define ARM_TBFLAG_PSTATE_SS(F) \
-    (((F) & ARM_TBFLAG_PSTATE_SS_MASK) >> ARM_TBFLAG_PSTATE_SS_SHIFT)
-#define ARM_TBFLAG_FPEXC_EL(F) \
-    (((F) & ARM_TBFLAG_FPEXC_EL_MASK) >> ARM_TBFLAG_FPEXC_EL_SHIFT)
-#define ARM_TBFLAG_THUMB(F) \
-    (((F) & ARM_TBFLAG_THUMB_MASK) >> ARM_TBFLAG_THUMB_SHIFT)
-#define ARM_TBFLAG_VECLEN(F) \
-    (((F) & ARM_TBFLAG_VECLEN_MASK) >> ARM_TBFLAG_VECLEN_SHIFT)
-#define ARM_TBFLAG_VECSTRIDE(F) \
-    (((F) & ARM_TBFLAG_VECSTRIDE_MASK) >> ARM_TBFLAG_VECSTRIDE_SHIFT)
-#define ARM_TBFLAG_VFPEN(F) \
-    (((F) & ARM_TBFLAG_VFPEN_MASK) >> ARM_TBFLAG_VFPEN_SHIFT)
-#define ARM_TBFLAG_CONDEXEC(F) \
-    (((F) & ARM_TBFLAG_CONDEXEC_MASK) >> ARM_TBFLAG_CONDEXEC_SHIFT)
-#define ARM_TBFLAG_SCTLR_B(F) \
-    (((F) & ARM_TBFLAG_SCTLR_B_MASK) >> ARM_TBFLAG_SCTLR_B_SHIFT)
-#define ARM_TBFLAG_XSCALE_CPAR(F) \
-    (((F) & ARM_TBFLAG_XSCALE_CPAR_MASK) >> ARM_TBFLAG_XSCALE_CPAR_SHIFT)
-#define ARM_TBFLAG_NS(F) \
-    (((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT)
-#define ARM_TBFLAG_BE_DATA(F) \
-    (((F) & ARM_TBFLAG_BE_DATA_MASK) >> ARM_TBFLAG_BE_DATA_SHIFT)
-#define ARM_TBFLAG_HANDLER(F) \
-    (((F) & ARM_TBFLAG_HANDLER_MASK) >> ARM_TBFLAG_HANDLER_SHIFT)
-#define ARM_TBFLAG_STACKCHECK(F) \
-    (((F) & ARM_TBFLAG_STACKCHECK_MASK) >> ARM_TBFLAG_STACKCHECK_SHIFT)
-#define ARM_TBFLAG_TBI0(F) \
-    (((F) & ARM_TBFLAG_TBI0_MASK) >> ARM_TBFLAG_TBI0_SHIFT)
-#define ARM_TBFLAG_TBI1(F) \
-    (((F) & ARM_TBFLAG_TBI1_MASK) >> ARM_TBFLAG_TBI1_SHIFT)
-#define ARM_TBFLAG_SVEEXC_EL(F) \
-    (((F) & ARM_TBFLAG_SVEEXC_EL_MASK) >> ARM_TBFLAG_SVEEXC_EL_SHIFT)
-#define ARM_TBFLAG_ZCR_LEN(F) \
-    (((F) & ARM_TBFLAG_ZCR_LEN_MASK) >> ARM_TBFLAG_ZCR_LEN_SHIFT)
+FIELD(TBFLAG_A64, TBI0, 0, 1)
+FIELD(TBFLAG_A64, TBI1, 1, 1)
+FIELD(TBFLAG_A64, SVEEXC_EL, 2, 2)
+FIELD(TBFLAG_A64, ZCR_LEN, 4, 4)
 
 static inline bool bswap_code(bool sctlr_b)
 {
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 644599b29d6..f00c141ef96 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -12955,16 +12955,18 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
     ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
     int current_el = arm_current_el(env);
     int fp_el = fp_exception_el(env, current_el);
-    uint32_t flags;
+    uint32_t flags = 0;
 
     if (is_a64(env)) {
         ARMCPU *cpu = arm_env_get_cpu(env);
 
         *pc = env->pc;
-        flags = ARM_TBFLAG_AARCH64_STATE_MASK;
+        flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
         /* Get control bits for tagged addresses */
-        flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
-        flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
+        flags = FIELD_DP32(flags, TBFLAG_A64, TBI0,
+                           arm_regime_tbi0(env, mmu_idx));
+        flags = FIELD_DP32(flags, TBFLAG_A64, TBI1,
+                           arm_regime_tbi1(env, mmu_idx));
 
         if (cpu_isar_feature(aa64_sve, cpu)) {
             int sve_el = sve_exception_el(env, current_el);
@@ -12978,28 +12980,25 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
             } else {
                 zcr_len = sve_zcr_len_for_el(env, current_el);
             }
-            flags |= sve_el << ARM_TBFLAG_SVEEXC_EL_SHIFT;
-            flags |= zcr_len << ARM_TBFLAG_ZCR_LEN_SHIFT;
+            flags = FIELD_DP32(flags, TBFLAG_A64, SVEEXC_EL, sve_el);
+            flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
         }
     } else {
         *pc = env->regs[15];
-        flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
-            | (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
-            | (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
-            | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
-            | (arm_sctlr_b(env) << ARM_TBFLAG_SCTLR_B_SHIFT);
-        if (!(access_secure_reg(env))) {
-            flags |= ARM_TBFLAG_NS_MASK;
-        }
+        flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
+        flags = FIELD_DP32(flags, TBFLAG_A32, VECLEN, env->vfp.vec_len);
+        flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE, env->vfp.vec_stride);
+        flags = FIELD_DP32(flags, TBFLAG_A32, CONDEXEC, env->condexec_bits);
+        flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
+        flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
         if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
             || arm_el_is_aa64(env, 1)) {
-            flags |= ARM_TBFLAG_VFPEN_MASK;
+            flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
         }
-        flags |= (extract32(env->cp15.c15_cpar, 0, 2)
-                  << ARM_TBFLAG_XSCALE_CPAR_SHIFT);
+        flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
     }
 
-    flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
+    flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
 
     /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
      * states defined in the ARM ARM for software singlestep:
@@ -13009,24 +13008,24 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
      *     1            1       Active-not-pending
      */
     if (arm_singlestep_active(env)) {
-        flags |= ARM_TBFLAG_SS_ACTIVE_MASK;
+        flags = FIELD_DP32(flags, TBFLAG_ANY, SS_ACTIVE, 1);
         if (is_a64(env)) {
             if (env->pstate & PSTATE_SS) {
-                flags |= ARM_TBFLAG_PSTATE_SS_MASK;
+                flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
             }
         } else {
             if (env->uncached_cpsr & PSTATE_SS) {
-                flags |= ARM_TBFLAG_PSTATE_SS_MASK;
+                flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
             }
         }
     }
     if (arm_cpu_data_is_big_endian(env)) {
-        flags |= ARM_TBFLAG_BE_DATA_MASK;
+        flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
     }
-    flags |= fp_el << ARM_TBFLAG_FPEXC_EL_SHIFT;
+    flags = FIELD_DP32(flags, TBFLAG_ANY, FPEXC_EL, fp_el);
 
     if (arm_v7m_is_handler_mode(env)) {
-        flags |= ARM_TBFLAG_HANDLER_MASK;
+        flags = FIELD_DP32(flags, TBFLAG_A32, HANDLER, 1);
     }
 
     /* v8M always applies stack limit checks unless CCR.STKOFHFNMIGN is
@@ -13036,7 +13035,7 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
         arm_feature(env, ARM_FEATURE_M) &&
         !((mmu_idx  & ARM_MMU_IDX_M_NEGPRI) &&
           (env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
-        flags |= ARM_TBFLAG_STACKCHECK_MASK;
+        flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
     }
 
     *pflags = flags;
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index e1da1e4d6f5..b7b6ab63716 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -13380,7 +13380,8 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
     DisasContext *dc = container_of(dcbase, DisasContext, base);
     CPUARMState *env = cpu->env_ptr;
     ARMCPU *arm_cpu = arm_env_get_cpu(env);
-    int bound;
+    uint32_t tb_flags = dc->base.tb->flags;
+    int bound, core_mmu_idx;
 
     dc->isar = &arm_cpu->isar;
     dc->pc = dc->base.pc_first;
@@ -13394,19 +13395,20 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
                                !arm_el_is_aa64(env, 3);
     dc->thumb = 0;
     dc->sctlr_b = 0;
-    dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
+    dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
     dc->condexec_mask = 0;
     dc->condexec_cond = 0;
-    dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(dc->base.tb->flags));
-    dc->tbi0 = ARM_TBFLAG_TBI0(dc->base.tb->flags);
-    dc->tbi1 = ARM_TBFLAG_TBI1(dc->base.tb->flags);
+    core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
+    dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
+    dc->tbi0 = FIELD_EX32(tb_flags, TBFLAG_A64, TBI0);
+    dc->tbi1 = FIELD_EX32(tb_flags, TBFLAG_A64, TBI1);
     dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
 #if !defined(CONFIG_USER_ONLY)
     dc->user = (dc->current_el == 0);
 #endif
-    dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
-    dc->sve_excp_el = ARM_TBFLAG_SVEEXC_EL(dc->base.tb->flags);
-    dc->sve_len = (ARM_TBFLAG_ZCR_LEN(dc->base.tb->flags) + 1) * 16;
+    dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
+    dc->sve_excp_el = FIELD_EX32(tb_flags, TBFLAG_A64, SVEEXC_EL);
+    dc->sve_len = (FIELD_EX32(tb_flags, TBFLAG_A64, ZCR_LEN) + 1) * 16;
     dc->vec_len = 0;
     dc->vec_stride = 0;
     dc->cp_regs = arm_cpu->cp_regs;
@@ -13427,8 +13429,8 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
      *   emit code to generate a software step exception
      *   end the TB
      */
-    dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
-    dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
+    dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
+    dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
     dc->is_ldex = false;
     dc->ss_same_el = (arm_debug_target_el(env) == dc->current_el);
 
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 7c4675ffd8a..ed3db0c3946 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -13021,6 +13021,8 @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     DisasContext *dc = container_of(dcbase, DisasContext, base);
     CPUARMState *env = cs->env_ptr;
     ARMCPU *cpu = arm_env_get_cpu(env);
+    uint32_t tb_flags = dc->base.tb->flags;
+    uint32_t condexec, core_mmu_idx;
 
     dc->isar = &cpu->isar;
     dc->pc = dc->base.pc_first;
@@ -13032,26 +13034,28 @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
      */
     dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
                                !arm_el_is_aa64(env, 3);
-    dc->thumb = ARM_TBFLAG_THUMB(dc->base.tb->flags);
-    dc->sctlr_b = ARM_TBFLAG_SCTLR_B(dc->base.tb->flags);
-    dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
-    dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) & 0xf) << 1;
-    dc->condexec_cond = ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) >> 4;
-    dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(dc->base.tb->flags));
+    dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
+    dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
+    dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
+    condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
+    dc->condexec_mask = (condexec & 0xf) << 1;
+    dc->condexec_cond = condexec >> 4;
+    core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
+    dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
     dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
 #if !defined(CONFIG_USER_ONLY)
     dc->user = (dc->current_el == 0);
 #endif
-    dc->ns = ARM_TBFLAG_NS(dc->base.tb->flags);
-    dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
-    dc->vfp_enabled = ARM_TBFLAG_VFPEN(dc->base.tb->flags);
-    dc->vec_len = ARM_TBFLAG_VECLEN(dc->base.tb->flags);
-    dc->vec_stride = ARM_TBFLAG_VECSTRIDE(dc->base.tb->flags);
-    dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(dc->base.tb->flags);
-    dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(dc->base.tb->flags);
+    dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
+    dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
+    dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
+    dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
+    dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
+    dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
+    dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
     dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
         regime_is_secure(env, dc->mmu_idx);
-    dc->v8m_stackcheck = ARM_TBFLAG_STACKCHECK(dc->base.tb->flags);
+    dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
     dc->cp_regs = cpu->cp_regs;
     dc->features = env->features;
 
@@ -13070,8 +13074,8 @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
      *   emit code to generate a software step exception
      *   end the TB
      */
-    dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
-    dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
+    dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
+    dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
     dc->is_ldex = false;
     dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
 
@@ -13516,11 +13520,11 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
     DisasContext dc;
     const TranslatorOps *ops = &arm_translator_ops;
 
-    if (ARM_TBFLAG_THUMB(tb->flags)) {
+    if (FIELD_EX32(tb->flags, TBFLAG_A32, THUMB)) {
         ops = &thumb_translator_ops;
     }
 #ifdef TARGET_AARCH64
-    if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
+    if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
         ops = &aarch64_translator_ops;
     }
 #endif
-- 
2.19.2

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

* [Qemu-devel] [PULL 02/37] target/arm: SVE brk[ab] merging does not have s bit
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 01/37] target/arm: Convert ARM_TBFLAG_* to FIELDs Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 03/37] hw/cpu: introduce CPU clusters Peter Maydell
                   ` (36 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Richard Henderson <richard.henderson@linaro.org>

While brk[ab] zeroing has a flags setting option, the merging variant
does not.  Retain the same argument structure, to share expansion but
force the flag zero and do not decode bit 22.

Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20181226215003.31438-1-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/sve.decode | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/arm/sve.decode b/target/arm/sve.decode
index e10b689454e..4f580a25e70 100644
--- a/target/arm/sve.decode
+++ b/target/arm/sve.decode
@@ -99,6 +99,7 @@
 
 # Two operand with governing predicate, flags setting
 @pd_pg_pn_s     ........ . s:1 ...... .. pg:4 . rn:4 . rd:4     &rpr_s
+@pd_pg_pn_s0    ........ . .   ...... .. pg:4 . rn:4 . rd:4     &rpr_s s=0
 
 # Three operand with unused vector element size
 @rd_rn_rm_e0    ........ ... rm:5 ... ... rn:5 rd:5             &rrr_esz esz=0
@@ -667,8 +668,8 @@ BRKPB           00100101 0. 00 .... 11 .... 0 .... 1 ....       @pd_pg_pn_pm_s
 # SVE partition break condition
 BRKA_z          00100101 0. 01000001 .... 0 .... 0 ....         @pd_pg_pn_s
 BRKB_z          00100101 1. 01000001 .... 0 .... 0 ....         @pd_pg_pn_s
-BRKA_m          00100101 0. 01000001 .... 0 .... 1 ....         @pd_pg_pn_s
-BRKB_m          00100101 1. 01000001 .... 0 .... 1 ....         @pd_pg_pn_s
+BRKA_m          00100101 00 01000001 .... 0 .... 1 ....         @pd_pg_pn_s0
+BRKB_m          00100101 10 01000001 .... 0 .... 1 ....         @pd_pg_pn_s0
 
 # SVE propagate break to next partition
 BRKN            00100101 0. 01100001 .... 0 .... 0 ....         @pd_pg_pn_s
-- 
2.19.2

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

* [Qemu-devel] [PULL 03/37] hw/cpu: introduce CPU clusters
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 01/37] target/arm: Convert ARM_TBFLAG_* to FIELDs Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 02/37] target/arm: SVE brk[ab] merging does not have s bit Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 04/37] gdbstub: introduce GDB processes Peter Maydell
                   ` (35 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Luc Michel <luc.michel@greensocs.com>

This commit adds the cpu-cluster type. It aims at gathering CPUs from
the same cluster in a machine.

For now it only has a `cluster-id` property.

Documentation in cluster.h written with the help of Peter Maydell.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 20181207090135.7651-2-luc.michel@greensocs.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/cpu/Makefile.objs     |  2 +-
 include/hw/cpu/cluster.h | 58 ++++++++++++++++++++++++++++++++++++++++
 hw/cpu/cluster.c         | 50 ++++++++++++++++++++++++++++++++++
 MAINTAINERS              |  2 ++
 4 files changed, 111 insertions(+), 1 deletion(-)
 create mode 100644 include/hw/cpu/cluster.h
 create mode 100644 hw/cpu/cluster.c

diff --git a/hw/cpu/Makefile.objs b/hw/cpu/Makefile.objs
index cd52d20b652..8db9e8a7b3c 100644
--- a/hw/cpu/Makefile.objs
+++ b/hw/cpu/Makefile.objs
@@ -2,4 +2,4 @@ obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o
 obj-$(CONFIG_REALVIEW) += realview_mpcore.o
 obj-$(CONFIG_A9MPCORE) += a9mpcore.o
 obj-$(CONFIG_A15MPCORE) += a15mpcore.o
-common-obj-y += core.o
+common-obj-y += core.o cluster.o
diff --git a/include/hw/cpu/cluster.h b/include/hw/cpu/cluster.h
new file mode 100644
index 00000000000..73818232437
--- /dev/null
+++ b/include/hw/cpu/cluster.h
@@ -0,0 +1,58 @@
+/*
+ * QEMU CPU cluster
+ *
+ * Copyright (c) 2018 GreenSocs SAS
+ *
+ * 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/gpl-2.0.html>
+ */
+#ifndef HW_CPU_CLUSTER_H
+#define HW_CPU_CLUSTER_H
+
+#include "qemu/osdep.h"
+#include "hw/qdev.h"
+
+/*
+ * CPU Cluster type
+ *
+ * A cluster is a group of CPUs which are all identical and have the same view
+ * of the rest of the system. It is mainly an internal QEMU representation and
+ * does not necessarily match with the notion of clusters on the real hardware.
+ *
+ * If CPUs are not identical (for example, Cortex-A53 and Cortex-A57 CPUs in an
+ * Arm big.LITTLE system) they should be in different clusters. If the CPUs do
+ * not have the same view of memory (for example the main CPU and a management
+ * controller processor) they should be in different clusters.
+ */
+
+#define TYPE_CPU_CLUSTER "cpu-cluster"
+#define CPU_CLUSTER(obj) \
+    OBJECT_CHECK(CPUClusterState, (obj), TYPE_CPU_CLUSTER)
+
+/**
+ * CPUClusterState:
+ * @cluster_id: The cluster ID. This value is for internal use only and should
+ *   not be exposed directly to the user or to the guest.
+ *
+ * State of a CPU cluster.
+ */
+typedef struct CPUClusterState {
+    /*< private >*/
+    DeviceState parent_obj;
+
+    /*< public >*/
+    uint32_t cluster_id;
+} CPUClusterState;
+
+#endif
diff --git a/hw/cpu/cluster.c b/hw/cpu/cluster.c
new file mode 100644
index 00000000000..9d50a235d5c
--- /dev/null
+++ b/hw/cpu/cluster.c
@@ -0,0 +1,50 @@
+/*
+ * QEMU CPU cluster
+ *
+ * Copyright (c) 2018 GreenSocs SAS
+ *
+ * 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/gpl-2.0.html>
+ */
+
+#include "qemu/osdep.h"
+#include "hw/cpu/cluster.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+
+static Property cpu_cluster_properties[] = {
+    DEFINE_PROP_UINT32("cluster-id", CPUClusterState, cluster_id, 0),
+    DEFINE_PROP_END_OF_LIST()
+};
+
+static void cpu_cluster_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->props = cpu_cluster_properties;
+}
+
+static const TypeInfo cpu_cluster_type_info = {
+    .name = TYPE_CPU_CLUSTER,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(CPUClusterState),
+    .class_init = cpu_cluster_class_init,
+};
+
+static void cpu_cluster_register_types(void)
+{
+    type_register_static(&cpu_cluster_type_info);
+}
+
+type_init(cpu_cluster_register_types)
diff --git a/MAINTAINERS b/MAINTAINERS
index 19792cfb2da..471161742de 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1195,7 +1195,9 @@ M: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
 S: Supported
 F: hw/core/machine.c
 F: hw/core/null-machine.c
+F: hw/cpu/cluster.c
 F: include/hw/boards.h
+F: include/hw/cpu/cluster.h
 T: git https://github.com/ehabkost/qemu.git machine-next
 
 Xtensa Machines
-- 
2.19.2

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

* [Qemu-devel] [PULL 04/37] gdbstub: introduce GDB processes
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (2 preceding siblings ...)
  2019-01-07 16:30 ` [Qemu-devel] [PULL 03/37] hw/cpu: introduce CPU clusters Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 05/37] gdbstub: add multiprocess support to '?' packets Peter Maydell
                   ` (34 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Luc Michel <luc.michel@greensocs.com>

Add a structure GDBProcess that represents processes from the GDB
semantic point of view.

CPUs can be split into different processes, by grouping them under
different cpu-cluster objects.  Each occurrence of a cpu-cluster object
implies the existence of the corresponding process in the GDB stub. The
GDB process ID is derived from the corresponding cluster ID as follows:

  GDB PID = cluster ID + 1

This is because PIDs -1 and 0 are reserved in GDB and cannot be used by
processes.

A default process is created to handle CPUs that are not in a cluster.
This process gets the PID of the last process PID + 1.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20181207090135.7651-3-luc.michel@greensocs.com
[PMM: fixed checkpatch nit about block comment style]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 gdbstub.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)

diff --git a/gdbstub.c b/gdbstub.c
index c4e4f9f0821..9ac6f19a186 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -29,6 +29,7 @@
 #include "chardev/char-fe.h"
 #include "sysemu/sysemu.h"
 #include "exec/gdbstub.h"
+#include "hw/cpu/cluster.h"
 #endif
 
 #define MAX_PACKET_LENGTH 4096
@@ -296,6 +297,11 @@ typedef struct GDBRegisterState {
     struct GDBRegisterState *next;
 } GDBRegisterState;
 
+typedef struct GDBProcess {
+    uint32_t pid;
+    bool attached;
+} GDBProcess;
+
 enum RSState {
     RS_INACTIVE,
     RS_IDLE,
@@ -324,6 +330,9 @@ typedef struct GDBState {
     CharBackend chr;
     Chardev *mon_chr;
 #endif
+    bool multiprocess;
+    GDBProcess *processes;
+    int process_num;
     char syscall_buf[256];
     gdb_syscall_complete_cb current_syscall_cb;
 } GDBState;
@@ -1751,6 +1760,30 @@ void gdb_exit(CPUArchState *env, int code)
 #endif
 }
 
+/*
+ * Create the process that will contain all the "orphan" CPUs (that are not
+ * part of a CPU cluster). Note that if this process contains no CPUs, it won't
+ * be attachable and thus will be invisible to the user.
+ */
+static void create_default_process(GDBState *s)
+{
+    GDBProcess *process;
+    int max_pid = 0;
+
+    if (s->process_num) {
+        max_pid = s->processes[s->process_num - 1].pid;
+    }
+
+    s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
+    process = &s->processes[s->process_num - 1];
+
+    /* We need an available PID slot for this process */
+    assert(max_pid < UINT32_MAX);
+
+    process->pid = max_pid + 1;
+    process->attached = false;
+}
+
 #ifdef CONFIG_USER_ONLY
 int
 gdb_handlesig(CPUState *cpu, int sig)
@@ -1848,6 +1881,7 @@ static bool gdb_accept(void)
     s = g_malloc0(sizeof(GDBState));
     s->c_cpu = first_cpu;
     s->g_cpu = first_cpu;
+    create_default_process(s);
     s->fd = fd;
     gdb_has_xml = false;
 
@@ -2004,6 +2038,65 @@ static const TypeInfo char_gdb_type_info = {
     .class_init = char_gdb_class_init,
 };
 
+static int find_cpu_clusters(Object *child, void *opaque)
+{
+    if (object_dynamic_cast(child, TYPE_CPU_CLUSTER)) {
+        GDBState *s = (GDBState *) opaque;
+        CPUClusterState *cluster = CPU_CLUSTER(child);
+        GDBProcess *process;
+
+        s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
+
+        process = &s->processes[s->process_num - 1];
+
+        /*
+         * GDB process IDs -1 and 0 are reserved. To avoid subtle errors at
+         * runtime, we enforce here that the machine does not use a cluster ID
+         * that would lead to PID 0.
+         */
+        assert(cluster->cluster_id != UINT32_MAX);
+        process->pid = cluster->cluster_id + 1;
+        process->attached = false;
+
+        return 0;
+    }
+
+    return object_child_foreach(child, find_cpu_clusters, opaque);
+}
+
+static int pid_order(const void *a, const void *b)
+{
+    GDBProcess *pa = (GDBProcess *) a;
+    GDBProcess *pb = (GDBProcess *) b;
+
+    if (pa->pid < pb->pid) {
+        return -1;
+    } else if (pa->pid > pb->pid) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+static void create_processes(GDBState *s)
+{
+    object_child_foreach(object_get_root(), find_cpu_clusters, s);
+
+    if (s->processes) {
+        /* Sort by PID */
+        qsort(s->processes, s->process_num, sizeof(s->processes[0]), pid_order);
+    }
+
+    create_default_process(s);
+}
+
+static void cleanup_processes(GDBState *s)
+{
+    g_free(s->processes);
+    s->process_num = 0;
+    s->processes = NULL;
+}
+
 int gdbserver_start(const char *device)
 {
     trace_gdbstub_op_start(device);
@@ -2060,11 +2153,15 @@ int gdbserver_start(const char *device)
     } else {
         qemu_chr_fe_deinit(&s->chr, true);
         mon_chr = s->mon_chr;
+        cleanup_processes(s);
         memset(s, 0, sizeof(GDBState));
         s->mon_chr = mon_chr;
     }
     s->c_cpu = first_cpu;
     s->g_cpu = first_cpu;
+
+    create_processes(s);
+
     if (chr) {
         qemu_chr_fe_init(&s->chr, chr, &error_abort);
         qemu_chr_fe_set_handlers(&s->chr, gdb_chr_can_receive, gdb_chr_receive,
-- 
2.19.2

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

* [Qemu-devel] [PULL 05/37] gdbstub: add multiprocess support to '?' packets
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (3 preceding siblings ...)
  2019-01-07 16:30 ` [Qemu-devel] [PULL 04/37] gdbstub: introduce GDB processes Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 06/37] gdbstub: add multiprocess support to 'H' and 'T' packets Peter Maydell
                   ` (33 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Luc Michel <luc.michel@greensocs.com>

The gdb_get_cpu_pid() function does the PID lookup for the given CPU. It
checks if the CPU is a direct child of a CPU cluster. If it is, the
returned PID is the cluster ID plus one (cluster IDs start at 0, GDB
PIDs at 1). When the CPU is not a child of such a container, the PID of
the default process is returned.

The gdb_fmt_thread_id() function generates the string to be used to identify
a given thread, in a response packet for the peer. This function
supports generating thread IDs when multiprocess mode is enabled (in the
form `p<pid>.<tid>').

Use them in the reply to a '?' request.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 20181207090135.7651-4-luc.michel@greensocs.com
[PMM: fixed checkpatch blockquote style nit]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 gdbstub.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 64 insertions(+), 2 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 9ac6f19a186..02beb44d973 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -640,6 +640,54 @@ static int memtox(char *buf, const char *mem, int len)
     return p - buf;
 }
 
+static uint32_t gdb_get_cpu_pid(const GDBState *s, CPUState *cpu)
+{
+#ifndef CONFIG_USER_ONLY
+    gchar *path, *name = NULL;
+    Object *obj;
+    CPUClusterState *cluster;
+    uint32_t ret;
+
+    path = object_get_canonical_path(OBJECT(cpu));
+
+    if (path == NULL) {
+        /* Return the default process' PID */
+        ret = s->processes[s->process_num - 1].pid;
+        goto out;
+    }
+
+    name = object_get_canonical_path_component(OBJECT(cpu));
+    assert(name != NULL);
+
+    /*
+     * Retrieve the CPU parent path by removing the last '/' and the CPU name
+     * from the CPU canonical path.
+     */
+    path[strlen(path) - strlen(name) - 1] = '\0';
+
+    obj = object_resolve_path_type(path, TYPE_CPU_CLUSTER, NULL);
+
+    if (obj == NULL) {
+        /* Return the default process' PID */
+        ret = s->processes[s->process_num - 1].pid;
+        goto out;
+    }
+
+    cluster = CPU_CLUSTER(obj);
+    ret = cluster->cluster_id + 1;
+
+out:
+    g_free(name);
+    g_free(path);
+
+    return ret;
+
+#else
+    /* TODO: In user mode, we should use the task state PID */
+    return s->processes[s->process_num - 1].pid;
+#endif
+}
+
 static const char *get_feature_xml(const char *p, const char **newp,
                                    CPUClass *cc)
 {
@@ -909,6 +957,19 @@ static CPUState *find_cpu(uint32_t thread_id)
     return NULL;
 }
 
+static char *gdb_fmt_thread_id(const GDBState *s, CPUState *cpu,
+                           char *buf, size_t buf_size)
+{
+    if (s->multiprocess) {
+        snprintf(buf, buf_size, "p%02x.%02x",
+                 gdb_get_cpu_pid(s, cpu), cpu_gdb_index(cpu));
+    } else {
+        snprintf(buf, buf_size, "%02x", cpu_gdb_index(cpu));
+    }
+
+    return buf;
+}
+
 static int is_query_packet(const char *p, const char *query, char separator)
 {
     unsigned int query_len = strlen(query);
@@ -1020,6 +1081,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
     int ch, reg_size, type, res;
     uint8_t mem_buf[MAX_PACKET_LENGTH];
     char buf[sizeof(mem_buf) + 1 /* trailing NUL */];
+    char thread_id[16];
     uint8_t *registers;
     target_ulong addr, len;
 
@@ -1030,8 +1092,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
     switch(ch) {
     case '?':
         /* TODO: Make this return the correct value for user-mode.  */
-        snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP,
-                 cpu_gdb_index(s->c_cpu));
+        snprintf(buf, sizeof(buf), "T%02xthread:%s;", GDB_SIGNAL_TRAP,
+                 gdb_fmt_thread_id(s, s->c_cpu, thread_id, sizeof(thread_id)));
         put_packet(s, buf);
         /* Remove all the breakpoints when this query is issued,
          * because gdb is doing and initial connect and the state
-- 
2.19.2

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

* [Qemu-devel] [PULL 06/37] gdbstub: add multiprocess support to 'H' and 'T' packets
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (4 preceding siblings ...)
  2019-01-07 16:30 ` [Qemu-devel] [PULL 05/37] gdbstub: add multiprocess support to '?' packets Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-17 18:13   ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 07/37] gdbstub: add multiprocess support to vCont packets Peter Maydell
                   ` (32 subsequent siblings)
  38 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Luc Michel <luc.michel@greensocs.com>

Add a couple of helper functions to cope with GDB threads and processes.

The gdb_get_process() function looks for a process given a pid.

The gdb_get_cpu() function returns the CPU corresponding to the (pid,
tid) pair given as parameters.

The read_thread_id() function parses the thread-id sent by the peer.
This function supports the multiprocess extension thread-id syntax.  The
return value specifies if the parsing failed, or if a special case was
encountered (all processes or all threads).

Use them in 'H' and 'T' packets handling to support the multiprocess
extension.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20181207090135.7651-5-luc.michel@greensocs.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 gdbstub.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 136 insertions(+), 18 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 02beb44d973..644377db9f5 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -688,6 +688,71 @@ out:
 #endif
 }
 
+static GDBProcess *gdb_get_process(const GDBState *s, uint32_t pid)
+{
+    int i;
+
+    if (!pid) {
+        /* 0 means any process, we take the first one */
+        return &s->processes[0];
+    }
+
+    for (i = 0; i < s->process_num; i++) {
+        if (s->processes[i].pid == pid) {
+            return &s->processes[i];
+        }
+    }
+
+    return NULL;
+}
+
+static GDBProcess *gdb_get_cpu_process(const GDBState *s, CPUState *cpu)
+{
+    return gdb_get_process(s, gdb_get_cpu_pid(s, cpu));
+}
+
+static CPUState *find_cpu(uint32_t thread_id)
+{
+    CPUState *cpu;
+
+    CPU_FOREACH(cpu) {
+        if (cpu_gdb_index(cpu) == thread_id) {
+            return cpu;
+        }
+    }
+
+    return NULL;
+}
+
+static CPUState *gdb_get_cpu(const GDBState *s, uint32_t pid, uint32_t tid)
+{
+    GDBProcess *process;
+    CPUState *cpu;
+
+    if (!tid) {
+        /* 0 means any thread, we take the first one */
+        tid = 1;
+    }
+
+    cpu = find_cpu(tid);
+
+    if (cpu == NULL) {
+        return NULL;
+    }
+
+    process = gdb_get_cpu_process(s, cpu);
+
+    if (process->pid != pid) {
+        return NULL;
+    }
+
+    if (!process->attached) {
+        return NULL;
+    }
+
+    return cpu;
+}
+
 static const char *get_feature_xml(const char *p, const char **newp,
                                    CPUClass *cc)
 {
@@ -944,19 +1009,6 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
     cpu_set_pc(cpu, pc);
 }
 
-static CPUState *find_cpu(uint32_t thread_id)
-{
-    CPUState *cpu;
-
-    CPU_FOREACH(cpu) {
-        if (cpu_gdb_index(cpu) == thread_id) {
-            return cpu;
-        }
-    }
-
-    return NULL;
-}
-
 static char *gdb_fmt_thread_id(const GDBState *s, CPUState *cpu,
                            char *buf, size_t buf_size)
 {
@@ -970,6 +1022,60 @@ static char *gdb_fmt_thread_id(const GDBState *s, CPUState *cpu,
     return buf;
 }
 
+typedef enum GDBThreadIdKind {
+    GDB_ONE_THREAD = 0,
+    GDB_ALL_THREADS,     /* One process, all threads */
+    GDB_ALL_PROCESSES,
+    GDB_READ_THREAD_ERR
+} GDBThreadIdKind;
+
+static GDBThreadIdKind read_thread_id(const char *buf, const char **end_buf,
+                                      uint32_t *pid, uint32_t *tid)
+{
+    unsigned long p, t;
+    int ret;
+
+    if (*buf == 'p') {
+        buf++;
+        ret = qemu_strtoul(buf, &buf, 16, &p);
+
+        if (ret) {
+            return GDB_READ_THREAD_ERR;
+        }
+
+        /* Skip '.' */
+        buf++;
+    } else {
+        p = 1;
+    }
+
+    ret = qemu_strtoul(buf, &buf, 16, &t);
+
+    if (ret) {
+        return GDB_READ_THREAD_ERR;
+    }
+
+    *end_buf = buf;
+
+    if (p == -1) {
+        return GDB_ALL_PROCESSES;
+    }
+
+    if (pid) {
+        *pid = p;
+    }
+
+    if (t == -1) {
+        return GDB_ALL_THREADS;
+    }
+
+    if (tid) {
+        *tid = t;
+    }
+
+    return GDB_ONE_THREAD;
+}
+
 static int is_query_packet(const char *p, const char *query, char separator)
 {
     unsigned int query_len = strlen(query);
@@ -1078,12 +1184,14 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
     CPUClass *cc;
     const char *p;
     uint32_t thread;
+    uint32_t pid, tid;
     int ch, reg_size, type, res;
     uint8_t mem_buf[MAX_PACKET_LENGTH];
     char buf[sizeof(mem_buf) + 1 /* trailing NUL */];
     char thread_id[16];
     uint8_t *registers;
     target_ulong addr, len;
+    GDBThreadIdKind thread_kind;
 
     trace_gdbstub_io_command(line_buf);
 
@@ -1291,12 +1399,18 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         break;
     case 'H':
         type = *p++;
-        thread = strtoull(p, (char **)&p, 16);
-        if (thread == -1 || thread == 0) {
+
+        thread_kind = read_thread_id(p, &p, &pid, &tid);
+        if (thread_kind == GDB_READ_THREAD_ERR) {
+            put_packet(s, "E22");
+            break;
+        }
+
+        if (thread_kind != GDB_ONE_THREAD) {
             put_packet(s, "OK");
             break;
         }
-        cpu = find_cpu(thread);
+        cpu = gdb_get_cpu(s, pid, tid);
         if (cpu == NULL) {
             put_packet(s, "E22");
             break;
@@ -1316,8 +1430,12 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         }
         break;
     case 'T':
-        thread = strtoull(p, (char **)&p, 16);
-        cpu = find_cpu(thread);
+        thread_kind = read_thread_id(p, &p, &pid, &tid);
+        if (thread_kind == GDB_READ_THREAD_ERR) {
+            put_packet(s, "E22");
+            break;
+        }
+        cpu = gdb_get_cpu(s, pid, tid);
 
         if (cpu != NULL) {
             put_packet(s, "OK");
-- 
2.19.2

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

* [Qemu-devel] [PULL 07/37] gdbstub: add multiprocess support to vCont packets
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (5 preceding siblings ...)
  2019-01-07 16:30 ` [Qemu-devel] [PULL 06/37] gdbstub: add multiprocess support to 'H' and 'T' packets Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 08/37] gdbstub: add multiprocess support to 'sC' packets Peter Maydell
                   ` (31 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Luc Michel <luc.michel@greensocs.com>

Add the gdb_first_attached_cpu() and gdb_next_attached_cpu() to iterate
over all the CPUs in currently attached processes.

Add the gdb_first_cpu_in_process() and gdb_next_cpu_in_process() to
iterate over CPUs of a given process.

Use them to add multiprocess extension support to vCont packets.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20181207090135.7651-6-luc.michel@greensocs.com
[PMM: corrected checkpatch comment style nit]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 gdbstub.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 100 insertions(+), 15 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 644377db9f5..09114ea7769 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -724,6 +724,36 @@ static CPUState *find_cpu(uint32_t thread_id)
     return NULL;
 }
 
+static CPUState *get_first_cpu_in_process(const GDBState *s,
+                                          GDBProcess *process)
+{
+    CPUState *cpu;
+
+    CPU_FOREACH(cpu) {
+        if (gdb_get_cpu_pid(s, cpu) == process->pid) {
+            return cpu;
+        }
+    }
+
+    return NULL;
+}
+
+static CPUState *gdb_next_cpu_in_process(const GDBState *s, CPUState *cpu)
+{
+    uint32_t pid = gdb_get_cpu_pid(s, cpu);
+    cpu = CPU_NEXT(cpu);
+
+    while (cpu) {
+        if (gdb_get_cpu_pid(s, cpu) == pid) {
+            break;
+        }
+
+        cpu = CPU_NEXT(cpu);
+    }
+
+    return cpu;
+}
+
 static CPUState *gdb_get_cpu(const GDBState *s, uint32_t pid, uint32_t tid)
 {
     GDBProcess *process;
@@ -753,6 +783,35 @@ static CPUState *gdb_get_cpu(const GDBState *s, uint32_t pid, uint32_t tid)
     return cpu;
 }
 
+/* Return the cpu following @cpu, while ignoring unattached processes. */
+static CPUState *gdb_next_attached_cpu(const GDBState *s, CPUState *cpu)
+{
+    cpu = CPU_NEXT(cpu);
+
+    while (cpu) {
+        if (gdb_get_cpu_process(s, cpu)->attached) {
+            break;
+        }
+
+        cpu = CPU_NEXT(cpu);
+    }
+
+    return cpu;
+}
+
+/* Return the first attached cpu */
+static CPUState *gdb_first_attached_cpu(const GDBState *s)
+{
+    CPUState *cpu = first_cpu;
+    GDBProcess *process = gdb_get_cpu_process(s, cpu);
+
+    if (!process->attached) {
+        return gdb_next_attached_cpu(s, cpu);
+    }
+
+    return cpu;
+}
+
 static const char *get_feature_xml(const char *p, const char **newp,
                                    CPUClass *cc)
 {
@@ -1091,10 +1150,12 @@ static int is_query_packet(const char *p, const char *query, char separator)
  */
 static int gdb_handle_vcont(GDBState *s, const char *p)
 {
-    int res, idx, signal = 0;
+    int res, signal = 0;
     char cur_action;
     char *newstates;
     unsigned long tmp;
+    uint32_t pid, tid;
+    GDBProcess *process;
     CPUState *cpu;
 #ifdef CONFIG_USER_ONLY
     int max_cpus = 1; /* global variable max_cpus exists only in system mode */
@@ -1137,25 +1198,48 @@ static int gdb_handle_vcont(GDBState *s, const char *p)
             res = -ENOTSUP;
             goto out;
         }
-        /* thread specification. special values: (none), -1 = all; 0 = any */
-        if ((p[0] == ':' && p[1] == '-' && p[2] == '1') || (p[0] != ':')) {
-            if (*p == ':') {
-                p += 3;
-            }
-            for (idx = 0; idx < max_cpus; idx++) {
-                if (newstates[idx] == 1) {
-                    newstates[idx] = cur_action;
+
+        if (*p++ != ':') {
+            res = -ENOTSUP;
+            goto out;
+        }
+
+        switch (read_thread_id(p, &p, &pid, &tid)) {
+        case GDB_READ_THREAD_ERR:
+            res = -EINVAL;
+            goto out;
+
+        case GDB_ALL_PROCESSES:
+            cpu = gdb_first_attached_cpu(s);
+            while (cpu) {
+                if (newstates[cpu->cpu_index] == 1) {
+                    newstates[cpu->cpu_index] = cur_action;
                 }
+
+                cpu = gdb_next_attached_cpu(s, cpu);
             }
-        } else if (*p == ':') {
-            p++;
-            res = qemu_strtoul(p, &p, 16, &tmp);
-            if (res) {
+            break;
+
+        case GDB_ALL_THREADS:
+            process = gdb_get_process(s, pid);
+
+            if (!process->attached) {
+                res = -EINVAL;
                 goto out;
             }
 
-            /* 0 means any thread, so we pick the first valid CPU */
-            cpu = tmp ? find_cpu(tmp) : first_cpu;
+            cpu = get_first_cpu_in_process(s, process);
+            while (cpu) {
+                if (newstates[cpu->cpu_index] == 1) {
+                    newstates[cpu->cpu_index] = cur_action;
+                }
+
+                cpu = gdb_next_cpu_in_process(s, cpu);
+            }
+            break;
+
+        case GDB_ONE_THREAD:
+            cpu = gdb_get_cpu(s, pid, tid);
 
             /* invalid CPU/thread specified */
             if (!cpu) {
@@ -1167,6 +1251,7 @@ static int gdb_handle_vcont(GDBState *s, const char *p)
             if (newstates[cpu->cpu_index] == 1) {
                 newstates[cpu->cpu_index] = cur_action;
             }
+            break;
         }
     }
     s->signal = signal;
-- 
2.19.2

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

* [Qemu-devel] [PULL 08/37] gdbstub: add multiprocess support to 'sC' packets
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (6 preceding siblings ...)
  2019-01-07 16:30 ` [Qemu-devel] [PULL 07/37] gdbstub: add multiprocess support to vCont packets Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 09/37] gdbstub: add multiprocess support to (f|s)ThreadInfo and ThreadExtraInfo Peter Maydell
                   ` (30 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Luc Michel <luc.michel@greensocs.com>

Change the sC packet handling to support the multiprocess extension.
Instead of returning the first thread, we return the first thread of the
current process.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 20181207090135.7651-7-luc.michel@greensocs.com
[PMM: corrected checkpatch comment style nit]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 gdbstub.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 09114ea7769..1ba7aa6a28a 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1554,9 +1554,15 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             put_packet(s, "OK");
             break;
         } else if (strcmp(p,"C") == 0) {
-            /* "Current thread" remains vague in the spec, so always return
-             *  the first CPU (gdb returns the first thread). */
-            put_packet(s, "QC1");
+            /*
+             * "Current thread" remains vague in the spec, so always return
+             * the first thread of the current process (gdb returns the
+             * first thread).
+             */
+            cpu = get_first_cpu_in_process(s, gdb_get_cpu_process(s, s->g_cpu));
+            snprintf(buf, sizeof(buf), "QC%s",
+                     gdb_fmt_thread_id(s, cpu, thread_id, sizeof(thread_id)));
+            put_packet(s, buf);
             break;
         } else if (strcmp(p,"fThreadInfo") == 0) {
             s->query_cpu = first_cpu;
-- 
2.19.2

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

* [Qemu-devel] [PULL 09/37] gdbstub: add multiprocess support to (f|s)ThreadInfo and ThreadExtraInfo
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (7 preceding siblings ...)
  2019-01-07 16:30 ` [Qemu-devel] [PULL 08/37] gdbstub: add multiprocess support to 'sC' packets Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 10/37] gdbstub: add multiprocess support to Xfer:features:read: Peter Maydell
                   ` (29 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Luc Michel <luc.michel@greensocs.com>

Change the thread info related packets handling to support multiprocess
extension.

Add the CPUs class name in the extra info to help differentiate
them in multiprocess mode.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20181207090135.7651-8-luc.michel@greensocs.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 gdbstub.c | 37 +++++++++++++++++++++++++++----------
 1 file changed, 27 insertions(+), 10 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 1ba7aa6a28a..f70b5a326fe 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1268,7 +1268,6 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
     CPUState *cpu;
     CPUClass *cc;
     const char *p;
-    uint32_t thread;
     uint32_t pid, tid;
     int ch, reg_size, type, res;
     uint8_t mem_buf[MAX_PACKET_LENGTH];
@@ -1565,26 +1564,44 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             put_packet(s, buf);
             break;
         } else if (strcmp(p,"fThreadInfo") == 0) {
-            s->query_cpu = first_cpu;
+            s->query_cpu = gdb_first_attached_cpu(s);
             goto report_cpuinfo;
         } else if (strcmp(p,"sThreadInfo") == 0) {
         report_cpuinfo:
             if (s->query_cpu) {
-                snprintf(buf, sizeof(buf), "m%x", cpu_gdb_index(s->query_cpu));
+                snprintf(buf, sizeof(buf), "m%s",
+                         gdb_fmt_thread_id(s, s->query_cpu,
+                                       thread_id, sizeof(thread_id)));
                 put_packet(s, buf);
-                s->query_cpu = CPU_NEXT(s->query_cpu);
+                s->query_cpu = gdb_next_attached_cpu(s, s->query_cpu);
             } else
                 put_packet(s, "l");
             break;
         } else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) {
-            thread = strtoull(p+16, (char **)&p, 16);
-            cpu = find_cpu(thread);
+            if (read_thread_id(p + 16, &p, &pid, &tid) == GDB_READ_THREAD_ERR) {
+                put_packet(s, "E22");
+                break;
+            }
+            cpu = gdb_get_cpu(s, pid, tid);
             if (cpu != NULL) {
                 cpu_synchronize_state(cpu);
-                /* memtohex() doubles the required space */
-                len = snprintf((char *)mem_buf, sizeof(buf) / 2,
-                               "CPU#%d [%s]", cpu->cpu_index,
-                               cpu->halted ? "halted " : "running");
+
+                if (s->multiprocess && (s->process_num > 1)) {
+                    /* Print the CPU model and name in multiprocess mode */
+                    ObjectClass *oc = object_get_class(OBJECT(cpu));
+                    const char *cpu_model = object_class_get_name(oc);
+                    char *cpu_name =
+                        object_get_canonical_path_component(OBJECT(cpu));
+                    len = snprintf((char *)mem_buf, sizeof(buf) / 2,
+                                   "%s %s [%s]", cpu_model, cpu_name,
+                                   cpu->halted ? "halted " : "running");
+                    g_free(cpu_name);
+                } else {
+                    /* memtohex() doubles the required space */
+                    len = snprintf((char *)mem_buf, sizeof(buf) / 2,
+                                   "CPU#%d [%s]", cpu->cpu_index,
+                                   cpu->halted ? "halted " : "running");
+                }
                 trace_gdbstub_op_extra_info((char *)mem_buf);
                 memtohex(buf, mem_buf, len);
                 put_packet(s, buf);
-- 
2.19.2

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

* [Qemu-devel] [PULL 10/37] gdbstub: add multiprocess support to Xfer:features:read:
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (8 preceding siblings ...)
  2019-01-07 16:30 ` [Qemu-devel] [PULL 09/37] gdbstub: add multiprocess support to (f|s)ThreadInfo and ThreadExtraInfo Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-17 17:22   ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 11/37] gdbstub: add multiprocess support to gdb_vm_state_change() Peter Maydell
                   ` (28 subsequent siblings)
  38 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Luc Michel <luc.michel@greensocs.com>

Change the Xfer:features:read: packet handling to support the
multiprocess extension. This packet is used to request the XML
description of the CPU. In multiprocess mode, different descriptions can
be sent for different processes.

This function now takes the process to send the description for as a
parameter, and use a buffer in the process structure to store the
generated description.

It takes the first CPU of the process to generate the description.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20181207090135.7651-9-luc.michel@greensocs.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 gdbstub.c | 52 ++++++++++++++++++++++++++++++----------------------
 1 file changed, 30 insertions(+), 22 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index f70b5a326fe..1f2b155490d 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -300,6 +300,8 @@ typedef struct GDBRegisterState {
 typedef struct GDBProcess {
     uint32_t pid;
     bool attached;
+
+    char target_xml[1024];
 } GDBProcess;
 
 enum RSState {
@@ -812,13 +814,14 @@ static CPUState *gdb_first_attached_cpu(const GDBState *s)
     return cpu;
 }
 
-static const char *get_feature_xml(const char *p, const char **newp,
-                                   CPUClass *cc)
+static const char *get_feature_xml(const GDBState *s, const char *p,
+                                   const char **newp, GDBProcess *process)
 {
     size_t len;
     int i;
     const char *name;
-    static char target_xml[1024];
+    CPUState *cpu = get_first_cpu_in_process(s, process);
+    CPUClass *cc = CPU_GET_CLASS(cpu);
 
     len = 0;
     while (p[len] && p[len] != ':')
@@ -827,36 +830,37 @@ static const char *get_feature_xml(const char *p, const char **newp,
 
     name = NULL;
     if (strncmp(p, "target.xml", len) == 0) {
-        /* Generate the XML description for this CPU.  */
-        if (!target_xml[0]) {
-            GDBRegisterState *r;
-            CPUState *cpu = first_cpu;
+        char *buf = process->target_xml;
+        const size_t buf_sz = sizeof(process->target_xml);
 
-            pstrcat(target_xml, sizeof(target_xml),
+        /* Generate the XML description for this CPU.  */
+        if (!buf[0]) {
+            GDBRegisterState *r;
+
+            pstrcat(buf, buf_sz,
                     "<?xml version=\"1.0\"?>"
                     "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
                     "<target>");
             if (cc->gdb_arch_name) {
                 gchar *arch = cc->gdb_arch_name(cpu);
-                pstrcat(target_xml, sizeof(target_xml), "<architecture>");
-                pstrcat(target_xml, sizeof(target_xml), arch);
-                pstrcat(target_xml, sizeof(target_xml), "</architecture>");
+                pstrcat(buf, buf_sz, "<architecture>");
+                pstrcat(buf, buf_sz, arch);
+                pstrcat(buf, buf_sz, "</architecture>");
                 g_free(arch);
             }
-            pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
-            pstrcat(target_xml, sizeof(target_xml), cc->gdb_core_xml_file);
-            pstrcat(target_xml, sizeof(target_xml), "\"/>");
+            pstrcat(buf, buf_sz, "<xi:include href=\"");
+            pstrcat(buf, buf_sz, cc->gdb_core_xml_file);
+            pstrcat(buf, buf_sz, "\"/>");
             for (r = cpu->gdb_regs; r; r = r->next) {
-                pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
-                pstrcat(target_xml, sizeof(target_xml), r->xml);
-                pstrcat(target_xml, sizeof(target_xml), "\"/>");
+                pstrcat(buf, buf_sz, "<xi:include href=\"");
+                pstrcat(buf, buf_sz, r->xml);
+                pstrcat(buf, buf_sz, "\"/>");
             }
-            pstrcat(target_xml, sizeof(target_xml), "</target>");
+            pstrcat(buf, buf_sz, "</target>");
         }
-        return target_xml;
+        return buf;
     }
     if (cc->gdb_get_dynamic_xml) {
-        CPUState *cpu = first_cpu;
         char *xmlname = g_strndup(p, len);
         const char *xml = cc->gdb_get_dynamic_xml(cpu, xmlname);
 
@@ -1266,6 +1270,7 @@ out:
 static int gdb_handle_packet(GDBState *s, const char *line_buf)
 {
     CPUState *cpu;
+    GDBProcess *process;
     CPUClass *cc;
     const char *p;
     uint32_t pid, tid;
@@ -1650,14 +1655,15 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             const char *xml;
             target_ulong total_len;
 
-            cc = CPU_GET_CLASS(first_cpu);
+            process = gdb_get_cpu_process(s, s->g_cpu);
+            cc = CPU_GET_CLASS(s->g_cpu);
             if (cc->gdb_core_xml_file == NULL) {
                 goto unknown_command;
             }
 
             gdb_has_xml = true;
             p += 19;
-            xml = get_feature_xml(p, &p, cc);
+            xml = get_feature_xml(s, p, &p, process);
             if (!xml) {
                 snprintf(buf, sizeof(buf), "E00");
                 put_packet(s, buf);
@@ -2070,6 +2076,7 @@ static void create_default_process(GDBState *s)
 
     process->pid = max_pid + 1;
     process->attached = false;
+    process->target_xml[0] = '\0';
 }
 
 #ifdef CONFIG_USER_ONLY
@@ -2345,6 +2352,7 @@ static int find_cpu_clusters(Object *child, void *opaque)
         assert(cluster->cluster_id != UINT32_MAX);
         process->pid = cluster->cluster_id + 1;
         process->attached = false;
+        process->target_xml[0] = '\0';
 
         return 0;
     }
-- 
2.19.2

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

* [Qemu-devel] [PULL 11/37] gdbstub: add multiprocess support to gdb_vm_state_change()
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (9 preceding siblings ...)
  2019-01-07 16:30 ` [Qemu-devel] [PULL 10/37] gdbstub: add multiprocess support to Xfer:features:read: Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 12/37] gdbstub: add multiprocess support to 'D' packets Peter Maydell
                   ` (27 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Luc Michel <luc.michel@greensocs.com>

Add support for multiprocess extension in gdb_vm_state_change()
function.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20181207090135.7651-10-luc.michel@greensocs.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 gdbstub.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 1f2b155490d..edee38b6136 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1724,6 +1724,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
     GDBState *s = gdbserver_state;
     CPUState *cpu = s->c_cpu;
     char buf[256];
+    char thread_id[16];
     const char *type;
     int ret;
 
@@ -1735,6 +1736,14 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
         put_packet(s, s->syscall_buf);
         return;
     }
+
+    if (cpu == NULL) {
+        /* No process attached */
+        return;
+    }
+
+    gdb_fmt_thread_id(s, cpu, thread_id, sizeof(thread_id));
+
     switch (state) {
     case RUN_STATE_DEBUG:
         if (cpu->watchpoint_hit) {
@@ -1752,8 +1761,8 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
             trace_gdbstub_hit_watchpoint(type, cpu_gdb_index(cpu),
                     (target_ulong)cpu->watchpoint_hit->vaddr);
             snprintf(buf, sizeof(buf),
-                     "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
-                     GDB_SIGNAL_TRAP, cpu_gdb_index(cpu), type,
+                     "T%02xthread:%s;%swatch:" TARGET_FMT_lx ";",
+                     GDB_SIGNAL_TRAP, thread_id, type,
                      (target_ulong)cpu->watchpoint_hit->vaddr);
             cpu->watchpoint_hit = NULL;
             goto send_packet;
@@ -1795,7 +1804,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
         break;
     }
     gdb_set_stop_cpu(cpu);
-    snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_gdb_index(cpu));
+    snprintf(buf, sizeof(buf), "T%02xthread:%s;", ret, thread_id);
 
 send_packet:
     put_packet(s, buf);
-- 
2.19.2

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

* [Qemu-devel] [PULL 12/37] gdbstub: add multiprocess support to 'D' packets
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (10 preceding siblings ...)
  2019-01-07 16:30 ` [Qemu-devel] [PULL 11/37] gdbstub: add multiprocess support to gdb_vm_state_change() Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 13/37] gdbstub: add support for extended mode packet Peter Maydell
                   ` (26 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Luc Michel <luc.michel@greensocs.com>

'D' packets are used by GDB to detach from a process. In multiprocess
mode, the PID to detach from is sent in the request.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20181207090135.7651-11-luc.michel@greensocs.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 gdbstub.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 53 insertions(+), 7 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index edee38b6136..2c7032f53ab 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1047,6 +1047,24 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
     }
 }
 
+static inline void gdb_cpu_breakpoint_remove_all(CPUState *cpu)
+{
+    cpu_breakpoint_remove_all(cpu, BP_GDB);
+#ifndef CONFIG_USER_ONLY
+    cpu_watchpoint_remove_all(cpu, BP_GDB);
+#endif
+}
+
+static void gdb_process_breakpoint_remove_all(const GDBState *s, GDBProcess *p)
+{
+    CPUState *cpu = get_first_cpu_in_process(s, p);
+
+    while (cpu) {
+        gdb_cpu_breakpoint_remove_all(cpu);
+        cpu = gdb_next_cpu_in_process(s, cpu);
+    }
+}
+
 static void gdb_breakpoint_remove_all(void)
 {
     CPUState *cpu;
@@ -1057,10 +1075,7 @@ static void gdb_breakpoint_remove_all(void)
     }
 
     CPU_FOREACH(cpu) {
-        cpu_breakpoint_remove_all(cpu, BP_GDB);
-#ifndef CONFIG_USER_ONLY
-        cpu_watchpoint_remove_all(cpu, BP_GDB);
-#endif
+        gdb_cpu_breakpoint_remove_all(cpu);
     }
 }
 
@@ -1339,9 +1354,40 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         exit(0);
     case 'D':
         /* Detach packet */
-        gdb_breakpoint_remove_all();
-        gdb_syscall_mode = GDB_SYS_DISABLED;
-        gdb_continue(s);
+        pid = 1;
+
+        if (s->multiprocess) {
+            unsigned long lpid;
+            if (*p != ';') {
+                put_packet(s, "E22");
+                break;
+            }
+
+            if (qemu_strtoul(p + 1, &p, 16, &lpid)) {
+                put_packet(s, "E22");
+                break;
+            }
+
+            pid = lpid;
+        }
+
+        process = gdb_get_process(s, pid);
+        gdb_process_breakpoint_remove_all(s, process);
+        process->attached = false;
+
+        if (pid == gdb_get_cpu_pid(s, s->c_cpu)) {
+            s->c_cpu = gdb_first_attached_cpu(s);
+        }
+
+        if (pid == gdb_get_cpu_pid(s, s->g_cpu)) {
+            s->g_cpu = gdb_first_attached_cpu(s);
+        }
+
+        if (s->c_cpu == NULL) {
+            /* No more process attached */
+            gdb_syscall_mode = GDB_SYS_DISABLED;
+            gdb_continue(s);
+        }
         put_packet(s, "OK");
         break;
     case 's':
-- 
2.19.2

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

* [Qemu-devel] [PULL 13/37] gdbstub: add support for extended mode packet
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (11 preceding siblings ...)
  2019-01-07 16:30 ` [Qemu-devel] [PULL 12/37] gdbstub: add multiprocess support to 'D' packets Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 14/37] gdbstub: add support for vAttach packets Peter Maydell
                   ` (25 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Luc Michel <luc.michel@greensocs.com>

Add support for the '!' extended mode packet. This is required for the
multiprocess extension.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20181207090135.7651-12-luc.michel@greensocs.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 gdbstub.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gdbstub.c b/gdbstub.c
index 2c7032f53ab..9b6b4d20a02 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1302,6 +1302,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
     p = line_buf;
     ch = *p++;
     switch(ch) {
+    case '!':
+        put_packet(s, "OK");
+        break;
     case '?':
         /* TODO: Make this return the correct value for user-mode.  */
         snprintf(buf, sizeof(buf), "T%02xthread:%s;", GDB_SIGNAL_TRAP,
-- 
2.19.2

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

* [Qemu-devel] [PULL 14/37] gdbstub: add support for vAttach packets
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (12 preceding siblings ...)
  2019-01-07 16:30 ` [Qemu-devel] [PULL 13/37] gdbstub: add support for extended mode packet Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 15/37] gdbstub: processes initialization on new peer connection Peter Maydell
                   ` (24 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Luc Michel <luc.michel@greensocs.com>

Add support for the vAttach packets. In multiprocess mode, GDB sends
them to attach to additional processes.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20181207090135.7651-13-luc.michel@greensocs.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 gdbstub.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/gdbstub.c b/gdbstub.c
index 9b6b4d20a02..d80af955cea 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1348,6 +1348,41 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
                 goto unknown_command;
             }
             break;
+        } else if (strncmp(p, "Attach;", 7) == 0) {
+            unsigned long pid;
+
+            p += 7;
+
+            if (qemu_strtoul(p, &p, 16, &pid)) {
+                put_packet(s, "E22");
+                break;
+            }
+
+            process = gdb_get_process(s, pid);
+
+            if (process == NULL) {
+                put_packet(s, "E22");
+                break;
+            }
+
+            cpu = get_first_cpu_in_process(s, process);
+
+            if (cpu == NULL) {
+                /* Refuse to attach an empty process */
+                put_packet(s, "E22");
+                break;
+            }
+
+            process->attached = true;
+
+            s->g_cpu = cpu;
+            s->c_cpu = cpu;
+
+            snprintf(buf, sizeof(buf), "T%02xthread:%s;", GDB_SIGNAL_TRAP,
+                     gdb_fmt_thread_id(s, cpu, thread_id, sizeof(thread_id)));
+
+            put_packet(s, buf);
+            break;
         } else {
             goto unknown_command;
         }
-- 
2.19.2

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

* [Qemu-devel] [PULL 15/37] gdbstub: processes initialization on new peer connection
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (13 preceding siblings ...)
  2019-01-07 16:30 ` [Qemu-devel] [PULL 14/37] gdbstub: add support for vAttach packets Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 16/37] gdbstub: gdb_set_stop_cpu: ignore request when process is not attached Peter Maydell
                   ` (23 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Luc Michel <luc.michel@greensocs.com>

When a new connection is established, we set the first process to be
attached, and the others detached. The first CPU of the first process
is selected as the current CPU.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20181207090135.7651-14-luc.michel@greensocs.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 gdbstub.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index d80af955cea..432e7d2f7da 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2267,9 +2267,10 @@ static bool gdb_accept(void)
     }
 
     s = g_malloc0(sizeof(GDBState));
-    s->c_cpu = first_cpu;
-    s->g_cpu = first_cpu;
     create_default_process(s);
+    s->processes[0].attached = true;
+    s->c_cpu = gdb_first_attached_cpu(s);
+    s->g_cpu = s->c_cpu;
     s->fd = fd;
     gdb_has_xml = false;
 
@@ -2355,8 +2356,19 @@ static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
 
 static void gdb_chr_event(void *opaque, int event)
 {
+    int i;
+    GDBState *s = (GDBState *) opaque;
+
     switch (event) {
     case CHR_EVENT_OPENED:
+        /* Start with first process attached, others detached */
+        for (i = 0; i < s->process_num; i++) {
+            s->processes[i].attached = !i;
+        }
+
+        s->c_cpu = gdb_first_attached_cpu(s);
+        s->g_cpu = s->c_cpu;
+
         vm_stop(RUN_STATE_PAUSED);
         gdb_has_xml = false;
         break;
@@ -2546,15 +2558,13 @@ int gdbserver_start(const char *device)
         memset(s, 0, sizeof(GDBState));
         s->mon_chr = mon_chr;
     }
-    s->c_cpu = first_cpu;
-    s->g_cpu = first_cpu;
 
     create_processes(s);
 
     if (chr) {
         qemu_chr_fe_init(&s->chr, chr, &error_abort);
         qemu_chr_fe_set_handlers(&s->chr, gdb_chr_can_receive, gdb_chr_receive,
-                                 gdb_chr_event, NULL, NULL, NULL, true);
+                                 gdb_chr_event, NULL, s, NULL, true);
     }
     s->state = chr ? RS_IDLE : RS_INACTIVE;
     s->mon_chr = mon_chr;
-- 
2.19.2

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

* [Qemu-devel] [PULL 16/37] gdbstub: gdb_set_stop_cpu: ignore request when process is not attached
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (14 preceding siblings ...)
  2019-01-07 16:30 ` [Qemu-devel] [PULL 15/37] gdbstub: processes initialization on new peer connection Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 17/37] gdbstub: add multiprocess extension support Peter Maydell
                   ` (22 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Luc Michel <luc.michel@greensocs.com>

When gdb_set_stop_cpu() is called with a CPU associated to a process
currently not attached by the GDB client, return without modifying the
stop CPU. Otherwise, GDB gets confused if it receives packets with a
thread-id it does not know about.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 20181207090135.7651-15-luc.michel@greensocs.com
[PMM: fix checkpatch comment style nit]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 gdbstub.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/gdbstub.c b/gdbstub.c
index 432e7d2f7da..1517563abe1 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1798,6 +1798,16 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
 
 void gdb_set_stop_cpu(CPUState *cpu)
 {
+    GDBProcess *p = gdb_get_cpu_process(gdbserver_state, cpu);
+
+    if (!p->attached) {
+        /*
+         * Having a stop CPU corresponding to a process that is not attached
+         * confuses GDB. So we ignore the request.
+         */
+        return;
+    }
+
     gdbserver_state->c_cpu = cpu;
     gdbserver_state->g_cpu = cpu;
 }
-- 
2.19.2

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

* [Qemu-devel] [PULL 17/37] gdbstub: add multiprocess extension support
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (15 preceding siblings ...)
  2019-01-07 16:30 ` [Qemu-devel] [PULL 16/37] gdbstub: gdb_set_stop_cpu: ignore request when process is not attached Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 18/37] arm/xlnx-zynqmp: put APUs and RPUs in separate CPU clusters Peter Maydell
                   ` (21 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Luc Michel <luc.michel@greensocs.com>

Add multiprocess extension support by enabling multiprocess mode when
the peer requests it, and by replying that we actually support it in the
qSupported reply packet.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 20181207090135.7651-16-luc.michel@greensocs.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 gdbstub.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/gdbstub.c b/gdbstub.c
index 1517563abe1..bfc7afb5096 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1732,6 +1732,12 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             if (cc->gdb_core_xml_file != NULL) {
                 pstrcat(buf, sizeof(buf), ";qXfer:features:read+");
             }
+
+            if (strstr(p, "multiprocess+")) {
+                s->multiprocess = true;
+            }
+            pstrcat(buf, sizeof(buf), ";multiprocess+");
+
             put_packet(s, buf);
             break;
         }
-- 
2.19.2

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

* [Qemu-devel] [PULL 18/37] arm/xlnx-zynqmp: put APUs and RPUs in separate CPU clusters
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (16 preceding siblings ...)
  2019-01-07 16:30 ` [Qemu-devel] [PULL 17/37] gdbstub: add multiprocess extension support Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-07 16:30 ` [Qemu-devel] [PULL 19/37] Revert "armv7m: Guard against no -kernel argument" Peter Maydell
                   ` (20 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Luc Michel <luc.michel@greensocs.com>

Create two separate CPU clusters for APUs and RPUs.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20181207090135.7651-17-luc.michel@greensocs.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/xlnx-zynqmp.h |  3 +++
 hw/arm/xlnx-zynqmp.c         | 23 +++++++++++++++++++----
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
index 98f925ab84a..591515c7600 100644
--- a/include/hw/arm/xlnx-zynqmp.h
+++ b/include/hw/arm/xlnx-zynqmp.h
@@ -31,6 +31,7 @@
 #include "hw/display/xlnx_dp.h"
 #include "hw/intc/xlnx-zynqmp-ipi.h"
 #include "hw/timer/xlnx-zynqmp-rtc.h"
+#include "hw/cpu/cluster.h"
 
 #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp"
 #define XLNX_ZYNQMP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \
@@ -77,6 +78,8 @@ typedef struct XlnxZynqMPState {
     DeviceState parent_obj;
 
     /*< public >*/
+    CPUClusterState apu_cluster;
+    CPUClusterState rpu_cluster;
     ARMCPU apu_cpu[XLNX_ZYNQMP_NUM_APU_CPUS];
     ARMCPU rpu_cpu[XLNX_ZYNQMP_NUM_RPU_CPUS];
     GICState gic;
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index c1950403505..c67ac2e64ac 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -178,12 +178,19 @@ static void xlnx_zynqmp_create_rpu(XlnxZynqMPState *s, const char *boot_cpu,
     int i;
     int num_rpus = MIN(smp_cpus - XLNX_ZYNQMP_NUM_APU_CPUS, XLNX_ZYNQMP_NUM_RPU_CPUS);
 
+    object_initialize_child(OBJECT(s), "rpu-cluster", &s->rpu_cluster,
+                            sizeof(s->rpu_cluster), TYPE_CPU_CLUSTER,
+                            &error_abort, NULL);
+    qdev_prop_set_uint32(DEVICE(&s->rpu_cluster), "cluster-id", 1);
+
+    qdev_init_nofail(DEVICE(&s->rpu_cluster));
+
     for (i = 0; i < num_rpus; i++) {
         char *name;
 
         object_initialize(&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]),
                           "cortex-r5f-" TYPE_ARM_CPU);
-        object_property_add_child(OBJECT(s), "rpu-cpu[*]",
+        object_property_add_child(OBJECT(&s->rpu_cluster), "rpu-cpu[*]",
                                   OBJECT(&s->rpu_cpu[i]), &error_abort);
 
         name = object_get_canonical_path_component(OBJECT(&s->rpu_cpu[i]));
@@ -213,10 +220,16 @@ static void xlnx_zynqmp_init(Object *obj)
     int i;
     int num_apus = MIN(smp_cpus, XLNX_ZYNQMP_NUM_APU_CPUS);
 
+    object_initialize_child(obj, "apu-cluster", &s->apu_cluster,
+                            sizeof(s->apu_cluster), TYPE_CPU_CLUSTER,
+                            &error_abort, NULL);
+    qdev_prop_set_uint32(DEVICE(&s->apu_cluster), "cluster-id", 0);
+
     for (i = 0; i < num_apus; i++) {
-        object_initialize_child(obj, "apu-cpu[*]", &s->apu_cpu[i],
-                                sizeof(s->apu_cpu[i]),
-                                "cortex-a53-" TYPE_ARM_CPU, &error_abort, NULL);
+        object_initialize_child(OBJECT(&s->apu_cluster), "apu-cpu[*]",
+                                &s->apu_cpu[i], sizeof(s->apu_cpu[i]),
+                                "cortex-a53-" TYPE_ARM_CPU, &error_abort,
+                                NULL);
     }
 
     sysbus_init_child_obj(obj, "gic", &s->gic, sizeof(s->gic),
@@ -333,6 +346,8 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
     qdev_prop_set_bit(DEVICE(&s->gic),
                       "has-virtualization-extensions", s->virt);
 
+    qdev_init_nofail(DEVICE(&s->apu_cluster));
+
     /* Realize APUs before realizing the GIC. KVM requires this.  */
     for (i = 0; i < num_apus; i++) {
         char *name;
-- 
2.19.2

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

* [Qemu-devel] [PULL 19/37] Revert "armv7m: Guard against no -kernel argument"
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (17 preceding siblings ...)
  2019-01-07 16:30 ` [Qemu-devel] [PULL 18/37] arm/xlnx-zynqmp: put APUs and RPUs in separate CPU clusters Peter Maydell
@ 2019-01-07 16:30 ` Peter Maydell
  2019-01-07 16:31 ` [Qemu-devel] [PULL 20/37] hw/arm: versal: Plug memory leaks Peter Maydell
                   ` (19 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:30 UTC (permalink / raw)
  To: qemu-devel

From: Stefan Hajnoczi <stefanha@redhat.com>

This reverts commit 01fd41ab3fb69971c24a69ed49cde96086d81278.

The generic loader device (-device loader,file=kernel.bin) can be used
to load a kernel instead of the -kernel option.  Some boards have flash
memory (pflash) that is set via the -pflash or -drive options.

Allow starting QEMU without the -kernel option to accommodate these
scenarios.

Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20190103144124.18917-1-stefanha@redhat.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/armv7m.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 4bf9131b81e..f4446528307 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -285,11 +285,6 @@ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
     big_endian = 0;
 #endif
 
-    if (!kernel_filename && !qtest_enabled()) {
-        error_report("Guest image must be specified (using -kernel)");
-        exit(1);
-    }
-
     if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
         asidx = ARMASIdx_S;
     } else {
-- 
2.19.2

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

* [Qemu-devel] [PULL 20/37] hw/arm: versal: Plug memory leaks
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (18 preceding siblings ...)
  2019-01-07 16:30 ` [Qemu-devel] [PULL 19/37] Revert "armv7m: Guard against no -kernel argument" Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-07 16:31 ` [Qemu-devel] [PULL 21/37] MAINTAINERS: Add ARM-related files for hw/[misc|input|timer]/ Peter Maydell
                   ` (18 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

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

Plug a couple of "board creation time" memory leaks.

Fixes: 6f16da53ffe4567 ("hw/arm: versal: Add a virtual Xilinx Versal board")
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190104104749.5314-2-edgar.iglesias@gmail.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/xlnx-versal-virt.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index c6feeac532f..f95fde2309b 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -130,6 +130,7 @@ static void fdt_add_gic_nodes(VersalVirt *s)
                                  2, MM_GIC_APU_REDIST_0_SIZE);
     qemu_fdt_setprop_cell(s->fdt, nodename, "#interrupt-cells", 3);
     qemu_fdt_setprop_string(s->fdt, nodename, "compatible", "arm,gic-v3");
+    g_free(nodename);
 }
 
 static void fdt_add_timer_nodes(VersalVirt *s)
@@ -364,6 +365,7 @@ static void create_virtio_regions(VersalVirt *s)
         sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic_irq);
         mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
         memory_region_add_subregion(&s->soc.mr_ps, base, mr);
+        g_free(name);
     }
 
     for (i = 0; i < NUM_VIRTIO_TRANSPORT; i++) {
-- 
2.19.2

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

* [Qemu-devel] [PULL 21/37] MAINTAINERS: Add ARM-related files for hw/[misc|input|timer]/
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (19 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 20/37] hw/arm: versal: Plug memory leaks Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-07 16:31 ` [Qemu-devel] [PULL 22/37] cpus.c: Fix race condition in cpu_stop_current() Peter Maydell
                   ` (17 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

From: Thomas Huth <thuth@redhat.com>

Some of the files in hw/input/, hw/misc/ and hw/timer/ are only
used by one of the ARM machines, so we can assign these files to
the corresponding boards.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 1546433583-18397-1-git-send-email-thuth@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 MAINTAINERS | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 471161742de..0bfd95a4ef7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -515,6 +515,7 @@ F: hw/intc/arm*
 F: hw/intc/gic_internal.h
 F: hw/misc/a9scu.c
 F: hw/misc/arm11scu.c
+F: hw/misc/arm_l2x0.c
 F: hw/timer/a9gtimer*
 F: hw/timer/arm*
 F: include/hw/arm/arm*.h
@@ -587,6 +588,7 @@ L: qemu-arm@nongnu.org
 S: Maintained
 F: hw/arm/integratorcp.c
 F: hw/misc/arm_integrator_debug.c
+F: include/hw/misc/arm_integrator_debug.h
 
 MCIMX6UL EVK / i.MX6ul
 M: Peter Maydell <peter.maydell@linaro.org>
@@ -606,7 +608,9 @@ L: qemu-arm@nongnu.org
 S: Odd Fixes
 F: hw/arm/mcimx7d-sabre.c
 F: hw/arm/fsl-imx7.c
+F: hw/misc/imx7_*.c
 F: include/hw/arm/fsl-imx7.h
+F: include/hw/misc/imx7_*.h
 F: hw/pci-host/designware.c
 F: include/hw/pci-host/designware.h
 
@@ -640,6 +644,10 @@ M: Peter Maydell <peter.maydell@linaro.org>
 L: qemu-arm@nongnu.org
 S: Odd Fixes
 F: hw/arm/nseries.c
+F: hw/input/lm832x.c
+F: hw/input/tsc2005.c
+F: hw/misc/cbus.c
+F: hw/timer/twl92230.c
 
 Palm
 M: Andrzej Zaborowski <balrogg@gmail.com>
@@ -647,6 +655,7 @@ M: Peter Maydell <peter.maydell@linaro.org>
 L: qemu-arm@nongnu.org
 S: Odd Fixes
 F: hw/arm/palm.c
+F: hw/input/tsc210x.c
 
 Raspberry Pi
 M: Peter Maydell <peter.maydell@linaro.org>
@@ -683,6 +692,7 @@ F: hw/display/tc6393xb.c
 F: hw/gpio/max7310.c
 F: hw/gpio/zaurus.c
 F: hw/misc/mst_fpga.c
+F: hw/misc/max111x.c
 F: include/hw/arm/pxa.h
 F: include/hw/arm/sharpsl.h
 
@@ -693,10 +703,10 @@ L: qemu-arm@nongnu.org
 S: Odd Fixes
 F: hw/arm/sabrelite.c
 F: hw/arm/fsl-imx6.c
-F: hw/misc/imx6_src.c
+F: hw/misc/imx6_*.c
 F: hw/ssi/imx_spi.c
 F: include/hw/arm/fsl-imx6.h
-F: include/hw/misc/imx6_src.h
+F: include/hw/misc/imx6_*.h
 F: include/hw/ssi/imx_spi.h
 
 Sharp SL-5500 (Collie) PDA
@@ -807,7 +817,9 @@ R: Joel Stanley <joel@jms.id.au>
 L: qemu-arm@nongnu.org
 S: Maintained
 F: hw/*/*aspeed*
+F: hw/misc/pca9552.c
 F: include/hw/*/*aspeed*
+F: include/hw/misc/pca9552*.h
 F: hw/net/ftgmac100.c
 F: include/hw/net/ftgmac100.h
 
-- 
2.19.2

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

* [Qemu-devel] [PULL 22/37] cpus.c: Fix race condition in cpu_stop_current()
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (20 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 21/37] MAINTAINERS: Add ARM-related files for hw/[misc|input|timer]/ Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-07 16:31 ` [Qemu-devel] [PULL 23/37] hw/arm/allwinner-a10: Add the 'A' SRAM and the SRAM controller Peter Maydell
                   ` (16 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

We use cpu_stop_current() to ensure the current CPU has stopped
from places like qemu_system_reset_request(). Unfortunately its
current implementation has a race. It calls qemu_cpu_stop(),
which sets cpu->stopped to true even though the CPU hasn't
actually stopped yet. The main thread will look at the flags
set by qemu_system_reset_request() and call pause_all_vcpus().
pause_all_vcpus() waits for every cpu to have cpu->stopped true,
so it can continue (and we will start the system reset operation)
before the vcpu thread has got back to its top level loop.

Instead, just set cpu->stop and call cpu_exit(). This will
cause the vcpu to exit back to the top level loop, and there
(as part of the wait_io_event code) it will call qemu_cpu_stop().

This fixes bugs where the reset request appeared to be ignored
or the CPU misbehaved because the reset operation started
to change vcpu state while the vcpu thread was still using it.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Emilio G. Cota <cota@braap.org>
Tested-by: Jaap Crezee <jaap@jcz.nl>
Message-id: 20181207155911.12710-1-peter.maydell@linaro.org
---
 cpus.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/cpus.c b/cpus.c
index 0ddeeefc14f..b09b7027126 100644
--- a/cpus.c
+++ b/cpus.c
@@ -2100,7 +2100,8 @@ void qemu_init_vcpu(CPUState *cpu)
 void cpu_stop_current(void)
 {
     if (current_cpu) {
-        qemu_cpu_stop(current_cpu, true);
+        current_cpu->stop = true;
+        cpu_exit(current_cpu);
     }
 }
 
-- 
2.19.2

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

* [Qemu-devel] [PULL 23/37] hw/arm/allwinner-a10: Add the 'A' SRAM and the SRAM controller
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (21 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 22/37] cpus.c: Fix race condition in cpu_stop_current() Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-07 16:31 ` [Qemu-devel] [PULL 24/37] qtest: Add set_irq_in command to set IRQ/GPIO level Peter Maydell
                   ` (15 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

From: Philippe Mathieu-Daudé <f4bug@amsat.org>

>From the "A10 User Manual V1.20" p.29: "3.2. Memory Mapping" and:

 7. System Control
  7.1. Overview

  A10 embeds a high-speed SRAM which has been split into five segments.
  See detailed memory mapping in following table:

  Area          Address        Size (Bytes)
   A1    0x00000000-0x00003FFF 16K
   A2    0x00004000-0x00007FFF 16K
   A3    0x00008000-0x0000B3FF 13K
   A4    0x0000B400-0x0000BFFF  3K

Since for emulation purpose we don't need the segmentations, we simply define
the 'A' area as a single 48KB SRAM.

We don't implement the following others areas:
- 'B': 'Secure RAM' (64K),
- 'C': Debug/ISP SRAM
- 'D': USB SRAM

(qemu) info mtree
address-space: memory
  0000000000000000-ffffffffffffffff (prio 0, i/o): system
    0000000000000000-000000000000bfff (prio 0, ram): sram A
    0000000001c00000-0000000001c00fff (prio -1000, i/o): a10-sram-ctrl
    0000000001c0b000-0000000001c0bfff (prio 0, i/o): aw_emac
    0000000001c18000-0000000001c18fff (prio 0, i/o): ahci
      0000000001c18080-0000000001c180ff (prio 0, i/o): allwinner-ahci
    0000000001c20400-0000000001c207ff (prio 0, i/o): allwinner-a10-pic
    0000000001c20c00-0000000001c20fff (prio 0, i/o): allwinner-A10-timer
    0000000001c28000-0000000001c2801f (prio 0, i/o): serial
    0000000040000000-0000000047ffffff (prio 0, ram): cubieboard.ram

Reported-by: Charlie Smurthwaite <charlie@atech.media>
Tested-by: Charlie Smurthwaite <charlie@atech.media>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 20190104142921.878-1-f4bug@amsat.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/allwinner-a10.h | 1 +
 hw/arm/allwinner-a10.c         | 6 ++++++
 2 files changed, 7 insertions(+)

diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
index efb8fc81236..389e128d0fc 100644
--- a/include/hw/arm/allwinner-a10.h
+++ b/include/hw/arm/allwinner-a10.h
@@ -35,6 +35,7 @@ typedef struct AwA10State {
     AwA10PICState intc;
     AwEmacState emac;
     AllwinnerAHCIState sata;
+    MemoryRegion sram_a;
 } AwA10State;
 
 #define ALLWINNER_H_
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
index 9fe875cdb5e..df0d079ad0a 100644
--- a/hw/arm/allwinner-a10.c
+++ b/hw/arm/allwinner-a10.c
@@ -22,6 +22,7 @@
 #include "hw/sysbus.h"
 #include "hw/devices.h"
 #include "hw/arm/allwinner-a10.h"
+#include "hw/misc/unimp.h"
 
 static void aw_a10_init(Object *obj)
 {
@@ -85,6 +86,11 @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
     sysbus_connect_irq(sysbusdev, 4, s->irq[67]);
     sysbus_connect_irq(sysbusdev, 5, s->irq[68]);
 
+    memory_region_init_ram(&s->sram_a, OBJECT(dev), "sram A", 48 * KiB,
+                           &error_fatal);
+    memory_region_add_subregion(get_system_memory(), 0x00000000, &s->sram_a);
+    create_unimplemented_device("a10-sram-ctrl", 0x01c00000, 4 * KiB);
+
     /* FIXME use qdev NIC properties instead of nd_table[] */
     if (nd_table[0].used) {
         qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC);
-- 
2.19.2

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

* [Qemu-devel] [PULL 24/37] qtest: Add set_irq_in command to set IRQ/GPIO level
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (22 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 23/37] hw/arm/allwinner-a10: Add the 'A' SRAM and the SRAM controller Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-09  5:58   ` Matthew Ogilvie
  2019-01-07 16:31 ` [Qemu-devel] [PULL 25/37] arm: Add header to host common definition for nRF51 SOC peripherals Peter Maydell
                   ` (14 subsequent siblings)
  38 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

From: Steffen Görtz <contrib@steffen-goertz.de>

Adds a new qtest command "set_irq_in" which allows
to set qemu gpio lines to a given level.

Based on https://lists.gnu.org/archive/html/qemu-devel/2012-12/msg02363.html
which never got merged.

Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20190103091119.9367-2-stefanha@redhat.com
Originally-by: Matthew Ogilvie <mmogilvi_qemu@miniinfo.net>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 tests/libqtest.h | 13 +++++++++++++
 qtest.c          | 43 +++++++++++++++++++++++++++++++++++++++++++
 tests/libqtest.c | 10 ++++++++++
 3 files changed, 66 insertions(+)

diff --git a/tests/libqtest.h b/tests/libqtest.h
index 9758c51be61..7ea94139b0c 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -230,6 +230,19 @@ void qtest_irq_intercept_in(QTestState *s, const char *string);
  */
 void qtest_irq_intercept_out(QTestState *s, const char *string);
 
+/**
+ * qtest_set_irq_in:
+ * @s: QTestState instance to operate on.
+ * @string: QOM path of a device
+ * @name: IRQ name
+ * @irq: IRQ number
+ * @level: IRQ level
+ *
+ * Force given device/irq GPIO-in pin to the given level.
+ */
+void qtest_set_irq_in(QTestState *s, const char *string, const char *name,
+                      int irq, int level);
+
 /**
  * qtest_outb:
  * @s: #QTestState instance to operate on.
diff --git a/qtest.c b/qtest.c
index 69b9e9962b5..451696b5dae 100644
--- a/qtest.c
+++ b/qtest.c
@@ -164,6 +164,17 @@ static bool qtest_opened;
  * where NUM is an IRQ number.  For the PC, interrupts can be intercepted
  * simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with
  * NUM=0 even though it is remapped to GSI 2).
+ *
+ * Setting interrupt level:
+ *
+ *  > set_irq_in QOM-PATH NAME NUM LEVEL
+ *  < OK
+ *
+ *  where NAME is the name of the irq/gpio list, NUM is an IRQ number and
+ *  LEVEL is an signed integer IRQ level.
+ *
+ * Forcibly set the given interrupt pin to the given level.
+ *
  */
 
 static int hex2nib(char ch)
@@ -326,7 +337,39 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
         irq_intercept_dev = dev;
         qtest_send_prefix(chr);
         qtest_send(chr, "OK\n");
+    } else if (strcmp(words[0], "set_irq_in") == 0) {
+        DeviceState *dev;
+        qemu_irq irq;
+        char *name;
+        int ret;
+        int num;
+        int level;
 
+        g_assert(words[1] && words[2] && words[3] && words[4]);
+
+        dev = DEVICE(object_resolve_path(words[1], NULL));
+        if (!dev) {
+            qtest_send_prefix(chr);
+            qtest_send(chr, "FAIL Unknown device\n");
+            return;
+        }
+
+        if (strcmp(words[2], "unnamed-gpio-in") == 0) {
+            name = NULL;
+        } else {
+            name = words[2];
+        }
+
+        ret = qemu_strtoi(words[3], NULL, 0, &num);
+        g_assert(!ret);
+        ret = qemu_strtoi(words[4], NULL, 0, &level);
+        g_assert(!ret);
+
+        irq = qdev_get_gpio_in_named(dev, name, num);
+
+        qemu_set_irq(irq, level);
+        qtest_send_prefix(chr);
+        qtest_send(chr, "OK\n");
     } else if (strcmp(words[0], "outb") == 0 ||
                strcmp(words[0], "outw") == 0 ||
                strcmp(words[0], "outl") == 0) {
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 1d75d3c9363..55750dd68de 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -753,6 +753,16 @@ void qtest_irq_intercept_in(QTestState *s, const char *qom_path)
     qtest_rsp(s, 0);
 }
 
+void qtest_set_irq_in(QTestState *s, const char *qom_path, const char *name,
+                      int num, int level)
+{
+    if (!name) {
+        name = "unnamed-gpio-in";
+    }
+    qtest_sendf(s, "set_irq_in %s %s %d %d\n", qom_path, name, num, level);
+    qtest_rsp(s, 0);
+}
+
 static void qtest_out(QTestState *s, const char *cmd, uint16_t addr, uint32_t value)
 {
     qtest_sendf(s, "%s 0x%x 0x%x\n", cmd, addr, value);
-- 
2.19.2

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

* [Qemu-devel] [PULL 25/37] arm: Add header to host common definition for nRF51 SOC peripherals
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (23 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 24/37] qtest: Add set_irq_in command to set IRQ/GPIO level Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-07 16:31 ` [Qemu-devel] [PULL 26/37] hw/misc/nrf51_rng: Add NRF51 random number generator peripheral Peter Maydell
                   ` (13 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

From: Steffen Görtz <contrib@steffen-goertz.de>

Adds a header that provides definitions that are used
across nRF51 peripherals

Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20190103091119.9367-3-stefanha@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/nrf51.h       | 45 ++++++++++++++++++++++++++++++++++++
 include/hw/char/nrf51_uart.h |  1 -
 hw/arm/nrf51_soc.c           | 33 ++++++++++----------------
 3 files changed, 57 insertions(+), 22 deletions(-)
 create mode 100644 include/hw/arm/nrf51.h

diff --git a/include/hw/arm/nrf51.h b/include/hw/arm/nrf51.h
new file mode 100644
index 00000000000..175bb6c301e
--- /dev/null
+++ b/include/hw/arm/nrf51.h
@@ -0,0 +1,45 @@
+/*
+ * Nordic Semiconductor nRF51 Series SOC Common Defines
+ *
+ * This file hosts generic defines used in various nRF51 peripheral devices.
+ *
+ * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
+ * Product Spec: http://infocenter.nordicsemi.com/pdf/nRF51822_PS_v3.1.pdf
+ *
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#ifndef NRF51_H
+#define NRF51_H
+
+#define NRF51_FLASH_BASE      0x00000000
+#define NRF51_FICR_BASE       0x10000000
+#define NRF51_FICR_SIZE       0x00000100
+#define NRF51_UICR_BASE       0x10001000
+#define NRF51_SRAM_BASE       0x20000000
+
+#define NRF51_IOMEM_BASE      0x40000000
+#define NRF51_IOMEM_SIZE      0x20000000
+
+#define NRF51_UART_BASE       0x40002000
+#define NRF51_TIMER_BASE      0x40008000
+#define NRF51_TIMER_SIZE      0x00001000
+#define NRF51_RNG_BASE        0x4000D000
+#define NRF51_NVMC_BASE       0x4001E000
+#define NRF51_GPIO_BASE       0x50000000
+
+#define NRF51_PRIVATE_BASE    0xF0000000
+#define NRF51_PRIVATE_SIZE    0x10000000
+
+#define NRF51_PAGE_SIZE       1024
+
+/* Trigger */
+#define NRF51_TRIGGER_TASK 0x01
+
+/* Events */
+#define NRF51_EVENT_CLEAR  0x00
+
+#endif
diff --git a/include/hw/char/nrf51_uart.h b/include/hw/char/nrf51_uart.h
index e3ecb7c81c2..eb1c15b490b 100644
--- a/include/hw/char/nrf51_uart.h
+++ b/include/hw/char/nrf51_uart.h
@@ -16,7 +16,6 @@
 #include "hw/registerfields.h"
 
 #define UART_FIFO_LENGTH 6
-#define UART_BASE 0x40002000
 #define UART_SIZE 0x1000
 
 #define TYPE_NRF51_UART "nrf51_soc.uart"
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
index b89c1bdea08..55f8eaafcb0 100644
--- a/hw/arm/nrf51_soc.c
+++ b/hw/arm/nrf51_soc.c
@@ -21,27 +21,16 @@
 #include "qemu/log.h"
 #include "cpu.h"
 
+#include "hw/arm/nrf51.h"
 #include "hw/arm/nrf51_soc.h"
 
-#define IOMEM_BASE      0x40000000
-#define IOMEM_SIZE      0x20000000
-
-#define FICR_BASE       0x10000000
-#define FICR_SIZE       0x000000fc
-
-#define FLASH_BASE      0x00000000
-#define SRAM_BASE       0x20000000
-
-#define PRIVATE_BASE    0xF0000000
-#define PRIVATE_SIZE    0x10000000
-
 /*
  * The size and base is for the NRF51822 part. If other parts
  * are supported in the future, add a sub-class of NRF51SoC for
  * the specific variants
  */
-#define NRF51822_FLASH_SIZE     (256 * 1024)
-#define NRF51822_SRAM_SIZE      (16 * 1024)
+#define NRF51822_FLASH_SIZE     (256 * NRF51_PAGE_SIZE)
+#define NRF51822_SRAM_SIZE      (16 * NRF51_PAGE_SIZE)
 
 #define BASE_TO_IRQ(base) ((base >> 12) & 0x1F)
 
@@ -76,14 +65,14 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
         error_propagate(errp, err);
         return;
     }
-    memory_region_add_subregion(&s->container, FLASH_BASE, &s->flash);
+    memory_region_add_subregion(&s->container, NRF51_FLASH_BASE, &s->flash);
 
     memory_region_init_ram(&s->sram, NULL, "nrf51.sram", s->sram_size, &err);
     if (err) {
         error_propagate(errp, err);
         return;
     }
-    memory_region_add_subregion(&s->container, SRAM_BASE, &s->sram);
+    memory_region_add_subregion(&s->container, NRF51_SRAM_BASE, &s->sram);
 
     /* UART */
     object_property_set_bool(OBJECT(&s->uart), true, "realized", &err);
@@ -92,15 +81,17 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
         return;
     }
     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->uart), 0);
-    memory_region_add_subregion_overlap(&s->container, UART_BASE, mr, 0);
+    memory_region_add_subregion_overlap(&s->container, NRF51_UART_BASE, mr, 0);
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart), 0,
                        qdev_get_gpio_in(DEVICE(&s->cpu),
-                       BASE_TO_IRQ(UART_BASE)));
+                       BASE_TO_IRQ(NRF51_UART_BASE)));
 
-    create_unimplemented_device("nrf51_soc.io", IOMEM_BASE, IOMEM_SIZE);
-    create_unimplemented_device("nrf51_soc.ficr", FICR_BASE, FICR_SIZE);
+    create_unimplemented_device("nrf51_soc.io", NRF51_IOMEM_BASE,
+                                NRF51_IOMEM_SIZE);
+    create_unimplemented_device("nrf51_soc.ficr", NRF51_FICR_BASE,
+                                NRF51_FICR_SIZE);
     create_unimplemented_device("nrf51_soc.private",
-                                PRIVATE_BASE, PRIVATE_SIZE);
+                                NRF51_PRIVATE_BASE, NRF51_PRIVATE_SIZE);
 }
 
 static void nrf51_soc_init(Object *obj)
-- 
2.19.2

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

* [Qemu-devel] [PULL 26/37] hw/misc/nrf51_rng: Add NRF51 random number generator peripheral
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (24 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 25/37] arm: Add header to host common definition for nRF51 SOC peripherals Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-07 16:31 ` [Qemu-devel] [PULL 27/37] arm: Instantiate NRF51 random number generator Peter Maydell
                   ` (12 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

From: Steffen Görtz <contrib@steffen-goertz.de>

Add a model of the NRF51 random number generator peripheral.
This is a simple random generator that continuously generates
new random values after startup.

Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf

Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20190103091119.9367-4-stefanha@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/misc/Makefile.objs       |   1 +
 include/hw/misc/nrf51_rng.h |  83 ++++++++++++
 hw/misc/nrf51_rng.c         | 262 ++++++++++++++++++++++++++++++++++++
 3 files changed, 346 insertions(+)
 create mode 100644 include/hw/misc/nrf51_rng.h
 create mode 100644 hw/misc/nrf51_rng.c

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 680350b3c3b..04f3bfa516e 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -74,3 +74,4 @@ obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_AUX) += auxbus.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
 obj-$(CONFIG_MSF2) += msf2-sysreg.o
+obj-$(CONFIG_NRF51_SOC) += nrf51_rng.o
diff --git a/include/hw/misc/nrf51_rng.h b/include/hw/misc/nrf51_rng.h
new file mode 100644
index 00000000000..3d6bf799977
--- /dev/null
+++ b/include/hw/misc/nrf51_rng.h
@@ -0,0 +1,83 @@
+/*
+ * nRF51 Random Number Generator
+ *
+ * QEMU interface:
+ * + Property "period_unfiltered_us": Time between two biased values in
+ *   microseconds.
+ * + Property "period_filtered_us": Time between two unbiased values in
+ *   microseconds.
+ * + sysbus MMIO regions 0: Memory Region with tasks, events and registers
+ *   to be mapped to the peripherals instance address by the SOC.
+ * + Named GPIO output "irq": Interrupt line of the peripheral. Must be
+ *   connected to the associated peripheral interrupt line of the NVIC.
+ * + Named GPIO output "eep_valrdy": Event set when new random value is ready
+ *   to be read.
+ * + Named GPIO input "tep_start": Task that triggers start of continuous
+ *   generation of random values.
+ * + Named GPIO input "tep_stop": Task that ends continuous generation of
+ *   random values.
+ *
+ * Accuracy of the peripheral model:
+ * + Stochastic properties of different configurations of the random source
+ *   are not modeled.
+ * + Generation of unfiltered and filtered random values take at least the
+ *   average generation time stated in the production specification;
+ *   non-deterministic generation times are not modeled.
+ *
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+#ifndef NRF51_RNG_H
+#define NRF51_RNG_H
+
+#include "hw/sysbus.h"
+#include "qemu/timer.h"
+#define TYPE_NRF51_RNG "nrf51_soc.rng"
+#define NRF51_RNG(obj) OBJECT_CHECK(NRF51RNGState, (obj), TYPE_NRF51_RNG)
+
+#define NRF51_RNG_SIZE         0x1000
+
+#define NRF51_RNG_TASK_START   0x000
+#define NRF51_RNG_TASK_STOP    0x004
+#define NRF51_RNG_EVENT_VALRDY 0x100
+#define NRF51_RNG_REG_SHORTS   0x200
+#define NRF51_RNG_REG_SHORTS_VALRDY_STOP 0
+#define NRF51_RNG_REG_INTEN    0x300
+#define NRF51_RNG_REG_INTEN_VALRDY 0
+#define NRF51_RNG_REG_INTENSET 0x304
+#define NRF51_RNG_REG_INTENCLR 0x308
+#define NRF51_RNG_REG_CONFIG   0x504
+#define NRF51_RNG_REG_CONFIG_DECEN 0
+#define NRF51_RNG_REG_VALUE    0x508
+
+typedef struct {
+    SysBusDevice parent_obj;
+
+    MemoryRegion mmio;
+    qemu_irq irq;
+
+    /* Event End Points */
+    qemu_irq eep_valrdy;
+
+    QEMUTimer timer;
+
+    /* Time between generation of successive unfiltered values in us */
+    uint16_t period_unfiltered_us;
+    /* Time between generation of successive filtered values in us */
+    uint16_t period_filtered_us;
+
+    uint8_t value;
+
+    uint32_t active;
+    uint32_t event_valrdy;
+    uint32_t shortcut_stop_on_valrdy;
+    uint32_t interrupt_enabled;
+    uint32_t filter_enabled;
+
+} NRF51RNGState;
+
+
+#endif /* NRF51_RNG_H_ */
diff --git a/hw/misc/nrf51_rng.c b/hw/misc/nrf51_rng.c
new file mode 100644
index 00000000000..d188f044f4c
--- /dev/null
+++ b/hw/misc/nrf51_rng.c
@@ -0,0 +1,262 @@
+/*
+ * nRF51 Random Number Generator
+ *
+ * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.1.pdf
+ *
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "hw/arm/nrf51.h"
+#include "hw/misc/nrf51_rng.h"
+#include "crypto/random.h"
+
+static void update_irq(NRF51RNGState *s)
+{
+    bool irq = s->interrupt_enabled && s->event_valrdy;
+    qemu_set_irq(s->irq, irq);
+}
+
+static uint64_t rng_read(void *opaque, hwaddr offset, unsigned int size)
+{
+    NRF51RNGState *s = NRF51_RNG(opaque);
+    uint64_t r = 0;
+
+    switch (offset) {
+    case NRF51_RNG_EVENT_VALRDY:
+        r = s->event_valrdy;
+        break;
+    case NRF51_RNG_REG_SHORTS:
+        r = s->shortcut_stop_on_valrdy;
+        break;
+    case NRF51_RNG_REG_INTEN:
+    case NRF51_RNG_REG_INTENSET:
+    case NRF51_RNG_REG_INTENCLR:
+        r = s->interrupt_enabled;
+        break;
+    case NRF51_RNG_REG_CONFIG:
+        r = s->filter_enabled;
+        break;
+    case NRF51_RNG_REG_VALUE:
+        r = s->value;
+        break;
+
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: bad read offset 0x%" HWADDR_PRIx "\n",
+                      __func__, offset);
+    }
+
+    return r;
+}
+
+static int64_t calc_next_timeout(NRF51RNGState *s)
+{
+    int64_t timeout = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL);
+    if (s->filter_enabled) {
+        timeout += s->period_filtered_us;
+    } else {
+        timeout += s->period_unfiltered_us;
+    }
+
+    return timeout;
+}
+
+
+static void rng_update_timer(NRF51RNGState *s)
+{
+    if (s->active) {
+        timer_mod(&s->timer, calc_next_timeout(s));
+    } else {
+        timer_del(&s->timer);
+    }
+}
+
+
+static void rng_write(void *opaque, hwaddr offset,
+                       uint64_t value, unsigned int size)
+{
+    NRF51RNGState *s = NRF51_RNG(opaque);
+
+    switch (offset) {
+    case NRF51_RNG_TASK_START:
+        if (value == NRF51_TRIGGER_TASK) {
+            s->active = 1;
+            rng_update_timer(s);
+        }
+        break;
+    case NRF51_RNG_TASK_STOP:
+        if (value == NRF51_TRIGGER_TASK) {
+            s->active = 0;
+            rng_update_timer(s);
+        }
+        break;
+    case NRF51_RNG_EVENT_VALRDY:
+        if (value == NRF51_EVENT_CLEAR) {
+            s->event_valrdy = 0;
+        }
+        break;
+    case NRF51_RNG_REG_SHORTS:
+        s->shortcut_stop_on_valrdy =
+                (value & BIT_MASK(NRF51_RNG_REG_SHORTS_VALRDY_STOP)) ? 1 : 0;
+        break;
+    case NRF51_RNG_REG_INTEN:
+        s->interrupt_enabled =
+                (value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) ? 1 : 0;
+        break;
+    case NRF51_RNG_REG_INTENSET:
+        if (value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) {
+            s->interrupt_enabled = 1;
+        }
+        break;
+    case NRF51_RNG_REG_INTENCLR:
+        if (value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) {
+            s->interrupt_enabled = 0;
+        }
+        break;
+    case NRF51_RNG_REG_CONFIG:
+        s->filter_enabled =
+                      (value & BIT_MASK(NRF51_RNG_REG_CONFIG_DECEN)) ? 1 : 0;
+        break;
+
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: bad write offset 0x%" HWADDR_PRIx "\n",
+                      __func__, offset);
+    }
+
+    update_irq(s);
+}
+
+static const MemoryRegionOps rng_ops = {
+    .read =  rng_read,
+    .write = rng_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl.min_access_size = 4,
+    .impl.max_access_size = 4
+};
+
+static void nrf51_rng_timer_expire(void *opaque)
+{
+    NRF51RNGState *s = NRF51_RNG(opaque);
+
+    qcrypto_random_bytes(&s->value, 1, &error_abort);
+
+    s->event_valrdy = 1;
+    qemu_set_irq(s->eep_valrdy, 1);
+
+    if (s->shortcut_stop_on_valrdy) {
+        s->active = 0;
+    }
+
+    rng_update_timer(s);
+    update_irq(s);
+}
+
+static void nrf51_rng_tep_start(void *opaque, int n, int level)
+{
+    NRF51RNGState *s = NRF51_RNG(opaque);
+
+    if (level) {
+        s->active = 1;
+        rng_update_timer(s);
+    }
+}
+
+static void nrf51_rng_tep_stop(void *opaque, int n, int level)
+{
+    NRF51RNGState *s = NRF51_RNG(opaque);
+
+    if (level) {
+        s->active = 0;
+        rng_update_timer(s);
+    }
+}
+
+
+static void nrf51_rng_init(Object *obj)
+{
+    NRF51RNGState *s = NRF51_RNG(obj);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+    memory_region_init_io(&s->mmio, obj, &rng_ops, s,
+            TYPE_NRF51_RNG, NRF51_RNG_SIZE);
+    sysbus_init_mmio(sbd, &s->mmio);
+
+    timer_init_us(&s->timer, QEMU_CLOCK_VIRTUAL, nrf51_rng_timer_expire, s);
+
+    sysbus_init_irq(sbd, &s->irq);
+
+    /* Tasks */
+    qdev_init_gpio_in_named(DEVICE(s), nrf51_rng_tep_start, "tep_start", 1);
+    qdev_init_gpio_in_named(DEVICE(s), nrf51_rng_tep_stop, "tep_stop", 1);
+
+    /* Events */
+    qdev_init_gpio_out_named(DEVICE(s), &s->eep_valrdy, "eep_valrdy", 1);
+}
+
+static void nrf51_rng_reset(DeviceState *dev)
+{
+    NRF51RNGState *s = NRF51_RNG(dev);
+
+    s->value = 0;
+    s->active = 0;
+    s->event_valrdy = 0;
+    s->shortcut_stop_on_valrdy = 0;
+    s->interrupt_enabled = 0;
+    s->filter_enabled = 0;
+
+    rng_update_timer(s);
+}
+
+
+static Property nrf51_rng_properties[] = {
+    DEFINE_PROP_UINT16("period_unfiltered_us", NRF51RNGState,
+            period_unfiltered_us, 167),
+    DEFINE_PROP_UINT16("period_filtered_us", NRF51RNGState,
+            period_filtered_us, 660),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static const VMStateDescription vmstate_rng = {
+    .name = "nrf51_soc.rng",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(active, NRF51RNGState),
+        VMSTATE_UINT32(event_valrdy, NRF51RNGState),
+        VMSTATE_UINT32(shortcut_stop_on_valrdy, NRF51RNGState),
+        VMSTATE_UINT32(interrupt_enabled, NRF51RNGState),
+        VMSTATE_UINT32(filter_enabled, NRF51RNGState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void nrf51_rng_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->props = nrf51_rng_properties;
+    dc->vmsd = &vmstate_rng;
+    dc->reset = nrf51_rng_reset;
+}
+
+static const TypeInfo nrf51_rng_info = {
+    .name = TYPE_NRF51_RNG,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(NRF51RNGState),
+    .instance_init = nrf51_rng_init,
+    .class_init = nrf51_rng_class_init
+};
+
+static void nrf51_rng_register_types(void)
+{
+    type_register_static(&nrf51_rng_info);
+}
+
+type_init(nrf51_rng_register_types)
-- 
2.19.2

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

* [Qemu-devel] [PULL 27/37] arm: Instantiate NRF51 random number generator
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (25 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 26/37] hw/misc/nrf51_rng: Add NRF51 random number generator peripheral Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-07 16:31 ` [Qemu-devel] [PULL 28/37] hw/gpio/nrf51_gpio: Add nRF51 GPIO peripheral Peter Maydell
                   ` (11 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

From: Steffen Görtz <contrib@steffen-goertz.de>

Use RNG in SOC.

Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20190103091119.9367-5-stefanha@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/nrf51_soc.h |  2 ++
 hw/arm/nrf51_soc.c         | 16 ++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/include/hw/arm/nrf51_soc.h b/include/hw/arm/nrf51_soc.h
index 73fc92e9a8d..9e3ba916bd0 100644
--- a/include/hw/arm/nrf51_soc.h
+++ b/include/hw/arm/nrf51_soc.h
@@ -13,6 +13,7 @@
 #include "hw/sysbus.h"
 #include "hw/arm/armv7m.h"
 #include "hw/char/nrf51_uart.h"
+#include "hw/misc/nrf51_rng.h"
 
 #define TYPE_NRF51_SOC "nrf51-soc"
 #define NRF51_SOC(obj) \
@@ -26,6 +27,7 @@ typedef struct NRF51State {
     ARMv7MState cpu;
 
     NRF51UARTState uart;
+    NRF51RNGState rng;
 
     MemoryRegion iomem;
     MemoryRegion sram;
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
index 55f8eaafcb0..d2a19b8eadd 100644
--- a/hw/arm/nrf51_soc.c
+++ b/hw/arm/nrf51_soc.c
@@ -86,6 +86,19 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
                        qdev_get_gpio_in(DEVICE(&s->cpu),
                        BASE_TO_IRQ(NRF51_UART_BASE)));
 
+    /* RNG */
+    object_property_set_bool(OBJECT(&s->rng), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->rng), 0);
+    memory_region_add_subregion_overlap(&s->container, NRF51_RNG_BASE, mr, 0);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->rng), 0,
+                       qdev_get_gpio_in(DEVICE(&s->cpu),
+                       BASE_TO_IRQ(NRF51_RNG_BASE)));
+
     create_unimplemented_device("nrf51_soc.io", NRF51_IOMEM_BASE,
                                 NRF51_IOMEM_SIZE);
     create_unimplemented_device("nrf51_soc.ficr", NRF51_FICR_BASE,
@@ -110,6 +123,9 @@ static void nrf51_soc_init(Object *obj)
                            TYPE_NRF51_UART);
     object_property_add_alias(obj, "serial0", OBJECT(&s->uart), "chardev",
                               &error_abort);
+
+    sysbus_init_child_obj(obj, "rng", &s->rng, sizeof(s->rng),
+                           TYPE_NRF51_RNG);
 }
 
 static Property nrf51_soc_properties[] = {
-- 
2.19.2

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

* [Qemu-devel] [PULL 28/37] hw/gpio/nrf51_gpio: Add nRF51 GPIO peripheral
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (26 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 27/37] arm: Instantiate NRF51 random number generator Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-07 16:31 ` [Qemu-devel] [PULL 29/37] arm: Instantiate NRF51 general purpose I/O Peter Maydell
                   ` (10 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

From: Steffen Görtz <contrib@steffen-goertz.de>

This adds a model of the nRF51 GPIO peripheral.

Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf

The nRF51 series microcontrollers support up to 32 GPIO pins in various configurations.
The pins can be used as input pins with pull-ups or pull-down.
Furthermore, three different output driver modes per level are
available (disconnected, standard, high-current).

The GPIO-Peripheral has a mechanism for detecting level changes which is
not featured in this model.

Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20190103091119.9367-6-stefanha@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 Makefile.objs                |   1 +
 hw/gpio/Makefile.objs        |   1 +
 include/hw/gpio/nrf51_gpio.h |  69 ++++++++
 hw/gpio/nrf51_gpio.c         | 300 +++++++++++++++++++++++++++++++++++
 hw/gpio/trace-events         |   7 +
 5 files changed, 378 insertions(+)
 create mode 100644 include/hw/gpio/nrf51_gpio.h
 create mode 100644 hw/gpio/nrf51_gpio.c
 create mode 100644 hw/gpio/trace-events

diff --git a/Makefile.objs b/Makefile.objs
index bc5b8a8442f..456115992a4 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -184,6 +184,7 @@ trace-events-subdirs += hw/vfio
 trace-events-subdirs += hw/virtio
 trace-events-subdirs += hw/watchdog
 trace-events-subdirs += hw/xen
+trace-events-subdirs += hw/gpio
 trace-events-subdirs += io
 trace-events-subdirs += linux-user
 trace-events-subdirs += migration
diff --git a/hw/gpio/Makefile.objs b/hw/gpio/Makefile.objs
index fa0a72e6d0c..e5da0cb54fe 100644
--- a/hw/gpio/Makefile.objs
+++ b/hw/gpio/Makefile.objs
@@ -8,3 +8,4 @@ common-obj-$(CONFIG_GPIO_KEY) += gpio_key.o
 obj-$(CONFIG_OMAP) += omap_gpio.o
 obj-$(CONFIG_IMX) += imx_gpio.o
 obj-$(CONFIG_RASPI) += bcm2835_gpio.o
+obj-$(CONFIG_NRF51_SOC) += nrf51_gpio.o
diff --git a/include/hw/gpio/nrf51_gpio.h b/include/hw/gpio/nrf51_gpio.h
new file mode 100644
index 00000000000..337ee534bbc
--- /dev/null
+++ b/include/hw/gpio/nrf51_gpio.h
@@ -0,0 +1,69 @@
+/*
+ * nRF51 System-on-Chip general purpose input/output register definition
+ *
+ * QEMU interface:
+ * + sysbus MMIO regions 0: GPIO registers
+ * + Unnamed GPIO inputs 0-31: Set tri-state input level for GPIO pin.
+ *   Level -1: Externally Disconnected/Floating; Pull-up/down will be regarded
+ *   Level 0: Input externally driven LOW
+ *   Level 1: Input externally driven HIGH
+ * + Unnamed GPIO outputs 0-31:
+ *   Level -1: Disconnected/Floating
+ *   Level 0: Driven LOW
+ *   Level 1: Driven HIGH
+ *
+ * Accuracy of the peripheral model:
+ * + The nRF51 GPIO output driver supports two modes, standard and high-current
+ *   mode. These different drive modes are not modeled and handled the same.
+ * + Pin SENSEing is not modeled/implemented.
+ *
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+#ifndef NRF51_GPIO_H
+#define NRF51_GPIO_H
+
+#include "hw/sysbus.h"
+#define TYPE_NRF51_GPIO "nrf51_soc.gpio"
+#define NRF51_GPIO(obj) OBJECT_CHECK(NRF51GPIOState, (obj), TYPE_NRF51_GPIO)
+
+#define NRF51_GPIO_PINS 32
+
+#define NRF51_GPIO_SIZE 0x1000
+
+#define NRF51_GPIO_REG_OUT          0x504
+#define NRF51_GPIO_REG_OUTSET       0x508
+#define NRF51_GPIO_REG_OUTCLR       0x50C
+#define NRF51_GPIO_REG_IN           0x510
+#define NRF51_GPIO_REG_DIR          0x514
+#define NRF51_GPIO_REG_DIRSET       0x518
+#define NRF51_GPIO_REG_DIRCLR       0x51C
+#define NRF51_GPIO_REG_CNF_START    0x700
+#define NRF51_GPIO_REG_CNF_END      0x77F
+
+#define NRF51_GPIO_PULLDOWN 1
+#define NRF51_GPIO_PULLUP 3
+
+typedef struct NRF51GPIOState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion mmio;
+    qemu_irq irq;
+
+    uint32_t out;
+    uint32_t in;
+    uint32_t in_mask;
+    uint32_t dir;
+    uint32_t cnf[NRF51_GPIO_PINS];
+
+    uint32_t old_out;
+    uint32_t old_out_connected;
+
+    qemu_irq output[NRF51_GPIO_PINS];
+} NRF51GPIOState;
+
+
+#endif
diff --git a/hw/gpio/nrf51_gpio.c b/hw/gpio/nrf51_gpio.c
new file mode 100644
index 00000000000..86e047d649f
--- /dev/null
+++ b/hw/gpio/nrf51_gpio.c
@@ -0,0 +1,300 @@
+/*
+ * nRF51 System-on-Chip general purpose input/output register definition
+ *
+ * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
+ * Product Spec: http://infocenter.nordicsemi.com/pdf/nRF51822_PS_v3.1.pdf
+ *
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "hw/gpio/nrf51_gpio.h"
+#include "trace.h"
+
+/*
+ * Check if the output driver is connected to the direction switch
+ * given the current configuration and logic level.
+ * It is not differentiated between standard and "high"(-power) drive modes.
+ */
+static bool is_connected(uint32_t config, uint32_t level)
+{
+    bool state;
+    uint32_t drive_config = extract32(config, 8, 3);
+
+    switch (drive_config) {
+    case 0 ... 3:
+        state = true;
+        break;
+    case 4 ... 5:
+        state = level != 0;
+        break;
+    case 6 ... 7:
+        state = level == 0;
+        break;
+    default:
+        g_assert_not_reached();
+        break;
+    }
+
+    return state;
+}
+
+static void update_output_irq(NRF51GPIOState *s, size_t i,
+                              bool connected, bool level)
+{
+    int64_t irq_level = connected ? level : -1;
+    bool old_connected = extract32(s->old_out_connected, i, 1);
+    bool old_level = extract32(s->old_out, i, 1);
+
+    if ((old_connected != connected) || (old_level != level)) {
+        qemu_set_irq(s->output[i], irq_level);
+        trace_nrf51_gpio_update_output_irq(i, irq_level);
+    }
+
+    s->old_out = deposit32(s->old_out, i, 1, level);
+    s->old_out_connected = deposit32(s->old_out_connected, i, 1, connected);
+}
+
+static void update_state(NRF51GPIOState *s)
+{
+    uint32_t pull;
+    size_t i;
+    bool connected_out, dir, connected_in, out, input;
+
+    for (i = 0; i < NRF51_GPIO_PINS; i++) {
+        pull = extract32(s->cnf[i], 2, 2);
+        dir = extract32(s->cnf[i], 0, 1);
+        connected_in = extract32(s->in_mask, i, 1);
+        out = extract32(s->out, i, 1);
+        input = !extract32(s->cnf[i], 1, 1);
+        connected_out = is_connected(s->cnf[i], out) && dir;
+
+        update_output_irq(s, i, connected_out, out);
+
+        /* Pin both driven externally and internally */
+        if (connected_out && connected_in) {
+            qemu_log_mask(LOG_GUEST_ERROR, "GPIO pin %zu short circuited\n", i);
+        }
+
+        /*
+         * Input buffer disconnected from internal/external drives, so
+         * pull-up/pull-down becomes relevant
+         */
+        if (!input || (input && !connected_in && !connected_out)) {
+            if (pull == NRF51_GPIO_PULLDOWN) {
+                s->in = deposit32(s->in, i, 1, 0);
+            } else if (pull == NRF51_GPIO_PULLUP) {
+                s->in = deposit32(s->in, i, 1, 1);
+            }
+        }
+
+        /* Self stimulation through internal output driver */
+        if (connected_out && !connected_in && input) {
+            s->in = deposit32(s->in, i, 1, out);
+        }
+    }
+
+}
+
+/*
+ * Direction is exposed in both the DIR register and the DIR bit
+ * of each PINs CNF configuration register. Reflect bits for pins in DIR
+ * to individual pin configuration registers.
+ */
+static void reflect_dir_bit_in_cnf(NRF51GPIOState *s)
+{
+    size_t i;
+
+    uint32_t value = s->dir;
+
+    for (i = 0; i < NRF51_GPIO_PINS; i++) {
+        s->cnf[i] = (s->cnf[i] & ~(1UL)) | ((value >> i) & 0x01);
+    }
+}
+
+static uint64_t nrf51_gpio_read(void *opaque, hwaddr offset, unsigned int size)
+{
+    NRF51GPIOState *s = NRF51_GPIO(opaque);
+    uint64_t r = 0;
+    size_t idx;
+
+    switch (offset) {
+    case NRF51_GPIO_REG_OUT ... NRF51_GPIO_REG_OUTCLR:
+        r = s->out;
+        break;
+
+    case NRF51_GPIO_REG_IN:
+        r = s->in;
+        break;
+
+    case NRF51_GPIO_REG_DIR ... NRF51_GPIO_REG_DIRCLR:
+        r = s->dir;
+        break;
+
+    case NRF51_GPIO_REG_CNF_START ... NRF51_GPIO_REG_CNF_END:
+        idx = (offset - NRF51_GPIO_REG_CNF_START) / 4;
+        r = s->cnf[idx];
+        break;
+
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                "%s: bad read offset 0x%" HWADDR_PRIx "\n",
+                      __func__, offset);
+    }
+
+    trace_nrf51_gpio_read(offset, r);
+
+    return r;
+}
+
+static void nrf51_gpio_write(void *opaque, hwaddr offset,
+                       uint64_t value, unsigned int size)
+{
+    NRF51GPIOState *s = NRF51_GPIO(opaque);
+    size_t idx;
+
+    trace_nrf51_gpio_write(offset, value);
+
+    switch (offset) {
+    case NRF51_GPIO_REG_OUT:
+        s->out = value;
+        break;
+
+    case NRF51_GPIO_REG_OUTSET:
+        s->out |= value;
+        break;
+
+    case NRF51_GPIO_REG_OUTCLR:
+        s->out &= ~value;
+        break;
+
+    case NRF51_GPIO_REG_DIR:
+        s->dir = value;
+        reflect_dir_bit_in_cnf(s);
+        break;
+
+    case NRF51_GPIO_REG_DIRSET:
+        s->dir |= value;
+        reflect_dir_bit_in_cnf(s);
+        break;
+
+    case NRF51_GPIO_REG_DIRCLR:
+        s->dir &= ~value;
+        reflect_dir_bit_in_cnf(s);
+        break;
+
+    case NRF51_GPIO_REG_CNF_START ... NRF51_GPIO_REG_CNF_END:
+        idx = (offset - NRF51_GPIO_REG_CNF_START) / 4;
+        s->cnf[idx] = value;
+        /*
+         * direction is exposed in both the DIR register and the DIR bit
+         * of each PINs CNF configuration register.
+         */
+        s->dir = (s->dir & ~(1UL << idx)) | ((value & 0x01) << idx);
+        break;
+
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: bad write offset 0x%" HWADDR_PRIx "\n",
+                      __func__, offset);
+    }
+
+    update_state(s);
+}
+
+static const MemoryRegionOps gpio_ops = {
+    .read =  nrf51_gpio_read,
+    .write = nrf51_gpio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl.min_access_size = 4,
+    .impl.max_access_size = 4,
+};
+
+static void nrf51_gpio_set(void *opaque, int line, int value)
+{
+    NRF51GPIOState *s = NRF51_GPIO(opaque);
+
+    trace_nrf51_gpio_set(line, value);
+
+    assert(line >= 0 && line < NRF51_GPIO_PINS);
+
+    s->in_mask = deposit32(s->in_mask, line, 1, value >= 0);
+    if (value >= 0) {
+        s->in = deposit32(s->in, line, 1, value != 0);
+    }
+
+    update_state(s);
+}
+
+static void nrf51_gpio_reset(DeviceState *dev)
+{
+    NRF51GPIOState *s = NRF51_GPIO(dev);
+    size_t i;
+
+    s->out = 0;
+    s->old_out = 0;
+    s->old_out_connected = 0;
+    s->in = 0;
+    s->in_mask = 0;
+    s->dir = 0;
+
+    for (i = 0; i < NRF51_GPIO_PINS; i++) {
+        s->cnf[i] = 0x00000002;
+    }
+}
+
+static const VMStateDescription vmstate_nrf51_gpio = {
+    .name = TYPE_NRF51_GPIO,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(out, NRF51GPIOState),
+        VMSTATE_UINT32(in, NRF51GPIOState),
+        VMSTATE_UINT32(in_mask, NRF51GPIOState),
+        VMSTATE_UINT32(dir, NRF51GPIOState),
+        VMSTATE_UINT32_ARRAY(cnf, NRF51GPIOState, NRF51_GPIO_PINS),
+        VMSTATE_UINT32(old_out, NRF51GPIOState),
+        VMSTATE_UINT32(old_out_connected, NRF51GPIOState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void nrf51_gpio_init(Object *obj)
+{
+    NRF51GPIOState *s = NRF51_GPIO(obj);
+
+    memory_region_init_io(&s->mmio, obj, &gpio_ops, s,
+            TYPE_NRF51_GPIO, NRF51_GPIO_SIZE);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+
+    qdev_init_gpio_in(DEVICE(s), nrf51_gpio_set, NRF51_GPIO_PINS);
+    qdev_init_gpio_out(DEVICE(s), s->output, NRF51_GPIO_PINS);
+}
+
+static void nrf51_gpio_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->vmsd = &vmstate_nrf51_gpio;
+    dc->reset = nrf51_gpio_reset;
+    dc->desc = "nRF51 GPIO";
+}
+
+static const TypeInfo nrf51_gpio_info = {
+    .name = TYPE_NRF51_GPIO,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(NRF51GPIOState),
+    .instance_init = nrf51_gpio_init,
+    .class_init = nrf51_gpio_class_init
+};
+
+static void nrf51_gpio_register_types(void)
+{
+    type_register_static(&nrf51_gpio_info);
+}
+
+type_init(nrf51_gpio_register_types)
diff --git a/hw/gpio/trace-events b/hw/gpio/trace-events
new file mode 100644
index 00000000000..cb41a897569
--- /dev/null
+++ b/hw/gpio/trace-events
@@ -0,0 +1,7 @@
+# See docs/devel/tracing.txt for syntax documentation.
+
+# hw/gpio/nrf51_gpio.c
+nrf51_gpio_read(uint64_t offset, uint64_t r) "offset 0x%" PRIx64 " value 0x%" PRIx64
+nrf51_gpio_write(uint64_t offset, uint64_t value) "offset 0x%" PRIx64 " value 0x%" PRIx64
+nrf51_gpio_set(int64_t line, int64_t value) "line %" PRIi64 " value %" PRIi64
+nrf51_gpio_update_output_irq(int64_t line, int64_t value) "line %" PRIi64 " value %" PRIi64
\ No newline at end of file
-- 
2.19.2

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

* [Qemu-devel] [PULL 29/37] arm: Instantiate NRF51 general purpose I/O
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (27 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 28/37] hw/gpio/nrf51_gpio: Add nRF51 GPIO peripheral Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-07 16:31 ` [Qemu-devel] [PULL 30/37] tests/microbit-test: Add Tests for nRF51 GPIO Peter Maydell
                   ` (9 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

From: Steffen Görtz <contrib@steffen-goertz.de>

Instantiates GPIO peripheral model

Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20190103091119.9367-7-stefanha@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/nrf51_soc.h |  2 ++
 hw/arm/nrf51_soc.c         | 16 ++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/include/hw/arm/nrf51_soc.h b/include/hw/arm/nrf51_soc.h
index 9e3ba916bd0..84e0278881b 100644
--- a/include/hw/arm/nrf51_soc.h
+++ b/include/hw/arm/nrf51_soc.h
@@ -14,6 +14,7 @@
 #include "hw/arm/armv7m.h"
 #include "hw/char/nrf51_uart.h"
 #include "hw/misc/nrf51_rng.h"
+#include "hw/gpio/nrf51_gpio.h"
 
 #define TYPE_NRF51_SOC "nrf51-soc"
 #define NRF51_SOC(obj) \
@@ -28,6 +29,7 @@ typedef struct NRF51State {
 
     NRF51UARTState uart;
     NRF51RNGState rng;
+    NRF51GPIOState gpio;
 
     MemoryRegion iomem;
     MemoryRegion sram;
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
index d2a19b8eadd..db817fe5064 100644
--- a/hw/arm/nrf51_soc.c
+++ b/hw/arm/nrf51_soc.c
@@ -99,6 +99,19 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
                        qdev_get_gpio_in(DEVICE(&s->cpu),
                        BASE_TO_IRQ(NRF51_RNG_BASE)));
 
+    /* GPIO */
+    object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gpio), 0);
+    memory_region_add_subregion_overlap(&s->container, NRF51_GPIO_BASE, mr, 0);
+
+    /* Pass all GPIOs to the SOC layer so they are available to the board */
+    qdev_pass_gpios(DEVICE(&s->gpio), dev_soc, NULL);
+
     create_unimplemented_device("nrf51_soc.io", NRF51_IOMEM_BASE,
                                 NRF51_IOMEM_SIZE);
     create_unimplemented_device("nrf51_soc.ficr", NRF51_FICR_BASE,
@@ -126,6 +139,9 @@ static void nrf51_soc_init(Object *obj)
 
     sysbus_init_child_obj(obj, "rng", &s->rng, sizeof(s->rng),
                            TYPE_NRF51_RNG);
+
+    sysbus_init_child_obj(obj, "gpio", &s->gpio, sizeof(s->gpio),
+                          TYPE_NRF51_GPIO);
 }
 
 static Property nrf51_soc_properties[] = {
-- 
2.19.2

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

* [Qemu-devel] [PULL 30/37] tests/microbit-test: Add Tests for nRF51 GPIO
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (28 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 29/37] arm: Instantiate NRF51 general purpose I/O Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-07 16:31 ` [Qemu-devel] [PULL 31/37] hw/timer/nrf51_timer: Add nRF51 Timer peripheral Peter Maydell
                   ` (8 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

From: Steffen Görtz <contrib@steffen-goertz.de>

The test suite for the nRF51 GPIO peripheral for now
only tests initial state. Additionally a set of
tests testing an implementation detail of the model
are included.

Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20190103091119.9367-8-stefanha@redhat.com
[PMM: fixed stray space at start of file]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 tests/Makefile.include |   2 +
 tests/microbit-test.c  | 160 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 162 insertions(+)
 create mode 100644 tests/microbit-test.c

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 3f5a1d0c308..9c84bbd8296 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -277,6 +277,7 @@ check-qtest-sparc64-y += tests/boot-serial-test$(EXESUF)
 check-qtest-arm-y += tests/tmp105-test$(EXESUF)
 check-qtest-arm-y += tests/pca9552-test$(EXESUF)
 check-qtest-arm-y += tests/ds1338-test$(EXESUF)
+check-qtest-arm-y += tests/microbit-test$(EXESUF)
 check-qtest-arm-y += tests/m25p80-test$(EXESUF)
 check-qtest-arm-y += tests/virtio-blk-test$(EXESUF)
 check-qtest-arm-y += tests/test-arm-mptimer$(EXESUF)
@@ -708,6 +709,7 @@ tests/pxe-test$(EXESUF): tests/pxe-test.o tests/boot-sector.o $(libqos-obj-y)
 tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
 tests/pca9552-test$(EXESUF): tests/pca9552-test.o $(libqos-omap-obj-y)
 tests/ds1338-test$(EXESUF): tests/ds1338-test.o $(libqos-imx-obj-y)
+tests/microbit-test$(EXESUF): tests/microbit-test.o
 tests/m25p80-test$(EXESUF): tests/m25p80-test.o
 tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
 tests/q35-test$(EXESUF): tests/q35-test.o $(libqos-pc-obj-y)
diff --git a/tests/microbit-test.c b/tests/microbit-test.c
new file mode 100644
index 00000000000..f0a180cbc6f
--- /dev/null
+++ b/tests/microbit-test.c
@@ -0,0 +1,160 @@
+/*
+ * QTest testcase for Microbit board using the Nordic Semiconductor nRF51 SoC.
+ *
+ * nRF51:
+ * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
+ * Product Spec: http://infocenter.nordicsemi.com/pdf/nRF51822_PS_v3.1.pdf
+ *
+ * Microbit Board: http://microbit.org/
+ *
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+
+#include "qemu/osdep.h"
+#include "exec/hwaddr.h"
+#include "libqtest.h"
+
+#include "hw/arm/nrf51.h"
+#include "hw/gpio/nrf51_gpio.h"
+
+static void test_nrf51_gpio(void)
+{
+    size_t i;
+    uint32_t actual, expected;
+
+    struct {
+        hwaddr addr;
+        uint32_t expected;
+    } const reset_state[] = {
+        {NRF51_GPIO_REG_OUT, 0x00000000}, {NRF51_GPIO_REG_OUTSET, 0x00000000},
+        {NRF51_GPIO_REG_OUTCLR, 0x00000000}, {NRF51_GPIO_REG_IN, 0x00000000},
+        {NRF51_GPIO_REG_DIR, 0x00000000}, {NRF51_GPIO_REG_DIRSET, 0x00000000},
+        {NRF51_GPIO_REG_DIRCLR, 0x00000000}
+    };
+
+    /* Check reset state */
+    for (i = 0; i < ARRAY_SIZE(reset_state); i++) {
+        expected = reset_state[i].expected;
+        actual = readl(NRF51_GPIO_BASE + reset_state[i].addr);
+        g_assert_cmpuint(actual, ==, expected);
+    }
+
+    for (i = 0; i < NRF51_GPIO_PINS; i++) {
+        expected = 0x00000002;
+        actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START + i * 4);
+        g_assert_cmpuint(actual, ==, expected);
+    }
+
+    /* Check dir bit consistency between dir and cnf */
+    /* Check set via DIRSET */
+    expected = 0x80000001;
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_DIRSET, expected);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR);
+    g_assert_cmpuint(actual, ==, expected);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START) & 0x01;
+    g_assert_cmpuint(actual, ==, 0x01);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_END) & 0x01;
+    g_assert_cmpuint(actual, ==, 0x01);
+
+    /* Check clear via DIRCLR */
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_DIRCLR, 0x80000001);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR);
+    g_assert_cmpuint(actual, ==, 0x00000000);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START) & 0x01;
+    g_assert_cmpuint(actual, ==, 0x00);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_END) & 0x01;
+    g_assert_cmpuint(actual, ==, 0x00);
+
+    /* Check set via DIR */
+    expected = 0x80000001;
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR, expected);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR);
+    g_assert_cmpuint(actual, ==, expected);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START) & 0x01;
+    g_assert_cmpuint(actual, ==, 0x01);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_END) & 0x01;
+    g_assert_cmpuint(actual, ==, 0x01);
+
+    /* Reset DIR */
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR, 0x00000000);
+
+    /* Check Input propagates */
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x00);
+    qtest_set_irq_in(global_qtest, "/machine/nrf51", "unnamed-gpio-in", 0, 0);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
+    g_assert_cmpuint(actual, ==, 0x00);
+    qtest_set_irq_in(global_qtest, "/machine/nrf51", "unnamed-gpio-in", 0, 1);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
+    g_assert_cmpuint(actual, ==, 0x01);
+    qtest_set_irq_in(global_qtest, "/machine/nrf51", "unnamed-gpio-in", 0, -1);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
+    g_assert_cmpuint(actual, ==, 0x01);
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x02);
+
+    /* Check pull-up working */
+    qtest_set_irq_in(global_qtest, "/machine/nrf51", "unnamed-gpio-in", 0, 0);
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b0000);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
+    g_assert_cmpuint(actual, ==, 0x00);
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b1110);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
+    g_assert_cmpuint(actual, ==, 0x01);
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x02);
+
+    /* Check pull-down working */
+    qtest_set_irq_in(global_qtest, "/machine/nrf51", "unnamed-gpio-in", 0, 1);
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b0000);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
+    g_assert_cmpuint(actual, ==, 0x01);
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b0110);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
+    g_assert_cmpuint(actual, ==, 0x00);
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x02);
+    qtest_set_irq_in(global_qtest, "/machine/nrf51", "unnamed-gpio-in", 0, -1);
+
+    /* Check Output propagates */
+    irq_intercept_out("/machine/nrf51");
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b0011);
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTSET, 0x01);
+    g_assert_true(get_irq(0));
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTCLR, 0x01);
+    g_assert_false(get_irq(0));
+
+    /* Check self-stimulation */
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b01);
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTSET, 0x01);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
+    g_assert_cmpuint(actual, ==, 0x01);
+
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTCLR, 0x01);
+    actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
+    g_assert_cmpuint(actual, ==, 0x00);
+
+    /*
+     * Check short-circuit - generates an guest_error which must be checked
+     * manually as long as qtest can not scan qemu_log messages
+     */
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b01);
+    writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTSET, 0x01);
+    qtest_set_irq_in(global_qtest, "/machine/nrf51", "unnamed-gpio-in", 0, 0);
+}
+
+int main(int argc, char **argv)
+{
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+
+    global_qtest = qtest_initf("-machine microbit");
+
+    qtest_add_func("/microbit/nrf51/gpio", test_nrf51_gpio);
+
+    ret = g_test_run();
+
+    qtest_quit(global_qtest);
+    return ret;
+}
-- 
2.19.2

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

* [Qemu-devel] [PULL 31/37] hw/timer/nrf51_timer: Add nRF51 Timer peripheral
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (29 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 30/37] tests/microbit-test: Add Tests for nRF51 GPIO Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-07 16:31 ` [Qemu-devel] [PULL 32/37] arm: Instantiate NRF51 Timers Peter Maydell
                   ` (7 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

From: Steffen Görtz <contrib@steffen-goertz.de>

This patch adds the model for the nRF51 timer peripheral.
Currently, only the TIMER mode is implemented.

Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20190103091119.9367-9-stefanha@redhat.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/timer/Makefile.objs         |   1 +
 include/hw/timer/nrf51_timer.h |  80 +++++++
 hw/timer/nrf51_timer.c         | 393 +++++++++++++++++++++++++++++++++
 hw/timer/trace-events          |   5 +
 4 files changed, 479 insertions(+)
 create mode 100644 include/hw/timer/nrf51_timer.h
 create mode 100644 hw/timer/nrf51_timer.c

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index b32194d153d..0e9a4530f84 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -23,6 +23,7 @@ common-obj-$(CONFIG_IMX) += imx_gpt.o
 common-obj-$(CONFIG_LM32) += lm32_timer.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o
 common-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp-rtc.o
+common-obj-$(CONFIG_NRF51_SOC) += nrf51_timer.o
 
 obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_mct.o
diff --git a/include/hw/timer/nrf51_timer.h b/include/hw/timer/nrf51_timer.h
new file mode 100644
index 00000000000..85cad2300df
--- /dev/null
+++ b/include/hw/timer/nrf51_timer.h
@@ -0,0 +1,80 @@
+/*
+ * nRF51 System-on-Chip Timer peripheral
+ *
+ * QEMU interface:
+ * + sysbus MMIO regions 0: GPIO registers
+ * + sysbus irq
+ *
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+#ifndef NRF51_TIMER_H
+#define NRF51_TIMER_H
+
+#include "hw/sysbus.h"
+#include "qemu/timer.h"
+#define TYPE_NRF51_TIMER "nrf51_soc.timer"
+#define NRF51_TIMER(obj) OBJECT_CHECK(NRF51TimerState, (obj), TYPE_NRF51_TIMER)
+
+#define NRF51_TIMER_REG_COUNT 4
+
+#define NRF51_TIMER_TASK_START 0x000
+#define NRF51_TIMER_TASK_STOP 0x004
+#define NRF51_TIMER_TASK_COUNT 0x008
+#define NRF51_TIMER_TASK_CLEAR 0x00C
+#define NRF51_TIMER_TASK_SHUTDOWN 0x010
+#define NRF51_TIMER_TASK_CAPTURE_0 0x040
+#define NRF51_TIMER_TASK_CAPTURE_3 0x04C
+
+#define NRF51_TIMER_EVENT_COMPARE_0 0x140
+#define NRF51_TIMER_EVENT_COMPARE_1 0x144
+#define NRF51_TIMER_EVENT_COMPARE_2 0x148
+#define NRF51_TIMER_EVENT_COMPARE_3 0x14C
+
+#define NRF51_TIMER_REG_SHORTS 0x200
+#define NRF51_TIMER_REG_SHORTS_MASK 0xf0f
+#define NRF51_TIMER_REG_INTENSET 0x304
+#define NRF51_TIMER_REG_INTENCLR 0x308
+#define NRF51_TIMER_REG_INTEN_MASK 0xf0000
+#define NRF51_TIMER_REG_MODE 0x504
+#define NRF51_TIMER_REG_MODE_MASK 0x01
+#define NRF51_TIMER_TIMER 0
+#define NRF51_TIMER_COUNTER 1
+#define NRF51_TIMER_REG_BITMODE 0x508
+#define NRF51_TIMER_REG_BITMODE_MASK 0x03
+#define NRF51_TIMER_WIDTH_16 0
+#define NRF51_TIMER_WIDTH_8 1
+#define NRF51_TIMER_WIDTH_24 2
+#define NRF51_TIMER_WIDTH_32 3
+#define NRF51_TIMER_REG_PRESCALER 0x510
+#define NRF51_TIMER_REG_PRESCALER_MASK 0x0F
+#define NRF51_TIMER_REG_CC0 0x540
+#define NRF51_TIMER_REG_CC3 0x54C
+
+typedef struct NRF51TimerState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion iomem;
+    qemu_irq irq;
+
+    QEMUTimer timer;
+    int64_t timer_start_ns;
+    int64_t update_counter_ns;
+    uint32_t counter;
+
+    bool running;
+
+    uint8_t events_compare[NRF51_TIMER_REG_COUNT];
+    uint32_t cc[NRF51_TIMER_REG_COUNT];
+    uint32_t shorts;
+    uint32_t inten;
+    uint32_t mode;
+    uint32_t bitmode;
+    uint32_t prescaler;
+
+} NRF51TimerState;
+
+
+#endif
diff --git a/hw/timer/nrf51_timer.c b/hw/timer/nrf51_timer.c
new file mode 100644
index 00000000000..0c90662896e
--- /dev/null
+++ b/hw/timer/nrf51_timer.c
@@ -0,0 +1,393 @@
+/*
+ * nRF51 System-on-Chip Timer peripheral
+ *
+ * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
+ * Product Spec: http://infocenter.nordicsemi.com/pdf/nRF51822_PS_v3.1.pdf
+ *
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
+ * Copyright (c) 2019 Red Hat, Inc.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "hw/arm/nrf51.h"
+#include "hw/timer/nrf51_timer.h"
+#include "trace.h"
+
+#define TIMER_CLK_FREQ 16000000UL
+
+static uint32_t const bitwidths[] = {16, 8, 24, 32};
+
+static uint32_t ns_to_ticks(NRF51TimerState *s, int64_t ns)
+{
+    uint32_t freq = TIMER_CLK_FREQ >> s->prescaler;
+
+    return muldiv64(ns, freq, NANOSECONDS_PER_SECOND);
+}
+
+static int64_t ticks_to_ns(NRF51TimerState *s, uint32_t ticks)
+{
+    uint32_t freq = TIMER_CLK_FREQ >> s->prescaler;
+
+    return muldiv64(ticks, NANOSECONDS_PER_SECOND, freq);
+}
+
+/* Returns number of ticks since last call */
+static uint32_t update_counter(NRF51TimerState *s, int64_t now)
+{
+    uint32_t ticks = ns_to_ticks(s, now - s->update_counter_ns);
+
+    s->counter = (s->counter + ticks) % BIT(bitwidths[s->bitmode]);
+    s->update_counter_ns = now;
+    return ticks;
+}
+
+/* Assumes s->counter is up-to-date */
+static void rearm_timer(NRF51TimerState *s, int64_t now)
+{
+    int64_t min_ns = INT64_MAX;
+    size_t i;
+
+    for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
+        int64_t delta_ns;
+
+        if (s->events_compare[i]) {
+            continue; /* already expired, ignore it for now */
+        }
+
+        if (s->cc[i] <= s->counter) {
+            delta_ns = ticks_to_ns(s, BIT(bitwidths[s->bitmode]) -
+                                      s->counter + s->cc[i]);
+        } else {
+            delta_ns = ticks_to_ns(s, s->cc[i] - s->counter);
+        }
+
+        if (delta_ns < min_ns) {
+            min_ns = delta_ns;
+        }
+    }
+
+    if (min_ns != INT64_MAX) {
+        timer_mod_ns(&s->timer, now + min_ns);
+    }
+}
+
+static void update_irq(NRF51TimerState *s)
+{
+    bool flag = false;
+    size_t i;
+
+    for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
+        flag |= s->events_compare[i] && extract32(s->inten, 16 + i, 1);
+    }
+    qemu_set_irq(s->irq, flag);
+}
+
+static void timer_expire(void *opaque)
+{
+    NRF51TimerState *s = NRF51_TIMER(opaque);
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    uint32_t cc_remaining[NRF51_TIMER_REG_COUNT];
+    bool should_stop = false;
+    uint32_t ticks;
+    size_t i;
+
+    for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
+        if (s->cc[i] > s->counter) {
+            cc_remaining[i] = s->cc[i] - s->counter;
+        } else {
+            cc_remaining[i] = BIT(bitwidths[s->bitmode]) -
+                              s->counter + s->cc[i];
+        }
+    }
+
+    ticks = update_counter(s, now);
+
+    for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
+        if (cc_remaining[i] <= ticks) {
+            s->events_compare[i] = 1;
+
+            if (s->shorts & BIT(i)) {
+                s->timer_start_ns = now;
+                s->update_counter_ns = s->timer_start_ns;
+                s->counter = 0;
+            }
+
+            should_stop |= s->shorts & BIT(i + 8);
+        }
+    }
+
+    update_irq(s);
+
+    if (should_stop) {
+        s->running = false;
+        timer_del(&s->timer);
+    } else {
+        rearm_timer(s, now);
+    }
+}
+
+static void counter_compare(NRF51TimerState *s)
+{
+    uint32_t counter = s->counter;
+    size_t i;
+
+    for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
+        if (counter == s->cc[i]) {
+            s->events_compare[i] = 1;
+
+            if (s->shorts & BIT(i)) {
+                s->counter = 0;
+            }
+        }
+    }
+}
+
+static uint64_t nrf51_timer_read(void *opaque, hwaddr offset, unsigned int size)
+{
+    NRF51TimerState *s = NRF51_TIMER(opaque);
+    uint64_t r = 0;
+
+    switch (offset) {
+    case NRF51_TIMER_EVENT_COMPARE_0 ... NRF51_TIMER_EVENT_COMPARE_3:
+        r = s->events_compare[(offset - NRF51_TIMER_EVENT_COMPARE_0) / 4];
+        break;
+    case NRF51_TIMER_REG_SHORTS:
+        r = s->shorts;
+        break;
+    case NRF51_TIMER_REG_INTENSET:
+        r = s->inten;
+        break;
+    case NRF51_TIMER_REG_INTENCLR:
+        r = s->inten;
+        break;
+    case NRF51_TIMER_REG_MODE:
+        r = s->mode;
+        break;
+    case NRF51_TIMER_REG_BITMODE:
+        r = s->bitmode;
+        break;
+    case NRF51_TIMER_REG_PRESCALER:
+        r = s->prescaler;
+        break;
+    case NRF51_TIMER_REG_CC0 ... NRF51_TIMER_REG_CC3:
+        r = s->cc[(offset - NRF51_TIMER_REG_CC0) / 4];
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                "%s: bad read offset 0x%" HWADDR_PRIx "\n",
+                      __func__, offset);
+    }
+
+    trace_nrf51_timer_read(offset, r, size);
+
+    return r;
+}
+
+static void nrf51_timer_write(void *opaque, hwaddr offset,
+                       uint64_t value, unsigned int size)
+{
+    NRF51TimerState *s = NRF51_TIMER(opaque);
+    uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    size_t idx;
+
+    trace_nrf51_timer_write(offset, value, size);
+
+    switch (offset) {
+    case NRF51_TIMER_TASK_START:
+        if (value == NRF51_TRIGGER_TASK && s->mode == NRF51_TIMER_TIMER) {
+            s->running = true;
+            s->timer_start_ns = now - ticks_to_ns(s, s->counter);
+            s->update_counter_ns = s->timer_start_ns;
+            rearm_timer(s, now);
+        }
+        break;
+    case NRF51_TIMER_TASK_STOP:
+    case NRF51_TIMER_TASK_SHUTDOWN:
+        if (value == NRF51_TRIGGER_TASK) {
+            s->running = false;
+            timer_del(&s->timer);
+        }
+        break;
+    case NRF51_TIMER_TASK_COUNT:
+        if (value == NRF51_TRIGGER_TASK && s->mode == NRF51_TIMER_COUNTER) {
+            s->counter = (s->counter + 1) % BIT(bitwidths[s->bitmode]);
+            counter_compare(s);
+        }
+        break;
+    case NRF51_TIMER_TASK_CLEAR:
+        if (value == NRF51_TRIGGER_TASK) {
+            s->timer_start_ns = now;
+            s->update_counter_ns = s->timer_start_ns;
+            s->counter = 0;
+            if (s->running) {
+                rearm_timer(s, now);
+            }
+        }
+        break;
+    case NRF51_TIMER_TASK_CAPTURE_0 ... NRF51_TIMER_TASK_CAPTURE_3:
+        if (value == NRF51_TRIGGER_TASK) {
+            if (s->running) {
+                timer_expire(s); /* update counter and all state */
+            }
+
+            idx = (offset - NRF51_TIMER_TASK_CAPTURE_0) / 4;
+            s->cc[idx] = s->counter;
+        }
+        break;
+    case NRF51_TIMER_EVENT_COMPARE_0 ... NRF51_TIMER_EVENT_COMPARE_3:
+        if (value == NRF51_EVENT_CLEAR) {
+            s->events_compare[(offset - NRF51_TIMER_EVENT_COMPARE_0) / 4] = 0;
+
+            if (s->running) {
+                timer_expire(s); /* update counter and all state */
+            }
+        }
+        break;
+    case NRF51_TIMER_REG_SHORTS:
+        s->shorts = value & NRF51_TIMER_REG_SHORTS_MASK;
+        break;
+    case NRF51_TIMER_REG_INTENSET:
+        s->inten |= value & NRF51_TIMER_REG_INTEN_MASK;
+        break;
+    case NRF51_TIMER_REG_INTENCLR:
+        s->inten &= ~(value & NRF51_TIMER_REG_INTEN_MASK);
+        break;
+    case NRF51_TIMER_REG_MODE:
+        s->mode = value;
+        break;
+    case NRF51_TIMER_REG_BITMODE:
+        if (s->mode == NRF51_TIMER_TIMER && s->running) {
+            qemu_log_mask(LOG_GUEST_ERROR,
+                    "%s: erroneous change of BITMODE while timer is running\n",
+                    __func__);
+        }
+        s->bitmode = value & NRF51_TIMER_REG_BITMODE_MASK;
+        break;
+    case NRF51_TIMER_REG_PRESCALER:
+        if (s->mode == NRF51_TIMER_TIMER && s->running) {
+            qemu_log_mask(LOG_GUEST_ERROR,
+                "%s: erroneous change of PRESCALER while timer is running\n",
+                __func__);
+        }
+        s->prescaler = value & NRF51_TIMER_REG_PRESCALER_MASK;
+        break;
+    case NRF51_TIMER_REG_CC0 ... NRF51_TIMER_REG_CC3:
+        if (s->running) {
+            timer_expire(s); /* update counter */
+        }
+
+        idx = (offset - NRF51_TIMER_REG_CC0) / 4;
+        s->cc[idx] = value % BIT(bitwidths[s->bitmode]);
+
+        if (s->running) {
+            rearm_timer(s, now);
+        }
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: bad write offset 0x%" HWADDR_PRIx "\n",
+                      __func__, offset);
+    }
+
+    update_irq(s);
+}
+
+static const MemoryRegionOps rng_ops = {
+    .read =  nrf51_timer_read,
+    .write = nrf51_timer_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl.min_access_size = 4,
+    .impl.max_access_size = 4,
+};
+
+static void nrf51_timer_init(Object *obj)
+{
+    NRF51TimerState *s = NRF51_TIMER(obj);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+    memory_region_init_io(&s->iomem, obj, &rng_ops, s,
+            TYPE_NRF51_TIMER, NRF51_TIMER_SIZE);
+    sysbus_init_mmio(sbd, &s->iomem);
+    sysbus_init_irq(sbd, &s->irq);
+
+    timer_init_ns(&s->timer, QEMU_CLOCK_VIRTUAL, timer_expire, s);
+}
+
+static void nrf51_timer_reset(DeviceState *dev)
+{
+    NRF51TimerState *s = NRF51_TIMER(dev);
+
+    timer_del(&s->timer);
+    s->timer_start_ns = 0x00;
+    s->update_counter_ns = 0x00;
+    s->counter = 0x00;
+    s->running = false;
+
+    memset(s->events_compare, 0x00, sizeof(s->events_compare));
+    memset(s->cc, 0x00, sizeof(s->cc));
+
+    s->shorts = 0x00;
+    s->inten = 0x00;
+    s->mode = 0x00;
+    s->bitmode = 0x00;
+    s->prescaler = 0x00;
+}
+
+static int nrf51_timer_post_load(void *opaque, int version_id)
+{
+    NRF51TimerState *s = NRF51_TIMER(opaque);
+
+    if (s->running && s->mode == NRF51_TIMER_TIMER) {
+        timer_expire(s);
+    }
+    return 0;
+}
+
+static const VMStateDescription vmstate_nrf51_timer = {
+    .name = TYPE_NRF51_TIMER,
+    .version_id = 1,
+    .post_load = nrf51_timer_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_TIMER(timer, NRF51TimerState),
+        VMSTATE_INT64(timer_start_ns, NRF51TimerState),
+        VMSTATE_INT64(update_counter_ns, NRF51TimerState),
+        VMSTATE_UINT32(counter, NRF51TimerState),
+        VMSTATE_BOOL(running, NRF51TimerState),
+        VMSTATE_UINT8_ARRAY(events_compare, NRF51TimerState,
+                            NRF51_TIMER_REG_COUNT),
+        VMSTATE_UINT32_ARRAY(cc, NRF51TimerState, NRF51_TIMER_REG_COUNT),
+        VMSTATE_UINT32(shorts, NRF51TimerState),
+        VMSTATE_UINT32(inten, NRF51TimerState),
+        VMSTATE_UINT32(mode, NRF51TimerState),
+        VMSTATE_UINT32(bitmode, NRF51TimerState),
+        VMSTATE_UINT32(prescaler, NRF51TimerState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void nrf51_timer_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->reset = nrf51_timer_reset;
+    dc->vmsd = &vmstate_nrf51_timer;
+}
+
+static const TypeInfo nrf51_timer_info = {
+    .name = TYPE_NRF51_TIMER,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(NRF51TimerState),
+    .instance_init = nrf51_timer_init,
+    .class_init = nrf51_timer_class_init
+};
+
+static void nrf51_timer_register_types(void)
+{
+    type_register_static(&nrf51_timer_info);
+}
+
+type_init(nrf51_timer_register_types)
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
index 75bd3b1042a..0144a68951c 100644
--- a/hw/timer/trace-events
+++ b/hw/timer/trace-events
@@ -72,3 +72,8 @@ sun4v_rtc_write(uint64_t addr, uint64_t value) "write: addr 0x%" PRIx64 " value
 
 # hw/timer/xlnx-zynqmp-rtc.c
 xlnx_zynqmp_rtc_gettime(int year, int month, int day, int hour, int min, int sec) "Get time from host: %d-%d-%d %2d:%02d:%02d"
+
+# hw/timer/nrf51_timer.c
+nrf51_timer_read(uint64_t addr, uint32_t value, unsigned size) "read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
+nrf51_timer_write(uint64_t addr, uint32_t value, unsigned size) "write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
+
-- 
2.19.2

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

* [Qemu-devel] [PULL 32/37] arm: Instantiate NRF51 Timers
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (30 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 31/37] hw/timer/nrf51_timer: Add nRF51 Timer peripheral Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-07 16:31 ` [Qemu-devel] [PULL 33/37] tests/microbit-test: Add Tests for nRF51 Timer Peter Maydell
                   ` (6 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

From: Steffen Görtz <contrib@steffen-goertz.de>

Instantiates TIMER0 - TIMER2

Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20190103091119.9367-10-stefanha@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/nrf51_soc.h |  4 ++++
 hw/arm/nrf51_soc.c         | 26 ++++++++++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/include/hw/arm/nrf51_soc.h b/include/hw/arm/nrf51_soc.h
index 84e0278881b..39e613e1c97 100644
--- a/include/hw/arm/nrf51_soc.h
+++ b/include/hw/arm/nrf51_soc.h
@@ -15,11 +15,14 @@
 #include "hw/char/nrf51_uart.h"
 #include "hw/misc/nrf51_rng.h"
 #include "hw/gpio/nrf51_gpio.h"
+#include "hw/timer/nrf51_timer.h"
 
 #define TYPE_NRF51_SOC "nrf51-soc"
 #define NRF51_SOC(obj) \
     OBJECT_CHECK(NRF51State, (obj), TYPE_NRF51_SOC)
 
+#define NRF51_NUM_TIMERS 3
+
 typedef struct NRF51State {
     /*< private >*/
     SysBusDevice parent_obj;
@@ -30,6 +33,7 @@ typedef struct NRF51State {
     NRF51UARTState uart;
     NRF51RNGState rng;
     NRF51GPIOState gpio;
+    NRF51TimerState timer[NRF51_NUM_TIMERS];
 
     MemoryRegion iomem;
     MemoryRegion sram;
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
index db817fe5064..ef70bd62fa4 100644
--- a/hw/arm/nrf51_soc.c
+++ b/hw/arm/nrf51_soc.c
@@ -39,6 +39,8 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
     NRF51State *s = NRF51_SOC(dev_soc);
     MemoryRegion *mr;
     Error *err = NULL;
+    uint8_t i = 0;
+    hwaddr base_addr = 0;
 
     if (!s->board_memory) {
         error_setg(errp, "memory property was not set");
@@ -112,6 +114,22 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
     /* Pass all GPIOs to the SOC layer so they are available to the board */
     qdev_pass_gpios(DEVICE(&s->gpio), dev_soc, NULL);
 
+    /* TIMER */
+    for (i = 0; i < NRF51_NUM_TIMERS; i++) {
+        object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);
+        if (err) {
+            error_propagate(errp, err);
+            return;
+        }
+
+        base_addr = NRF51_TIMER_BASE + i * NRF51_TIMER_SIZE;
+
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->timer[i]), 0, base_addr);
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer[i]), 0,
+                           qdev_get_gpio_in(DEVICE(&s->cpu),
+                                            BASE_TO_IRQ(base_addr)));
+    }
+
     create_unimplemented_device("nrf51_soc.io", NRF51_IOMEM_BASE,
                                 NRF51_IOMEM_SIZE);
     create_unimplemented_device("nrf51_soc.ficr", NRF51_FICR_BASE,
@@ -122,6 +140,8 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
 
 static void nrf51_soc_init(Object *obj)
 {
+    uint8_t i = 0;
+
     NRF51State *s = NRF51_SOC(obj);
 
     memory_region_init(&s->container, obj, "nrf51-container", UINT64_MAX);
@@ -142,6 +162,12 @@ static void nrf51_soc_init(Object *obj)
 
     sysbus_init_child_obj(obj, "gpio", &s->gpio, sizeof(s->gpio),
                           TYPE_NRF51_GPIO);
+
+    for (i = 0; i < NRF51_NUM_TIMERS; i++) {
+        sysbus_init_child_obj(obj, "timer[*]", &s->timer[i],
+                              sizeof(s->timer[i]), TYPE_NRF51_TIMER);
+
+    }
 }
 
 static Property nrf51_soc_properties[] = {
-- 
2.19.2

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

* [Qemu-devel] [PULL 33/37] tests/microbit-test: Add Tests for nRF51 Timer
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (31 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 32/37] arm: Instantiate NRF51 Timers Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-07 16:31 ` [Qemu-devel] [PULL 34/37] arm: Add Clock peripheral stub to NRF51 SOC Peter Maydell
                   ` (5 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

From: Steffen Görtz <contrib@steffen-goertz.de>

Basic tests for nRF51 Timer Peripheral.

Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20190103091119.9367-11-stefanha@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 tests/microbit-test.c | 95 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 95 insertions(+)

diff --git a/tests/microbit-test.c b/tests/microbit-test.c
index f0a180cbc6f..0c125535f64 100644
--- a/tests/microbit-test.c
+++ b/tests/microbit-test.c
@@ -20,6 +20,7 @@
 
 #include "hw/arm/nrf51.h"
 #include "hw/gpio/nrf51_gpio.h"
+#include "hw/timer/nrf51_timer.h"
 
 static void test_nrf51_gpio(void)
 {
@@ -143,6 +144,99 @@ static void test_nrf51_gpio(void)
     qtest_set_irq_in(global_qtest, "/machine/nrf51", "unnamed-gpio-in", 0, 0);
 }
 
+static void timer_task(hwaddr task)
+{
+    writel(NRF51_TIMER_BASE + task, NRF51_TRIGGER_TASK);
+}
+
+static void timer_clear_event(hwaddr event)
+{
+    writel(NRF51_TIMER_BASE + event, NRF51_EVENT_CLEAR);
+}
+
+static void timer_set_bitmode(uint8_t mode)
+{
+    writel(NRF51_TIMER_BASE + NRF51_TIMER_REG_BITMODE, mode);
+}
+
+static void timer_set_prescaler(uint8_t prescaler)
+{
+    writel(NRF51_TIMER_BASE + NRF51_TIMER_REG_PRESCALER, prescaler);
+}
+
+static void timer_set_cc(size_t idx, uint32_t value)
+{
+    writel(NRF51_TIMER_BASE + NRF51_TIMER_REG_CC0 + idx * 4, value);
+}
+
+static void timer_assert_events(uint32_t ev0, uint32_t ev1, uint32_t ev2,
+                                uint32_t ev3)
+{
+    g_assert(readl(NRF51_TIMER_BASE + NRF51_TIMER_EVENT_COMPARE_0) == ev0);
+    g_assert(readl(NRF51_TIMER_BASE + NRF51_TIMER_EVENT_COMPARE_1) == ev1);
+    g_assert(readl(NRF51_TIMER_BASE + NRF51_TIMER_EVENT_COMPARE_2) == ev2);
+    g_assert(readl(NRF51_TIMER_BASE + NRF51_TIMER_EVENT_COMPARE_3) == ev3);
+}
+
+static void test_nrf51_timer(void)
+{
+    uint32_t steps_to_overflow = 408;
+
+    /* Compare Match */
+    timer_task(NRF51_TIMER_TASK_STOP);
+    timer_task(NRF51_TIMER_TASK_CLEAR);
+
+    timer_clear_event(NRF51_TIMER_EVENT_COMPARE_0);
+    timer_clear_event(NRF51_TIMER_EVENT_COMPARE_1);
+    timer_clear_event(NRF51_TIMER_EVENT_COMPARE_2);
+    timer_clear_event(NRF51_TIMER_EVENT_COMPARE_3);
+
+    timer_set_bitmode(NRF51_TIMER_WIDTH_16); /* 16 MHz Timer */
+    timer_set_prescaler(0);
+    /* Swept over in first step */
+    timer_set_cc(0, 2);
+    /* Barely miss on first step */
+    timer_set_cc(1, 162);
+    /* Spot on on third step */
+    timer_set_cc(2, 480);
+
+    timer_assert_events(0, 0, 0, 0);
+
+    timer_task(NRF51_TIMER_TASK_START);
+    clock_step(10000);
+    timer_assert_events(1, 0, 0, 0);
+
+    /* Swept over on first overflow */
+    timer_set_cc(3, 114);
+
+    clock_step(10000);
+    timer_assert_events(1, 1, 0, 0);
+
+    clock_step(10000);
+    timer_assert_events(1, 1, 1, 0);
+
+    /* Wrap time until internal counter overflows */
+    while (steps_to_overflow--) {
+        timer_assert_events(1, 1, 1, 0);
+        clock_step(10000);
+    }
+
+    timer_assert_events(1, 1, 1, 1);
+
+    timer_clear_event(NRF51_TIMER_EVENT_COMPARE_0);
+    timer_clear_event(NRF51_TIMER_EVENT_COMPARE_1);
+    timer_clear_event(NRF51_TIMER_EVENT_COMPARE_2);
+    timer_clear_event(NRF51_TIMER_EVENT_COMPARE_3);
+    timer_assert_events(0, 0, 0, 0);
+
+    timer_task(NRF51_TIMER_TASK_STOP);
+
+    /* Test Proposal: Stop/Shutdown */
+    /* Test Proposal: Shortcut Compare -> Clear */
+    /* Test Proposal: Shortcut Compare -> Stop */
+    /* Test Proposal: Counter Mode */
+}
+
 int main(int argc, char **argv)
 {
     int ret;
@@ -152,6 +246,7 @@ int main(int argc, char **argv)
     global_qtest = qtest_initf("-machine microbit");
 
     qtest_add_func("/microbit/nrf51/gpio", test_nrf51_gpio);
+    qtest_add_func("/microbit/nrf51/timer", test_nrf51_timer);
 
     ret = g_test_run();
 
-- 
2.19.2

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

* [Qemu-devel] [PULL 34/37] arm: Add Clock peripheral stub to NRF51 SOC
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (32 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 33/37] tests/microbit-test: Add Tests for nRF51 Timer Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-07 16:31 ` [Qemu-devel] [PULL 35/37] target/arm: Emit barriers for A32/T32 load-acquire/store-release insns Peter Maydell
                   ` (4 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

From: Steffen Görtz <contrib@steffen-goertz.de>

This stubs enables the microbit-micropython firmware to run
on the microbit machine.

Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20190103091119.9367-12-stefanha@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/nrf51_soc.h |  1 +
 hw/arm/nrf51_soc.c         | 26 ++++++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/include/hw/arm/nrf51_soc.h b/include/hw/arm/nrf51_soc.h
index 39e613e1c97..e06f0304b48 100644
--- a/include/hw/arm/nrf51_soc.h
+++ b/include/hw/arm/nrf51_soc.h
@@ -38,6 +38,7 @@ typedef struct NRF51State {
     MemoryRegion iomem;
     MemoryRegion sram;
     MemoryRegion flash;
+    MemoryRegion clock;
 
     uint32_t sram_size;
     uint32_t flash_size;
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
index ef70bd62fa4..1630c275940 100644
--- a/hw/arm/nrf51_soc.c
+++ b/hw/arm/nrf51_soc.c
@@ -34,6 +34,26 @@
 
 #define BASE_TO_IRQ(base) ((base >> 12) & 0x1F)
 
+static uint64_t clock_read(void *opaque, hwaddr addr, unsigned int size)
+{
+    qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
+                  __func__, addr, size);
+    return 1;
+}
+
+static void clock_write(void *opaque, hwaddr addr, uint64_t data,
+                        unsigned int size)
+{
+    qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64 " [%u]\n",
+                  __func__, addr, data, size);
+}
+
+static const MemoryRegionOps clock_ops = {
+    .read = clock_read,
+    .write = clock_write
+};
+
+
 static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
 {
     NRF51State *s = NRF51_SOC(dev_soc);
@@ -130,6 +150,12 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
                                             BASE_TO_IRQ(base_addr)));
     }
 
+    /* STUB Peripherals */
+    memory_region_init_io(&s->clock, NULL, &clock_ops, NULL,
+                          "nrf51_soc.clock", 0x1000);
+    memory_region_add_subregion_overlap(&s->container,
+                                        NRF51_IOMEM_BASE, &s->clock, -1);
+
     create_unimplemented_device("nrf51_soc.io", NRF51_IOMEM_BASE,
                                 NRF51_IOMEM_SIZE);
     create_unimplemented_device("nrf51_soc.ficr", NRF51_FICR_BASE,
-- 
2.19.2

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

* [Qemu-devel] [PULL 35/37] target/arm: Emit barriers for A32/T32 load-acquire/store-release insns
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (33 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 34/37] arm: Add Clock peripheral stub to NRF51 SOC Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-07 16:31 ` [Qemu-devel] [PULL 36/37] hw/misc/tz-mpc: Fix value of BLK_MAX register Peter Maydell
                   ` (3 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

Now that MTTCG is here, the comment in the 32-bit Arm decoder that
"Since the emulation does not have barriers, the acquire/release
semantics need no special handling" is no longer true. Emit the
correct barriers for the load-acquire/store-release insns, as
we already do in the A64 decoder.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
---
 target/arm/translate.c | 33 ++++++++++++++++++++++++++-------
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index ed3db0c3946..66cf28c8cbe 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -9733,6 +9733,8 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
                     rd = (insn >> 12) & 0xf;
                     if (insn & (1 << 23)) {
                         /* load/store exclusive */
+                        bool is_ld = extract32(insn, 20, 1);
+                        bool is_lasr = !extract32(insn, 8, 1);
                         int op2 = (insn >> 8) & 3;
                         op1 = (insn >> 21) & 0x3;
 
@@ -9760,11 +9762,12 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
                         addr = tcg_temp_local_new_i32();
                         load_reg_var(s, addr, rn);
 
-                        /* Since the emulation does not have barriers,
-                           the acquire/release semantics need no special
-                           handling */
+                        if (is_lasr && !is_ld) {
+                            tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
+                        }
+
                         if (op2 == 0) {
-                            if (insn & (1 << 20)) {
+                            if (is_ld) {
                                 tmp = tcg_temp_new_i32();
                                 switch (op1) {
                                 case 0: /* lda */
@@ -9810,7 +9813,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
                                 }
                                 tcg_temp_free_i32(tmp);
                             }
-                        } else if (insn & (1 << 20)) {
+                        } else if (is_ld) {
                             switch (op1) {
                             case 0: /* ldrex */
                                 gen_load_exclusive(s, rd, 15, addr, 2);
@@ -9847,6 +9850,10 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
                             }
                         }
                         tcg_temp_free_i32(addr);
+
+                        if (is_lasr && is_ld) {
+                            tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
+                        }
                     } else if ((insn & 0x00300f00) == 0) {
                         /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
                         *  - SWP, SWPB
@@ -10862,6 +10869,8 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
                 tcg_gen_addi_i32(tmp, tmp, s->pc);
                 store_reg(s, 15, tmp);
             } else {
+                bool is_lasr = false;
+                bool is_ld = extract32(insn, 20, 1);
                 int op2 = (insn >> 6) & 0x3;
                 op = (insn >> 4) & 0x3;
                 switch (op2) {
@@ -10883,12 +10892,18 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
                 case 3:
                     /* Load-acquire/store-release exclusive */
                     ARCH(8);
+                    is_lasr = true;
                     break;
                 }
+
+                if (is_lasr && !is_ld) {
+                    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
+                }
+
                 addr = tcg_temp_local_new_i32();
                 load_reg_var(s, addr, rn);
                 if (!(op2 & 1)) {
-                    if (insn & (1 << 20)) {
+                    if (is_ld) {
                         tmp = tcg_temp_new_i32();
                         switch (op) {
                         case 0: /* ldab */
@@ -10927,12 +10942,16 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
                         }
                         tcg_temp_free_i32(tmp);
                     }
-                } else if (insn & (1 << 20)) {
+                } else if (is_ld) {
                     gen_load_exclusive(s, rs, rd, addr, op);
                 } else {
                     gen_store_exclusive(s, rm, rs, rd, addr, op);
                 }
                 tcg_temp_free_i32(addr);
+
+                if (is_lasr && is_ld) {
+                    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
+                }
             }
         } else {
             /* Load/store multiple, RFE, SRS.  */
-- 
2.19.2

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

* [Qemu-devel] [PULL 36/37] hw/misc/tz-mpc: Fix value of BLK_MAX register
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (34 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 35/37] target/arm: Emit barriers for A32/T32 load-acquire/store-release insns Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-07 16:31 ` [Qemu-devel] [PULL 37/37] Support u-boot noload images for arm as used by, NetBSD/evbarm GENERIC kernel Peter Maydell
                   ` (2 subsequent siblings)
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

In the TZ Memory Protection Controller, the BLK_MAX register is supposed
to return the maximum permitted value of the BLK_IDX register. Our
implementation incorrectly returned max+1 (ie the total number of
valid index values, since BLK_IDX is zero-based).

Correct this off-by-one error. Since we consistently initialize
and use s->blk_max throughout the implementation as the 'size'
of the LUT, just adjust the value we return when the guest reads
the BLK_MAX register, rather than trying to change the semantics
of the s->blk_max internal struct field.

Fixes: https://bugs.launchpad.net/qemu/+bug/1806824
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20181213183249.3468-1-peter.maydell@linaro.org
---
 hw/misc/tz-mpc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/misc/tz-mpc.c b/hw/misc/tz-mpc.c
index fb48a1540b9..9a84be75ed6 100644
--- a/hw/misc/tz-mpc.c
+++ b/hw/misc/tz-mpc.c
@@ -150,7 +150,7 @@ static MemTxResult tz_mpc_reg_read(void *opaque, hwaddr addr,
         r = s->ctrl;
         break;
     case A_BLK_MAX:
-        r = s->blk_max;
+        r = s->blk_max - 1;
         break;
     case A_BLK_CFG:
         /* We are never in "init in progress state", so this just indicates
-- 
2.19.2

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

* [Qemu-devel] [PULL 37/37] Support u-boot noload images for arm as used by, NetBSD/evbarm GENERIC kernel.
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (35 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 36/37] hw/misc/tz-mpc: Fix value of BLK_MAX register Peter Maydell
@ 2019-01-07 16:31 ` Peter Maydell
  2019-01-07 18:24 ` [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
  2019-01-07 20:29 ` no-reply
  38 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-07 16:31 UTC (permalink / raw)
  To: qemu-devel

From: Nick Hudson <nick.hudson@gmx.co.uk>

noload kernels are loaded with the u-boot image header and as a result
the header size needs adding to the entry point.  Fake up a hdr so the
kernel image is loaded at the right address and the entry point is
adjusted appropriately.

The default location for the uboot file is 32MiB above bottom of DRAM.
This matches the recommendation in Documentation/arm/Booting.

Clarify the load_uimage API to state the passing of a load address when an
image doesn't specify one, or when loading a ramdisk is expected.

Adjust callers of load_uimage, etc.

Signed-off-by: Nick Hudson <skrll@netbsd.org>
Message-id: 11488a08-1fe0-a278-2210-deb64731107f@gmx.co.uk
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/core/uboot_image.h  |  1 +
 include/hw/loader.h    |  7 ++++++-
 hw/arm/boot.c          |  8 +++++---
 hw/core/loader.c       | 19 ++++++++++++++++---
 hw/microblaze/boot.c   |  2 +-
 hw/nios2/boot.c        |  2 +-
 hw/ppc/e500.c          |  1 +
 hw/ppc/ppc440_bamboo.c |  2 +-
 hw/ppc/sam460ex.c      |  2 +-
 9 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/hw/core/uboot_image.h b/hw/core/uboot_image.h
index 34c11a70a67..608022de6ec 100644
--- a/hw/core/uboot_image.h
+++ b/hw/core/uboot_image.h
@@ -124,6 +124,7 @@
 #define IH_TYPE_SCRIPT		6	/* Script file			*/
 #define IH_TYPE_FILESYSTEM	7	/* Filesystem Image (any type)	*/
 #define IH_TYPE_FLATDT		8	/* Binary Flat Device Tree Blob	*/
+#define IH_TYPE_KERNEL_NOLOAD  14	/* OS Kernel Image (noload)	*/
 
 /*
  * Compression Types
diff --git a/include/hw/loader.h b/include/hw/loader.h
index 0a0ad808ea3..de8a29603b0 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -175,10 +175,15 @@ void load_elf_hdr(const char *filename, void *hdr, bool *is64, Error **errp);
 int load_aout(const char *filename, hwaddr addr, int max_sz,
               int bswap_needed, hwaddr target_page_size);
 
+#define LOAD_UIMAGE_LOADADDR_INVALID (-1)
+
 /** load_uimage_as:
  * @filename: Path of uimage file
  * @ep: Populated with program entry point. Ignored if NULL.
- * @loadaddr: Populated with the load address. Ignored if NULL.
+ * @loadaddr: load address if none specified in the image or when loading a
+ *            ramdisk. Populated with the load address. Ignored if NULL or
+ *            LOAD_UIMAGE_LOADADDR_INVALID (images which do not specify a load
+ *            address will not be loadable).
  * @is_linux: Is set to true if the image loaded is Linux. Ignored if NULL.
  * @translate_fn: optional function to translate load addresses
  * @translate_opaque: opaque data passed to @translate_fn
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 94fce128028..c7a67af7a97 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -30,8 +30,9 @@
  * Documentation/arm/Booting and Documentation/arm64/booting.txt
  * They have different preferred image load offsets from system RAM base.
  */
-#define KERNEL_ARGS_ADDR 0x100
-#define KERNEL_LOAD_ADDR 0x00010000
+#define KERNEL_ARGS_ADDR   0x100
+#define KERNEL_NOLOAD_ADDR 0x02000000
+#define KERNEL_LOAD_ADDR   0x00010000
 #define KERNEL64_LOAD_ADDR 0x00080000
 
 #define ARM64_TEXT_OFFSET_OFFSET    8
@@ -1082,7 +1083,8 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
     }
     entry = elf_entry;
     if (kernel_size < 0) {
-        kernel_size = load_uimage_as(info->kernel_filename, &entry, NULL,
+        uint64_t loadaddr = info->loader_start + KERNEL_NOLOAD_ADDR;
+        kernel_size = load_uimage_as(info->kernel_filename, &entry, &loadaddr,
                                      &is_linux, NULL, NULL, as);
     }
     if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && kernel_size < 0) {
diff --git a/hw/core/loader.c b/hw/core/loader.c
index fa41842280a..c7182dfa64b 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -613,13 +613,26 @@ static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr,
         goto out;
 
     if (hdr->ih_type != image_type) {
-        fprintf(stderr, "Wrong image type %d, expected %d\n", hdr->ih_type,
-                image_type);
-        goto out;
+        if (!(image_type == IH_TYPE_KERNEL &&
+            hdr->ih_type == IH_TYPE_KERNEL_NOLOAD)) {
+            fprintf(stderr, "Wrong image type %d, expected %d\n", hdr->ih_type,
+                    image_type);
+            goto out;
+        }
     }
 
     /* TODO: Implement other image types.  */
     switch (hdr->ih_type) {
+    case IH_TYPE_KERNEL_NOLOAD:
+        if (!loadaddr || *loadaddr == LOAD_UIMAGE_LOADADDR_INVALID) {
+            fprintf(stderr, "this image format (kernel_noload) cannot be "
+                    "loaded on this machine type");
+            goto out;
+        }
+
+        hdr->ih_load = *loadaddr + sizeof(*hdr);
+        hdr->ih_ep += hdr->ih_load;
+        /* fall through */
     case IH_TYPE_KERNEL:
         address = hdr->ih_load;
         if (translate_fn) {
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index 35bfeda7aa7..489ab839b7c 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -156,7 +156,7 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
 
         /* If it wasn't an ELF image, try an u-boot image.  */
         if (kernel_size < 0) {
-            hwaddr uentry, loadaddr;
+            hwaddr uentry, loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
 
             kernel_size = load_uimage(kernel_filename, &uentry, &loadaddr, 0,
                                       NULL, NULL);
diff --git a/hw/nios2/boot.c b/hw/nios2/boot.c
index 4bb5b601d3a..ed5cb28e942 100644
--- a/hw/nios2/boot.c
+++ b/hw/nios2/boot.c
@@ -161,7 +161,7 @@ void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base,
 
         /* If it wasn't an ELF image, try an u-boot image. */
         if (kernel_size < 0) {
-            hwaddr uentry, loadaddr;
+            hwaddr uentry, loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
 
             kernel_size = load_uimage(kernel_filename, &uentry, &loadaddr, 0,
                                       NULL, NULL);
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index b20fea0dfce..0581e9e3d4c 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -995,6 +995,7 @@ void ppce500_init(MachineState *machine)
          * Hrm. No ELF image? Try a uImage, maybe someone is giving us an
          * ePAPR compliant kernel
          */
+        loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
         payload_size = load_uimage(filename, &bios_entry, &loadaddr, NULL,
                                    NULL, NULL);
         if (payload_size < 0) {
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index b8aa55d5266..fc061915887 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -179,7 +179,7 @@ static void bamboo_init(MachineState *machine)
     CPUPPCState *env;
     uint64_t elf_entry;
     uint64_t elf_lowaddr;
-    hwaddr loadaddr = 0;
+    hwaddr loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
     target_long initrd_size = 0;
     DeviceState *dev;
     int success;
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index 4b051c0950a..84ea592749c 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -402,7 +402,7 @@ static void sam460ex_init(MachineState *machine)
     CPUPPCState *env;
     PPC4xxI2CState *i2c[2];
     hwaddr entry = UBOOT_ENTRY;
-    hwaddr loadaddr = 0;
+    hwaddr loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
     target_long initrd_size = 0;
     DeviceState *dev;
     SysBusDevice *sbdev;
-- 
2.19.2

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

* Re: [Qemu-devel] [PULL 00/37] target-arm queue
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (36 preceding siblings ...)
  2019-01-07 16:31 ` [Qemu-devel] [PULL 37/37] Support u-boot noload images for arm as used by, NetBSD/evbarm GENERIC kernel Peter Maydell
@ 2019-01-07 18:24 ` Peter Maydell
  2019-01-07 20:29 ` no-reply
  38 siblings, 0 replies; 49+ 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] 49+ messages in thread

* Re: [Qemu-devel] [PULL 00/37] target-arm queue
  2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
                   ` (37 preceding siblings ...)
  2019-01-07 18:24 ` [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
@ 2019-01-07 20:29 ` no-reply
  38 siblings, 0 replies; 49+ 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] 49+ messages in thread

* Re: [Qemu-devel] [PULL 24/37] qtest: Add set_irq_in command to set IRQ/GPIO level
  2019-01-07 16:31 ` [Qemu-devel] [PULL 24/37] qtest: Add set_irq_in command to set IRQ/GPIO level Peter Maydell
@ 2019-01-09  5:58   ` Matthew Ogilvie
  2019-01-10 15:53     ` Peter Maydell
  0 siblings, 1 reply; 49+ messages in thread
From: Matthew Ogilvie @ 2019-01-09  5:58 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel

On Mon, Jan 07, 2019 at 04:31:04PM +0000, Peter Maydell wrote:
> From: Steffen Görtz <contrib@steffen-goertz.de>
> 
> Adds a new qtest command "set_irq_in" which allows
> to set qemu gpio lines to a given level.
> 
> Based on https://lists.gnu.org/archive/html/qemu-devel/2012-12/msg02363.html
> which never got merged.
> 
> Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
> Reviewed-by: Thomas Huth <thuth@redhat.com>
> Reviewed-by: Laurent Vivier <lvivier@redhat.com>
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> Message-id: 20190103091119.9367-2-stefanha@redhat.com
> Originally-by: Matthew Ogilvie <mmogilvi_qemu@miniinfo.net>

It is kind of interesting to see a part of my old thread(s)
resurrected, even if it isn't the part I was actually interested
in.

Note that my miniinfo email account no longer exists, but I
can still be reached at mmogilvi+qemu@zoho.com if desired.

Regarding the patch, I haven't kept up with changes to qemu
well enough to really have a useful opinion, although superficially
it looks good.  Perhaps it would make sense to include both
my old and new email addresses in the sign-off section, to both
tie it to the old threads and make it easier to reach me
if someone wants to contact me?  (But I'm not sure of a "clean"
way to do so, and it is probably low priority.  Perhaps this
current email is good enough?)

                - Matthew Ogilvie

P.S.: Explanation and keywords to find this message (and me) with
search tools:

With regards to qemu, my primary interest (from that thread and
related 2012 threads) is/was being able to run
"Microport UNIX System V/386 v2.1" (ca. 1987) under qemu, which
especially required:
   - Fixing various inaccuracies in qemu's model of the i8259
     interrupt controller.
   - Implementing very old graphics card model(s) that Microport UNIX
     actually knows how to control properly.  Perhaps original
     IBM monochrome display adaptor (MDA), CGA, and/or hercules
     graphics card.  Or else my nasty qemu hackish patches I wrote
     that allowed VGA to work in text mode despite Microport driving
     it like CGA in a way that didn't work with real VGA hardware.

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

* Re: [Qemu-devel] [PULL 24/37] qtest: Add set_irq_in command to set IRQ/GPIO level
  2019-01-09  5:58   ` Matthew Ogilvie
@ 2019-01-10 15:53     ` Peter Maydell
  2019-01-10 16:26       ` Eric Blake
  0 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2019-01-10 15:53 UTC (permalink / raw)
  To: Matthew Ogilvie; +Cc: QEMU Developers

On Wed, 9 Jan 2019 at 05:59, Matthew Ogilvie <mmogilvi+qemu@zoho.com> wrote:
>
> On Mon, Jan 07, 2019 at 04:31:04PM +0000, Peter Maydell wrote:
> > From: Steffen Görtz <contrib@steffen-goertz.de>
> >
> > Adds a new qtest command "set_irq_in" which allows
> > to set qemu gpio lines to a given level.
> >
> > Based on https://lists.gnu.org/archive/html/qemu-devel/2012-12/msg02363.html
> > which never got merged.
> >
> > Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
> > Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
> > Reviewed-by: Thomas Huth <thuth@redhat.com>
> > Reviewed-by: Laurent Vivier <lvivier@redhat.com>
> > Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> > Message-id: 20190103091119.9367-2-stefanha@redhat.com
> > Originally-by: Matthew Ogilvie <mmogilvi_qemu@miniinfo.net>
>
> It is kind of interesting to see a part of my old thread(s)
> resurrected, even if it isn't the part I was actually interested
> in.
>
> Note that my miniinfo email account no longer exists, but I
> can still be reached at mmogilvi+qemu@zoho.com if desired.
>
> Regarding the patch, I haven't kept up with changes to qemu
> well enough to really have a useful opinion, although superficially
> it looks good.  Perhaps it would make sense to include both
> my old and new email addresses in the sign-off section, to both
> tie it to the old threads and make it easier to reach me
> if someone wants to contact me?  (But I'm not sure of a "clean"
> way to do so, and it is probably low priority.  Perhaps this
> current email is good enough?)

Thanks for the followup. Unfortunately the commit is already
in master so we can't tweak the commit message at this point.
That shouldn't matter much, people don't often fish emails out
of old commit message logs to email anyway :-)

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 24/37] qtest: Add set_irq_in command to set IRQ/GPIO level
  2019-01-10 15:53     ` Peter Maydell
@ 2019-01-10 16:26       ` Eric Blake
  0 siblings, 0 replies; 49+ messages in thread
From: Eric Blake @ 2019-01-10 16:26 UTC (permalink / raw)
  To: Peter Maydell, Matthew Ogilvie; +Cc: QEMU Developers

[-- Attachment #1: Type: text/plain, Size: 1478 bytes --]

On 1/10/19 9:53 AM, Peter Maydell wrote:

>> Note that my miniinfo email account no longer exists, but I
>> can still be reached at mmogilvi+qemu@zoho.com if desired.
>>
>> Regarding the patch, I haven't kept up with changes to qemu
>> well enough to really have a useful opinion, although superficially
>> it looks good.  Perhaps it would make sense to include both
>> my old and new email addresses in the sign-off section, to both
>> tie it to the old threads and make it easier to reach me
>> if someone wants to contact me?  (But I'm not sure of a "clean"
>> way to do so, and it is probably low priority.  Perhaps this
>> current email is good enough?)
> 
> Thanks for the followup. Unfortunately the commit is already
> in master so we can't tweak the commit message at this point.
> That shouldn't matter much, people don't often fish emails out
> of old commit message logs to email anyway :-)

We can't change the commit message body, but if you are worried about
people still being able to reach you based about a patch they found
while browsing git history, we DO have .mailmap where you can list a new
preferred email address to use in place of any commits you made under an
old address.  Patching .mailmap is a nice (but optional) way to let
people know how to reach you, if you still expect to be reached.

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


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [Qemu-devel] [PULL 10/37] gdbstub: add multiprocess support to Xfer:features:read:
  2019-01-07 16:30 ` [Qemu-devel] [PULL 10/37] gdbstub: add multiprocess support to Xfer:features:read: Peter Maydell
@ 2019-01-17 17:22   ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-17 17:22 UTC (permalink / raw)
  To: QEMU Developers; +Cc: Luc Michel

On Mon, 7 Jan 2019 at 16:31, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> From: Luc Michel <luc.michel@greensocs.com>
>
> Change the Xfer:features:read: packet handling to support the
> multiprocess extension. This packet is used to request the XML
> description of the CPU. In multiprocess mode, different descriptions can
> be sent for different processes.
>
> This function now takes the process to send the description for as a
> parameter, and use a buffer in the process structure to store the
> generated description.
>
> It takes the first CPU of the process to generate the description.

> @@ -1650,14 +1655,15 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
>              const char *xml;
>              target_ulong total_len;
>
> -            cc = CPU_GET_CLASS(first_cpu);
> +            process = gdb_get_cpu_process(s, s->g_cpu);
> +            cc = CPU_GET_CLASS(s->g_cpu);
>              if (cc->gdb_core_xml_file == NULL) {
>                  goto unknown_command;
>              }
>
>              gdb_has_xml = true;
>              p += 19;
> -            xml = get_feature_xml(p, &p, cc);
> +            xml = get_feature_xml(s, p, &p, process);
>              if (!xml) {
>                  snprintf(buf, sizeof(buf), "E00");
>                  put_packet(s, buf);

I've just run in to a segv in the gdbstub code in this bit,
because s->g_cpu is NULL.

Looking at the protocol trace from the gdb end:
(gdb) set debug remote 1
(gdb) target remote :1234
Remote debugging using :1234
Sending packet:
$qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;xmlRegisters=i386#6a...Ack
Packet received: PacketSize=1000;qXfer:features:read+;multiprocess+
Packet qSupported (supported-packets) is supported
Sending packet: $vMustReplyEmpty#3a...Ack
Packet received:
Sending packet: $Hgp0.0#ad...Ack
Packet received: E22
Sending packet: $qXfer:features:read:target.xml:0,ffb#79...Ack
[here is where QEMU crashes]

What seems to happen is that GDB's attempt to set the
current thread with the "Hg" command fails because
gdb_get_cpu() fails[*], and so we return an E22 error status.
GDB (incorrectly) ignores this and issues a general command
anyway, and then QEMU crashes because we don't handle s->g_cpu
being NULL in this command's handling code.

[*] This happens with an out-of-tree board model I'm working
on that uses the cpu cluster stuff, so it's probably a bug in
my code that causes it.

I think it would be nice to do something more robust in these
cases, even if it does only happen when a QEMU bug and a GDB
bug collide :-)

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 06/37] gdbstub: add multiprocess support to 'H' and 'T' packets
  2019-01-07 16:30 ` [Qemu-devel] [PULL 06/37] gdbstub: add multiprocess support to 'H' and 'T' packets Peter Maydell
@ 2019-01-17 18:13   ` Peter Maydell
  2019-01-17 18:19     ` Peter Maydell
  0 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2019-01-17 18:13 UTC (permalink / raw)
  To: QEMU Developers; +Cc: Luc Michel

On Mon, 7 Jan 2019 at 16:31, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> From: Luc Michel <luc.michel@greensocs.com>
>
> Add a couple of helper functions to cope with GDB threads and processes.
>
> The gdb_get_process() function looks for a process given a pid.
>
> The gdb_get_cpu() function returns the CPU corresponding to the (pid,
> tid) pair given as parameters.
>
> The read_thread_id() function parses the thread-id sent by the peer.
> This function supports the multiprocess extension thread-id syntax.  The
> return value specifies if the parsing failed, or if a special case was
> encountered (all processes or all threads).
>
> Use them in 'H' and 'T' packets handling to support the multiprocess
> extension.

> +static CPUState *gdb_get_cpu(const GDBState *s, uint32_t pid, uint32_t tid)
> +{
> +    GDBProcess *process;
> +    CPUState *cpu;
> +
> +    if (!tid) {
> +        /* 0 means any thread, we take the first one */
> +        tid = 1;
> +    }
> +
> +    cpu = find_cpu(tid);
> +
> +    if (cpu == NULL) {
> +        return NULL;
> +    }
> +
> +    process = gdb_get_cpu_process(s, cpu);
> +
> +    if (process->pid != pid) {
> +        return NULL;
> +    }
> +
> +    if (!process->attached) {
> +        return NULL;
> +    }
> +
> +    return cpu;
> +}

I'm finding that (with my out-of-tree board model) gdb
asks for "process 0 thread 0", which should mean "anything you
like", so we end up calling gdb_get_cpu(s, 0, 0). Then we
find a CPU via its TID, and of course it has some specific
PID in process->pid which is not zero, so we fail the
"process->pid != pid" test and return NULL here incorrectly.

Should that check be
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -736,7 +736,8 @@ static CPUState *gdb_get_cpu(const GDBState *s,
uint32_t pid, uint32_t tid)

     process = gdb_get_cpu_process(s, cpu);

-    if (process->pid != pid) {
+    /* pid == 0 means any process, so this one is fine */
+    if (pid != 0 && process->pid != pid) {
         return NULL;
     }

?

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 06/37] gdbstub: add multiprocess support to 'H' and 'T' packets
  2019-01-17 18:13   ` Peter Maydell
@ 2019-01-17 18:19     ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2019-01-17 18:19 UTC (permalink / raw)
  To: QEMU Developers; +Cc: Luc Michel

On Thu, 17 Jan 2019 at 18:13, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Mon, 7 Jan 2019 at 16:31, Peter Maydell <peter.maydell@linaro.org> wrote:
> >
> > From: Luc Michel <luc.michel@greensocs.com>
> >
> > Add a couple of helper functions to cope with GDB threads and processes.
> >
> > The gdb_get_process() function looks for a process given a pid.
> >
> > The gdb_get_cpu() function returns the CPU corresponding to the (pid,
> > tid) pair given as parameters.
> >
> > The read_thread_id() function parses the thread-id sent by the peer.
> > This function supports the multiprocess extension thread-id syntax.  The
> > return value specifies if the parsing failed, or if a special case was
> > encountered (all processes or all threads).
> >
> > Use them in 'H' and 'T' packets handling to support the multiprocess
> > extension.
>
> > +static CPUState *gdb_get_cpu(const GDBState *s, uint32_t pid, uint32_t tid)
> > +{
> > +    GDBProcess *process;
> > +    CPUState *cpu;
> > +
> > +    if (!tid) {
> > +        /* 0 means any thread, we take the first one */
> > +        tid = 1;
> > +    }
> > +
> > +    cpu = find_cpu(tid);
> > +
> > +    if (cpu == NULL) {
> > +        return NULL;
> > +    }
> > +
> > +    process = gdb_get_cpu_process(s, cpu);
> > +
> > +    if (process->pid != pid) {
> > +        return NULL;
> > +    }
> > +
> > +    if (!process->attached) {
> > +        return NULL;
> > +    }
> > +
> > +    return cpu;
> > +}
>
> I'm finding that (with my out-of-tree board model) gdb
> asks for "process 0 thread 0", which should mean "anything you
> like", so we end up calling gdb_get_cpu(s, 0, 0). Then we
> find a CPU via its TID, and of course it has some specific
> PID in process->pid which is not zero, so we fail the
> "process->pid != pid" test and return NULL here incorrectly.

Also, the "use TID 1 if asked for any-task" logic assumes
that TID 1 is actually part of the requested process and
that that task is attached. Shouldn't we instead find the
requested process (or any random attached process, if tid == 0)
and then pick one of the TIDs it has?

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 00/37] target-arm queue
  2018-12-13 14:54 Peter Maydell
@ 2018-12-14 16:43 ` Peter Maydell
  0 siblings, 0 replies; 49+ 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] 49+ 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; 49+ 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] 49+ messages in thread

* [Qemu-devel] [PULL 00/37] target-arm queue
@ 2013-12-10 14:42 Peter Maydell
  0 siblings, 0 replies; 49+ 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] 49+ messages in thread

end of thread, other threads:[~2019-01-17 18:19 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-07 16:30 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 01/37] target/arm: Convert ARM_TBFLAG_* to FIELDs Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 02/37] target/arm: SVE brk[ab] merging does not have s bit Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 03/37] hw/cpu: introduce CPU clusters Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 04/37] gdbstub: introduce GDB processes Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 05/37] gdbstub: add multiprocess support to '?' packets Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 06/37] gdbstub: add multiprocess support to 'H' and 'T' packets Peter Maydell
2019-01-17 18:13   ` Peter Maydell
2019-01-17 18:19     ` Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 07/37] gdbstub: add multiprocess support to vCont packets Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 08/37] gdbstub: add multiprocess support to 'sC' packets Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 09/37] gdbstub: add multiprocess support to (f|s)ThreadInfo and ThreadExtraInfo Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 10/37] gdbstub: add multiprocess support to Xfer:features:read: Peter Maydell
2019-01-17 17:22   ` Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 11/37] gdbstub: add multiprocess support to gdb_vm_state_change() Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 12/37] gdbstub: add multiprocess support to 'D' packets Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 13/37] gdbstub: add support for extended mode packet Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 14/37] gdbstub: add support for vAttach packets Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 15/37] gdbstub: processes initialization on new peer connection Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 16/37] gdbstub: gdb_set_stop_cpu: ignore request when process is not attached Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 17/37] gdbstub: add multiprocess extension support Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 18/37] arm/xlnx-zynqmp: put APUs and RPUs in separate CPU clusters Peter Maydell
2019-01-07 16:30 ` [Qemu-devel] [PULL 19/37] Revert "armv7m: Guard against no -kernel argument" Peter Maydell
2019-01-07 16:31 ` [Qemu-devel] [PULL 20/37] hw/arm: versal: Plug memory leaks Peter Maydell
2019-01-07 16:31 ` [Qemu-devel] [PULL 21/37] MAINTAINERS: Add ARM-related files for hw/[misc|input|timer]/ Peter Maydell
2019-01-07 16:31 ` [Qemu-devel] [PULL 22/37] cpus.c: Fix race condition in cpu_stop_current() Peter Maydell
2019-01-07 16:31 ` [Qemu-devel] [PULL 23/37] hw/arm/allwinner-a10: Add the 'A' SRAM and the SRAM controller Peter Maydell
2019-01-07 16:31 ` [Qemu-devel] [PULL 24/37] qtest: Add set_irq_in command to set IRQ/GPIO level Peter Maydell
2019-01-09  5:58   ` Matthew Ogilvie
2019-01-10 15:53     ` Peter Maydell
2019-01-10 16:26       ` Eric Blake
2019-01-07 16:31 ` [Qemu-devel] [PULL 25/37] arm: Add header to host common definition for nRF51 SOC peripherals Peter Maydell
2019-01-07 16:31 ` [Qemu-devel] [PULL 26/37] hw/misc/nrf51_rng: Add NRF51 random number generator peripheral Peter Maydell
2019-01-07 16:31 ` [Qemu-devel] [PULL 27/37] arm: Instantiate NRF51 random number generator Peter Maydell
2019-01-07 16:31 ` [Qemu-devel] [PULL 28/37] hw/gpio/nrf51_gpio: Add nRF51 GPIO peripheral Peter Maydell
2019-01-07 16:31 ` [Qemu-devel] [PULL 29/37] arm: Instantiate NRF51 general purpose I/O Peter Maydell
2019-01-07 16:31 ` [Qemu-devel] [PULL 30/37] tests/microbit-test: Add Tests for nRF51 GPIO Peter Maydell
2019-01-07 16:31 ` [Qemu-devel] [PULL 31/37] hw/timer/nrf51_timer: Add nRF51 Timer peripheral Peter Maydell
2019-01-07 16:31 ` [Qemu-devel] [PULL 32/37] arm: Instantiate NRF51 Timers Peter Maydell
2019-01-07 16:31 ` [Qemu-devel] [PULL 33/37] tests/microbit-test: Add Tests for nRF51 Timer Peter Maydell
2019-01-07 16:31 ` [Qemu-devel] [PULL 34/37] arm: Add Clock peripheral stub to NRF51 SOC Peter Maydell
2019-01-07 16:31 ` [Qemu-devel] [PULL 35/37] target/arm: Emit barriers for A32/T32 load-acquire/store-release insns Peter Maydell
2019-01-07 16:31 ` [Qemu-devel] [PULL 36/37] hw/misc/tz-mpc: Fix value of BLK_MAX register Peter Maydell
2019-01-07 16:31 ` [Qemu-devel] [PULL 37/37] Support u-boot noload images for arm as used by, NetBSD/evbarm GENERIC kernel Peter Maydell
2019-01-07 18:24 ` [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
2019-01-07 20:29 ` no-reply
  -- strict thread matches above, loose matches on Subject: below --
2018-12-13 14:54 Peter Maydell
2018-12-14 16:43 ` Peter Maydell
2013-12-10 14:42 Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.