qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/25] target-arm queue
@ 2018-08-20 10:31 Peter Maydell
  2018-08-20 10:31 ` [Qemu-devel] [PULL 01/25] target/arm: Fix crash on conditional instruction in an IT block Peter Maydell
                   ` (25 more replies)
  0 siblings, 26 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:31 UTC (permalink / raw)
  To: qemu-devel

Some more outstanding target-arm patches; nothing terribly
exciting. Mostly they're mine; I'm trying to reduce the
number of patches I still have in flight, so I've picked
out some of the reviewed patches from a couple of sets I've
sent out and will resend v2 versions of those sets with the
remaining patches with fixes for issues noted in review once
this is in master.

thanks
-- PMM


The following changes since commit adaec191bfb31e12d40af8ab1b869f5b40d61ee9:

  Merge remote-tracking branch 'remotes/ehabkost/tags/machine-next-pull-request' into staging (2018-08-20 09:48:03 +0100)

are available in the Git repository at:

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

for you to fetch changes up to b85fad1588e812566f897f747e38da345a7016d6:

  hw/dma/pl080: Remove hw_error() if DMA is enabled (2018-08-20 11:24:33 +0100)

----------------------------------------------------------------
target-arm queue:
 * Fix crash on conditional instruction in an IT block
 * docs/generic-loader: mention U-Boot and Intel HEX executable formats
 * hw/intc/arm_gicv3_its: downgrade error_report to warn_report in kvm_arm_its_reset
 * imx_serial: Generate interrupt on receive data ready if enabled
 * Fix various minor bugs in AArch32 Hyp related coprocessor registers
 * Permit accesses to ELR_Hyp from Hyp mode via MSR/MRS (banked)
 * Implement AArch32 ERET instruction
 * hw/arm/virt: Add virt-3.1 machine type
 * sdhci: add i.MX SD Stable Clock bit
 * Remove now-obsolete MMIO request_ptr APIs
 * hw/timer/m48t59: Move away from old_mmio accessors
 * hw/watchdog/cmsdk_apb_watchdog: Implement CMSDK APB watchdog module
 * nvic: Expose NMI line
 * hw/dma/pl080: cleanups and new features required for use in MPS boards

----------------------------------------------------------------
Andrew Jones (1):
      hw/arm/virt: Add virt-3.1 machine type

Hans-Erik Floryd (2):
      imx_serial: Generate interrupt on receive data ready if enabled
      sdhci: add i.MX SD Stable Clock bit

Jia He (1):
      hw/intc/arm_gicv3_its: downgrade error_report to warn_report in kvm_arm_its_reset

Peter Maydell (19):
      target/arm: Correct typo in HAMAIR1 regdef name
      target/arm: Add missing .cp = 15 to HMAIR1 and HAMAIR1 regdefs
      target/arm: Implement AArch32 HVBAR
      target/arm: Implement AArch32 Hyp FARs
      target/arm: Implement ESR_EL2/HSR for AArch32 and no-EL2
      target/arm: Permit accesses to ELR_Hyp from Hyp mode via MSR/MRS (banked)
      target/arm: Implement AArch32 ERET instruction
      hw/ssi/xilinx_spips: Remove unneeded MMIO request_ptr code
      memory: Remove MMIO request_ptr APIs
      hw/misc: Remove mmio_interface device
      hw/timer/m48t59: Move away from old_mmio accessors
      hw/watchdog/cmsdk_apb_watchdog: Implement CMSDK APB watchdog module
      nvic: Expose NMI line
      hw/dma/pl080: Allow use as embedded-struct device
      hw/dma/pl080: Support all three interrupt lines
      hw/dma/pl080: Don't use CPU address space for DMA accesses
      hw/dma/pl080: Provide device reset function
      hw/dma/pl080: Correct bug in register address decode logic
      hw/dma/pl080: Remove hw_error() if DMA is enabled

Roman Kapl (1):
      target/arm: Fix crash on conditional instruction in an IT block

Stefan Hajnoczi (1):
      docs/generic-loader: mention U-Boot and Intel HEX executable formats

 docs/generic-loader.txt                  |  20 +-
 Makefile.objs                            |   1 +
 hw/misc/Makefile.objs                    |   1 -
 hw/watchdog/Makefile.objs                |   1 +
 hw/sd/sdhci-internal.h                   |   2 +
 include/exec/memory.h                    |  35 ----
 include/hw/char/imx_serial.h             |   1 +
 include/hw/dma/pl080.h                   |  71 +++++++
 include/hw/misc/mmio_interface.h         |  49 -----
 include/hw/watchdog/cmsdk-apb-watchdog.h |  59 ++++++
 hw/arm/armv7m.c                          |   1 +
 hw/arm/realview.c                        |   8 +-
 hw/arm/versatilepb.c                     |   9 +-
 hw/arm/virt.c                            |  23 ++-
 hw/char/imx_serial.c                     |   3 +-
 hw/dma/pl080.c                           | 113 ++++++-----
 hw/intc/arm_gicv3_its_kvm.c              |   2 +-
 hw/intc/armv7m_nvic.c                    |  19 ++
 hw/misc/mmio_interface.c                 | 135 -------------
 hw/sd/sdhci.c                            |   8 +
 hw/ssi/xilinx_spips.c                    |  46 -----
 hw/timer/m48t59.c                        |  59 ++----
 hw/watchdog/cmsdk-apb-watchdog.c         | 326 +++++++++++++++++++++++++++++++
 memory.c                                 | 110 -----------
 target/arm/helper.c                      |  36 +++-
 target/arm/op_helper.c                   |  22 +--
 target/arm/translate.c                   |  76 +++++--
 MAINTAINERS                              |   3 +
 default-configs/arm-softmmu.mak          |   1 +
 hw/intc/trace-events                     |   1 +
 hw/watchdog/trace-events                 |   6 +
 31 files changed, 717 insertions(+), 530 deletions(-)
 create mode 100644 include/hw/dma/pl080.h
 delete mode 100644 include/hw/misc/mmio_interface.h
 create mode 100644 include/hw/watchdog/cmsdk-apb-watchdog.h
 delete mode 100644 hw/misc/mmio_interface.c
 create mode 100644 hw/watchdog/cmsdk-apb-watchdog.c
 create mode 100644 hw/watchdog/trace-events

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

* [Qemu-devel] [PULL 01/25] target/arm: Fix crash on conditional instruction in an IT block
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
@ 2018-08-20 10:31 ` Peter Maydell
  2018-08-20 10:31 ` [Qemu-devel] [PULL 02/25] docs/generic-loader: mention U-Boot and Intel HEX executable formats Peter Maydell
                   ` (24 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:31 UTC (permalink / raw)
  To: qemu-devel

From: Roman Kapl <rka@sysgo.com>

If an instruction is conditional (like CBZ) and it is executed
conditionally (using the ITx instruction), a jump to an undefined
label is generated, and QEMU crashes.

CBZ in IT block is an UNPREDICTABLE behavior, but we should not
crash.  Honouring the condition code is allowed by the spec in this
case (constrained unpredictable, ARMv8, section K1.1.7), and matches
what we do for other "UNPREDICTABLE inside an IT block" instructions.

Fix the 'skip on condition' code to create a new label only if it
does not already exist.  Previously multiple labels were created, but
only the last one of them was set.

Signed-off-by: Roman Kapl <rka@sysgo.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180816120533.6587-1-rka@sysgo.com
[PMM: fixed ^ 1 being applied to wrong argument, fixed typo]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/translate.c | 35 +++++++++++++++++++++--------------
 1 file changed, 21 insertions(+), 14 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index f845da7c638..14aa2cd3cd5 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -8480,6 +8480,22 @@ static void gen_srs(DisasContext *s,
     s->base.is_jmp = DISAS_UPDATE;
 }
 
+/* Generate a label used for skipping this instruction */
+static void arm_gen_condlabel(DisasContext *s)
+{
+    if (!s->condjmp) {
+        s->condlabel = gen_new_label();
+        s->condjmp = 1;
+    }
+}
+
+/* Skip this instruction if the ARM condition is false */
+static void arm_skip_unless(DisasContext *s, uint32_t cond)
+{
+    arm_gen_condlabel(s);
+    arm_gen_test_cc(cond ^ 1, s->condlabel);
+}
+
 static void disas_arm_insn(DisasContext *s, unsigned int insn)
 {
     unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
@@ -8709,9 +8725,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
     if (cond != 0xe) {
         /* if not always execute, we generate a conditional jump to
            next instruction */
-        s->condlabel = gen_new_label();
-        arm_gen_test_cc(cond ^ 1, s->condlabel);
-        s->condjmp = 1;
+        arm_skip_unless(s, cond);
     }
     if ((insn & 0x0f900000) == 0x03000000) {
         if ((insn & (1 << 21)) == 0) {
@@ -11205,9 +11219,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
                 /* Conditional branch.  */
                 op = (insn >> 22) & 0xf;
                 /* Generate a conditional jump to next instruction.  */
-                s->condlabel = gen_new_label();
-                arm_gen_test_cc(op ^ 1, s->condlabel);
-                s->condjmp = 1;
+                arm_skip_unless(s, op);
 
                 /* offset[11:1] = insn[10:0] */
                 offset = (insn & 0x7ff) << 1;
@@ -12131,8 +12143,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
         case 1: case 3: case 9: case 11: /* czb */
             rm = insn & 7;
             tmp = load_reg(s, rm);
-            s->condlabel = gen_new_label();
-            s->condjmp = 1;
+            arm_gen_condlabel(s);
             if (insn & (1 << 11))
                 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
             else
@@ -12295,9 +12306,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
             break;
         }
         /* generate a conditional jump to next instruction */
-        s->condlabel = gen_new_label();
-        arm_gen_test_cc(cond ^ 1, s->condlabel);
-        s->condjmp = 1;
+        arm_skip_unless(s, cond);
 
         /* jump to the offset */
         val = (uint32_t)s->pc + 2;
@@ -12676,9 +12685,7 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
         uint32_t cond = dc->condexec_cond;
 
         if (cond != 0x0e) {     /* Skip conditional when condition is AL. */
-            dc->condlabel = gen_new_label();
-            arm_gen_test_cc(cond ^ 1, dc->condlabel);
-            dc->condjmp = 1;
+            arm_skip_unless(dc, cond);
         }
     }
 
-- 
2.18.0

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

* [Qemu-devel] [PULL 02/25] docs/generic-loader: mention U-Boot and Intel HEX executable formats
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
  2018-08-20 10:31 ` [Qemu-devel] [PULL 01/25] target/arm: Fix crash on conditional instruction in an IT block Peter Maydell
@ 2018-08-20 10:31 ` Peter Maydell
  2018-08-20 10:31 ` [Qemu-devel] [PULL 03/25] hw/intc/arm_gicv3_its: downgrade error_report to warn_report in kvm_arm_its_reset Peter Maydell
                   ` (23 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:31 UTC (permalink / raw)
  To: qemu-devel

From: Stefan Hajnoczi <stefanha@redhat.com>

The generic loader device supports the U-Boot and Intel HEX executable
formats in addition to the document raw and ELF formats.  Reword the
documentation to include these formats and explain how various options
depend on the executable format.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20180816145554.9814-1-stefanha@redhat.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 docs/generic-loader.txt | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/docs/generic-loader.txt b/docs/generic-loader.txt
index 31bbcd42f6b..a9603a2af76 100644
--- a/docs/generic-loader.txt
+++ b/docs/generic-loader.txt
@@ -56,25 +56,25 @@ An example of setting CPU 0's PC to 0x8000 is:
 
 Loading Files
 -------------
-The loader device also allows files to be loaded into memory. It can load raw
-files and ELF executable files.  Raw files are loaded verbatim.  ELF executable
-files are loaded by an ELF loader.  The syntax is shown below:
+The loader device also allows files to be loaded into memory. It can load ELF,
+U-Boot, and Intel HEX executable formats as well as raw images.  The syntax is
+shown below:
 
     -device loader,file=<file>[,addr=<addr>][,cpu-num=<cpu-num>][,force-raw=<raw>]
 
     <file>      - A file to be loaded into memory
-    <addr>      - The addr in memory that the file should be loaded. This is
-                  ignored if you are using an ELF (unless force-raw is true).
-                  This is required if you aren't loading an ELF.
+    <addr>      - The memory address where the file should be loaded. This is
+                  required for raw images and ignored for non-raw files.
     <cpu-num>   - This specifies the CPU that should be used. This is an
                   optional argument and will cause the CPU's PC to be set to
-                  where the image is stored or in the case of an ELF file to
-                  the value in the header. This option should only be used
-                  for the boot image.
+                  the memory address where the raw file is loaded or the entry
+                  point specified in the executable format header. This option
+                  should only be used for the boot image.
                   This will also cause the image to be written to the specified
                   CPU's address space. If not specified, the default is CPU 0.
     <force-raw> - Setting force-raw=on forces the file to be treated as a raw
-                  image.  This can be used to load ELF files as if they were raw.
+                  image.  This can be used to load supported executable formats
+                  as if they were raw.
 
 All values are parsed using the standard QemuOps parsing. This allows the user
 to specify any values in any format supported. By default the values
-- 
2.18.0

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

* [Qemu-devel] [PULL 03/25] hw/intc/arm_gicv3_its: downgrade error_report to warn_report in kvm_arm_its_reset
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
  2018-08-20 10:31 ` [Qemu-devel] [PULL 01/25] target/arm: Fix crash on conditional instruction in an IT block Peter Maydell
  2018-08-20 10:31 ` [Qemu-devel] [PULL 02/25] docs/generic-loader: mention U-Boot and Intel HEX executable formats Peter Maydell
@ 2018-08-20 10:31 ` Peter Maydell
  2018-08-20 10:31 ` [Qemu-devel] [PULL 04/25] imx_serial: Generate interrupt on receive data ready if enabled Peter Maydell
                   ` (22 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:31 UTC (permalink / raw)
  To: qemu-devel

From: Jia He <hejianet@gmail.com>

In scripts/arch-run.bash of kvm-unit-tests, it will check the qemu
output log with:
if [ -z "$(echo "$errors" | grep -vi warning)" ]; then

Thus without the warning prefix, all of the test fail.

Since it is not unrecoverable error in kvm_arm_its_reset for
current implementation, downgrading the report from error to
warn makes sense.

Signed-off-by: Jia He <jia.he@hxt-semitech.com>
Message-id: 1531969910-32843-1-git-send-email-jia.he@hxt-semitech.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/intc/arm_gicv3_its_kvm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
index 271ebe461c8..01573abb488 100644
--- a/hw/intc/arm_gicv3_its_kvm.c
+++ b/hw/intc/arm_gicv3_its_kvm.c
@@ -211,7 +211,7 @@ static void kvm_arm_its_reset(DeviceState *dev)
         return;
     }
 
-    error_report("ITS KVM: full reset is not supported by the host kernel");
+    warn_report("ITS KVM: full reset is not supported by the host kernel");
 
     if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
                                GITS_CTLR)) {
-- 
2.18.0

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

* [Qemu-devel] [PULL 04/25] imx_serial: Generate interrupt on receive data ready if enabled
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (2 preceding siblings ...)
  2018-08-20 10:31 ` [Qemu-devel] [PULL 03/25] hw/intc/arm_gicv3_its: downgrade error_report to warn_report in kvm_arm_its_reset Peter Maydell
@ 2018-08-20 10:31 ` Peter Maydell
  2018-08-20 10:31 ` [Qemu-devel] [PULL 05/25] target/arm: Correct typo in HAMAIR1 regdef name Peter Maydell
                   ` (21 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:31 UTC (permalink / raw)
  To: qemu-devel

From: Hans-Erik Floryd <hans-erik.floryd@rt-labs.com>

Generate an interrupt if USR2_RDR and UCR4_DREN are both set.

Signed-off-by: Hans-Erik Floryd <hans-erik.floryd@rt-labs.com>
Message-id: 1534341354-11956-1-git-send-email-hans-erik.floryd@rt-labs.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/char/imx_serial.h | 1 +
 hw/char/imx_serial.c         | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h
index ee80da12e60..c8b74284f87 100644
--- a/include/hw/char/imx_serial.h
+++ b/include/hw/char/imx_serial.h
@@ -68,6 +68,7 @@
 #define UCR2_RXEN       (1<<1)    /* Receiver enable */
 #define UCR2_SRST       (1<<0)    /* Reset complete */
 
+#define UCR4_DREN       BIT(0)    /* Receive Data Ready interrupt enable */
 #define UCR4_TCEN       BIT(3)    /* TX complete interrupt enable */
 
 #define UTS1_TXEMPTY    (1<<6)
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index 0747db9f2b9..1e363190e3d 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -74,8 +74,9 @@ static void imx_update(IMXSerialState *s)
     mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
     /*
      * TCEN and TXDC are both bit 3
+     * RDR and DREN are both bit 0
      */
-    mask |= s->ucr4 & UCR4_TCEN;
+    mask |= s->ucr4 & (UCR4_TCEN | UCR4_DREN);
 
     usr2 = s->usr2 & mask;
 
-- 
2.18.0

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

* [Qemu-devel] [PULL 05/25] target/arm: Correct typo in HAMAIR1 regdef name
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (3 preceding siblings ...)
  2018-08-20 10:31 ` [Qemu-devel] [PULL 04/25] imx_serial: Generate interrupt on receive data ready if enabled Peter Maydell
@ 2018-08-20 10:31 ` Peter Maydell
  2018-08-20 10:31 ` [Qemu-devel] [PULL 06/25] target/arm: Add missing .cp = 15 to HMAIR1 and HAMAIR1 regdefs Peter Maydell
                   ` (20 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:31 UTC (permalink / raw)
  To: qemu-devel

We implement the HAMAIR1 register as RAZ/WI; we had a typo in the
regdef, though, and were incorrectly naming it HMAIR1 (which is
a different register which we also implement as RAZ/WI).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
Message-id: 20180814124254.5229-2-peter.maydell@linaro.org
---
 target/arm/helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index a3124082a63..3e20467ac6b 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3773,7 +3773,7 @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
       .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0,
       .access = PL2_RW, .type = ARM_CP_CONST,
       .resetvalue = 0 },
-    { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
+    { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
       .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
       .access = PL2_RW, .type = ARM_CP_CONST,
       .resetvalue = 0 },
@@ -3925,7 +3925,7 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
       .access = PL2_RW, .type = ARM_CP_CONST,
       .resetvalue = 0 },
     /* HAMAIR1 is mapped to AMAIR_EL2[63:32] */
-    { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
+    { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
       .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
       .access = PL2_RW, .type = ARM_CP_CONST,
       .resetvalue = 0 },
-- 
2.18.0

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

* [Qemu-devel] [PULL 06/25] target/arm: Add missing .cp = 15 to HMAIR1 and HAMAIR1 regdefs
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (4 preceding siblings ...)
  2018-08-20 10:31 ` [Qemu-devel] [PULL 05/25] target/arm: Correct typo in HAMAIR1 regdef name Peter Maydell
@ 2018-08-20 10:31 ` Peter Maydell
  2018-08-20 10:31 ` [Qemu-devel] [PULL 07/25] target/arm: Implement AArch32 HVBAR Peter Maydell
                   ` (19 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:31 UTC (permalink / raw)
  To: qemu-devel

ARMCPRegInfo structs will default to .cp = 15 if they
are ARM_CP_STATE_BOTH, but not if they are ARM_CP_STATE_AA32
(because a coprocessor number of 0 is valid for AArch32).
We forgot to explicitly set .cp = 15 for the HMAIR1 and
HAMAIR1 regdefs, which meant they would UNDEF when the guest
tried to access them under cp15.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
Message-id: 20180814124254.5229-3-peter.maydell@linaro.org
---
 target/arm/helper.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 3e20467ac6b..a68577a06aa 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3767,14 +3767,14 @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
       .access = PL2_RW, .type = ARM_CP_CONST,
       .resetvalue = 0 },
     { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
-      .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
+      .cp = 15, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
       .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
     { .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0,
       .access = PL2_RW, .type = ARM_CP_CONST,
       .resetvalue = 0 },
     { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
-      .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
+      .cp = 15, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
       .access = PL2_RW, .type = ARM_CP_CONST,
       .resetvalue = 0 },
     { .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH,
@@ -3917,7 +3917,7 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
       .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[2]),
       .resetvalue = 0 },
     { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
-      .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
+      .cp = 15, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
       .access = PL2_RW, .type = ARM_CP_ALIAS,
       .fieldoffset = offsetofhigh32(CPUARMState, cp15.mair_el[2]) },
     { .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH,
@@ -3926,7 +3926,7 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
       .resetvalue = 0 },
     /* HAMAIR1 is mapped to AMAIR_EL2[63:32] */
     { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
-      .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
+      .cp = 15, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
       .access = PL2_RW, .type = ARM_CP_CONST,
       .resetvalue = 0 },
     { .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH,
-- 
2.18.0

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

* [Qemu-devel] [PULL 07/25] target/arm: Implement AArch32 HVBAR
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (5 preceding siblings ...)
  2018-08-20 10:31 ` [Qemu-devel] [PULL 06/25] target/arm: Add missing .cp = 15 to HMAIR1 and HAMAIR1 regdefs Peter Maydell
@ 2018-08-20 10:31 ` Peter Maydell
  2018-08-20 10:31 ` [Qemu-devel] [PULL 08/25] target/arm: Implement AArch32 Hyp FARs Peter Maydell
                   ` (18 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:31 UTC (permalink / raw)
  To: qemu-devel

Implement the AArch32 HVBAR register; we can do this just by
making the existing VBAR_EL2 regdefs be STATE_BOTH.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
Message-id: 20180814124254.5229-5-peter.maydell@linaro.org
---
 target/arm/helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index a68577a06aa..274fb219122 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3750,7 +3750,7 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
 
 /* Used to describe the behaviour of EL2 regs when EL2 does not exist.  */
 static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
-    { .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64,
+    { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
       .access = PL2_RW,
       .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore },
@@ -3899,7 +3899,7 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
       .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
       .access = PL2_RW,
       .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_HYP]) },
-    { .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64,
+    { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
       .access = PL2_RW, .writefn = vbar_write,
       .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[2]),
-- 
2.18.0

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

* [Qemu-devel] [PULL 08/25] target/arm: Implement AArch32 Hyp FARs
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (6 preceding siblings ...)
  2018-08-20 10:31 ` [Qemu-devel] [PULL 07/25] target/arm: Implement AArch32 HVBAR Peter Maydell
@ 2018-08-20 10:31 ` Peter Maydell
  2018-08-20 10:31 ` [Qemu-devel] [PULL 09/25] target/arm: Implement ESR_EL2/HSR for AArch32 and no-EL2 Peter Maydell
                   ` (17 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:31 UTC (permalink / raw)
  To: qemu-devel

The AArch32 virtualization extensions support these fault address
registers:
 * HDFAR: aliased with AArch64 FAR_EL2[31:0] and AArch32 DFAR(S)
 * HIFAR: aliased with AArch64 FAR_EL2[63:32] and AArch32 IFAR(S)

Implement the accessors for these. This fixes in passing a bug
where we weren't implementing the "RES0 from EL3 if EL2 not
implemented" behaviour for AArch64 FAR_EL2.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
Message-id: 20180814124254.5229-7-peter.maydell@linaro.org
---
 target/arm/helper.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 274fb219122..bb08bd4e4bf 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3843,6 +3843,13 @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
     { .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
       .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+    { .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
+      .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+    { .name = "HIFAR", .state = ARM_CP_STATE_AA32,
+      .type = ARM_CP_CONST,
+      .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2,
+      .access = PL2_RW, .resetvalue = 0 },
     REGINFO_SENTINEL
 };
 
@@ -3891,9 +3898,14 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
     { .name = "ESR_EL2", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
       .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[2]) },
-    { .name = "FAR_EL2", .state = ARM_CP_STATE_AA64,
+    { .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
       .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[2]) },
+    { .name = "HIFAR", .state = ARM_CP_STATE_AA32,
+      .type = ARM_CP_ALIAS,
+      .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2,
+      .access = PL2_RW,
+      .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el[2]) },
     { .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64,
       .type = ARM_CP_ALIAS,
       .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
-- 
2.18.0

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

* [Qemu-devel] [PULL 09/25] target/arm: Implement ESR_EL2/HSR for AArch32 and no-EL2
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (7 preceding siblings ...)
  2018-08-20 10:31 ` [Qemu-devel] [PULL 08/25] target/arm: Implement AArch32 Hyp FARs Peter Maydell
@ 2018-08-20 10:31 ` Peter Maydell
  2018-08-20 10:31 ` [Qemu-devel] [PULL 10/25] target/arm: Permit accesses to ELR_Hyp from Hyp mode via MSR/MRS (banked) Peter Maydell
                   ` (16 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:31 UTC (permalink / raw)
  To: qemu-devel

The AArch32 HSR is the equivalent of AArch64 ESR_EL2;
we can implement it by marking our existing ESR_EL2 regdef
as STATE_BOTH. It also needs to be "RES0 from EL3 if
EL2 not implemented", so add the missing stanza to
el3_no_el2_cp_reginfo.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
Message-id: 20180814124254.5229-8-peter.maydell@linaro.org
---
 target/arm/helper.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index bb08bd4e4bf..c9bce1efcb2 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3759,6 +3759,10 @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
       .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
       .access = PL2_RW,
       .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore },
+    { .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
+      .access = PL2_RW,
+      .type = ARM_CP_CONST, .resetvalue = 0 },
     { .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2,
       .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
@@ -3895,7 +3899,7 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
       .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
       .access = PL2_RW,
       .fieldoffset = offsetof(CPUARMState, elr_el[2]) },
-    { .name = "ESR_EL2", .state = ARM_CP_STATE_AA64,
+    { .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
       .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[2]) },
     { .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
-- 
2.18.0

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

* [Qemu-devel] [PULL 10/25] target/arm: Permit accesses to ELR_Hyp from Hyp mode via MSR/MRS (banked)
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (8 preceding siblings ...)
  2018-08-20 10:31 ` [Qemu-devel] [PULL 09/25] target/arm: Implement ESR_EL2/HSR for AArch32 and no-EL2 Peter Maydell
@ 2018-08-20 10:31 ` Peter Maydell
  2018-08-20 10:31 ` [Qemu-devel] [PULL 11/25] target/arm: Implement AArch32 ERET instruction Peter Maydell
                   ` (15 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:31 UTC (permalink / raw)
  To: qemu-devel

The MSR (banked) and MRS (banked) instructions allow accesses to ELR_Hyp
from either Monitor or Hyp mode. Our translate time check
was overly strict and only permitted access from Monitor mode.

The runtime check we do in msr_mrs_banked_exc_checks() had the
correct code in it, but never got there because of the earlier
"currmode == tgtmode" check. Special case ELR_Hyp.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
Message-id: 20180814124254.5229-9-peter.maydell@linaro.org
---
 target/arm/op_helper.c | 22 +++++++++++-----------
 target/arm/translate.c | 10 +++++++---
 2 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index d550978b5b9..952b8d122b7 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -611,6 +611,14 @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
      */
     int curmode = env->uncached_cpsr & CPSR_M;
 
+    if (regno == 17) {
+        /* ELR_Hyp: a special case because access from tgtmode is OK */
+        if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
+            goto undef;
+        }
+        return;
+    }
+
     if (curmode == tgtmode) {
         goto undef;
     }
@@ -638,17 +646,9 @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
     }
 
     if (tgtmode == ARM_CPU_MODE_HYP) {
-        switch (regno) {
-        case 17: /* ELR_Hyp */
-            if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
-                goto undef;
-            }
-            break;
-        default:
-            if (curmode != ARM_CPU_MODE_MON) {
-                goto undef;
-            }
-            break;
+        /* SPSR_Hyp, r13_hyp: accessible from Monitor mode only */
+        if (curmode != ARM_CPU_MODE_MON) {
+            goto undef;
         }
     }
 
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 14aa2cd3cd5..8405c08fd1a 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -4506,10 +4506,14 @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
         }
         break;
     case ARM_CPU_MODE_HYP:
-        /* Note that we can forbid accesses from EL2 here because they
-         * must be from Hyp mode itself
+        /*
+         * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
+         * (and so we can forbid accesses from EL2 or below). elr_hyp
+         * can be accessed also from Hyp mode, so forbid accesses from
+         * EL0 or EL1.
          */
-        if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 3) {
+        if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
+            (s->current_el < 3 && *regno != 17)) {
             goto undef;
         }
         break;
-- 
2.18.0

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

* [Qemu-devel] [PULL 11/25] target/arm: Implement AArch32 ERET instruction
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (9 preceding siblings ...)
  2018-08-20 10:31 ` [Qemu-devel] [PULL 10/25] target/arm: Permit accesses to ELR_Hyp from Hyp mode via MSR/MRS (banked) Peter Maydell
@ 2018-08-20 10:31 ` Peter Maydell
  2018-08-20 10:31 ` [Qemu-devel] [PULL 12/25] hw/arm/virt: Add virt-3.1 machine type Peter Maydell
                   ` (14 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:31 UTC (permalink / raw)
  To: qemu-devel

ARMv7VE introduced the ERET instruction, which is necessary to
return from an exception taken to Hyp mode. Implement this.
In A32 encoding it is a completely new encoding; in T32 it
is an adjustment of the behaviour of the existing
"SUBS PC, LR, #<imm8>" instruction.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
Message-id: 20180814124254.5229-10-peter.maydell@linaro.org
---
 target/arm/translate.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 8405c08fd1a..bcfc29c5a6a 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -8901,6 +8901,25 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
             tcg_temp_free_i32(tmp2);
             store_reg(s, rd, tmp);
             break;
+        case 0x6: /* ERET */
+            if (op1 != 3) {
+                goto illegal_op;
+            }
+            if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
+                goto illegal_op;
+            }
+            if ((insn & 0x000fff0f) != 0x0000000e) {
+                /* UNPREDICTABLE; we choose to UNDEF */
+                goto illegal_op;
+            }
+
+            if (s->current_el == 2) {
+                tmp = load_cpu_field(elr_el[2]);
+            } else {
+                tmp = load_reg(s, 14);
+            }
+            gen_exception_return(s, tmp);
+            break;
         case 7:
         {
             int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
@@ -11158,8 +11177,16 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
                         if (rn != 14 || rd != 15) {
                             goto illegal_op;
                         }
-                        tmp = load_reg(s, rn);
-                        tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
+                        if (s->current_el == 2) {
+                            /* ERET from Hyp uses ELR_Hyp, not LR */
+                            if (insn & 0xff) {
+                                goto illegal_op;
+                            }
+                            tmp = load_cpu_field(elr_el[2]);
+                        } else {
+                            tmp = load_reg(s, rn);
+                            tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
+                        }
                         gen_exception_return(s, tmp);
                         break;
                     case 6: /* MRS */
-- 
2.18.0

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

* [Qemu-devel] [PULL 12/25] hw/arm/virt: Add virt-3.1 machine type
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (10 preceding siblings ...)
  2018-08-20 10:31 ` [Qemu-devel] [PULL 11/25] target/arm: Implement AArch32 ERET instruction Peter Maydell
@ 2018-08-20 10:31 ` Peter Maydell
  2018-08-20 10:32 ` [Qemu-devel] [PULL 13/25] sdhci: add i.MX SD Stable Clock bit Peter Maydell
                   ` (13 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:31 UTC (permalink / raw)
  To: qemu-devel

From: Andrew Jones <drjones@redhat.com>

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/virt.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 0807be985c0..0b57f87abcb 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1791,10 +1791,7 @@ static void machvirt_machine_init(void)
 }
 type_init(machvirt_machine_init);
 
-#define VIRT_COMPAT_2_12 \
-    HW_COMPAT_2_12
-
-static void virt_3_0_instance_init(Object *obj)
+static void virt_3_1_instance_init(Object *obj)
 {
     VirtMachineState *vms = VIRT_MACHINE(obj);
     VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
@@ -1864,10 +1861,24 @@ static void virt_3_0_instance_init(Object *obj)
     vms->irqmap = a15irqmap;
 }
 
-static void virt_machine_3_0_options(MachineClass *mc)
+static void virt_machine_3_1_options(MachineClass *mc)
 {
 }
-DEFINE_VIRT_MACHINE_AS_LATEST(3, 0)
+DEFINE_VIRT_MACHINE_AS_LATEST(3, 1)
+
+static void virt_3_0_instance_init(Object *obj)
+{
+    virt_3_1_instance_init(obj);
+}
+
+static void virt_machine_3_0_options(MachineClass *mc)
+{
+    virt_machine_3_1_options(mc);
+}
+DEFINE_VIRT_MACHINE(3, 0)
+
+#define VIRT_COMPAT_2_12 \
+    HW_COMPAT_2_12
 
 static void virt_2_12_instance_init(Object *obj)
 {
-- 
2.18.0

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

* [Qemu-devel] [PULL 13/25] sdhci: add i.MX SD Stable Clock bit
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (11 preceding siblings ...)
  2018-08-20 10:31 ` [Qemu-devel] [PULL 12/25] hw/arm/virt: Add virt-3.1 machine type Peter Maydell
@ 2018-08-20 10:32 ` Peter Maydell
  2018-08-20 10:32 ` [Qemu-devel] [PULL 14/25] hw/ssi/xilinx_spips: Remove unneeded MMIO request_ptr code Peter Maydell
                   ` (12 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:32 UTC (permalink / raw)
  To: qemu-devel

From: Hans-Erik Floryd <hans-erik.floryd@rt-labs.com>

Add the ESDHC PRSSTAT_SDSTB bit, using the value of SDHC_CLOCK_INT_STABLE.
Freescale recommends checking this bit when changing clock frequency.

Signed-off-by: Hans-Erik Floryd <hans-erik.floryd@rt-labs.com>
Message-id: 1534507843-4251-1-git-send-email-hans-erik.floryd@rt-labs.com
[PMM: fixed indentation]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/sd/sdhci-internal.h | 2 ++
 hw/sd/sdhci.c          | 8 ++++++++
 2 files changed, 10 insertions(+)

diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
index 756ef3f3c2e..19665fd4013 100644
--- a/hw/sd/sdhci-internal.h
+++ b/hw/sd/sdhci-internal.h
@@ -302,4 +302,6 @@ extern const VMStateDescription sdhci_vmstate;
 #define ESDHC_CTRL_4BITBUS              (0x1 << 1)
 #define ESDHC_CTRL_8BITBUS              (0x2 << 1)
 
+#define ESDHC_PRNSTS_SDSTB              (1 << 3)
+
 #endif
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 8f58c31265a..81bbf032794 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1651,6 +1651,14 @@ static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size)
 
         break;
 
+    case SDHC_PRNSTS:
+        /* Add SDSTB (SD Clock Stable) bit to PRNSTS */
+        ret = sdhci_read(opaque, offset, size) & ~ESDHC_PRNSTS_SDSTB;
+        if (s->clkcon & SDHC_CLOCK_INT_STABLE) {
+            ret |= ESDHC_PRNSTS_SDSTB;
+        }
+        break;
+
     case ESDHC_DLL_CTRL:
     case ESDHC_TUNE_CTRL_STATUS:
     case ESDHC_UNDOCUMENTED_REG27:
-- 
2.18.0

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

* [Qemu-devel] [PULL 14/25] hw/ssi/xilinx_spips: Remove unneeded MMIO request_ptr code
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (12 preceding siblings ...)
  2018-08-20 10:32 ` [Qemu-devel] [PULL 13/25] sdhci: add i.MX SD Stable Clock bit Peter Maydell
@ 2018-08-20 10:32 ` Peter Maydell
  2018-08-20 10:32 ` [Qemu-devel] [PULL 15/25] memory: Remove MMIO request_ptr APIs Peter Maydell
                   ` (11 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:32 UTC (permalink / raw)
  To: qemu-devel

We now support direct execution from MMIO regions in the
core memory subsystem. This means that we don't need to
have device-specific support for it, and we can remove
the request_ptr handling from the Xilinx SPIPS device.
(It was broken anyway due to race conditions, and disabled
by default.)

This device is the only in-tree user of this API.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
Message-id: 20180817114619.22354-2-peter.maydell@linaro.org
---
 hw/ssi/xilinx_spips.c | 46 -------------------------------------------
 1 file changed, 46 deletions(-)

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index c052bfc4b3c..16f88f74029 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -1031,14 +1031,6 @@ static const MemoryRegionOps spips_ops = {
 
 static void xilinx_qspips_invalidate_mmio_ptr(XilinxQSPIPS *q)
 {
-    XilinxSPIPS *s = &q->parent_obj;
-
-    if ((q->mmio_execution_enabled) && (q->lqspi_cached_addr != ~0ULL)) {
-        /* Invalidate the current mapped mmio */
-        memory_region_invalidate_mmio_ptr(&s->mmlqspi, q->lqspi_cached_addr,
-                                          LQSPI_CACHE_SIZE);
-    }
-
     q->lqspi_cached_addr = ~0ULL;
 }
 
@@ -1207,23 +1199,6 @@ static void lqspi_load_cache(void *opaque, hwaddr addr)
     }
 }
 
-static void *lqspi_request_mmio_ptr(void *opaque, hwaddr addr, unsigned *size,
-                                    unsigned *offset)
-{
-    XilinxQSPIPS *q = opaque;
-    hwaddr offset_within_the_region;
-
-    if (!q->mmio_execution_enabled) {
-        return NULL;
-    }
-
-    offset_within_the_region = addr & ~(LQSPI_CACHE_SIZE - 1);
-    lqspi_load_cache(opaque, offset_within_the_region);
-    *size = LQSPI_CACHE_SIZE;
-    *offset = offset_within_the_region;
-    return q->lqspi_buf;
-}
-
 static uint64_t
 lqspi_read(void *opaque, hwaddr addr, unsigned int size)
 {
@@ -1245,7 +1220,6 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
 
 static const MemoryRegionOps lqspi_ops = {
     .read = lqspi_read,
-    .request_ptr = lqspi_request_mmio_ptr,
     .endianness = DEVICE_NATIVE_ENDIAN,
     .valid = {
         .min_access_size = 1,
@@ -1322,15 +1296,6 @@ static void xilinx_qspips_realize(DeviceState *dev, Error **errp)
     sysbus_init_mmio(sbd, &s->mmlqspi);
 
     q->lqspi_cached_addr = ~0ULL;
-
-    /* mmio_execution breaks migration better aborting than having strange
-     * bugs.
-     */
-    if (q->mmio_execution_enabled) {
-        error_setg(&q->migration_blocker,
-                   "enabling mmio_execution breaks migration");
-        migrate_add_blocker(q->migration_blocker, &error_fatal);
-    }
 }
 
 static void xlnx_zynqmp_qspips_realize(DeviceState *dev, Error **errp)
@@ -1427,16 +1392,6 @@ static Property xilinx_zynqmp_qspips_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static Property xilinx_qspips_properties[] = {
-    /* We had to turn this off for 2.10 as it is not compatible with migration.
-     * It can be enabled but will prevent the device to be migrated.
-     * This will go aways when a fix will be released.
-     */
-    DEFINE_PROP_BOOL("x-mmio-exec", XilinxQSPIPS, mmio_execution_enabled,
-                     false),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
 static Property xilinx_spips_properties[] = {
     DEFINE_PROP_UINT8("num-busses", XilinxSPIPS, num_busses, 1),
     DEFINE_PROP_UINT8("num-ss-bits", XilinxSPIPS, num_cs, 4),
@@ -1450,7 +1405,6 @@ static void xilinx_qspips_class_init(ObjectClass *klass, void * data)
     XilinxSPIPSClass *xsc = XILINX_SPIPS_CLASS(klass);
 
     dc->realize = xilinx_qspips_realize;
-    dc->props = xilinx_qspips_properties;
     xsc->reg_ops = &qspips_ops;
     xsc->rx_fifo_size = RXFF_A_Q;
     xsc->tx_fifo_size = TXFF_A_Q;
-- 
2.18.0

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

* [Qemu-devel] [PULL 15/25] memory: Remove MMIO request_ptr APIs
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (13 preceding siblings ...)
  2018-08-20 10:32 ` [Qemu-devel] [PULL 14/25] hw/ssi/xilinx_spips: Remove unneeded MMIO request_ptr code Peter Maydell
@ 2018-08-20 10:32 ` Peter Maydell
  2018-08-20 10:32 ` [Qemu-devel] [PULL 16/25] hw/misc: Remove mmio_interface device Peter Maydell
                   ` (10 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:32 UTC (permalink / raw)
  To: qemu-devel

Remove the obsolete MMIO request_ptr APIs; they have no
users now.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
Message-id: 20180817114619.22354-3-peter.maydell@linaro.org
---
 include/exec/memory.h |  35 --------------
 memory.c              | 110 ------------------------------------------
 2 files changed, 145 deletions(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 448d41a7529..68636561821 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -141,15 +141,6 @@ struct MemoryRegionOps {
                                     uint64_t data,
                                     unsigned size,
                                     MemTxAttrs attrs);
-    /* Instruction execution pre-callback:
-     * @addr is the address of the access relative to the @mr.
-     * @size is the size of the area returned by the callback.
-     * @offset is the location of the pointer inside @mr.
-     *
-     * Returns a pointer to a location which contains guest code.
-     */
-    void *(*request_ptr)(void *opaque, hwaddr addr, unsigned *size,
-                         unsigned *offset);
 
     enum device_endian endianness;
     /* Guest-visible constraints: */
@@ -1667,32 +1658,6 @@ void memory_global_dirty_log_stop(void);
 void mtree_info(fprintf_function mon_printf, void *f, bool flatview,
                 bool dispatch_tree, bool owner);
 
-/**
- * memory_region_request_mmio_ptr: request a pointer to an mmio
- * MemoryRegion. If it is possible map a RAM MemoryRegion with this pointer.
- * When the device wants to invalidate the pointer it will call
- * memory_region_invalidate_mmio_ptr.
- *
- * @mr: #MemoryRegion to check
- * @addr: address within that region
- *
- * Returns true on success, false otherwise.
- */
-bool memory_region_request_mmio_ptr(MemoryRegion *mr, hwaddr addr);
-
-/**
- * memory_region_invalidate_mmio_ptr: invalidate the pointer to an mmio
- * previously requested.
- * In the end that means that if something wants to execute from this area it
- * will need to request the pointer again.
- *
- * @mr: #MemoryRegion associated to the pointer.
- * @offset: offset within the memory region
- * @size: size of that area.
- */
-void memory_region_invalidate_mmio_ptr(MemoryRegion *mr, hwaddr offset,
-                                       unsigned size);
-
 /**
  * memory_region_dispatch_read: perform a read directly to the specified
  * MemoryRegion.
diff --git a/memory.c b/memory.c
index 2ea16e7bfb0..8b44672c132 100644
--- a/memory.c
+++ b/memory.c
@@ -29,7 +29,6 @@
 #include "exec/ram_addr.h"
 #include "sysemu/kvm.h"
 #include "sysemu/sysemu.h"
-#include "hw/misc/mmio_interface.h"
 #include "hw/qdev-properties.h"
 #include "migration/vmstate.h"
 
@@ -2680,115 +2679,6 @@ void memory_listener_unregister(MemoryListener *listener)
     listener->address_space = NULL;
 }
 
-bool memory_region_request_mmio_ptr(MemoryRegion *mr, hwaddr addr)
-{
-    void *host;
-    unsigned size = 0;
-    unsigned offset = 0;
-    Object *new_interface;
-
-    if (!mr || !mr->ops->request_ptr) {
-        return false;
-    }
-
-    /*
-     * Avoid an update if the request_ptr call
-     * memory_region_invalidate_mmio_ptr which seems to be likely when we use
-     * a cache.
-     */
-    memory_region_transaction_begin();
-
-    host = mr->ops->request_ptr(mr->opaque, addr - mr->addr, &size, &offset);
-
-    if (!host || !size) {
-        memory_region_transaction_commit();
-        return false;
-    }
-
-    new_interface = object_new("mmio_interface");
-    qdev_prop_set_uint64(DEVICE(new_interface), "start", offset);
-    qdev_prop_set_uint64(DEVICE(new_interface), "end", offset + size - 1);
-    qdev_prop_set_bit(DEVICE(new_interface), "ro", true);
-    qdev_prop_set_ptr(DEVICE(new_interface), "host_ptr", host);
-    qdev_prop_set_ptr(DEVICE(new_interface), "subregion", mr);
-    object_property_set_bool(OBJECT(new_interface), true, "realized", NULL);
-
-    memory_region_transaction_commit();
-    return true;
-}
-
-typedef struct MMIOPtrInvalidate {
-    MemoryRegion *mr;
-    hwaddr offset;
-    unsigned size;
-    int busy;
-    int allocated;
-} MMIOPtrInvalidate;
-
-#define MAX_MMIO_INVALIDATE 10
-static MMIOPtrInvalidate mmio_ptr_invalidate_list[MAX_MMIO_INVALIDATE];
-
-static void memory_region_do_invalidate_mmio_ptr(CPUState *cpu,
-                                                 run_on_cpu_data data)
-{
-    MMIOPtrInvalidate *invalidate_data = (MMIOPtrInvalidate *)data.host_ptr;
-    MemoryRegion *mr = invalidate_data->mr;
-    hwaddr offset = invalidate_data->offset;
-    unsigned size = invalidate_data->size;
-    MemoryRegionSection section = memory_region_find(mr, offset, size);
-
-    qemu_mutex_lock_iothread();
-
-    /* Reset dirty so this doesn't happen later. */
-    cpu_physical_memory_test_and_clear_dirty(offset, size, 1);
-
-    if (section.mr != mr) {
-        /* memory_region_find add a ref on section.mr */
-        memory_region_unref(section.mr);
-        if (MMIO_INTERFACE(section.mr->owner)) {
-            /* We found the interface just drop it. */
-            object_property_set_bool(section.mr->owner, false, "realized",
-                                     NULL);
-            object_unref(section.mr->owner);
-            object_unparent(section.mr->owner);
-        }
-    }
-
-    qemu_mutex_unlock_iothread();
-
-    if (invalidate_data->allocated) {
-        g_free(invalidate_data);
-    } else {
-        invalidate_data->busy = 0;
-    }
-}
-
-void memory_region_invalidate_mmio_ptr(MemoryRegion *mr, hwaddr offset,
-                                       unsigned size)
-{
-    size_t i;
-    MMIOPtrInvalidate *invalidate_data = NULL;
-
-    for (i = 0; i < MAX_MMIO_INVALIDATE; i++) {
-        if (atomic_cmpxchg(&(mmio_ptr_invalidate_list[i].busy), 0, 1) == 0) {
-            invalidate_data = &mmio_ptr_invalidate_list[i];
-            break;
-        }
-    }
-
-    if (!invalidate_data) {
-        invalidate_data = g_malloc0(sizeof(MMIOPtrInvalidate));
-        invalidate_data->allocated = 1;
-    }
-
-    invalidate_data->mr = mr;
-    invalidate_data->offset = offset;
-    invalidate_data->size = size;
-
-    async_safe_run_on_cpu(first_cpu, memory_region_do_invalidate_mmio_ptr,
-                          RUN_ON_CPU_HOST_PTR(invalidate_data));
-}
-
 void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
 {
     memory_region_ref(root);
-- 
2.18.0

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

* [Qemu-devel] [PULL 16/25] hw/misc: Remove mmio_interface device
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (14 preceding siblings ...)
  2018-08-20 10:32 ` [Qemu-devel] [PULL 15/25] memory: Remove MMIO request_ptr APIs Peter Maydell
@ 2018-08-20 10:32 ` Peter Maydell
  2018-08-20 10:32 ` [Qemu-devel] [PULL 17/25] hw/timer/m48t59: Move away from old_mmio accessors Peter Maydell
                   ` (9 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:32 UTC (permalink / raw)
  To: qemu-devel

The mmio_interface device was a purely internal artifact
of the implementation of the memory subsystem's request_ptr
APIs. Now that we have removed those APIs, we can remove
the mmio_interface device too.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
Message-id: 20180817114619.22354-4-peter.maydell@linaro.org
---
 hw/misc/Makefile.objs            |   1 -
 include/hw/misc/mmio_interface.h |  49 -----------
 hw/misc/mmio_interface.c         | 135 -------------------------------
 3 files changed, 185 deletions(-)
 delete mode 100644 include/hw/misc/mmio_interface.h
 delete mode 100644 hw/misc/mmio_interface.c

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 51d27b3af1e..22714b08510 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -71,5 +71,4 @@ obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
 obj-$(CONFIG_AUX) += auxbus.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
-obj-y += mmio_interface.o
 obj-$(CONFIG_MSF2) += msf2-sysreg.o
diff --git a/include/hw/misc/mmio_interface.h b/include/hw/misc/mmio_interface.h
deleted file mode 100644
index 90d34fb2286..00000000000
--- a/include/hw/misc/mmio_interface.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * mmio_interface.h
- *
- *  Copyright (C) 2017 : GreenSocs
- *      http://www.greensocs.com/ , email: info@greensocs.com
- *
- *  Developed by :
- *  Frederic Konrad   <fred.konrad@greensocs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option)any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef MMIO_INTERFACE_H
-#define MMIO_INTERFACE_H
-
-#include "exec/memory.h"
-
-#define TYPE_MMIO_INTERFACE "mmio_interface"
-#define MMIO_INTERFACE(obj) OBJECT_CHECK(MMIOInterface, (obj),                 \
-                                         TYPE_MMIO_INTERFACE)
-
-typedef struct MMIOInterface {
-    DeviceState parent_obj;
-
-    MemoryRegion *subregion;
-    MemoryRegion ram_mem;
-    uint64_t start;
-    uint64_t end;
-    bool ro;
-    uint64_t id;
-    void *host_ptr;
-} MMIOInterface;
-
-void mmio_interface_map(MMIOInterface *s);
-void mmio_interface_unmap(MMIOInterface *s);
-
-#endif /* MMIO_INTERFACE_H */
diff --git a/hw/misc/mmio_interface.c b/hw/misc/mmio_interface.c
deleted file mode 100644
index 3b0e2039a36..00000000000
--- a/hw/misc/mmio_interface.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * mmio_interface.c
- *
- *  Copyright (C) 2017 : GreenSocs
- *      http://www.greensocs.com/ , email: info@greensocs.com
- *
- *  Developed by :
- *  Frederic Konrad   <fred.konrad@greensocs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option)any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qemu/log.h"
-#include "trace.h"
-#include "hw/qdev-properties.h"
-#include "hw/misc/mmio_interface.h"
-#include "qapi/error.h"
-
-#ifndef DEBUG_MMIO_INTERFACE
-#define DEBUG_MMIO_INTERFACE 0
-#endif
-
-static uint64_t mmio_interface_counter;
-
-#define DPRINTF(fmt, ...) do {                                                 \
-    if (DEBUG_MMIO_INTERFACE) {                                                \
-        qemu_log("mmio_interface: 0x%" PRIX64 ": " fmt, s->id, ## __VA_ARGS__);\
-    }                                                                          \
-} while (0)
-
-static void mmio_interface_init(Object *obj)
-{
-    MMIOInterface *s = MMIO_INTERFACE(obj);
-
-    if (DEBUG_MMIO_INTERFACE) {
-        s->id = mmio_interface_counter++;
-    }
-
-    DPRINTF("interface created\n");
-    s->host_ptr = 0;
-    s->subregion = 0;
-}
-
-static void mmio_interface_realize(DeviceState *dev, Error **errp)
-{
-    MMIOInterface *s = MMIO_INTERFACE(dev);
-
-    DPRINTF("realize from 0x%" PRIX64 " to 0x%" PRIX64 " map host pointer"
-            " %p\n", s->start, s->end, s->host_ptr);
-
-    if (!s->host_ptr) {
-        error_setg(errp, "host_ptr property must be set");
-        return;
-    }
-
-    if (!s->subregion) {
-        error_setg(errp, "subregion property must be set");
-        return;
-    }
-
-    memory_region_init_ram_ptr(&s->ram_mem, OBJECT(s), "ram",
-                               s->end - s->start + 1, s->host_ptr);
-    memory_region_set_readonly(&s->ram_mem, s->ro);
-    memory_region_add_subregion(s->subregion, s->start, &s->ram_mem);
-}
-
-static void mmio_interface_unrealize(DeviceState *dev, Error **errp)
-{
-    MMIOInterface *s = MMIO_INTERFACE(dev);
-
-    DPRINTF("unrealize from 0x%" PRIX64 " to 0x%" PRIX64 " map host pointer"
-            " %p\n", s->start, s->end, s->host_ptr);
-    memory_region_del_subregion(s->subregion, &s->ram_mem);
-}
-
-static void mmio_interface_finalize(Object *obj)
-{
-    MMIOInterface *s = MMIO_INTERFACE(obj);
-
-    DPRINTF("finalize from 0x%" PRIX64 " to 0x%" PRIX64 " map host pointer"
-            " %p\n", s->start, s->end, s->host_ptr);
-    object_unparent(OBJECT(&s->ram_mem));
-}
-
-static Property mmio_interface_properties[] = {
-    DEFINE_PROP_UINT64("start", MMIOInterface, start, 0),
-    DEFINE_PROP_UINT64("end", MMIOInterface, end, 0),
-    DEFINE_PROP_PTR("host_ptr", MMIOInterface, host_ptr),
-    DEFINE_PROP_BOOL("ro", MMIOInterface, ro, false),
-    DEFINE_PROP_MEMORY_REGION("subregion", MMIOInterface, subregion),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void mmio_interface_class_init(ObjectClass *oc, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(oc);
-
-    dc->realize = mmio_interface_realize;
-    dc->unrealize = mmio_interface_unrealize;
-    dc->props = mmio_interface_properties;
-    /* Reason: pointer property "host_ptr", and this device
-     * is an implementation detail of the memory subsystem,
-     * not intended to be created directly by the user.
-     */
-    dc->user_creatable = false;
-}
-
-static const TypeInfo mmio_interface_info = {
-    .name          = TYPE_MMIO_INTERFACE,
-    .parent        = TYPE_DEVICE,
-    .instance_size = sizeof(MMIOInterface),
-    .instance_init = mmio_interface_init,
-    .instance_finalize = mmio_interface_finalize,
-    .class_init    = mmio_interface_class_init,
-};
-
-static void mmio_interface_register_types(void)
-{
-    type_register_static(&mmio_interface_info);
-}
-
-type_init(mmio_interface_register_types)
-- 
2.18.0

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

* [Qemu-devel] [PULL 17/25] hw/timer/m48t59: Move away from old_mmio accessors
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (15 preceding siblings ...)
  2018-08-20 10:32 ` [Qemu-devel] [PULL 16/25] hw/misc: Remove mmio_interface device Peter Maydell
@ 2018-08-20 10:32 ` Peter Maydell
  2018-08-20 10:32 ` [Qemu-devel] [PULL 18/25] hw/watchdog/cmsdk_apb_watchdog: Implement CMSDK APB watchdog module Peter Maydell
                   ` (8 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:32 UTC (permalink / raw)
  To: qemu-devel

Move the m48t59 device away from using old_mmio MemoryRegionOps
accessors.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-id: 20180802180602.22047-1-peter.maydell@linaro.org
---
 hw/timer/m48t59.c | 59 +++++++++--------------------------------------
 1 file changed, 11 insertions(+), 48 deletions(-)

diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
index f2991762ab0..ca3ed445de7 100644
--- a/hw/timer/m48t59.c
+++ b/hw/timer/m48t59.c
@@ -493,66 +493,29 @@ static uint64_t NVRAM_readb(void *opaque, hwaddr addr, unsigned size)
     return retval;
 }
 
-static void nvram_writeb (void *opaque, hwaddr addr, uint32_t value)
-{
-    M48t59State *NVRAM = opaque;
-
-    m48t59_write(NVRAM, addr, value & 0xff);
-}
-
-static void nvram_writew (void *opaque, hwaddr addr, uint32_t value)
-{
-    M48t59State *NVRAM = opaque;
-
-    m48t59_write(NVRAM, addr, (value >> 8) & 0xff);
-    m48t59_write(NVRAM, addr + 1, value & 0xff);
-}
-
-static void nvram_writel (void *opaque, hwaddr addr, uint32_t value)
-{
-    M48t59State *NVRAM = opaque;
-
-    m48t59_write(NVRAM, addr, (value >> 24) & 0xff);
-    m48t59_write(NVRAM, addr + 1, (value >> 16) & 0xff);
-    m48t59_write(NVRAM, addr + 2, (value >> 8) & 0xff);
-    m48t59_write(NVRAM, addr + 3, value & 0xff);
-}
-
-static uint32_t nvram_readb (void *opaque, hwaddr addr)
+static uint64_t nvram_read(void *opaque, hwaddr addr, unsigned size)
 {
     M48t59State *NVRAM = opaque;
 
     return m48t59_read(NVRAM, addr);
 }
 
-static uint32_t nvram_readw (void *opaque, hwaddr addr)
+static void nvram_write(void *opaque, hwaddr addr, uint64_t value,
+                        unsigned size)
 {
     M48t59State *NVRAM = opaque;
-    uint32_t retval;
 
-    retval = m48t59_read(NVRAM, addr) << 8;
-    retval |= m48t59_read(NVRAM, addr + 1);
-    return retval;
-}
-
-static uint32_t nvram_readl (void *opaque, hwaddr addr)
-{
-    M48t59State *NVRAM = opaque;
-    uint32_t retval;
-
-    retval = m48t59_read(NVRAM, addr) << 24;
-    retval |= m48t59_read(NVRAM, addr + 1) << 16;
-    retval |= m48t59_read(NVRAM, addr + 2) << 8;
-    retval |= m48t59_read(NVRAM, addr + 3);
-    return retval;
+    return m48t59_write(NVRAM, addr, value);
 }
 
 static const MemoryRegionOps nvram_ops = {
-    .old_mmio = {
-        .read = { nvram_readb, nvram_readw, nvram_readl, },
-        .write = { nvram_writeb, nvram_writew, nvram_writel, },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+    .read = nvram_read,
+    .write = nvram_write,
+    .impl.min_access_size = 1,
+    .impl.max_access_size = 1,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 4,
+    .endianness = DEVICE_BIG_ENDIAN,
 };
 
 static const VMStateDescription vmstate_m48t59 = {
-- 
2.18.0

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

* [Qemu-devel] [PULL 18/25] hw/watchdog/cmsdk_apb_watchdog: Implement CMSDK APB watchdog module
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (16 preceding siblings ...)
  2018-08-20 10:32 ` [Qemu-devel] [PULL 17/25] hw/timer/m48t59: Move away from old_mmio accessors Peter Maydell
@ 2018-08-20 10:32 ` Peter Maydell
  2018-08-20 10:32 ` [Qemu-devel] [PULL 19/25] nvic: Expose NMI line Peter Maydell
                   ` (7 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:32 UTC (permalink / raw)
  To: qemu-devel

The Arm Cortex-M System Design Kit includes a simple watchdog module
based on a 32-bit down-counter. Implement this.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 Makefile.objs                            |   1 +
 hw/watchdog/Makefile.objs                |   1 +
 include/hw/watchdog/cmsdk-apb-watchdog.h |  59 ++++
 hw/watchdog/cmsdk-apb-watchdog.c         | 326 +++++++++++++++++++++++
 MAINTAINERS                              |   2 +
 default-configs/arm-softmmu.mak          |   1 +
 hw/watchdog/trace-events                 |   6 +
 7 files changed, 396 insertions(+)
 create mode 100644 include/hw/watchdog/cmsdk-apb-watchdog.h
 create mode 100644 hw/watchdog/cmsdk-apb-watchdog.c
 create mode 100644 hw/watchdog/trace-events

diff --git a/Makefile.objs b/Makefile.objs
index 7a9828da282..ce9c79235e6 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -240,6 +240,7 @@ trace-events-subdirs += hw/tpm
 trace-events-subdirs += hw/usb
 trace-events-subdirs += hw/vfio
 trace-events-subdirs += hw/virtio
+trace-events-subdirs += hw/watchdog
 trace-events-subdirs += hw/xen
 trace-events-subdirs += io
 trace-events-subdirs += linux-user
diff --git a/hw/watchdog/Makefile.objs b/hw/watchdog/Makefile.objs
index 9589bed63a3..3f536d1cad8 100644
--- a/hw/watchdog/Makefile.objs
+++ b/hw/watchdog/Makefile.objs
@@ -1,4 +1,5 @@
 common-obj-y += watchdog.o
+common-obj-$(CONFIG_CMSDK_APB_WATCHDOG) += cmsdk-apb-watchdog.o
 common-obj-$(CONFIG_WDT_IB6300ESB) += wdt_i6300esb.o
 common-obj-$(CONFIG_WDT_IB700) += wdt_ib700.o
 common-obj-$(CONFIG_WDT_DIAG288) += wdt_diag288.o
diff --git a/include/hw/watchdog/cmsdk-apb-watchdog.h b/include/hw/watchdog/cmsdk-apb-watchdog.h
new file mode 100644
index 00000000000..ab8b5987a19
--- /dev/null
+++ b/include/hw/watchdog/cmsdk-apb-watchdog.h
@@ -0,0 +1,59 @@
+/*
+ * ARM CMSDK APB watchdog emulation
+ *
+ * Copyright (c) 2018 Linaro Limited
+ * Written by Peter Maydell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 or
+ *  (at your option) any later version.
+ */
+
+/*
+ * This is a model of the "APB watchdog" which is part of the Cortex-M
+ * System Design Kit (CMSDK) and documented in the Cortex-M System
+ * Design Kit Technical Reference Manual (ARM DDI0479C):
+ * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
+ *
+ * QEMU interface:
+ *  + QOM property "wdogclk-frq": frequency at which the watchdog is clocked
+ *  + sysbus MMIO region 0: the register bank
+ *  + sysbus IRQ 0: watchdog interrupt
+ *
+ * In real hardware the watchdog's reset output is just a GPIO line
+ * which can then be masked by the board or treated as a simple interrupt.
+ * (For instance the IoTKit does this with the non-secure watchdog, so that
+ * secure code can control whether non-secure code can perform a system
+ * reset via its watchdog.) In QEMU, we just wire up the watchdog reset
+ * to watchdog_perform_action(), at least for the moment.
+ */
+
+#ifndef CMSDK_APB_WATCHDOG_H
+#define CMSDK_APB_WATCHDOG_H
+
+#include "hw/sysbus.h"
+#include "hw/ptimer.h"
+
+#define TYPE_CMSDK_APB_WATCHDOG "cmsdk-apb-watchdog"
+#define CMSDK_APB_WATCHDOG(obj) OBJECT_CHECK(CMSDKAPBWatchdog, (obj), \
+                                              TYPE_CMSDK_APB_WATCHDOG)
+
+typedef struct CMSDKAPBWatchdog {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    MemoryRegion iomem;
+    qemu_irq wdogint;
+    uint32_t wdogclk_frq;
+    struct ptimer_state *timer;
+
+    uint32_t control;
+    uint32_t intstatus;
+    uint32_t lock;
+    uint32_t itcr;
+    uint32_t itop;
+    uint32_t resetstatus;
+} CMSDKAPBWatchdog;
+
+#endif
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
new file mode 100644
index 00000000000..eb79a73fa6c
--- /dev/null
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
@@ -0,0 +1,326 @@
+/*
+ * ARM CMSDK APB watchdog emulation
+ *
+ * Copyright (c) 2018 Linaro Limited
+ * Written by Peter Maydell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 or
+ *  (at your option) any later version.
+ */
+
+/*
+ * This is a model of the "APB watchdog" which is part of the Cortex-M
+ * System Design Kit (CMSDK) and documented in the Cortex-M System
+ * Design Kit Technical Reference Manual (ARM DDI0479C):
+ * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "trace.h"
+#include "qapi/error.h"
+#include "qemu/main-loop.h"
+#include "sysemu/watchdog.h"
+#include "hw/sysbus.h"
+#include "hw/registerfields.h"
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
+
+REG32(WDOGLOAD, 0x0)
+REG32(WDOGVALUE, 0x4)
+REG32(WDOGCONTROL, 0x8)
+    FIELD(WDOGCONTROL, INTEN, 0, 1)
+    FIELD(WDOGCONTROL, RESEN, 1, 1)
+#define R_WDOGCONTROL_VALID_MASK (R_WDOGCONTROL_INTEN_MASK | \
+                                  R_WDOGCONTROL_RESEN_MASK)
+REG32(WDOGINTCLR, 0xc)
+REG32(WDOGRIS, 0x10)
+    FIELD(WDOGRIS, INT, 0, 1)
+REG32(WDOGMIS, 0x14)
+REG32(WDOGLOCK, 0xc00)
+#define WDOG_UNLOCK_VALUE 0x1ACCE551
+REG32(WDOGITCR, 0xf00)
+    FIELD(WDOGITCR, ENABLE, 0, 1)
+#define R_WDOGITCR_VALID_MASK R_WDOGITCR_ENABLE_MASK
+REG32(WDOGITOP, 0xf04)
+    FIELD(WDOGITOP, WDOGRES, 0, 1)
+    FIELD(WDOGITOP, WDOGINT, 1, 1)
+#define R_WDOGITOP_VALID_MASK (R_WDOGITOP_WDOGRES_MASK | \
+                               R_WDOGITOP_WDOGINT_MASK)
+REG32(PID4, 0xfd0)
+REG32(PID5, 0xfd4)
+REG32(PID6, 0xfd8)
+REG32(PID7, 0xfdc)
+REG32(PID0, 0xfe0)
+REG32(PID1, 0xfe4)
+REG32(PID2, 0xfe8)
+REG32(PID3, 0xfec)
+REG32(CID0, 0xff0)
+REG32(CID1, 0xff4)
+REG32(CID2, 0xff8)
+REG32(CID3, 0xffc)
+
+/* PID/CID values */
+static const int watchdog_id[] = {
+    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
+    0x24, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
+    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
+};
+
+static bool cmsdk_apb_watchdog_intstatus(CMSDKAPBWatchdog *s)
+{
+    /* Return masked interrupt status */
+    return s->intstatus && (s->control & R_WDOGCONTROL_INTEN_MASK);
+}
+
+static bool cmsdk_apb_watchdog_resetstatus(CMSDKAPBWatchdog *s)
+{
+    /* Return masked reset status */
+    return s->resetstatus && (s->control & R_WDOGCONTROL_RESEN_MASK);
+}
+
+static void cmsdk_apb_watchdog_update(CMSDKAPBWatchdog *s)
+{
+    bool wdogint;
+    bool wdogres;
+
+    if (s->itcr) {
+        wdogint = s->itop & R_WDOGITOP_WDOGINT_MASK;
+        wdogres = s->itop & R_WDOGITOP_WDOGRES_MASK;
+    } else {
+        wdogint = cmsdk_apb_watchdog_intstatus(s);
+        wdogres = cmsdk_apb_watchdog_resetstatus(s);
+    }
+
+    qemu_set_irq(s->wdogint, wdogint);
+    if (wdogres) {
+        watchdog_perform_action();
+    }
+}
+
+static uint64_t cmsdk_apb_watchdog_read(void *opaque, hwaddr offset,
+                                        unsigned size)
+{
+    CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
+    uint64_t r;
+
+    switch (offset) {
+    case A_WDOGLOAD:
+        r = ptimer_get_limit(s->timer);
+        break;
+    case A_WDOGVALUE:
+        r = ptimer_get_count(s->timer);
+        break;
+    case A_WDOGCONTROL:
+        r = s->control;
+        break;
+    case A_WDOGRIS:
+        r = s->intstatus;
+        break;
+    case A_WDOGMIS:
+        r = cmsdk_apb_watchdog_intstatus(s);
+        break;
+    case A_WDOGLOCK:
+        r = s->lock;
+        break;
+    case A_WDOGITCR:
+        r = s->itcr;
+        break;
+    case A_PID4 ... A_CID3:
+        r = watchdog_id[(offset - A_PID4) / 4];
+        break;
+    case A_WDOGINTCLR:
+    case A_WDOGITOP:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "CMSDK APB watchdog read: read of WO offset %x\n",
+                      (int)offset);
+        r = 0;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "CMSDK APB watchdog read: bad offset %x\n", (int)offset);
+        r = 0;
+        break;
+    }
+    trace_cmsdk_apb_watchdog_read(offset, r, size);
+    return r;
+}
+
+static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
+                                     uint64_t value, unsigned size)
+{
+    CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
+
+    trace_cmsdk_apb_watchdog_write(offset, value, size);
+
+    if (s->lock && offset != A_WDOGLOCK) {
+        /* Write access is disabled via WDOGLOCK */
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "CMSDK APB watchdog write: write to locked watchdog\n");
+        return;
+    }
+
+    switch (offset) {
+    case A_WDOGLOAD:
+        /*
+         * Reset the load value and the current count, and make sure
+         * we're counting.
+         */
+        ptimer_set_limit(s->timer, value, 1);
+        ptimer_run(s->timer, 0);
+        break;
+    case A_WDOGCONTROL:
+        s->control = value & R_WDOGCONTROL_VALID_MASK;
+        cmsdk_apb_watchdog_update(s);
+        break;
+    case A_WDOGINTCLR:
+        s->intstatus = 0;
+        ptimer_set_count(s->timer, ptimer_get_limit(s->timer));
+        cmsdk_apb_watchdog_update(s);
+        break;
+    case A_WDOGLOCK:
+        s->lock = (value != WDOG_UNLOCK_VALUE);
+        break;
+    case A_WDOGITCR:
+        s->itcr = value & R_WDOGITCR_VALID_MASK;
+        cmsdk_apb_watchdog_update(s);
+        break;
+    case A_WDOGITOP:
+        s->itop = value & R_WDOGITOP_VALID_MASK;
+        cmsdk_apb_watchdog_update(s);
+        break;
+    case A_WDOGVALUE:
+    case A_WDOGRIS:
+    case A_WDOGMIS:
+    case A_PID4 ... A_CID3:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "CMSDK APB watchdog write: write to RO offset 0x%x\n",
+                      (int)offset);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "CMSDK APB watchdog write: bad offset 0x%x\n",
+                      (int)offset);
+        break;
+    }
+}
+
+static const MemoryRegionOps cmsdk_apb_watchdog_ops = {
+    .read = cmsdk_apb_watchdog_read,
+    .write = cmsdk_apb_watchdog_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    /* byte/halfword accesses are just zero-padded on reads and writes */
+    .impl.min_access_size = 4,
+    .impl.max_access_size = 4,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 4,
+};
+
+static void cmsdk_apb_watchdog_tick(void *opaque)
+{
+    CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
+
+    if (!s->intstatus) {
+        /* Count expired for the first time: raise interrupt */
+        s->intstatus = R_WDOGRIS_INT_MASK;
+    } else {
+        /* Count expired for the second time: raise reset and stop clock */
+        s->resetstatus = 1;
+        ptimer_stop(s->timer);
+    }
+    cmsdk_apb_watchdog_update(s);
+}
+
+static void cmsdk_apb_watchdog_reset(DeviceState *dev)
+{
+    CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(dev);
+
+    trace_cmsdk_apb_watchdog_reset();
+    s->control = 0;
+    s->intstatus = 0;
+    s->lock = 0;
+    s->itcr = 0;
+    s->itop = 0;
+    s->resetstatus = 0;
+    /* Set the limit and the count */
+    ptimer_set_limit(s->timer, 0xffffffff, 1);
+    ptimer_run(s->timer, 0);
+}
+
+static void cmsdk_apb_watchdog_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(obj);
+
+    memory_region_init_io(&s->iomem, obj, &cmsdk_apb_watchdog_ops,
+                          s, "cmsdk-apb-watchdog", 0x1000);
+    sysbus_init_mmio(sbd, &s->iomem);
+    sysbus_init_irq(sbd, &s->wdogint);
+}
+
+static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
+{
+    CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(dev);
+    QEMUBH *bh;
+
+    if (s->wdogclk_frq == 0) {
+        error_setg(errp,
+                   "CMSDK APB watchdog: wdogclk-frq property must be set");
+        return;
+    }
+
+    bh = qemu_bh_new(cmsdk_apb_watchdog_tick, s);
+    s->timer = ptimer_init(bh,
+                           PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD |
+                           PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT |
+                           PTIMER_POLICY_NO_IMMEDIATE_RELOAD |
+                           PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
+
+    ptimer_set_freq(s->timer, s->wdogclk_frq);
+}
+
+static const VMStateDescription cmsdk_apb_watchdog_vmstate = {
+    .name = "cmsdk-apb-watchdog",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_PTIMER(timer, CMSDKAPBWatchdog),
+        VMSTATE_UINT32(control, CMSDKAPBWatchdog),
+        VMSTATE_UINT32(intstatus, CMSDKAPBWatchdog),
+        VMSTATE_UINT32(lock, CMSDKAPBWatchdog),
+        VMSTATE_UINT32(itcr, CMSDKAPBWatchdog),
+        VMSTATE_UINT32(itop, CMSDKAPBWatchdog),
+        VMSTATE_UINT32(resetstatus, CMSDKAPBWatchdog),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static Property cmsdk_apb_watchdog_properties[] = {
+    DEFINE_PROP_UINT32("wdogclk-frq", CMSDKAPBWatchdog, wdogclk_frq, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void cmsdk_apb_watchdog_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = cmsdk_apb_watchdog_realize;
+    dc->vmsd = &cmsdk_apb_watchdog_vmstate;
+    dc->reset = cmsdk_apb_watchdog_reset;
+    dc->props = cmsdk_apb_watchdog_properties;
+}
+
+static const TypeInfo cmsdk_apb_watchdog_info = {
+    .name = TYPE_CMSDK_APB_WATCHDOG,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(CMSDKAPBWatchdog),
+    .instance_init = cmsdk_apb_watchdog_init,
+    .class_init = cmsdk_apb_watchdog_class_init,
+};
+
+static void cmsdk_apb_watchdog_register_types(void)
+{
+    type_register_static(&cmsdk_apb_watchdog_info);
+}
+
+type_init(cmsdk_apb_watchdog_register_types);
diff --git a/MAINTAINERS b/MAINTAINERS
index 70651f7da0f..6698a7e0f81 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -456,6 +456,8 @@ F: hw/timer/cmsdk-apb-timer.c
 F: include/hw/timer/cmsdk-apb-timer.h
 F: hw/char/cmsdk-apb-uart.c
 F: include/hw/char/cmsdk-apb-uart.h
+F: hw/watchdog/cmsdk-apb-watchdog.c
+F: include/hw/watchdog/cmsdk-apb-watchdog.h
 F: hw/misc/tz-ppc.c
 F: include/hw/misc/tz-ppc.h
 F: hw/misc/tz-mpc.c
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 311584fd74e..a92bc34fb24 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -104,6 +104,7 @@ CONFIG_STM32F205_SOC=y
 
 CONFIG_CMSDK_APB_TIMER=y
 CONFIG_CMSDK_APB_UART=y
+CONFIG_CMSDK_APB_WATCHDOG=y
 
 CONFIG_MPS2_FPGAIO=y
 CONFIG_MPS2_SCC=y
diff --git a/hw/watchdog/trace-events b/hw/watchdog/trace-events
new file mode 100644
index 00000000000..fee95847df0
--- /dev/null
+++ b/hw/watchdog/trace-events
@@ -0,0 +1,6 @@
+# See docs/devel/tracing.txt for syntax documentation.
+
+# hw/char/cmsdk_apb_watchdog.c
+cmsdk_apb_watchdog_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+cmsdk_apb_watchdog_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+cmsdk_apb_watchdog_reset(void) "CMSDK APB watchdog: reset"
-- 
2.18.0

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

* [Qemu-devel] [PULL 19/25] nvic: Expose NMI line
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (17 preceding siblings ...)
  2018-08-20 10:32 ` [Qemu-devel] [PULL 18/25] hw/watchdog/cmsdk_apb_watchdog: Implement CMSDK APB watchdog module Peter Maydell
@ 2018-08-20 10:32 ` Peter Maydell
  2018-08-20 10:32 ` [Qemu-devel] [PULL 20/25] hw/dma/pl080: Allow use as embedded-struct device Peter Maydell
                   ` (6 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:32 UTC (permalink / raw)
  To: qemu-devel

On real v7M hardware, the NMI line is an externally visible signal
that an SoC or board can toggle to assert an NMI. Expose it in
our QEMU NVIC and armv7m container objects so that a board model
can wire it up if it needs to.

In particular, the MPS2 watchdog is wired to NMI.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/arm/armv7m.c       |  1 +
 hw/intc/armv7m_nvic.c | 19 +++++++++++++++++++
 hw/intc/trace-events  |  1 +
 3 files changed, 21 insertions(+)

diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 878613994d2..4bf9131b81e 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -202,6 +202,7 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
      */
     qdev_pass_gpios(DEVICE(&s->nvic), dev, NULL);
     qdev_pass_gpios(DEVICE(&s->nvic), dev, "SYSRESETREQ");
+    qdev_pass_gpios(DEVICE(&s->nvic), dev, "NMI");
 
     /* Wire the NVIC up to the CPU */
     sbd = SYS_BUS_DEVICE(&s->nvic);
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 351b69ab40b..0d816fdd2cc 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -774,6 +774,24 @@ static void set_irq_level(void *opaque, int n, int level)
     }
 }
 
+/* callback when external NMI line is changed */
+static void nvic_nmi_trigger(void *opaque, int n, int level)
+{
+    NVICState *s = opaque;
+
+    trace_nvic_set_nmi_level(level);
+
+    /*
+     * The architecture doesn't specify whether NMI should share
+     * the normal-interrupt behaviour of being resampled on
+     * exception handler return. We choose not to, so just
+     * set NMI pending here and don't track the current level.
+     */
+    if (level) {
+        armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false);
+    }
+}
+
 static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
 {
     ARMCPU *cpu = s->cpu;
@@ -2382,6 +2400,7 @@ static void armv7m_nvic_instance_init(Object *obj)
     qdev_init_gpio_out_named(dev, &nvic->sysresetreq, "SYSRESETREQ", 1);
     qdev_init_gpio_in_named(dev, nvic_systick_trigger, "systick-trigger",
                             M_REG_NUM_BANKS);
+    qdev_init_gpio_in_named(dev, nvic_nmi_trigger, "NMI", 1);
 }
 
 static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 81c7c399f7d..7769869a135 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -192,6 +192,7 @@ nvic_acknowledge_irq(int irq, int prio) "NVIC acknowledge IRQ: %d now active (pr
 nvic_get_pending_irq_info(int irq, bool secure) "NVIC next IRQ %d: targets_secure: %d"
 nvic_complete_irq(int irq, bool secure) "NVIC complete IRQ %d (secure %d)"
 nvic_set_irq_level(int irq, int level) "NVIC external irq %d level set to %d"
+nvic_set_nmi_level(int level) "NVIC external NMI level set to %d"
 nvic_sysreg_read(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
 nvic_sysreg_write(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
 
-- 
2.18.0

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

* [Qemu-devel] [PULL 20/25] hw/dma/pl080: Allow use as embedded-struct device
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (18 preceding siblings ...)
  2018-08-20 10:32 ` [Qemu-devel] [PULL 19/25] nvic: Expose NMI line Peter Maydell
@ 2018-08-20 10:32 ` Peter Maydell
  2018-08-20 10:32 ` [Qemu-devel] [PULL 21/25] hw/dma/pl080: Support all three interrupt lines Peter Maydell
                   ` (5 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:32 UTC (permalink / raw)
  To: qemu-devel

Create a new include file for the pl081's device struct,
type macros, etc, so that it can be instantiated using
the "embedded struct" coding style.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 include/hw/dma/pl080.h | 62 ++++++++++++++++++++++++++++++++++++++++++
 hw/dma/pl080.c         | 34 ++---------------------
 MAINTAINERS            |  1 +
 3 files changed, 65 insertions(+), 32 deletions(-)
 create mode 100644 include/hw/dma/pl080.h

diff --git a/include/hw/dma/pl080.h b/include/hw/dma/pl080.h
new file mode 100644
index 00000000000..7deb46c8578
--- /dev/null
+++ b/include/hw/dma/pl080.h
@@ -0,0 +1,62 @@
+/*
+ * ARM PrimeCell PL080/PL081 DMA controller
+ *
+ * Copyright (c) 2006 CodeSourcery.
+ * Copyright (c) 2018 Linaro Limited
+ * Written by Paul Brook, Peter Maydell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 or
+ * (at your option) any later version.
+ */
+
+/* This is a model of the Arm PrimeCell PL080/PL081 DMA controller:
+ * The PL080 TRM is:
+ * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0196g/DDI0196.pdf
+ * and the PL081 TRM is:
+ * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0218e/DDI0218.pdf
+ *
+ * QEMU interface:
+ * + sysbus IRQ: DMACINTR combined interrupt line
+ * + sysbus MMIO region 0: MemoryRegion for the device's registers
+ */
+
+#ifndef HW_DMA_PL080_H
+#define HW_DMA_PL080_H
+
+#include "hw/sysbus.h"
+
+#define PL080_MAX_CHANNELS 8
+
+typedef struct {
+    uint32_t src;
+    uint32_t dest;
+    uint32_t lli;
+    uint32_t ctrl;
+    uint32_t conf;
+} pl080_channel;
+
+#define TYPE_PL080 "pl080"
+#define TYPE_PL081 "pl081"
+#define PL080(obj) OBJECT_CHECK(PL080State, (obj), TYPE_PL080)
+
+typedef struct PL080State {
+    SysBusDevice parent_obj;
+
+    MemoryRegion iomem;
+    uint8_t tc_int;
+    uint8_t tc_mask;
+    uint8_t err_int;
+    uint8_t err_mask;
+    uint32_t conf;
+    uint32_t sync;
+    uint32_t req_single;
+    uint32_t req_burst;
+    pl080_channel chan[PL080_MAX_CHANNELS];
+    int nchannels;
+    /* Flag to avoid recursive DMA invocations.  */
+    int running;
+    qemu_irq irq;
+} PL080State;
+
+#endif
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
index 7724c93b8f2..0f79c2d8a6c 100644
--- a/hw/dma/pl080.c
+++ b/hw/dma/pl080.c
@@ -11,8 +11,8 @@
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
 #include "qemu/log.h"
+#include "hw/dma/pl080.h"
 
-#define PL080_MAX_CHANNELS 8
 #define PL080_CONF_E    0x1
 #define PL080_CONF_M1   0x2
 #define PL080_CONF_M2   0x4
@@ -30,36 +30,6 @@
 #define PL080_CCTRL_D   0x02000000
 #define PL080_CCTRL_S   0x01000000
 
-typedef struct {
-    uint32_t src;
-    uint32_t dest;
-    uint32_t lli;
-    uint32_t ctrl;
-    uint32_t conf;
-} pl080_channel;
-
-#define TYPE_PL080 "pl080"
-#define PL080(obj) OBJECT_CHECK(PL080State, (obj), TYPE_PL080)
-
-typedef struct PL080State {
-    SysBusDevice parent_obj;
-
-    MemoryRegion iomem;
-    uint8_t tc_int;
-    uint8_t tc_mask;
-    uint8_t err_int;
-    uint8_t err_mask;
-    uint32_t conf;
-    uint32_t sync;
-    uint32_t req_single;
-    uint32_t req_burst;
-    pl080_channel chan[PL080_MAX_CHANNELS];
-    int nchannels;
-    /* Flag to avoid recursive DMA invocations.  */
-    int running;
-    qemu_irq irq;
-} PL080State;
-
 static const VMStateDescription vmstate_pl080_channel = {
     .name = "pl080_channel",
     .version_id = 1,
@@ -408,7 +378,7 @@ static const TypeInfo pl080_info = {
 };
 
 static const TypeInfo pl081_info = {
-    .name          = "pl081",
+    .name          = TYPE_PL081,
     .parent        = TYPE_PL080,
     .instance_init = pl081_init,
 };
diff --git a/MAINTAINERS b/MAINTAINERS
index 6698a7e0f81..6902a568f44 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -445,6 +445,7 @@ F: hw/char/pl011.c
 F: include/hw/char/pl011.h
 F: hw/display/pl110*
 F: hw/dma/pl080.c
+F: include/hw/dma/pl080.h
 F: hw/dma/pl330.c
 F: hw/gpio/pl061.c
 F: hw/input/pl050.c
-- 
2.18.0

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

* [Qemu-devel] [PULL 21/25] hw/dma/pl080: Support all three interrupt lines
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (19 preceding siblings ...)
  2018-08-20 10:32 ` [Qemu-devel] [PULL 20/25] hw/dma/pl080: Allow use as embedded-struct device Peter Maydell
@ 2018-08-20 10:32 ` Peter Maydell
  2018-08-20 10:32 ` [Qemu-devel] [PULL 22/25] hw/dma/pl080: Don't use CPU address space for DMA accesses Peter Maydell
                   ` (4 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:32 UTC (permalink / raw)
  To: qemu-devel

The PL080 and PL081 have three outgoing interrupt lines:
 * DMACINTERR signals DMA errors
 * DMACINTTC is the DMA count interrupt
 * DMACINTR is a combined interrupt, the logical OR of the other two

We currently only implement DMACINTR, because that's all the
realview and versatile boards needed, but the instances of the
PL081 in the MPS2 firmware images use all three interrupt lines.
Implement the missing DMACINTERR and DMACINTTC.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 include/hw/dma/pl080.h |  6 +++++-
 hw/dma/pl080.c         | 13 ++++++++-----
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/include/hw/dma/pl080.h b/include/hw/dma/pl080.h
index 7deb46c8578..7c6a4184833 100644
--- a/include/hw/dma/pl080.h
+++ b/include/hw/dma/pl080.h
@@ -17,7 +17,9 @@
  * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0218e/DDI0218.pdf
  *
  * QEMU interface:
- * + sysbus IRQ: DMACINTR combined interrupt line
+ * + sysbus IRQ 0: DMACINTR combined interrupt line
+ * + sysbus IRQ 1: DMACINTERR error interrupt request
+ * + sysbus IRQ 2: DMACINTTC count interrupt request
  * + sysbus MMIO region 0: MemoryRegion for the device's registers
  */
 
@@ -57,6 +59,8 @@ typedef struct PL080State {
     /* Flag to avoid recursive DMA invocations.  */
     int running;
     qemu_irq irq;
+    qemu_irq interr;
+    qemu_irq inttc;
 } PL080State;
 
 #endif
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
index 0f79c2d8a6c..301030dd118 100644
--- a/hw/dma/pl080.c
+++ b/hw/dma/pl080.c
@@ -75,11 +75,12 @@ static const unsigned char pl081_id[] =
 
 static void pl080_update(PL080State *s)
 {
-    if ((s->tc_int & s->tc_mask)
-            || (s->err_int & s->err_mask))
-        qemu_irq_raise(s->irq);
-    else
-        qemu_irq_lower(s->irq);
+    bool tclevel = (s->tc_int & s->tc_mask);
+    bool errlevel = (s->err_int & s->err_mask);
+
+    qemu_set_irq(s->interr, errlevel);
+    qemu_set_irq(s->inttc, tclevel);
+    qemu_set_irq(s->irq, errlevel || tclevel);
 }
 
 static void pl080_run(PL080State *s)
@@ -352,6 +353,8 @@ static void pl080_init(Object *obj)
     memory_region_init_io(&s->iomem, OBJECT(s), &pl080_ops, s, "pl080", 0x1000);
     sysbus_init_mmio(sbd, &s->iomem);
     sysbus_init_irq(sbd, &s->irq);
+    sysbus_init_irq(sbd, &s->interr);
+    sysbus_init_irq(sbd, &s->inttc);
     s->nchannels = 8;
 }
 
-- 
2.18.0

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

* [Qemu-devel] [PULL 22/25] hw/dma/pl080: Don't use CPU address space for DMA accesses
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (20 preceding siblings ...)
  2018-08-20 10:32 ` [Qemu-devel] [PULL 21/25] hw/dma/pl080: Support all three interrupt lines Peter Maydell
@ 2018-08-20 10:32 ` Peter Maydell
  2018-08-20 10:32 ` [Qemu-devel] [PULL 23/25] hw/dma/pl080: Provide device reset function Peter Maydell
                   ` (3 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:32 UTC (permalink / raw)
  To: qemu-devel

Currently our PL080/PL081 model uses a combination of the CPU's
address space (via cpu_physical_memory_{read,write}()) and the
system address space for performing DMA accesses.

For the PL081s in the MPS FPGA images, their DMA accesses
must go via Master Security Controllers. Switch the
PL080/PL081 model to take a MemoryRegion property which
defines its downstream for making DMA accesses.

Since the PL08x are only used in two board models, we
make provision of the 'downstream' link mandatory and convert
both users at once, rather than having it be optional with
a default to the system address space.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 include/hw/dma/pl080.h |  5 +++++
 hw/arm/realview.c      |  8 +++++++-
 hw/arm/versatilepb.c   |  9 ++++++++-
 hw/dma/pl080.c         | 35 +++++++++++++++++++++++++++++------
 4 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/include/hw/dma/pl080.h b/include/hw/dma/pl080.h
index 7c6a4184833..9d4b3df143f 100644
--- a/include/hw/dma/pl080.h
+++ b/include/hw/dma/pl080.h
@@ -21,6 +21,8 @@
  * + sysbus IRQ 1: DMACINTERR error interrupt request
  * + sysbus IRQ 2: DMACINTTC count interrupt request
  * + sysbus MMIO region 0: MemoryRegion for the device's registers
+ * + QOM property "downstream": MemoryRegion defining where DMA
+ *   bus master transactions are made
  */
 
 #ifndef HW_DMA_PL080_H
@@ -61,6 +63,9 @@ typedef struct PL080State {
     qemu_irq irq;
     qemu_irq interr;
     qemu_irq inttc;
+
+    MemoryRegion *downstream;
+    AddressSpace downstream_as;
 } PL080State;
 
 #endif
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index cd585d94694..ab8c14fde38 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -201,7 +201,13 @@ static void realview_init(MachineState *machine,
     pl011_create(0x1000c000, pic[15], serial_hd(3));
 
     /* DMA controller is optional, apparently.  */
-    sysbus_create_simple("pl081", 0x10030000, pic[24]);
+    dev = qdev_create(NULL, "pl081");
+    object_property_set_link(OBJECT(dev), OBJECT(sysmem), "downstream",
+                             &error_fatal);
+    qdev_init_nofail(dev);
+    busdev = SYS_BUS_DEVICE(dev);
+    sysbus_mmio_map(busdev, 0, 0x10030000);
+    sysbus_connect_irq(busdev, 0, pic[24]);
 
     sysbus_create_simple("sp804", 0x10011000, pic[4]);
     sysbus_create_simple("sp804", 0x10012000, pic[5]);
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index a5a06b6d408..8b748570596 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -287,7 +287,14 @@ static void versatile_init(MachineState *machine, int board_id)
     pl011_create(0x101f3000, pic[14], serial_hd(2));
     pl011_create(0x10009000, sic[6], serial_hd(3));
 
-    sysbus_create_simple("pl080", 0x10130000, pic[17]);
+    dev = qdev_create(NULL, "pl080");
+    object_property_set_link(OBJECT(dev), OBJECT(sysmem), "downstream",
+                             &error_fatal);
+    qdev_init_nofail(dev);
+    busdev = SYS_BUS_DEVICE(dev);
+    sysbus_mmio_map(busdev, 0, 0x10130000);
+    sysbus_connect_irq(busdev, 0, pic[17]);
+
     sysbus_create_simple("sp804", 0x101e2000, pic[4]);
     sysbus_create_simple("sp804", 0x101e3000, pic[5]);
 
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
index 301030dd118..8f9f3e08d9a 100644
--- a/hw/dma/pl080.c
+++ b/hw/dma/pl080.c
@@ -12,6 +12,7 @@
 #include "exec/address-spaces.h"
 #include "qemu/log.h"
 #include "hw/dma/pl080.h"
+#include "qapi/error.h"
 
 #define PL080_CONF_E    0x1
 #define PL080_CONF_M1   0x2
@@ -161,14 +162,16 @@ again:
             swidth = 1 << ((ch->ctrl >> 18) & 7);
             dwidth = 1 << ((ch->ctrl >> 21) & 7);
             for (n = 0; n < dwidth; n+= swidth) {
-                cpu_physical_memory_read(ch->src, buff + n, swidth);
+                address_space_read(&s->downstream_as, ch->src,
+                                   MEMTXATTRS_UNSPECIFIED, buff + n, swidth);
                 if (ch->ctrl & PL080_CCTRL_SI)
                     ch->src += swidth;
             }
             xsize = (dwidth < swidth) ? swidth : dwidth;
             /* ??? This may pad the value incorrectly for dwidth < 32.  */
             for (n = 0; n < xsize; n += dwidth) {
-                cpu_physical_memory_write(ch->dest + n, buff + n, dwidth);
+                address_space_write(&s->downstream_as, ch->dest + n,
+                                    MEMTXATTRS_UNSPECIFIED, buff + n, dwidth);
                 if (ch->ctrl & PL080_CCTRL_DI)
                     ch->dest += swidth;
             }
@@ -178,19 +181,19 @@ again:
             if (size == 0) {
                 /* Transfer complete.  */
                 if (ch->lli) {
-                    ch->src = address_space_ldl_le(&address_space_memory,
+                    ch->src = address_space_ldl_le(&s->downstream_as,
                                                    ch->lli,
                                                    MEMTXATTRS_UNSPECIFIED,
                                                    NULL);
-                    ch->dest = address_space_ldl_le(&address_space_memory,
+                    ch->dest = address_space_ldl_le(&s->downstream_as,
                                                     ch->lli + 4,
                                                     MEMTXATTRS_UNSPECIFIED,
                                                     NULL);
-                    ch->ctrl = address_space_ldl_le(&address_space_memory,
+                    ch->ctrl = address_space_ldl_le(&s->downstream_as,
                                                     ch->lli + 12,
                                                     MEMTXATTRS_UNSPECIFIED,
                                                     NULL);
-                    ch->lli = address_space_ldl_le(&address_space_memory,
+                    ch->lli = address_space_ldl_le(&s->downstream_as,
                                                    ch->lli + 8,
                                                    MEMTXATTRS_UNSPECIFIED,
                                                    NULL);
@@ -358,6 +361,18 @@ static void pl080_init(Object *obj)
     s->nchannels = 8;
 }
 
+static void pl080_realize(DeviceState *dev, Error **errp)
+{
+    PL080State *s = PL080(dev);
+
+    if (!s->downstream) {
+        error_setg(errp, "PL080 'downstream' link not set");
+        return;
+    }
+
+    address_space_init(&s->downstream_as, s->downstream, "pl080-downstream");
+}
+
 static void pl081_init(Object *obj)
 {
     PL080State *s = PL080(obj);
@@ -365,11 +380,19 @@ static void pl081_init(Object *obj)
     s->nchannels = 2;
 }
 
+static Property pl080_properties[] = {
+    DEFINE_PROP_LINK("downstream", PL080State, downstream,
+                     TYPE_MEMORY_REGION, MemoryRegion *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void pl080_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
 
     dc->vmsd = &vmstate_pl080;
+    dc->realize = pl080_realize;
+    dc->props = pl080_properties;
 }
 
 static const TypeInfo pl080_info = {
-- 
2.18.0

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

* [Qemu-devel] [PULL 23/25] hw/dma/pl080: Provide device reset function
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (21 preceding siblings ...)
  2018-08-20 10:32 ` [Qemu-devel] [PULL 22/25] hw/dma/pl080: Don't use CPU address space for DMA accesses Peter Maydell
@ 2018-08-20 10:32 ` Peter Maydell
  2018-08-20 10:32 ` [Qemu-devel] [PULL 24/25] hw/dma/pl080: Correct bug in register address decode logic Peter Maydell
                   ` (2 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:32 UTC (permalink / raw)
  To: qemu-devel

The PL080/PL081 model is missing a reset function; implement it.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/dma/pl080.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
index 8f9f3e08d9a..a7aacad74f0 100644
--- a/hw/dma/pl080.c
+++ b/hw/dma/pl080.c
@@ -348,6 +348,30 @@ static const MemoryRegionOps pl080_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
+static void pl080_reset(DeviceState *dev)
+{
+    PL080State *s = PL080(dev);
+    int i;
+
+    s->tc_int = 0;
+    s->tc_mask = 0;
+    s->err_int = 0;
+    s->err_mask = 0;
+    s->conf = 0;
+    s->sync = 0;
+    s->req_single = 0;
+    s->req_burst = 0;
+    s->running = 0;
+
+    for (i = 0; i < s->nchannels; i++) {
+        s->chan[i].src = 0;
+        s->chan[i].dest = 0;
+        s->chan[i].lli = 0;
+        s->chan[i].ctrl = 0;
+        s->chan[i].conf = 0;
+    }
+}
+
 static void pl080_init(Object *obj)
 {
     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
@@ -393,6 +417,7 @@ static void pl080_class_init(ObjectClass *oc, void *data)
     dc->vmsd = &vmstate_pl080;
     dc->realize = pl080_realize;
     dc->props = pl080_properties;
+    dc->reset = pl080_reset;
 }
 
 static const TypeInfo pl080_info = {
-- 
2.18.0

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

* [Qemu-devel] [PULL 24/25] hw/dma/pl080: Correct bug in register address decode logic
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (22 preceding siblings ...)
  2018-08-20 10:32 ` [Qemu-devel] [PULL 23/25] hw/dma/pl080: Provide device reset function Peter Maydell
@ 2018-08-20 10:32 ` Peter Maydell
  2018-08-20 10:32 ` [Qemu-devel] [PULL 25/25] hw/dma/pl080: Remove hw_error() if DMA is enabled Peter Maydell
  2018-08-20 14:00 ` [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:32 UTC (permalink / raw)
  To: qemu-devel

A bug in the handling of the register address decode logic
for the PL08x meant that we were incorrectly treating
accesses to the DMA channel registers (DMACCxSrcAddr,
DMACCxDestaddr, DMACCxLLI, DMACCxControl, DMACCxConfiguration)
as bad offsets. Fix this long-standing bug.

Fixes: https://bugs.launchpad.net/qemu/+bug/1637974
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/dma/pl080.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
index a7aacad74f0..8f92550392b 100644
--- a/hw/dma/pl080.c
+++ b/hw/dma/pl080.c
@@ -229,7 +229,7 @@ static uint64_t pl080_read(void *opaque, hwaddr offset,
         i = (offset & 0xe0) >> 5;
         if (i >= s->nchannels)
             goto bad_offset;
-        switch (offset >> 2) {
+        switch ((offset >> 2) & 7) {
         case 0: /* SrcAddr */
             return s->chan[i].src;
         case 1: /* DestAddr */
@@ -290,7 +290,7 @@ static void pl080_write(void *opaque, hwaddr offset,
         i = (offset & 0xe0) >> 5;
         if (i >= s->nchannels)
             goto bad_offset;
-        switch (offset >> 2) {
+        switch ((offset >> 2) & 7) {
         case 0: /* SrcAddr */
             s->chan[i].src = value;
             break;
@@ -308,6 +308,7 @@ static void pl080_write(void *opaque, hwaddr offset,
             pl080_run(s);
             break;
         }
+        return;
     }
     switch (offset >> 2) {
     case 2: /* IntTCClear */
-- 
2.18.0

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

* [Qemu-devel] [PULL 25/25] hw/dma/pl080: Remove hw_error() if DMA is enabled
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (23 preceding siblings ...)
  2018-08-20 10:32 ` [Qemu-devel] [PULL 24/25] hw/dma/pl080: Correct bug in register address decode logic Peter Maydell
@ 2018-08-20 10:32 ` Peter Maydell
  2018-08-20 14:00 ` [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 10:32 UTC (permalink / raw)
  To: qemu-devel

The PL08x model currently will unconditionally call hw_error()
if the DMA engine is enabled by the guest. This has been
present since the PL080 model was edded in 2006, and is
presumably either unintentional debug code left enabled,
or a guard against untested DMA engine code being used.

Remove the hw_error(), since we now have a guest which
will actually try to use the DMA engine (the self-test
binary for the AN505 MPS2 FPGA image).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/dma/pl080.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
index 8f92550392b..ef15d3e628d 100644
--- a/hw/dma/pl080.c
+++ b/hw/dma/pl080.c
@@ -110,7 +110,6 @@ static void pl080_run(PL080State *s)
     if ((s->conf & PL080_CONF_E) == 0)
         return;
 
-hw_error("DMA active\n");
     /* If we are already in the middle of a DMA operation then indicate that
        there may be new DMA requests and return immediately.  */
     if (s->running) {
-- 
2.18.0

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

* Re: [Qemu-devel] [PULL 00/25] target-arm queue
  2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (24 preceding siblings ...)
  2018-08-20 10:32 ` [Qemu-devel] [PULL 25/25] hw/dma/pl080: Remove hw_error() if DMA is enabled Peter Maydell
@ 2018-08-20 14:00 ` Peter Maydell
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2018-08-20 14:00 UTC (permalink / raw)
  To: QEMU Developers

On 20 August 2018 at 11:31, Peter Maydell <peter.maydell@linaro.org> wrote:
> Some more outstanding target-arm patches; nothing terribly
> exciting. Mostly they're mine; I'm trying to reduce the
> number of patches I still have in flight, so I've picked
> out some of the reviewed patches from a couple of sets I've
> sent out and will resend v2 versions of those sets with the
> remaining patches with fixes for issues noted in review once
> this is in master.
>
> thanks
> -- PMM
>
>
> The following changes since commit adaec191bfb31e12d40af8ab1b869f5b40d61ee9:
>
>   Merge remote-tracking branch 'remotes/ehabkost/tags/machine-next-pull-request' into staging (2018-08-20 09:48:03 +0100)
>
> are available in the Git repository at:
>
>   https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180820
>
> for you to fetch changes up to b85fad1588e812566f897f747e38da345a7016d6:
>
>   hw/dma/pl080: Remove hw_error() if DMA is enabled (2018-08-20 11:24:33 +0100)
>
> ----------------------------------------------------------------
> target-arm queue:
>  * Fix crash on conditional instruction in an IT block
>  * docs/generic-loader: mention U-Boot and Intel HEX executable formats
>  * hw/intc/arm_gicv3_its: downgrade error_report to warn_report in kvm_arm_its_reset
>  * imx_serial: Generate interrupt on receive data ready if enabled
>  * Fix various minor bugs in AArch32 Hyp related coprocessor registers
>  * Permit accesses to ELR_Hyp from Hyp mode via MSR/MRS (banked)
>  * Implement AArch32 ERET instruction
>  * hw/arm/virt: Add virt-3.1 machine type
>  * sdhci: add i.MX SD Stable Clock bit
>  * Remove now-obsolete MMIO request_ptr APIs
>  * hw/timer/m48t59: Move away from old_mmio accessors
>  * hw/watchdog/cmsdk_apb_watchdog: Implement CMSDK APB watchdog module
>  * nvic: Expose NMI line
>  * hw/dma/pl080: cleanups and new features required for use in MPS boards
>

Applied, thanks.

-- PMM

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

end of thread, other threads:[~2018-08-20 14:00 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-08-20 10:31 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
2018-08-20 10:31 ` [Qemu-devel] [PULL 01/25] target/arm: Fix crash on conditional instruction in an IT block Peter Maydell
2018-08-20 10:31 ` [Qemu-devel] [PULL 02/25] docs/generic-loader: mention U-Boot and Intel HEX executable formats Peter Maydell
2018-08-20 10:31 ` [Qemu-devel] [PULL 03/25] hw/intc/arm_gicv3_its: downgrade error_report to warn_report in kvm_arm_its_reset Peter Maydell
2018-08-20 10:31 ` [Qemu-devel] [PULL 04/25] imx_serial: Generate interrupt on receive data ready if enabled Peter Maydell
2018-08-20 10:31 ` [Qemu-devel] [PULL 05/25] target/arm: Correct typo in HAMAIR1 regdef name Peter Maydell
2018-08-20 10:31 ` [Qemu-devel] [PULL 06/25] target/arm: Add missing .cp = 15 to HMAIR1 and HAMAIR1 regdefs Peter Maydell
2018-08-20 10:31 ` [Qemu-devel] [PULL 07/25] target/arm: Implement AArch32 HVBAR Peter Maydell
2018-08-20 10:31 ` [Qemu-devel] [PULL 08/25] target/arm: Implement AArch32 Hyp FARs Peter Maydell
2018-08-20 10:31 ` [Qemu-devel] [PULL 09/25] target/arm: Implement ESR_EL2/HSR for AArch32 and no-EL2 Peter Maydell
2018-08-20 10:31 ` [Qemu-devel] [PULL 10/25] target/arm: Permit accesses to ELR_Hyp from Hyp mode via MSR/MRS (banked) Peter Maydell
2018-08-20 10:31 ` [Qemu-devel] [PULL 11/25] target/arm: Implement AArch32 ERET instruction Peter Maydell
2018-08-20 10:31 ` [Qemu-devel] [PULL 12/25] hw/arm/virt: Add virt-3.1 machine type Peter Maydell
2018-08-20 10:32 ` [Qemu-devel] [PULL 13/25] sdhci: add i.MX SD Stable Clock bit Peter Maydell
2018-08-20 10:32 ` [Qemu-devel] [PULL 14/25] hw/ssi/xilinx_spips: Remove unneeded MMIO request_ptr code Peter Maydell
2018-08-20 10:32 ` [Qemu-devel] [PULL 15/25] memory: Remove MMIO request_ptr APIs Peter Maydell
2018-08-20 10:32 ` [Qemu-devel] [PULL 16/25] hw/misc: Remove mmio_interface device Peter Maydell
2018-08-20 10:32 ` [Qemu-devel] [PULL 17/25] hw/timer/m48t59: Move away from old_mmio accessors Peter Maydell
2018-08-20 10:32 ` [Qemu-devel] [PULL 18/25] hw/watchdog/cmsdk_apb_watchdog: Implement CMSDK APB watchdog module Peter Maydell
2018-08-20 10:32 ` [Qemu-devel] [PULL 19/25] nvic: Expose NMI line Peter Maydell
2018-08-20 10:32 ` [Qemu-devel] [PULL 20/25] hw/dma/pl080: Allow use as embedded-struct device Peter Maydell
2018-08-20 10:32 ` [Qemu-devel] [PULL 21/25] hw/dma/pl080: Support all three interrupt lines Peter Maydell
2018-08-20 10:32 ` [Qemu-devel] [PULL 22/25] hw/dma/pl080: Don't use CPU address space for DMA accesses Peter Maydell
2018-08-20 10:32 ` [Qemu-devel] [PULL 23/25] hw/dma/pl080: Provide device reset function Peter Maydell
2018-08-20 10:32 ` [Qemu-devel] [PULL 24/25] hw/dma/pl080: Correct bug in register address decode logic Peter Maydell
2018-08-20 10:32 ` [Qemu-devel] [PULL 25/25] hw/dma/pl080: Remove hw_error() if DMA is enabled Peter Maydell
2018-08-20 14:00 ` [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell

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