qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/25] target-arm queue
@ 2016-10-17 18:40 Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 01/25] docs/generic-loader: Update the document Peter Maydell
                   ` (25 more replies)
  0 siblings, 26 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

Random mix of stuff here, nothing in particular
very large. Includes a fix for the regression running
Thumb userspace code.

thanks
-- PMM


The following changes since commit 0975b8b823a888d474fa33821dfe84e6904db197:

  Merge remote-tracking branch 'remotes/gkurz/tags/for-upstream' into staging (2016-10-17 16:17:51 +0100)

are available in the git repository at:

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

for you to fetch changes up to 041ac05672993ff33a15f8017c0f729ca6dfad73:

  hw/char/pl011: Add trace events (2016-10-17 19:32:44 +0100)

----------------------------------------------------------------
target-arm:
 * target-arm: kvm: use AddressSpace-specific listener
 * aspeed: add SMC controllers
 * hw/arm/boot: allow using a command line specified dtb without a kernel
 * hw/dma/pl080: Fix bad bit mask
 * hw/intc/arm_gic_kvm: Fix build on aarch64 with some compilers
 * hw/arm/virt: fix ACPI tables for ITS
 * tests: add a m25p80 test
 * tests: cleanup ptimer-test
 * pxa2xx: Auto-assign name for i2c bus in i2c_init_bus
 * target-arm: handle tagged addresses in A64 code
 * target-arm: Fix masking of PC lower bits when doing exception returns
 * target-arm: Implement dummy MDCCINT_EL1
 * target-arm: Add trace events for the generic timers
 * hw/intc/arm_gicv3: Fix ICC register tracepoints
 * hw/char/pl011: Add trace events

----------------------------------------------------------------
Alistair Francis (1):
      docs/generic-loader: Update the document

Andrew Jones (2):
      hw/arm/virt-acpi-build: fix MADT generation
      hw/arm/virt: no ITS on older machine types

Christopher Covington (1):
      hw/intc/arm_gic_kvm: Fix build on aarch64

Cédric Le Goater (7):
      aspeed: rename the smc object to fmc
      aspeed: move the flash module mapping address under the controller definition
      aspeed: extend the number of host SPI controllers
      aspeed: add support for the AST2500 SoC SMC controllers
      aspeed: create mapping regions for the maximum number of slaves
      aspeed: add support for the SMC segment registers
      tests: add a m25p80 test

Michael Olbrich (1):
      hw/arm/boot: allow using a command line specified dtb without a kernel

Paolo Bonzini (2):
      target-arm: kvm: use AddressSpace-specific listener
      tests: cleanup ptimer-test

Peter Maydell (5):
      Fix masking of PC lower bits when doing exception returns
      target-arm: Implement dummy MDCCINT_EL1
      target-arm: Add trace events for the generic timers
      hw/intc/arm_gicv3: Fix ICC register tracepoints
      hw/char/pl011: Add trace events

Rutuja Shah (1):
      Reducing stack frame size in stream_process_mem2s()

Thomas Hanson (3):
      target-arm: Infrastucture changes to enable handling of tagged address loading into PC
      target-arm: Code changes to implement overwrite of tag field on PC load
      target-arm: Comments added to identify cases in a switch

Thomas Huth (1):
      hw/dma/pl080: Fix bad bit mask (PL080_CONF_M1 | PL080_CONF_M1)

Vijay Kumar B (1):
      pxa2xx: Auto-assign name for i2c bus in i2c_init_bus.

 Makefile.objs                    |   1 +
 docs/generic-loader.txt          |  22 ++--
 hw/arm/aspeed.c                  |   4 +-
 hw/arm/aspeed_soc.c              |  74 ++++++++----
 hw/arm/boot.c                    |   4 +-
 hw/arm/pxa2xx.c                  |   2 +-
 hw/arm/virt-acpi-build.c         |  14 +--
 hw/arm/virt.c                    |  15 ++-
 hw/char/pl011.c                  |  71 +++++++----
 hw/char/trace-events             |   9 ++
 hw/dma/pl080.c                   |   2 +-
 hw/dma/xilinx_axidma.c           |   8 +-
 hw/intc/arm_gic_kvm.c            |  14 ---
 hw/intc/arm_gicv3_cpuif.c        |  23 ++--
 hw/intc/trace-events             |  14 +--
 hw/ssi/aspeed_smc.c              | 194 ++++++++++++++++++++++++++++--
 include/hw/arm/aspeed_soc.h      |  10 +-
 include/hw/arm/virt-acpi-build.h |   1 +
 include/hw/ssi/aspeed_smc.h      |   3 +-
 stubs/vmstate.c                  |   5 -
 target-arm/cpu.h                 |  52 +++++++-
 target-arm/helper.c              |  74 +++++++++++-
 target-arm/kvm.c                 |   3 +-
 target-arm/op_helper.c           |   7 ++
 target-arm/trace-events          |  10 ++
 target-arm/translate-a64.c       |  90 ++++++++++++--
 target-arm/translate.c           |  29 +++--
 target-arm/translate.h           |   2 +
 tests/Makefile.include           |   7 +-
 tests/m25p80-test.c              | 252 +++++++++++++++++++++++++++++++++++++++
 tests/ptimer-test-stubs.c        |   7 ++
 tests/ptimer-test.c              |  22 ++--
 vl.c                             |   5 -
 33 files changed, 882 insertions(+), 168 deletions(-)
 create mode 100644 target-arm/trace-events
 create mode 100644 tests/m25p80-test.c

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

* [Qemu-devel] [PULL 01/25] docs/generic-loader: Update the document
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 02/25] Reducing stack frame size in stream_process_mem2s() Peter Maydell
                   ` (24 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Alistair Francis <alistair.francis@xilinx.com>

This patch does three things:
 - It adds a list of restrictions and ToDos
 - It corrects the header --- lines to match the length of the header
 - It clarifies the force-raw option

Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-id: e75d1d285cf8f45037c41ebe1bc3f68120f09cb9.1475702918.git.alistair.francis@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 docs/generic-loader.txt | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/docs/generic-loader.txt b/docs/generic-loader.txt
index 8fcb550..31bbcd4 100644
--- a/docs/generic-loader.txt
+++ b/docs/generic-loader.txt
@@ -8,7 +8,7 @@ The 'loader' device allows the user to load multiple images or values into
 QEMU at startup.
 
 Loading Data into Memory Values
----------------------
+-------------------------------
 The loader device allows memory values to be set from the command line. This
 can be done by following the syntax below:
 
@@ -36,7 +36,7 @@ An example of loading value 0x8000000e to address 0xfd1a0104 is:
     -device loader,addr=0xfd1a0104,data=0x8000000e,data-len=4
 
 Setting a CPU's Program Counter
----------------------
+-------------------------------
 The loader device allows the CPU's PC to be set from the command line. This
 can be done by following the syntax below:
 
@@ -55,9 +55,10 @@ An example of setting CPU 0's PC to 0x8000 is:
     -device loader,addr=0x8000,cpu-num=0
 
 Loading Files
----------------------
-The loader device also allows files to be loaded into memory. This can be done
-similarly to setting memory values. The syntax is shown below:
+-------------
+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:
 
     -device loader,file=<file>[,addr=<addr>][,cpu-num=<cpu-num>][,force-raw=<raw>]
 
@@ -72,8 +73,8 @@ similarly to setting memory values. The syntax is shown below:
                   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> - Forces the file to be treated as a raw image. This can be
-                  used to specify the load address of ELF files.
+    <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.
 
 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
@@ -82,3 +83,10 @@ with a '0x'.
 
 An example of loading an ELF file which CPU0 will boot is shown below:
     -device loader,file=./images/boot.elf,cpu-num=0
+
+Restrictions and ToDos
+----------------------
+ - At the moment it is just assumed that if you specify a cpu-num then you
+   want to set the PC as well. This might not always be the case. In future
+   the internal state 'set_pc' (which exists in the generic loader now) should
+   be exposed to the user so that they can choose if the PC is set or not.
-- 
2.7.4

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

* [Qemu-devel] [PULL 02/25] Reducing stack frame size in stream_process_mem2s()
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 01/25] docs/generic-loader: Update the document Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 03/25] target-arm: kvm: use AddressSpace-specific listener Peter Maydell
                   ` (23 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Rutuja Shah <rutu.shah.26@gmail.com>

This patch allocates memory for txbuf in struct Stream rather than the stack.
As a result, the stack frame size is reduced of stream_process_mem2s().

Signed-off-by: Rutuja Shah <rutu.shah.26@gmail.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/dma/xilinx_axidma.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
index b135a5f..6065689 100644
--- a/hw/dma/xilinx_axidma.c
+++ b/hw/dma/xilinx_axidma.c
@@ -111,6 +111,7 @@ struct Stream {
     unsigned int complete_cnt;
     uint32_t regs[R_MAX];
     uint8_t app[20];
+    unsigned char txbuf[16 * 1024];
 };
 
 struct XilinxAXIDMAStreamSlave {
@@ -256,7 +257,6 @@ static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev,
                                  StreamSlave *tx_control_dev)
 {
     uint32_t prev_d;
-    unsigned char txbuf[16 * 1024];
     unsigned int txlen;
 
     if (!stream_running(s) || stream_idle(s)) {
@@ -277,17 +277,17 @@ static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev,
         }
 
         txlen = s->desc.control & SDESC_CTRL_LEN_MASK;
-        if ((txlen + s->pos) > sizeof txbuf) {
+        if ((txlen + s->pos) > sizeof s->txbuf) {
             hw_error("%s: too small internal txbuf! %d\n", __func__,
                      txlen + s->pos);
         }
 
         cpu_physical_memory_read(s->desc.buffer_address,
-                                 txbuf + s->pos, txlen);
+                                 s->txbuf + s->pos, txlen);
         s->pos += txlen;
 
         if (stream_desc_eof(&s->desc)) {
-            stream_push(tx_data_dev, txbuf, s->pos);
+            stream_push(tx_data_dev, s->txbuf, s->pos);
             s->pos = 0;
             stream_complete(s);
         }
-- 
2.7.4

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

* [Qemu-devel] [PULL 03/25] target-arm: kvm: use AddressSpace-specific listener
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 01/25] docs/generic-loader: Update the document Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 02/25] Reducing stack frame size in stream_process_mem2s() Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 04/25] aspeed: rename the smc object to fmc Peter Maydell
                   ` (22 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Paolo Bonzini <pbonzini@redhat.com>

The only address space where the GIC devices are added is
address_space_memory.  There is no need to use a global
MemoryListener.

This removes the only user of global MemoryListeners.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[PMM: added missing #include "exec/address-spaces.h"]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1475219846-32609-1-git-send-email-pbonzini@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/kvm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index dbe393c..c00b94e 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -23,6 +23,7 @@
 #include "internals.h"
 #include "hw/arm/arm.h"
 #include "exec/memattrs.h"
+#include "exec/address-spaces.h"
 #include "hw/boards.h"
 #include "qemu/log.h"
 
@@ -283,7 +284,7 @@ void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid, uint64_t group,
     }
 
     if (QSLIST_EMPTY(&kvm_devices_head)) {
-        memory_listener_register(&devlistener, NULL);
+        memory_listener_register(&devlistener, &address_space_memory);
         qemu_add_machine_init_done_notifier(&notify);
     }
     kd = g_new0(KVMDevice, 1);
-- 
2.7.4

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

* [Qemu-devel] [PULL 04/25] aspeed: rename the smc object to fmc
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (2 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 03/25] target-arm: kvm: use AddressSpace-specific listener Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 05/25] aspeed: move the flash module mapping address under the controller definition Peter Maydell
                   ` (21 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Cédric Le Goater <clg@kaod.org>

The Aspeed SoC has three different types of SMC (Static Memory
Controller) controllers: the SMC (legacy), the FMC (the new one) and
the SPI for the host PNOR. The FMC and the SPI models are now
converging on the AST2500 SoC and the SMC, which was still available
on the AST2400 SoC, was removed.

The Aspeed SoC does not provide support for the legacy SMC
controller. So, let's rename the 'smc' object to 'fmc' to clarify its
nature.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Message-id: 1474977462-28032-2-git-send-email-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/aspeed.c             |  2 +-
 hw/arm/aspeed_soc.c         | 18 +++++++++---------
 include/hw/arm/aspeed_soc.h |  2 +-
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 6b18c7f..4bb33cb 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -128,7 +128,7 @@ static void aspeed_board_init(MachineState *machine,
     object_property_add_const_link(OBJECT(&bmc->soc), "ram", OBJECT(&bmc->ram),
                                    &error_abort);
 
-    aspeed_board_init_flashes(&bmc->soc.smc, "n25q256a", &error_abort);
+    aspeed_board_init_flashes(&bmc->soc.fmc, "n25q256a", &error_abort);
     aspeed_board_init_flashes(&bmc->soc.spi, "mx25l25635e", &error_abort);
 
     aspeed_board_binfo.kernel_filename = machine->kernel_filename;
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index c0a3102..479c0d2 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -100,9 +100,9 @@ static void aspeed_soc_init(Object *obj)
     object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
                               "hw-strap2", &error_abort);
 
-    object_initialize(&s->smc, sizeof(s->smc), "aspeed.smc.fmc");
-    object_property_add_child(obj, "smc", OBJECT(&s->smc), NULL);
-    qdev_set_parent_bus(DEVICE(&s->smc), sysbus_get_default());
+    object_initialize(&s->fmc, sizeof(s->fmc), "aspeed.smc.fmc");
+    object_property_add_child(obj, "fmc", OBJECT(&s->fmc), NULL);
+    qdev_set_parent_bus(DEVICE(&s->fmc), sysbus_get_default());
 
     object_initialize(&s->spi, sizeof(s->spi), "aspeed.smc.spi");
     object_property_add_child(obj, "spi", OBJECT(&s->spi), NULL);
@@ -178,17 +178,17 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
                        qdev_get_gpio_in(DEVICE(&s->vic), 12));
 
-    /* SMC */
-    object_property_set_int(OBJECT(&s->smc), 1, "num-cs", &err);
-    object_property_set_bool(OBJECT(&s->smc), true, "realized", &local_err);
+    /* FMC */
+    object_property_set_int(OBJECT(&s->fmc), 1, "num-cs", &err);
+    object_property_set_bool(OBJECT(&s->fmc), true, "realized", &local_err);
     error_propagate(&err, local_err);
     if (err) {
         error_propagate(errp, err);
         return;
     }
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->smc), 0, ASPEED_SOC_FMC_BASE);
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->smc), 1, ASPEED_SOC_FMC_FLASH_BASE);
-    sysbus_connect_irq(SYS_BUS_DEVICE(&s->smc), 0,
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, ASPEED_SOC_FMC_BASE);
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1, ASPEED_SOC_FMC_FLASH_BASE);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0,
                        qdev_get_gpio_in(DEVICE(&s->vic), 19));
 
     /* SPI */
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index 932704c..7359e25 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -31,7 +31,7 @@ typedef struct AspeedSoCState {
     AspeedTimerCtrlState timerctrl;
     AspeedI2CState i2c;
     AspeedSCUState scu;
-    AspeedSMCState smc;
+    AspeedSMCState fmc;
     AspeedSMCState spi;
     AspeedSDMCState sdmc;
 } AspeedSoCState;
-- 
2.7.4

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

* [Qemu-devel] [PULL 05/25] aspeed: move the flash module mapping address under the controller definition
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (3 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 04/25] aspeed: rename the smc object to fmc Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 06/25] aspeed: extend the number of host SPI controllers Peter Maydell
                   ` (20 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Cédric Le Goater <clg@kaod.org>

This will ease the definition of the new controllers for the AST2500
SoC and also ease the support of the segment registers, which provide
a way to reconfigure the mapping window of each slave.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Message-id: 1474977462-28032-3-git-send-email-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/aspeed_soc.c         |  9 ++++-----
 hw/ssi/aspeed_smc.c         | 15 +++++++++++----
 include/hw/ssi/aspeed_smc.h |  3 ++-
 3 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 479c0d2..80ad732 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -31,9 +31,6 @@
 #define ASPEED_SOC_TIMER_BASE       0x1E782000
 #define ASPEED_SOC_I2C_BASE         0x1E78A000
 
-#define ASPEED_SOC_FMC_FLASH_BASE   0x20000000
-#define ASPEED_SOC_SPI_FLASH_BASE   0x30000000
-
 static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
 static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
 
@@ -187,7 +184,8 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
         return;
     }
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, ASPEED_SOC_FMC_BASE);
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1, ASPEED_SOC_FMC_FLASH_BASE);
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1,
+                    s->fmc.ctrl->flash_window_base);
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0,
                        qdev_get_gpio_in(DEVICE(&s->vic), 19));
 
@@ -200,7 +198,8 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
         return;
     }
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 0, ASPEED_SOC_SPI_BASE);
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 1, ASPEED_SOC_SPI_FLASH_BASE);
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 1,
+                    s->spi.ctrl->flash_window_base);
 
     /* SDMC - SDRAM Memory Controller */
     object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err);
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index d319e04..84c1829 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -127,6 +127,10 @@
 #define R_SPI_MISC_CTRL   (0x10 / 4)
 #define R_SPI_TIMINGS     (0x14 / 4)
 
+#define ASPEED_SOC_SMC_FLASH_BASE   0x10000000
+#define ASPEED_SOC_FMC_FLASH_BASE   0x20000000
+#define ASPEED_SOC_SPI_FLASH_BASE   0x30000000
+
 /*
  * Default segments mapping addresses and size for each slave per
  * controller. These can be changed when board is initialized with the
@@ -151,11 +155,14 @@ static const AspeedSegments aspeed_segments_spi[] = {
 
 static const AspeedSMCController controllers[] = {
     { "aspeed.smc.smc", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
-      CONF_ENABLE_W0, 5, aspeed_segments_legacy, 0x6000000 },
+      CONF_ENABLE_W0, 5, aspeed_segments_legacy,
+      ASPEED_SOC_SMC_FLASH_BASE, 0x6000000 },
     { "aspeed.smc.fmc", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
-      CONF_ENABLE_W0, 5, aspeed_segments_fmc, 0x10000000 },
+      CONF_ENABLE_W0, 5, aspeed_segments_fmc,
+      ASPEED_SOC_FMC_FLASH_BASE, 0x10000000 },
     { "aspeed.smc.spi", R_SPI_CONF, 0xff, R_SPI_CTRL0, R_SPI_TIMINGS,
-      SPI_CONF_ENABLE_W0, 1, aspeed_segments_spi, 0x10000000 },
+      SPI_CONF_ENABLE_W0, 1, aspeed_segments_spi,
+      ASPEED_SOC_SPI_FLASH_BASE, 0x10000000 },
 };
 
 static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
@@ -395,7 +402,7 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
 
     memory_region_init_io(&s->mmio_flash, OBJECT(s),
                           &aspeed_smc_flash_default_ops, s, name,
-                          s->ctrl->mapping_window_size);
+                          s->ctrl->flash_window_size);
     sysbus_init_mmio(sbd, &s->mmio_flash);
 
     s->flashes = g_new0(AspeedSMCFlash, s->num_cs);
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
index def3b45..bdfbcc0 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -42,7 +42,8 @@ typedef struct AspeedSMCController {
     uint8_t conf_enable_w0;
     uint8_t max_slaves;
     const AspeedSegments *segments;
-    uint32_t mapping_window_size;
+    hwaddr flash_window_base;
+    uint32_t flash_window_size;
 } AspeedSMCController;
 
 typedef struct AspeedSMCFlash {
-- 
2.7.4

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

* [Qemu-devel] [PULL 06/25] aspeed: extend the number of host SPI controllers
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (4 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 05/25] aspeed: move the flash module mapping address under the controller definition Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 07/25] aspeed: add support for the AST2500 SoC SMC controllers Peter Maydell
                   ` (19 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Cédric Le Goater <clg@kaod.org>

The AST2500 SoC has two. Let's prepare ground for the next changes
which will add the required definitions for the second host SPI
controller.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Message-id: 1474977462-28032-4-git-send-email-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/aspeed.c             |  2 +-
 hw/arm/aspeed_soc.c         | 44 +++++++++++++++++++++++++++++---------------
 include/hw/arm/aspeed_soc.h |  6 +++++-
 3 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 4bb33cb..c7206fd 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -129,7 +129,7 @@ static void aspeed_board_init(MachineState *machine,
                                    &error_abort);
 
     aspeed_board_init_flashes(&bmc->soc.fmc, "n25q256a", &error_abort);
-    aspeed_board_init_flashes(&bmc->soc.spi, "mx25l25635e", &error_abort);
+    aspeed_board_init_flashes(&bmc->soc.spi[0], "mx25l25635e", &error_abort);
 
     aspeed_board_binfo.kernel_filename = machine->kernel_filename;
     aspeed_board_binfo.initrd_filename = machine->initrd_filename;
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 80ad732..b3103f3 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -37,10 +37,17 @@ static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
 #define AST2400_SDRAM_BASE       0x40000000
 #define AST2500_SDRAM_BASE       0x80000000
 
+static const hwaddr aspeed_soc_ast2400_spi_bases[] = { ASPEED_SOC_SPI_BASE };
+
+static const hwaddr aspeed_soc_ast2500_spi_bases[] = { ASPEED_SOC_SPI_BASE };
+
 static const AspeedSoCInfo aspeed_socs[] = {
-    { "ast2400-a0", "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE },
-    { "ast2400",    "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE },
-    { "ast2500-a1", "arm1176", AST2500_A1_SILICON_REV, AST2500_SDRAM_BASE },
+    { "ast2400-a0", "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE,
+      1, aspeed_soc_ast2400_spi_bases },
+    { "ast2400",    "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE,
+      1, aspeed_soc_ast2400_spi_bases },
+    { "ast2500-a1", "arm1176", AST2500_A1_SILICON_REV, AST2500_SDRAM_BASE,
+      1, aspeed_soc_ast2500_spi_bases },
 };
 
 /*
@@ -72,6 +79,7 @@ static void aspeed_soc_init(Object *obj)
 {
     AspeedSoCState *s = ASPEED_SOC(obj);
     AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+    int i;
 
     s->cpu = cpu_arm_init(sc->info->cpu_model);
 
@@ -101,9 +109,11 @@ static void aspeed_soc_init(Object *obj)
     object_property_add_child(obj, "fmc", OBJECT(&s->fmc), NULL);
     qdev_set_parent_bus(DEVICE(&s->fmc), sysbus_get_default());
 
-    object_initialize(&s->spi, sizeof(s->spi), "aspeed.smc.spi");
-    object_property_add_child(obj, "spi", OBJECT(&s->spi), NULL);
-    qdev_set_parent_bus(DEVICE(&s->spi), sysbus_get_default());
+    for (i = 0; i < sc->info->spis_num; i++) {
+        object_initialize(&s->spi[i], sizeof(s->spi[i]), "aspeed.smc.spi");
+        object_property_add_child(obj, "spi", OBJECT(&s->spi[i]), NULL);
+        qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
+    }
 
     object_initialize(&s->sdmc, sizeof(s->sdmc), TYPE_ASPEED_SDMC);
     object_property_add_child(obj, "sdmc", OBJECT(&s->sdmc), NULL);
@@ -118,6 +128,7 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
 {
     int i;
     AspeedSoCState *s = ASPEED_SOC(dev);
+    AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
     Error *err = NULL, *local_err = NULL;
 
     /* IO space */
@@ -190,16 +201,19 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
                        qdev_get_gpio_in(DEVICE(&s->vic), 19));
 
     /* SPI */
-    object_property_set_int(OBJECT(&s->spi), 1, "num-cs", &err);
-    object_property_set_bool(OBJECT(&s->spi), true, "realized", &local_err);
-    error_propagate(&err, local_err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
+    for (i = 0; i < sc->info->spis_num; i++) {
+        object_property_set_int(OBJECT(&s->spi[i]), 1, "num-cs", &err);
+        object_property_set_bool(OBJECT(&s->spi[i]), true, "realized",
+                                 &local_err);
+        error_propagate(&err, local_err);
+        if (err) {
+            error_propagate(errp, err);
+            return;
+        }
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, sc->info->spi_bases[i]);
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1,
+                        s->spi[i].ctrl->flash_window_base);
     }
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 0, ASPEED_SOC_SPI_BASE);
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 1,
-                    s->spi.ctrl->flash_window_base);
 
     /* SDMC - SDRAM Memory Controller */
     object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err);
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index 7359e25..f26a9f0 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -20,6 +20,8 @@
 #include "hw/i2c/aspeed_i2c.h"
 #include "hw/ssi/aspeed_smc.h"
 
+#define ASPEED_SPIS_NUM  2
+
 typedef struct AspeedSoCState {
     /*< private >*/
     DeviceState parent;
@@ -32,7 +34,7 @@ typedef struct AspeedSoCState {
     AspeedI2CState i2c;
     AspeedSCUState scu;
     AspeedSMCState fmc;
-    AspeedSMCState spi;
+    AspeedSMCState spi[ASPEED_SPIS_NUM];
     AspeedSDMCState sdmc;
 } AspeedSoCState;
 
@@ -44,6 +46,8 @@ typedef struct AspeedSoCInfo {
     const char *cpu_model;
     uint32_t silicon_rev;
     hwaddr sdram_base;
+    int spis_num;
+    const hwaddr *spi_bases;
 } AspeedSoCInfo;
 
 typedef struct AspeedSoCClass {
-- 
2.7.4

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

* [Qemu-devel] [PULL 07/25] aspeed: add support for the AST2500 SoC SMC controllers
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (5 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 06/25] aspeed: extend the number of host SPI controllers Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 08/25] aspeed: create mapping regions for the maximum number of slaves Peter Maydell
                   ` (18 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Cédric Le Goater <clg@kaod.org>

The SMC controllers on the Aspeed AST2500 SoC are very similar to the
ones found on the AST2400. The differences are on the number of
supported flash modules and their default mappings in the SoC address
space.

The Aspeed AST2500 has one SPI controller for the BMC firmware and two
for the host firmware. All controllers have now the same set of
registers compatible with the AST2400 FMC controller and the legacy
'SMC' controller is fully gone.

We keep the FMC object to act as the BMC SPI controller and add a new
SPI controller for the host. We also have to introduce new type names
to handle the differences in the flash modules memory mappping.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Message-id: 1474977462-28032-5-git-send-email-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/aspeed_soc.c         | 21 +++++++++++++++------
 hw/ssi/aspeed_smc.c         | 28 +++++++++++++++++++++++++++-
 include/hw/arm/aspeed_soc.h |  2 ++
 3 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index b3103f3..e14f5c2 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -25,6 +25,7 @@
 #define ASPEED_SOC_IOMEM_BASE       0x1E600000
 #define ASPEED_SOC_FMC_BASE         0x1E620000
 #define ASPEED_SOC_SPI_BASE         0x1E630000
+#define ASPEED_SOC_SPI2_BASE        0x1E631000
 #define ASPEED_SOC_VIC_BASE         0x1E6C0000
 #define ASPEED_SOC_SDMC_BASE        0x1E6E0000
 #define ASPEED_SOC_SCU_BASE         0x1E6E2000
@@ -38,16 +39,23 @@ static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
 #define AST2500_SDRAM_BASE       0x80000000
 
 static const hwaddr aspeed_soc_ast2400_spi_bases[] = { ASPEED_SOC_SPI_BASE };
+static const char *aspeed_soc_ast2400_typenames[] = { "aspeed.smc.spi" };
 
-static const hwaddr aspeed_soc_ast2500_spi_bases[] = { ASPEED_SOC_SPI_BASE };
+static const hwaddr aspeed_soc_ast2500_spi_bases[] = { ASPEED_SOC_SPI_BASE,
+                                                       ASPEED_SOC_SPI2_BASE};
+static const char *aspeed_soc_ast2500_typenames[] = {
+    "aspeed.smc.ast2500-spi1", "aspeed.smc.ast2500-spi2" };
 
 static const AspeedSoCInfo aspeed_socs[] = {
     { "ast2400-a0", "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE,
-      1, aspeed_soc_ast2400_spi_bases },
+      1, aspeed_soc_ast2400_spi_bases,
+      "aspeed.smc.fmc", aspeed_soc_ast2400_typenames },
     { "ast2400",    "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE,
-      1, aspeed_soc_ast2400_spi_bases },
+      1, aspeed_soc_ast2400_spi_bases,
+     "aspeed.smc.fmc", aspeed_soc_ast2400_typenames },
     { "ast2500-a1", "arm1176", AST2500_A1_SILICON_REV, AST2500_SDRAM_BASE,
-      1, aspeed_soc_ast2500_spi_bases },
+      2, aspeed_soc_ast2500_spi_bases,
+      "aspeed.smc.ast2500-fmc", aspeed_soc_ast2500_typenames },
 };
 
 /*
@@ -105,12 +113,13 @@ static void aspeed_soc_init(Object *obj)
     object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
                               "hw-strap2", &error_abort);
 
-    object_initialize(&s->fmc, sizeof(s->fmc), "aspeed.smc.fmc");
+    object_initialize(&s->fmc, sizeof(s->fmc), sc->info->fmc_typename);
     object_property_add_child(obj, "fmc", OBJECT(&s->fmc), NULL);
     qdev_set_parent_bus(DEVICE(&s->fmc), sysbus_get_default());
 
     for (i = 0; i < sc->info->spis_num; i++) {
-        object_initialize(&s->spi[i], sizeof(s->spi[i]), "aspeed.smc.spi");
+        object_initialize(&s->spi[i], sizeof(s->spi[i]),
+                          sc->info->spi_typename[i]);
         object_property_add_child(obj, "spi", OBJECT(&s->spi[i]), NULL);
         qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
     }
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 84c1829..21943f4 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -130,6 +130,7 @@
 #define ASPEED_SOC_SMC_FLASH_BASE   0x10000000
 #define ASPEED_SOC_FMC_FLASH_BASE   0x20000000
 #define ASPEED_SOC_SPI_FLASH_BASE   0x30000000
+#define ASPEED_SOC_SPI2_FLASH_BASE  0x38000000
 
 /*
  * Default segments mapping addresses and size for each slave per
@@ -142,7 +143,7 @@ static const AspeedSegments aspeed_segments_legacy[] = {
 };
 
 static const AspeedSegments aspeed_segments_fmc[] = {
-    { 0x20000000, 64 * 1024 * 1024 },
+    { 0x20000000, 64 * 1024 * 1024 }, /* start address is readonly */
     { 0x24000000, 32 * 1024 * 1024 },
     { 0x26000000, 32 * 1024 * 1024 },
     { 0x28000000, 32 * 1024 * 1024 },
@@ -153,6 +154,22 @@ static const AspeedSegments aspeed_segments_spi[] = {
     { 0x30000000, 64 * 1024 * 1024 },
 };
 
+static const AspeedSegments aspeed_segments_ast2500_fmc[] = {
+    { 0x20000000, 128 * 1024 * 1024 }, /* start address is readonly */
+    { 0x28000000,  32 * 1024 * 1024 },
+    { 0x2A000000,  32 * 1024 * 1024 },
+};
+
+static const AspeedSegments aspeed_segments_ast2500_spi1[] = {
+    { 0x30000000, 32 * 1024 * 1024 }, /* start address is readonly */
+    { 0x32000000, 96 * 1024 * 1024 }, /* end address is readonly */
+};
+
+static const AspeedSegments aspeed_segments_ast2500_spi2[] = {
+    { 0x38000000, 32 * 1024 * 1024 }, /* start address is readonly */
+    { 0x3A000000, 96 * 1024 * 1024 }, /* end address is readonly */
+};
+
 static const AspeedSMCController controllers[] = {
     { "aspeed.smc.smc", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
       CONF_ENABLE_W0, 5, aspeed_segments_legacy,
@@ -163,6 +180,15 @@ static const AspeedSMCController controllers[] = {
     { "aspeed.smc.spi", R_SPI_CONF, 0xff, R_SPI_CTRL0, R_SPI_TIMINGS,
       SPI_CONF_ENABLE_W0, 1, aspeed_segments_spi,
       ASPEED_SOC_SPI_FLASH_BASE, 0x10000000 },
+    { "aspeed.smc.ast2500-fmc", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
+      CONF_ENABLE_W0, 3, aspeed_segments_ast2500_fmc,
+      ASPEED_SOC_FMC_FLASH_BASE, 0x10000000 },
+    { "aspeed.smc.ast2500-spi1", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
+      CONF_ENABLE_W0, 2, aspeed_segments_ast2500_spi1,
+      ASPEED_SOC_SPI_FLASH_BASE, 0x8000000 },
+    { "aspeed.smc.ast2500-spi2", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
+      CONF_ENABLE_W0, 2, aspeed_segments_ast2500_spi2,
+      ASPEED_SOC_SPI2_FLASH_BASE, 0x8000000 },
 };
 
 static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index f26a9f0..5406b49 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -48,6 +48,8 @@ typedef struct AspeedSoCInfo {
     hwaddr sdram_base;
     int spis_num;
     const hwaddr *spi_bases;
+    const char *fmc_typename;
+    const char **spi_typename;
 } AspeedSoCInfo;
 
 typedef struct AspeedSoCClass {
-- 
2.7.4

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

* [Qemu-devel] [PULL 08/25] aspeed: create mapping regions for the maximum number of slaves
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (6 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 07/25] aspeed: add support for the AST2500 SoC SMC controllers Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 09/25] aspeed: add support for the SMC segment registers Peter Maydell
                   ` (17 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Cédric Le Goater <clg@kaod.org>

The SMC controller on the Aspeed SoC has a set of registers to
configure the mapping of each flash module in the SoC address
space. These mapping windows are configurable even though no SPI slave
is attached to the controller.

Also rewrite a bit the comments in the code on this topic.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Message-id: 1474977462-28032-6-git-send-email-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/ssi/aspeed_smc.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 21943f4..ecf39cc 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -417,12 +417,15 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
 
     aspeed_smc_reset(dev);
 
+    /* The memory region for the controller registers */
     memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_smc_ops, s,
                           s->ctrl->name, ASPEED_SMC_R_MAX * 4);
     sysbus_init_mmio(sbd, &s->mmio);
 
     /*
-     * Memory region where flash modules are remapped
+     * The container memory region representing the address space
+     * window in which the flash modules are mapped. The size and
+     * address depends on the SoC model and controller type.
      */
     snprintf(name, sizeof(name), "%s.flash", s->ctrl->name);
 
@@ -431,9 +434,16 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
                           s->ctrl->flash_window_size);
     sysbus_init_mmio(sbd, &s->mmio_flash);
 
-    s->flashes = g_new0(AspeedSMCFlash, s->num_cs);
+    s->flashes = g_new0(AspeedSMCFlash, s->ctrl->max_slaves);
 
-    for (i = 0; i < s->num_cs; ++i) {
+    /*
+     * Let's create a sub memory region for each possible slave. All
+     * have a configurable memory segment in the overall flash mapping
+     * window of the controller but, there is not necessarily a flash
+     * module behind to handle the memory accesses. This depends on
+     * the board configuration.
+     */
+    for (i = 0; i < s->ctrl->max_slaves; ++i) {
         AspeedSMCFlash *fl = &s->flashes[i];
 
         snprintf(name, sizeof(name), "%s.%d", s->ctrl->name, i);
-- 
2.7.4

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

* [Qemu-devel] [PULL 09/25] aspeed: add support for the SMC segment registers
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (7 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 08/25] aspeed: create mapping regions for the maximum number of slaves Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 10/25] hw/arm/boot: allow using a command line specified dtb without a kernel Peter Maydell
                   ` (16 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Cédric Le Goater <clg@kaod.org>

The SMC controller on the Aspeed SoC has a set of registers to
configure the mapping of each flash module in the SoC address
space. Writing to these registers triggers a remap of the memory
region and the spec requires a certain number of checks before doing
so.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Message-id: 1474977462-28032-7-git-send-email-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/ssi/aspeed_smc.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 130 insertions(+), 5 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index ecf39cc..6e8403e 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -79,10 +79,10 @@
 
 /* CEx Segment Address Register */
 #define R_SEG_ADDR0       (0x30 / 4)
-#define   SEG_SIZE_SHIFT       24   /* 8MB units */
-#define   SEG_SIZE_MASK        0x7f
+#define   SEG_END_SHIFT        24   /* 8MB units */
+#define   SEG_END_MASK         0xff
 #define   SEG_START_SHIFT      16   /* address bit [A29-A23] */
-#define   SEG_START_MASK       0x7f
+#define   SEG_START_MASK       0xff
 #define R_SEG_ADDR1       (0x34 / 4)
 #define R_SEG_ADDR2       (0x38 / 4)
 #define R_SEG_ADDR3       (0x3C / 4)
@@ -135,8 +135,7 @@
 /*
  * Default segments mapping addresses and size for each slave per
  * controller. These can be changed when board is initialized with the
- * Segment Address Registers but they don't seem do be used on the
- * field.
+ * Segment Address Registers.
  */
 static const AspeedSegments aspeed_segments_legacy[] = {
     { 0x10000000, 32 * 1024 * 1024 },
@@ -191,6 +190,118 @@ static const AspeedSMCController controllers[] = {
       ASPEED_SOC_SPI2_FLASH_BASE, 0x8000000 },
 };
 
+/*
+ * The Segment Register uses a 8MB unit to encode the start address
+ * and the end address of the mapping window of a flash SPI slave :
+ *
+ *        | byte 1 | byte 2 | byte 3 | byte 4 |
+ *        +--------+--------+--------+--------+
+ *        |  end   |  start |   0    |   0    |
+ *
+ */
+static inline uint32_t aspeed_smc_segment_to_reg(const AspeedSegments *seg)
+{
+    uint32_t reg = 0;
+    reg |= ((seg->addr >> 23) & SEG_START_MASK) << SEG_START_SHIFT;
+    reg |= (((seg->addr + seg->size) >> 23) & SEG_END_MASK) << SEG_END_SHIFT;
+    return reg;
+}
+
+static inline void aspeed_smc_reg_to_segment(uint32_t reg, AspeedSegments *seg)
+{
+    seg->addr = ((reg >> SEG_START_SHIFT) & SEG_START_MASK) << 23;
+    seg->size = (((reg >> SEG_END_SHIFT) & SEG_END_MASK) << 23) - seg->addr;
+}
+
+static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
+                                     const AspeedSegments *new,
+                                     int cs)
+{
+    AspeedSegments seg;
+    int i;
+
+    for (i = 0; i < s->ctrl->max_slaves; i++) {
+        if (i == cs) {
+            continue;
+        }
+
+        aspeed_smc_reg_to_segment(s->regs[R_SEG_ADDR0 + i], &seg);
+
+        if (new->addr + new->size > seg.addr &&
+            new->addr < seg.addr + seg.size) {
+            qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment CS%d [ 0x%"
+                          HWADDR_PRIx" - 0x%"HWADDR_PRIx" ] overlaps with "
+                          "CS%d [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
+                          s->ctrl->name, cs, new->addr, new->addr + new->size,
+                          i, seg.addr, seg.addr + seg.size);
+            return true;
+        }
+    }
+    return false;
+}
+
+static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
+                                         uint64_t new)
+{
+    AspeedSMCFlash *fl = &s->flashes[cs];
+    AspeedSegments seg;
+
+    aspeed_smc_reg_to_segment(new, &seg);
+
+    /* The start address of CS0 is read-only */
+    if (cs == 0 && seg.addr != s->ctrl->flash_window_base) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Tried to change CS0 start address to 0x%"
+                      HWADDR_PRIx "\n", s->ctrl->name, seg.addr);
+        return;
+    }
+
+    /*
+     * The end address of the AST2500 spi controllers is also
+     * read-only.
+     */
+    if ((s->ctrl->segments == aspeed_segments_ast2500_spi1 ||
+         s->ctrl->segments == aspeed_segments_ast2500_spi2) &&
+        cs == s->ctrl->max_slaves &&
+        seg.addr + seg.size != s->ctrl->segments[cs].addr +
+        s->ctrl->segments[cs].size) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Tried to change CS%d end address to 0x%"
+                      HWADDR_PRIx "\n", s->ctrl->name, cs, seg.addr);
+        return;
+    }
+
+    /* Keep the segment in the overall flash window */
+    if (seg.addr + seg.size <= s->ctrl->flash_window_base ||
+        seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is invalid : "
+                      "[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
+                      s->ctrl->name, cs, seg.addr, seg.addr + seg.size);
+        return;
+    }
+
+    /* Check start address vs. alignment */
+    if (seg.addr % seg.size) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is not "
+                      "aligned : [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
+                      s->ctrl->name, cs, seg.addr, seg.addr + seg.size);
+    }
+
+    /* And segments should not overlap */
+    if (aspeed_smc_flash_overlap(s, &seg, cs)) {
+        return;
+    }
+
+    /* All should be fine now to move the region */
+    memory_region_transaction_begin();
+    memory_region_set_size(&fl->mmio, seg.size);
+    memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
+    memory_region_set_enabled(&fl->mmio, true);
+    memory_region_transaction_commit();
+
+    s->regs[R_SEG_ADDR0 + cs] = new;
+}
+
 static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
                                               unsigned size)
 {
@@ -314,6 +425,12 @@ static void aspeed_smc_reset(DeviceState *d)
         s->regs[s->r_ctrl0 + i] |= CTRL_CE_STOP_ACTIVE;
     }
 
+    /* setup default segment register values for all */
+    for (i = 0; i < s->ctrl->max_slaves; ++i) {
+        s->regs[R_SEG_ADDR0 + i] =
+            aspeed_smc_segment_to_reg(&s->ctrl->segments[i]);
+    }
+
     aspeed_smc_update_cs(s);
 }
 
@@ -334,6 +451,7 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
         addr == s->r_timings ||
         addr == s->r_ce_ctrl ||
         addr == R_INTR_CTRL ||
+        (addr >= R_SEG_ADDR0 && addr < R_SEG_ADDR0 + s->ctrl->max_slaves) ||
         (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs)) {
         return s->regs[addr];
     } else {
@@ -365,6 +483,13 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
     } else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
         s->regs[addr] = value;
         aspeed_smc_update_cs(s);
+    } else if (addr >= R_SEG_ADDR0 &&
+               addr < R_SEG_ADDR0 + s->ctrl->max_slaves) {
+        int cs = addr - R_SEG_ADDR0;
+
+        if (value != s->regs[R_SEG_ADDR0 + cs]) {
+            aspeed_smc_flash_set_segment(s, cs, value);
+        }
     } else {
         qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
                       __func__, addr);
-- 
2.7.4

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

* [Qemu-devel] [PULL 10/25] hw/arm/boot: allow using a command line specified dtb without a kernel
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (8 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 09/25] aspeed: add support for the SMC segment registers Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 11/25] hw/dma/pl080: Fix bad bit mask (PL080_CONF_M1 | PL080_CONF_M1) Peter Maydell
                   ` (15 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Michael Olbrich <m.olbrich@pengutronix.de>

When kernel and device tree are specified in the QEMU commandline, then
this device tree may be modified e.g. to add virtio_mmio devices.
With a bootloader e.g. on a flash device these extra devices are not
available.
With this change, the device tree can be specified at the QEMU commandline.
The modified device tree made available to the bootloader with the same
mechanism already supported by device trees fully generated by QEMU.

Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
Message-id: 1473520054-402-1-git-send-email-m.olbrich@pengutronix.de
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/boot.c | 4 ++--
 vl.c          | 5 -----
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 1b913a4..942416d 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -773,6 +773,8 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
      */
     assert(!(info->secure_board_setup && kvm_enabled()));
 
+    info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
+
     /* Load the kernel.  */
     if (!info->kernel_filename || info->firmware_loaded) {
 
@@ -833,8 +835,6 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
         elf_machine = EM_ARM;
     }
 
-    info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
-
     if (!info->secondary_cpu_reset_hook) {
         info->secondary_cpu_reset_hook = default_reset_secondary;
     }
diff --git a/vl.c b/vl.c
index c657acd..2569ec2 100644
--- a/vl.c
+++ b/vl.c
@@ -4389,11 +4389,6 @@ int main(int argc, char **argv, char **envp)
         exit(1);
     }
 
-    if (!linux_boot && qemu_opt_get(machine_opts, "dtb")) {
-        error_report("-dtb only allowed with -kernel option");
-        exit(1);
-    }
-
     if (semihosting_enabled() && !semihosting_get_argc() && kernel_filename) {
         /* fall back to the -kernel/-append */
         semihosting_arg_fallback(kernel_filename, kernel_cmdline);
-- 
2.7.4

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

* [Qemu-devel] [PULL 11/25] hw/dma/pl080: Fix bad bit mask (PL080_CONF_M1 | PL080_CONF_M1)
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (9 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 10/25] hw/arm/boot: allow using a command line specified dtb without a kernel Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 12/25] hw/intc/arm_gic_kvm: Fix build on aarch64 Peter Maydell
                   ` (14 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Thomas Huth <thuth@redhat.com>

The M1 and M2 bits are both used for configuring the endianness
of the AHB master interfaces, so the second PL080_CONF_M1 should
be PL080_CONF_M2 instead.

Buglink: https://bugs.launchpad.net/qemu/+bug/1631773
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-id: 1476274451-26567-1-git-send-email-thuth@redhat.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/dma/pl080.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
index 3bed5c3..7724c93 100644
--- a/hw/dma/pl080.c
+++ b/hw/dma/pl080.c
@@ -351,7 +351,7 @@ static void pl080_write(void *opaque, hwaddr offset,
         break;
     case 12: /* Configuration */
         s->conf = value;
-        if (s->conf & (PL080_CONF_M1 | PL080_CONF_M1)) {
+        if (s->conf & (PL080_CONF_M1 | PL080_CONF_M2)) {
             qemu_log_mask(LOG_UNIMP,
                           "pl080_write: Big-endian DMA not implemented\n");
         }
-- 
2.7.4

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

* [Qemu-devel] [PULL 12/25] hw/intc/arm_gic_kvm: Fix build on aarch64
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (10 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 11/25] hw/dma/pl080: Fix bad bit mask (PL080_CONF_M1 | PL080_CONF_M1) Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 13/25] hw/arm/virt-acpi-build: fix MADT generation Peter Maydell
                   ` (13 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Christopher Covington <cov@codeaurora.org>

Remove unused debugging code to fix native building on aarch64. Without
this change, the following -Werr output inhibits make from completing.

  qemu/hw/intc/arm_gic_kvm.c:38:18: error: debug_gic_kvm defined but not used [-Werror=unused-const-variable=]
   static const int debug_gic_kvm = 0;
                    ^~~~~~~~~~~~~
  cc1: all warnings being treated as errors
  qemu/rules.mak:60: recipe for target 'hw/intc/arm_gic_kvm.o' failed
  make[1]: *** [hw/intc/arm_gic_kvm.o] Error 1
  Makefile:205: recipe for target 'subdir-aarch64-softmmu' failed

Signed-off-by: Christopher Covington <cov@codeaurora.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20161011163202.19720-1-cov@codeaurora.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/intc/arm_gic_kvm.c | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
index ae7ac58..11729ee 100644
--- a/hw/intc/arm_gic_kvm.c
+++ b/hw/intc/arm_gic_kvm.c
@@ -30,20 +30,6 @@
 #include "gic_internal.h"
 #include "vgic_common.h"
 
-//#define DEBUG_GIC_KVM
-
-#ifdef DEBUG_GIC_KVM
-static const int debug_gic_kvm = 1;
-#else
-static const int debug_gic_kvm = 0;
-#endif
-
-#define DPRINTF(fmt, ...) do { \
-        if (debug_gic_kvm) { \
-            printf("arm_gic: " fmt , ## __VA_ARGS__); \
-        } \
-    } while (0)
-
 #define TYPE_KVM_ARM_GIC "kvm-arm-gic"
 #define KVM_ARM_GIC(obj) \
      OBJECT_CHECK(GICState, (obj), TYPE_KVM_ARM_GIC)
-- 
2.7.4

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

* [Qemu-devel] [PULL 13/25] hw/arm/virt-acpi-build: fix MADT generation
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (11 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 12/25] hw/intc/arm_gic_kvm: Fix build on aarch64 Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 14/25] hw/arm/virt: no ITS on older machine types Peter Maydell
                   ` (12 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Andrew Jones <drjones@redhat.com>

We can't return early from build_* functions, as build_header is
only called at the end.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Message-id: 1476117341-32690-2-git-send-email-drjones@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/virt-acpi-build.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index c77525d..779d83d 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -554,15 +554,13 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
         gicr->base_address = cpu_to_le64(memmap[VIRT_GIC_REDIST].base);
         gicr->range_length = cpu_to_le32(memmap[VIRT_GIC_REDIST].size);
 
-        if (!its_class_name()) {
-            return;
+        if (its_class_name()) {
+            gic_its = acpi_data_push(table_data, sizeof *gic_its);
+            gic_its->type = ACPI_APIC_GENERIC_TRANSLATOR;
+            gic_its->length = sizeof(*gic_its);
+            gic_its->translation_id = 0;
+            gic_its->base_address = cpu_to_le64(memmap[VIRT_GIC_ITS].base);
         }
-
-        gic_its = acpi_data_push(table_data, sizeof *gic_its);
-        gic_its->type = ACPI_APIC_GENERIC_TRANSLATOR;
-        gic_its->length = sizeof(*gic_its);
-        gic_its->translation_id = 0;
-        gic_its->base_address = cpu_to_le64(memmap[VIRT_GIC_ITS].base);
     } else {
         gic_msi = acpi_data_push(table_data, sizeof *gic_msi);
         gic_msi->type = ACPI_APIC_GENERIC_MSI_FRAME;
-- 
2.7.4

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

* [Qemu-devel] [PULL 14/25] hw/arm/virt: no ITS on older machine types
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (12 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 13/25] hw/arm/virt-acpi-build: fix MADT generation Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 15/25] tests: add a m25p80 test Peter Maydell
                   ` (11 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Andrew Jones <drjones@redhat.com>

We should avoid exposing new hardware (through DT and ACPI) on older
machine types. This patch keeps 2.7 and older from changing, despite
the introduction of ITS support for 2.8.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Message-id: 1476117341-32690-3-git-send-email-drjones@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/virt-acpi-build.c         |  2 +-
 hw/arm/virt.c                    | 15 +++++++++++----
 include/hw/arm/virt-acpi-build.h |  1 +
 3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 779d83d..fa0655a 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -554,7 +554,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
         gicr->base_address = cpu_to_le64(memmap[VIRT_GIC_REDIST].base);
         gicr->range_length = cpu_to_le32(memmap[VIRT_GIC_REDIST].size);
 
-        if (its_class_name()) {
+        if (its_class_name() && !guest_info->no_its) {
             gic_its = acpi_data_push(table_data, sizeof *gic_its);
             gic_its->type = ACPI_APIC_GENERIC_TRANSLATOR;
             gic_its->length = sizeof(*gic_its);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 795740d..895446f 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -84,6 +84,7 @@ typedef struct {
     MachineClass parent;
     VirtBoardInfo *daughterboard;
     bool disallow_affinity_adjustment;
+    bool no_its;
 } VirtMachineClass;
 
 typedef struct {
@@ -551,7 +552,8 @@ static void create_v2m(VirtBoardInfo *vbi, qemu_irq *pic)
     fdt_add_v2m_gic_node(vbi);
 }
 
-static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic, int type, bool secure)
+static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic, int type,
+                       bool secure, bool no_its)
 {
     /* We create a standalone GIC */
     DeviceState *gicdev;
@@ -615,9 +617,9 @@ static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic, int type, bool secure)
 
     fdt_add_gic_node(vbi, type);
 
-    if (type == 3) {
+    if (type == 3 && !no_its) {
         create_its(vbi, gicdev);
-    } else {
+    } else if (type == 2) {
         create_v2m(vbi, pic);
     }
 }
@@ -1375,7 +1377,7 @@ static void machvirt_init(MachineState *machine)
 
     create_flash(vbi, sysmem, secure_sysmem ? secure_sysmem : sysmem);
 
-    create_gic(vbi, pic, gic_version, vms->secure);
+    create_gic(vbi, pic, gic_version, vms->secure, vmc->no_its);
 
     fdt_add_pmu_nodes(vbi, gic_version);
 
@@ -1407,6 +1409,7 @@ static void machvirt_init(MachineState *machine)
     guest_info->irqmap = vbi->irqmap;
     guest_info->use_highmem = vms->highmem;
     guest_info->gic_version = gic_version;
+    guest_info->no_its = vmc->no_its;
     guest_info_state->machine_done.notify = virt_guest_info_machine_done;
     qemu_add_machine_init_done_notifier(&guest_info_state->machine_done);
 
@@ -1561,8 +1564,12 @@ static void virt_2_7_instance_init(Object *obj)
 
 static void virt_machine_2_7_options(MachineClass *mc)
 {
+    VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
+
     virt_machine_2_8_options(mc);
     SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_7);
+    /* ITS was introduced with 2.8 */
+    vmc->no_its = true;
 }
 DEFINE_VIRT_MACHINE(2, 7)
 
diff --git a/include/hw/arm/virt-acpi-build.h b/include/hw/arm/virt-acpi-build.h
index e43330a..f5ec749 100644
--- a/include/hw/arm/virt-acpi-build.h
+++ b/include/hw/arm/virt-acpi-build.h
@@ -33,6 +33,7 @@ typedef struct VirtGuestInfo {
     const int *irqmap;
     bool use_highmem;
     int gic_version;
+    bool no_its;
 } VirtGuestInfo;
 
 
-- 
2.7.4

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

* [Qemu-devel] [PULL 15/25] tests: add a m25p80 test
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (13 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 14/25] hw/arm/virt: no ITS on older machine types Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 16/25] tests: cleanup ptimer-test Peter Maydell
                   ` (10 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Cédric Le Goater <clg@kaod.org>

This test uses the palmetto platform and the Aspeed SPI controller to
test the m25p80 flash module device model. The flash model is defined
by the platform (n25q256a) and it would be nice to find way to control
it, using a property probably.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1475787271-28794-1-git-send-email-clg@kaod.org
Brainstormed-with: Greg Kurz <groug@kaod.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 tests/Makefile.include |   2 +
 tests/m25p80-test.c    | 252 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 254 insertions(+)
 create mode 100644 tests/m25p80-test.c

diff --git a/tests/Makefile.include b/tests/Makefile.include
index a77777c..33ea83e 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -295,6 +295,7 @@ check-qtest-sparc64-y = tests/endianness-test$(EXESUF)
 
 check-qtest-arm-y = tests/tmp105-test$(EXESUF)
 check-qtest-arm-y += tests/ds1338-test$(EXESUF)
+check-qtest-arm-y += tests/m25p80-test$(EXESUF)
 gcov-files-arm-y += hw/misc/tmp105.c
 check-qtest-arm-y += tests/virtio-blk-test$(EXESUF)
 gcov-files-arm-y += arm-softmmu/hw/block/virtio-blk.c
@@ -626,6 +627,7 @@ tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o \
 tests/pxe-test$(EXESUF): tests/pxe-test.o tests/boot-sector.o $(libqos-obj-y)
 tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
 tests/ds1338-test$(EXESUF): tests/ds1338-test.o $(libqos-imx-obj-y)
+tests/m25p80-test$(EXESUF): tests/m25p80-test.o
 tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
 tests/q35-test$(EXESUF): tests/q35-test.o $(libqos-pc-obj-y)
 tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
diff --git a/tests/m25p80-test.c b/tests/m25p80-test.c
new file mode 100644
index 0000000..cb7ec81
--- /dev/null
+++ b/tests/m25p80-test.c
@@ -0,0 +1,252 @@
+/*
+ * QTest testcase for the M25P80 Flash (Using the Aspeed SPI
+ * Controller)
+ *
+ * Copyright (C) 2016 IBM Corp.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/bswap.h"
+#include "libqtest.h"
+
+/*
+ * ASPEED SPI Controller registers
+ */
+#define R_CONF              0x00
+#define   CONF_ENABLE_W0       (1 << 16)
+#define R_CE_CTRL           0x04
+#define   CRTL_EXTENDED0       0  /* 32 bit addressing for SPI */
+#define R_CTRL0             0x10
+#define   CTRL_CE_STOP_ACTIVE  (1 << 2)
+#define   CTRL_USERMODE        0x3
+
+#define ASPEED_FMC_BASE    0x1E620000
+#define ASPEED_FLASH_BASE  0x20000000
+
+/*
+ * Flash commands
+ */
+enum {
+    JEDEC_READ = 0x9f,
+    BULK_ERASE = 0xc7,
+    READ = 0x03,
+    PP = 0x02,
+    WREN = 0x6,
+    EN_4BYTE_ADDR = 0xB7,
+    ERASE_SECTOR = 0xd8,
+};
+
+#define FLASH_JEDEC         0x20ba19  /* n25q256a */
+#define FLASH_SIZE          (32 * 1024 * 1024)
+
+#define PAGE_SIZE           256
+
+/*
+ * Use an explicit bswap for the values read/wrote to the flash region
+ * as they are BE and the Aspeed CPU is LE.
+ */
+static inline uint32_t make_be32(uint32_t data)
+{
+    return bswap32(data);
+}
+
+static void spi_conf(uint32_t value)
+{
+    uint32_t conf = readl(ASPEED_FMC_BASE + R_CONF);
+
+    conf |= value;
+    writel(ASPEED_FMC_BASE + R_CONF, conf);
+}
+
+static void spi_ctrl_start_user(void)
+{
+    uint32_t ctrl = readl(ASPEED_FMC_BASE + R_CTRL0);
+
+    ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE;
+    writel(ASPEED_FMC_BASE + R_CTRL0, ctrl);
+
+    ctrl &= ~CTRL_CE_STOP_ACTIVE;
+    writel(ASPEED_FMC_BASE + R_CTRL0, ctrl);
+}
+
+static void spi_ctrl_stop_user(void)
+{
+    uint32_t ctrl = readl(ASPEED_FMC_BASE + R_CTRL0);
+
+    ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE;
+    writel(ASPEED_FMC_BASE + R_CTRL0, ctrl);
+}
+
+static void test_read_jedec(void)
+{
+    uint32_t jedec = 0x0;
+
+    spi_conf(CONF_ENABLE_W0);
+
+    spi_ctrl_start_user();
+    writeb(ASPEED_FLASH_BASE, JEDEC_READ);
+    jedec |= readb(ASPEED_FLASH_BASE) << 16;
+    jedec |= readb(ASPEED_FLASH_BASE) << 8;
+    jedec |= readb(ASPEED_FLASH_BASE);
+    spi_ctrl_stop_user();
+
+    g_assert_cmphex(jedec, ==, FLASH_JEDEC);
+}
+
+static void read_page(uint32_t addr, uint32_t *page)
+{
+    int i;
+
+    spi_ctrl_start_user();
+
+    writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR);
+    writeb(ASPEED_FLASH_BASE, READ);
+    writel(ASPEED_FLASH_BASE, make_be32(addr));
+
+    /* Continuous read are supported */
+    for (i = 0; i < PAGE_SIZE / 4; i++) {
+        page[i] = make_be32(readl(ASPEED_FLASH_BASE));
+    }
+    spi_ctrl_stop_user();
+}
+
+static void test_erase_sector(void)
+{
+    uint32_t some_page_addr = 0x600 * PAGE_SIZE;
+    uint32_t page[PAGE_SIZE / 4];
+    int i;
+
+    spi_conf(CONF_ENABLE_W0);
+
+    spi_ctrl_start_user();
+    writeb(ASPEED_FLASH_BASE, WREN);
+    writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR);
+    writeb(ASPEED_FLASH_BASE, ERASE_SECTOR);
+    writel(ASPEED_FLASH_BASE, make_be32(some_page_addr));
+    spi_ctrl_stop_user();
+
+    /* Previous page should be full of zeroes as backend is not
+     * initialized */
+    read_page(some_page_addr - PAGE_SIZE, page);
+    for (i = 0; i < PAGE_SIZE / 4; i++) {
+        g_assert_cmphex(page[i], ==, 0x0);
+    }
+
+    /* But this one was erased */
+    read_page(some_page_addr, page);
+    for (i = 0; i < PAGE_SIZE / 4; i++) {
+        g_assert_cmphex(page[i], ==, 0xffffffff);
+    }
+}
+
+static void test_erase_all(void)
+{
+    uint32_t some_page_addr = 0x15000 * PAGE_SIZE;
+    uint32_t page[PAGE_SIZE / 4];
+    int i;
+
+    spi_conf(CONF_ENABLE_W0);
+
+    /* Check some random page. Should be full of zeroes as backend is
+     * not initialized */
+    read_page(some_page_addr, page);
+    for (i = 0; i < PAGE_SIZE / 4; i++) {
+        g_assert_cmphex(page[i], ==, 0x0);
+    }
+
+    spi_ctrl_start_user();
+    writeb(ASPEED_FLASH_BASE, WREN);
+    writeb(ASPEED_FLASH_BASE, BULK_ERASE);
+    spi_ctrl_stop_user();
+
+    /* Recheck that some random page */
+    read_page(some_page_addr, page);
+    for (i = 0; i < PAGE_SIZE / 4; i++) {
+        g_assert_cmphex(page[i], ==, 0xffffffff);
+    }
+}
+
+static void test_write_page(void)
+{
+    uint32_t my_page_addr = 0x14000 * PAGE_SIZE; /* beyond 16MB */
+    uint32_t some_page_addr = 0x15000 * PAGE_SIZE;
+    uint32_t page[PAGE_SIZE / 4];
+    int i;
+
+    spi_conf(CONF_ENABLE_W0);
+
+    spi_ctrl_start_user();
+    writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR);
+    writeb(ASPEED_FLASH_BASE, PP);
+    writel(ASPEED_FLASH_BASE, make_be32(my_page_addr));
+
+    /* Fill the page with its own addresses */
+    for (i = 0; i < PAGE_SIZE / 4; i++) {
+        writel(ASPEED_FLASH_BASE, make_be32(my_page_addr + i * 4));
+    }
+    spi_ctrl_stop_user();
+
+    /* Check what was written */
+    read_page(my_page_addr, page);
+    for (i = 0; i < PAGE_SIZE / 4; i++) {
+        g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
+    }
+
+    /* Check some other page. It should be full of 0xff */
+    read_page(some_page_addr, page);
+    for (i = 0; i < PAGE_SIZE / 4; i++) {
+        g_assert_cmphex(page[i], ==, 0xffffffff);
+    }
+}
+
+static char tmp_path[] = "/tmp/qtest.m25p80.XXXXXX";
+
+int main(int argc, char **argv)
+{
+    int ret;
+    int fd;
+    char *args;
+
+    g_test_init(&argc, &argv, NULL);
+
+    fd = mkstemp(tmp_path);
+    g_assert(fd >= 0);
+    ret = ftruncate(fd, FLASH_SIZE);
+    g_assert(ret == 0);
+    close(fd);
+
+    args = g_strdup_printf("-m 256 -machine palmetto-bmc "
+                           "-drive file=%s,format=raw,if=mtd",
+                           tmp_path);
+    qtest_start(args);
+
+    qtest_add_func("/m25p80/read_jedec", test_read_jedec);
+    qtest_add_func("/m25p80/erase_sector", test_erase_sector);
+    qtest_add_func("/m25p80/erase_all",  test_erase_all);
+    qtest_add_func("/m25p80/write_page", test_write_page);
+
+    ret = g_test_run();
+
+    qtest_quit(global_qtest);
+    unlink(tmp_path);
+    g_free(args);
+    return ret;
+}
-- 
2.7.4

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

* [Qemu-devel] [PULL 16/25] tests: cleanup ptimer-test
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (14 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 15/25] tests: add a m25p80 test Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 17/25] pxa2xx: Auto-assign name for i2c bus in i2c_init_bus Peter Maydell
                   ` (9 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Paolo Bonzini <pbonzini@redhat.com>

1) ptimer-test is not a qtest---it runs the ptimer.c code directly in the
ptimer-test process

2) ptimer-test has its own stubs file, so there is no need to add more
stubs to stubs/vmstate.c

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 stubs/vmstate.c           |  5 -----
 tests/Makefile.include    |  5 +++--
 tests/ptimer-test-stubs.c |  7 +++++++
 tests/ptimer-test.c       | 22 +++++++++++-----------
 4 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/stubs/vmstate.c b/stubs/vmstate.c
index 94b831e..6590627 100644
--- a/stubs/vmstate.c
+++ b/stubs/vmstate.c
@@ -3,11 +3,6 @@
 #include "migration/vmstate.h"
 
 const VMStateDescription vmstate_dummy = {};
-const VMStateInfo vmstate_info_uint8;
-const VMStateInfo vmstate_info_uint32;
-const VMStateInfo vmstate_info_uint64;
-const VMStateInfo vmstate_info_int64;
-const VMStateInfo vmstate_info_timer;
 
 int vmstate_register_with_alias_id(DeviceState *dev,
                                    int instance_id,
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 33ea83e..cbe38ad 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -116,6 +116,8 @@ check-unit-$(CONFIG_REPLICATION) += tests/test-replication$(EXESUF)
 check-unit-y += tests/test-bufferiszero$(EXESUF)
 gcov-files-check-bufferiszero-y = util/bufferiszero.c
 check-unit-y += tests/test-uuid$(EXESUF)
+check-unit-y += tests/ptimer-test$(EXESUF)
+gcov-files-ptimer-test-y = hw/core/ptimer.c
 
 check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
 
@@ -307,7 +309,6 @@ check-qtest-xtensaeb-y = $(check-qtest-xtensa-y)
 check-qtest-s390x-y = tests/boot-serial-test$(EXESUF)
 
 check-qtest-generic-y += tests/qom-test$(EXESUF)
-check-qtest-generic-y += tests/ptimer-test$(EXESUF)
 
 qapi-schema += alternate-any.json
 qapi-schema += alternate-array.json
@@ -515,6 +516,7 @@ tests/test-timed-average$(EXESUF): tests/test-timed-average.o qemu-timer.o \
 	$(test-util-obj-y)
 tests/test-base64$(EXESUF): tests/test-base64.o \
 	libqemuutil.a libqemustub.a
+tests/ptimer-test$(EXESUF): tests/ptimer-test.o tests/ptimer-test-stubs.o hw/core/ptimer.o libqemustub.a
 
 tests/test-logging$(EXESUF): tests/test-logging.o $(test-util-obj-y)
 
@@ -677,7 +679,6 @@ tests/test-filter-redirector$(EXESUF): tests/test-filter-redirector.o $(qtest-ob
 tests/test-x86-cpuid-compat$(EXESUF): tests/test-x86-cpuid-compat.o $(qtest-obj-y)
 tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y)
 tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o
-tests/ptimer-test$(EXESUF): tests/ptimer-test.o tests/ptimer-test-stubs.o hw/core/ptimer.o
 tests/test-uuid$(EXESUF): tests/test-uuid.o $(test-util-obj-y)
 
 tests/migration/stress$(EXESUF): tests/migration/stress.o
diff --git a/tests/ptimer-test-stubs.c b/tests/ptimer-test-stubs.c
index 92a22fb..e028a81 100644
--- a/tests/ptimer-test-stubs.c
+++ b/tests/ptimer-test-stubs.c
@@ -11,9 +11,16 @@
 #include "qemu/osdep.h"
 #include "qemu/main-loop.h"
 #include "sysemu/replay.h"
+#include "migration/vmstate.h"
 
 #include "ptimer-test.h"
 
+const VMStateInfo vmstate_info_uint8;
+const VMStateInfo vmstate_info_uint32;
+const VMStateInfo vmstate_info_uint64;
+const VMStateInfo vmstate_info_int64;
+const VMStateInfo vmstate_info_timer;
+
 struct QEMUBH {
     QEMUBHFunc *cb;
     void *opaque;
diff --git a/tests/ptimer-test.c b/tests/ptimer-test.c
index f207eeb..7b0ddf6 100644
--- a/tests/ptimer-test.c
+++ b/tests/ptimer-test.c
@@ -505,47 +505,47 @@ static void add_ptimer_tests(uint8_t policy)
         g_sprintf(policy_name, "default");
     }
 
-    qtest_add_data_func(
+    g_test_add_data_func(
         g_strdup_printf("/ptimer/set_count policy=%s", policy_name),
         ppolicy, check_set_count);
 
-    qtest_add_data_func(
+    g_test_add_data_func(
         g_strdup_printf("/ptimer/set_limit policy=%s", policy_name),
         ppolicy, check_set_limit);
 
-    qtest_add_data_func(
+    g_test_add_data_func(
         g_strdup_printf("/ptimer/oneshot policy=%s", policy_name),
         ppolicy, check_oneshot);
 
-    qtest_add_data_func(
+    g_test_add_data_func(
         g_strdup_printf("/ptimer/periodic policy=%s", policy_name),
         ppolicy, check_periodic);
 
-    qtest_add_data_func(
+    g_test_add_data_func(
         g_strdup_printf("/ptimer/on_the_fly_mode_change policy=%s", policy_name),
         ppolicy, check_on_the_fly_mode_change);
 
-    qtest_add_data_func(
+    g_test_add_data_func(
         g_strdup_printf("/ptimer/on_the_fly_period_change policy=%s", policy_name),
         ppolicy, check_on_the_fly_period_change);
 
-    qtest_add_data_func(
+    g_test_add_data_func(
         g_strdup_printf("/ptimer/on_the_fly_freq_change policy=%s", policy_name),
         ppolicy, check_on_the_fly_freq_change);
 
-    qtest_add_data_func(
+    g_test_add_data_func(
         g_strdup_printf("/ptimer/run_with_period_0 policy=%s", policy_name),
         ppolicy, check_run_with_period_0);
 
-    qtest_add_data_func(
+    g_test_add_data_func(
         g_strdup_printf("/ptimer/run_with_delta_0 policy=%s", policy_name),
         ppolicy, check_run_with_delta_0);
 
-    qtest_add_data_func(
+    g_test_add_data_func(
         g_strdup_printf("/ptimer/periodic_with_load_0 policy=%s", policy_name),
         ppolicy, check_periodic_with_load_0);
 
-    qtest_add_data_func(
+    g_test_add_data_func(
         g_strdup_printf("/ptimer/oneshot_with_load_0 policy=%s", policy_name),
         ppolicy, check_oneshot_with_load_0);
 }
-- 
2.7.4

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

* [Qemu-devel] [PULL 17/25] pxa2xx: Auto-assign name for i2c bus in i2c_init_bus.
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (15 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 16/25] tests: cleanup ptimer-test Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 18/25] target-arm: Infrastucture changes to enable handling of tagged address loading into PC Peter Maydell
                   ` (8 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Vijay Kumar B <vijaykumar@zilogic.com>

If a name is provided, the same name is assigned to both the I2C
controllers. Leaving it NULL, causes names to be automatically
assigned with an ID suffix, giving unique names to each
controller. This helps us to uniquely identify each controller in the
device tree, for example when adding an I2C device.

Signed-off-by: Vijay Kumar B. <vijaykumar@zilogic.com>
Reviewed-by: Deepak S. <deepak@zilogic.com>
Message-id: 1476351885-8905-1-git-send-email-vijaykumar@zilogic.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/pxa2xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 0241e07..9898287 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -1505,7 +1505,7 @@ static void pxa2xx_i2c_initfn(Object *obj)
     PXA2xxI2CState *s = PXA2XX_I2C(obj);
     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 
-    s->bus = i2c_init_bus(dev, "i2c");
+    s->bus = i2c_init_bus(dev, NULL);
 
     memory_region_init_io(&s->iomem, obj, &pxa2xx_i2c_ops, s,
                           "pxa2xx-i2c", s->region_size);
-- 
2.7.4

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

* [Qemu-devel] [PULL 18/25] target-arm: Infrastucture changes to enable handling of tagged address loading into PC
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (16 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 17/25] pxa2xx: Auto-assign name for i2c bus in i2c_init_bus Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 19/25] target-arm: Code changes to implement overwrite of tag field on PC load Peter Maydell
                   ` (7 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Thomas Hanson <thomas.hanson@linaro.org>

When capturing the current CPU state for the TB, extract the TBI0 and TBI1
values from the correct TCR for the current EL and then add them to the TB
flags field.

Then, at the start of code generation for the block, copy the TBI fields
into the DisasContext structure.

Signed-off-by: Thomas Hanson <thomas.hanson@linaro.org>
Message-id: 1476301853-15774-2-git-send-email-thomas.hanson@linaro.org
[PMM: drop useless 'extern' keyword on function prototypes;
 provide CONFIG_USER_ONLY trivial versions of arm_regime_tbi[01]()]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu.h           | 52 ++++++++++++++++++++++++++++++++++++++++++++--
 target-arm/helper.c        | 46 ++++++++++++++++++++++++++++++++++++++++
 target-arm/translate-a64.c |  2 ++
 target-arm/translate.h     |  2 ++
 4 files changed, 100 insertions(+), 2 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 76d824d..2218c00 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -2191,7 +2191,11 @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
 #define ARM_TBFLAG_BE_DATA_SHIFT    20
 #define ARM_TBFLAG_BE_DATA_MASK     (1 << ARM_TBFLAG_BE_DATA_SHIFT)
 
-/* Bit usage when in AArch64 state: currently we have no A64 specific bits */
+/* Bit usage when in AArch64 state */
+#define ARM_TBFLAG_TBI0_SHIFT 0        /* TBI0 for EL0/1 or TBI for EL2/3 */
+#define ARM_TBFLAG_TBI0_MASK (0x1ull << ARM_TBFLAG_TBI0_SHIFT)
+#define ARM_TBFLAG_TBI1_SHIFT 1        /* TBI1 for EL0/1  */
+#define ARM_TBFLAG_TBI1_MASK (0x1ull << ARM_TBFLAG_TBI1_SHIFT)
 
 /* some convenience accessor macros */
 #define ARM_TBFLAG_AARCH64_STATE(F) \
@@ -2222,6 +2226,10 @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
     (((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT)
 #define ARM_TBFLAG_BE_DATA(F) \
     (((F) & ARM_TBFLAG_BE_DATA_MASK) >> ARM_TBFLAG_BE_DATA_SHIFT)
+#define ARM_TBFLAG_TBI0(F) \
+    (((F) & ARM_TBFLAG_TBI0_MASK) >> ARM_TBFLAG_TBI0_SHIFT)
+#define ARM_TBFLAG_TBI1(F) \
+    (((F) & ARM_TBFLAG_TBI1_MASK) >> ARM_TBFLAG_TBI1_SHIFT)
 
 static inline bool bswap_code(bool sctlr_b)
 {
@@ -2319,12 +2327,51 @@ static inline bool arm_cpu_bswap_data(CPUARMState *env)
 }
 #endif
 
+#ifndef CONFIG_USER_ONLY
+/**
+ * arm_regime_tbi0:
+ * @env: CPUARMState
+ * @mmu_idx: MMU index indicating required translation regime
+ *
+ * Extracts the TBI0 value from the appropriate TCR for the current EL
+ *
+ * Returns: the TBI0 value.
+ */
+uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx);
+
+/**
+ * arm_regime_tbi1:
+ * @env: CPUARMState
+ * @mmu_idx: MMU index indicating required translation regime
+ *
+ * Extracts the TBI1 value from the appropriate TCR for the current EL
+ *
+ * Returns: the TBI1 value.
+ */
+uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx);
+#else
+/* We can't handle tagged addresses properly in user-only mode */
+static inline uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx)
+{
+    return 0;
+}
+
+static inline uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx)
+{
+    return 0;
+}
+#endif
+
 static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
                                         target_ulong *cs_base, uint32_t *flags)
 {
+    ARMMMUIdx mmu_idx = cpu_mmu_index(env, false);
     if (is_a64(env)) {
         *pc = env->pc;
         *flags = ARM_TBFLAG_AARCH64_STATE_MASK;
+        /* Get control bits for tagged addresses */
+        *flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
+        *flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
     } else {
         *pc = env->regs[15];
         *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
@@ -2343,7 +2390,8 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
                    << ARM_TBFLAG_XSCALE_CPAR_SHIFT);
     }
 
-    *flags |= (cpu_mmu_index(env, false) << ARM_TBFLAG_MMUIDX_SHIFT);
+    *flags |= (mmu_idx << ARM_TBFLAG_MMUIDX_SHIFT);
+
     /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
      * states defined in the ARM ARM for software singlestep:
      *  SS_ACTIVE   PSTATE.SS   State
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 25f612d..70e2742 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -6720,6 +6720,52 @@ static inline TCR *regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx)
     return &env->cp15.tcr_el[regime_el(env, mmu_idx)];
 }
 
+/* Returns TBI0 value for current regime el */
+uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx)
+{
+    TCR *tcr;
+    uint32_t el;
+
+    /* For EL0 and EL1, TBI is controlled by stage 1's TCR, so convert
+       * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
+       */
+    if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
+        mmu_idx += ARMMMUIdx_S1NSE0;
+    }
+
+    tcr = regime_tcr(env, mmu_idx);
+    el = regime_el(env, mmu_idx);
+
+    if (el > 1) {
+        return extract64(tcr->raw_tcr, 20, 1);
+    } else {
+        return extract64(tcr->raw_tcr, 37, 1);
+    }
+}
+
+/* Returns TBI1 value for current regime el */
+uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx)
+{
+    TCR *tcr;
+    uint32_t el;
+
+    /* For EL0 and EL1, TBI is controlled by stage 1's TCR, so convert
+       * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
+       */
+    if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
+        mmu_idx += ARMMMUIdx_S1NSE0;
+    }
+
+    tcr = regime_tcr(env, mmu_idx);
+    el = regime_el(env, mmu_idx);
+
+    if (el > 1) {
+        return 0;
+    } else {
+        return extract64(tcr->raw_tcr, 38, 1);
+    }
+}
+
 /* Return the TTBR associated with this translation regime */
 static inline uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx,
                                    int ttbrn)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 307e281..3b15d2c 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -11175,6 +11175,8 @@ void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb)
     dc->condexec_mask = 0;
     dc->condexec_cond = 0;
     dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
+    dc->tbi0 = ARM_TBFLAG_TBI0(tb->flags);
+    dc->tbi1 = ARM_TBFLAG_TBI1(tb->flags);
     dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
 #if !defined(CONFIG_USER_ONLY)
     dc->user = (dc->current_el == 0);
diff --git a/target-arm/translate.h b/target-arm/translate.h
index dbd7ac8..a53f25a 100644
--- a/target-arm/translate.h
+++ b/target-arm/translate.h
@@ -22,6 +22,8 @@ typedef struct DisasContext {
     int user;
 #endif
     ARMMMUIdx mmu_idx; /* MMU index to use for normal loads/stores */
+    bool tbi0;         /* TBI0 for EL0/1 or TBI for EL2/3 */
+    bool tbi1;         /* TBI1 for EL0/1, not used for EL2/3 */
     bool ns;        /* Use non-secure CPREG bank on access */
     int fp_excp_el; /* FP exception EL or 0 if enabled */
     /* Flag indicating that exceptions from secure mode are routed to EL3. */
-- 
2.7.4

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

* [Qemu-devel] [PULL 19/25] target-arm: Code changes to implement overwrite of tag field on PC load
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (17 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 18/25] target-arm: Infrastucture changes to enable handling of tagged address loading into PC Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 20/25] target-arm: Comments added to identify cases in a switch Peter Maydell
                   ` (6 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Thomas Hanson <thomas.hanson@linaro.org>

For BR, BLR and RET instructions, if tagged addresses are enabled, the
tag field in the address must be cleared out prior to loading the
address into the PC.  Depending on the current EL, it will be set to
either all 0's or all 1's.

Signed-off-by: Thomas Hanson <thomas.hanson@linaro.org>
Message-id: 1476301853-15774-3-git-send-email-thomas.hanson@linaro.org
[PMM: remove unnecessary gen_a64_set_pc_reg() wrapper,
 rename gen_a64_set_pc_var() to gen_a64_set_pc(), fix stray
 misindentation]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/translate-a64.c | 82 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 77 insertions(+), 5 deletions(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 3b15d2c..16716a2 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -41,6 +41,7 @@ static TCGv_i64 cpu_pc;
 
 /* Load/store exclusive handling */
 static TCGv_i64 cpu_exclusive_high;
+static TCGv_i64 cpu_reg(DisasContext *s, int reg);
 
 static const char *regnames[] = {
     "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
@@ -176,6 +177,76 @@ void gen_a64_set_pc_im(uint64_t val)
     tcg_gen_movi_i64(cpu_pc, val);
 }
 
+/* Load the PC from a generic TCG variable.
+ *
+ * If address tagging is enabled via the TCR TBI bits, then loading
+ * an address into the PC will clear out any tag in the it:
+ *  + for EL2 and EL3 there is only one TBI bit, and if it is set
+ *    then the address is zero-extended, clearing bits [63:56]
+ *  + for EL0 and EL1, TBI0 controls addresses with bit 55 == 0
+ *    and TBI1 controls addressses with bit 55 == 1.
+ *    If the appropriate TBI bit is set for the address then
+ *    the address is sign-extended from bit 55 into bits [63:56]
+ *
+ * We can avoid doing this for relative-branches, because the
+ * PC + offset can never overflow into the tag bits (assuming
+ * that virtual addresses are less than 56 bits wide, as they
+ * are currently), but we must handle it for branch-to-register.
+ */
+static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
+{
+
+    if (s->current_el <= 1) {
+        /* Test if NEITHER or BOTH TBI values are set.  If so, no need to
+         * examine bit 55 of address, can just generate code.
+         * If mixed, then test via generated code
+         */
+        if (s->tbi0 && s->tbi1) {
+            TCGv_i64 tmp_reg = tcg_temp_new_i64();
+            /* Both bits set, sign extension from bit 55 into [63:56] will
+             * cover both cases
+             */
+            tcg_gen_shli_i64(tmp_reg, src, 8);
+            tcg_gen_sari_i64(cpu_pc, tmp_reg, 8);
+            tcg_temp_free_i64(tmp_reg);
+        } else if (!s->tbi0 && !s->tbi1) {
+            /* Neither bit set, just load it as-is */
+            tcg_gen_mov_i64(cpu_pc, src);
+        } else {
+            TCGv_i64 tcg_tmpval = tcg_temp_new_i64();
+            TCGv_i64 tcg_bit55  = tcg_temp_new_i64();
+            TCGv_i64 tcg_zero   = tcg_const_i64(0);
+
+            tcg_gen_andi_i64(tcg_bit55, src, (1ull << 55));
+
+            if (s->tbi0) {
+                /* tbi0==1, tbi1==0, so 0-fill upper byte if bit 55 = 0 */
+                tcg_gen_andi_i64(tcg_tmpval, src,
+                                 0x00FFFFFFFFFFFFFFull);
+                tcg_gen_movcond_i64(TCG_COND_EQ, cpu_pc, tcg_bit55, tcg_zero,
+                                    tcg_tmpval, src);
+            } else {
+                /* tbi0==0, tbi1==1, so 1-fill upper byte if bit 55 = 1 */
+                tcg_gen_ori_i64(tcg_tmpval, src,
+                                0xFF00000000000000ull);
+                tcg_gen_movcond_i64(TCG_COND_NE, cpu_pc, tcg_bit55, tcg_zero,
+                                    tcg_tmpval, src);
+            }
+            tcg_temp_free_i64(tcg_zero);
+            tcg_temp_free_i64(tcg_bit55);
+            tcg_temp_free_i64(tcg_tmpval);
+        }
+    } else {  /* EL > 1 */
+        if (s->tbi0) {
+            /* Force tag byte to all zero */
+            tcg_gen_andi_i64(cpu_pc, src, 0x00FFFFFFFFFFFFFFull);
+        } else {
+            /* Load unmodified address */
+            tcg_gen_mov_i64(cpu_pc, src);
+        }
+    }
+}
+
 typedef struct DisasCompare64 {
     TCGCond cond;
     TCGv_i64 value;
@@ -1704,12 +1775,13 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
 
     switch (opc) {
     case 0: /* BR */
-    case 2: /* RET */
-        tcg_gen_mov_i64(cpu_pc, cpu_reg(s, rn));
-        break;
     case 1: /* BLR */
-        tcg_gen_mov_i64(cpu_pc, cpu_reg(s, rn));
-        tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
+    case 2: /* RET */
+        gen_a64_set_pc(s, cpu_reg(s, rn));
+        /* BLR also needs to load return address */
+        if (opc == 1) {
+            tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
+        }
         break;
     case 4: /* ERET */
         if (s->current_el == 0) {
-- 
2.7.4

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

* [Qemu-devel] [PULL 20/25] target-arm: Comments added to identify cases in a switch
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (18 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 19/25] target-arm: Code changes to implement overwrite of tag field on PC load Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 21/25] Fix masking of PC lower bits when doing exception returns Peter Maydell
                   ` (5 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

From: Thomas Hanson <thomas.hanson@linaro.org>

3 cases in a switch in disas_exc() require reference to the
ARM ARM spec in order to determine what case they're handling.

Signed-off-by: Thomas Hanson <thomas.hanson@linaro.org>
Message-id: 1476301853-15774-5-git-send-email-thomas.hanson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/translate-a64.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 16716a2..96c2227 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1667,12 +1667,12 @@ static void disas_exc(DisasContext *s, uint32_t insn)
          * instruction works properly.
          */
         switch (op2_ll) {
-        case 1:
+        case 1:                                                     /* SVC */
             gen_ss_advance(s);
             gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16),
                                default_exception_el(s));
             break;
-        case 2:
+        case 2:                                                     /* HVC */
             if (s->current_el == 0) {
                 unallocated_encoding(s);
                 break;
@@ -1685,7 +1685,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
             gen_ss_advance(s);
             gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16), 2);
             break;
-        case 3:
+        case 3:                                                     /* SMC */
             if (s->current_el == 0) {
                 unallocated_encoding(s);
                 break;
-- 
2.7.4

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

* [Qemu-devel] [PULL 21/25] Fix masking of PC lower bits when doing exception returns
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (19 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 20/25] target-arm: Comments added to identify cases in a switch Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 22/25] target-arm: Implement dummy MDCCINT_EL1 Peter Maydell
                   ` (4 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

In commit 9b6a3ea7a699594 store_reg() was changed to mask
both bits 0 and 1 of the new PC value when in ARM mode.
Unfortunately this broke the exception return code paths
when doing a return from ARM mode to Thumb mode: in some
of these we write a new CPSR including new Thumb mode
bit via gen_helper_cpsr_write_eret(), and then use store_reg()
to write the new PC. In this case if the new CPSR specified
Thumb mode then masking bit 1 of the PC is incorrect
(these code paths correspond to the v8 ARM ARM pseudocode
function AArch32.ExceptionReturn(), which always aligns the
new PC appropriately for the new instruction set state).

Instead of using store_reg() in exception-return code paths,
call a new store_pc_exc_ret() which stores the raw new PC
value to env->regs[15], and then mask it appropriately in
the subsequent helper_cpsr_write_eret() where the new
env->thumb state is available.

This fixes a bug introduced by 9b6a3ea7a699594 which caused
crashes/hangs or otherwise bad behaviour for Linux when
userspace was using Thumb.

Reported-by: Jerome Forissier <jerome.forissier@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1476113163-24578-1-git-send-email-peter.maydell@linaro.org
---
 target-arm/op_helper.c |  7 +++++++
 target-arm/translate.c | 29 ++++++++++++++++++++---------
 2 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index be27b21..cd94216 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -479,6 +479,13 @@ void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val)
 {
     cpsr_write(env, val, CPSR_ERET_MASK, CPSRWriteExceptionReturn);
 
+    /* Generated code has already stored the new PC value, but
+     * without masking out its low bits, because which bits need
+     * masking depends on whether we're returning to Thumb or ARM
+     * state. Do the masking now.
+     */
+    env->regs[15] &= (env->thumb ? ~1 : ~3);
+
     arm_call_el_change_hook(arm_env_get_cpu(env));
 }
 
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 8df24bf..164b52a 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4363,26 +4363,35 @@ static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
     s->is_jmp = DISAS_UPDATE;
 }
 
-/* Generate an old-style exception return. Marks pc as dead. */
-static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
+/* Store value to PC as for an exception return (ie don't
+ * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
+ * will do the masking based on the new value of the Thumb bit.
+ */
+static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
 {
-    TCGv_i32 tmp;
-    store_reg(s, 15, pc);
-    tmp = load_cpu_field(spsr);
-    gen_helper_cpsr_write_eret(cpu_env, tmp);
-    tcg_temp_free_i32(tmp);
-    s->is_jmp = DISAS_JUMP;
+    tcg_gen_mov_i32(cpu_R[15], pc);
+    tcg_temp_free_i32(pc);
 }
 
 /* Generate a v6 exception return.  Marks both values as dead.  */
 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
 {
+    store_pc_exc_ret(s, pc);
+    /* The cpsr_write_eret helper will mask the low bits of PC
+     * appropriately depending on the new Thumb bit, so it must
+     * be called after storing the new PC.
+     */
     gen_helper_cpsr_write_eret(cpu_env, cpsr);
     tcg_temp_free_i32(cpsr);
-    store_reg(s, 15, pc);
     s->is_jmp = DISAS_JUMP;
 }
 
+/* Generate an old-style exception return. Marks pc as dead. */
+static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
+{
+    gen_rfe(s, pc, load_cpu_field(spsr));
+}
+
 static void gen_nop_hint(DisasContext *s, int val)
 {
     switch (val) {
@@ -9366,6 +9375,8 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
                             } else if (i == rn) {
                                 loaded_var = tmp;
                                 loaded_base = 1;
+                            } else if (rn == 15 && exc_return) {
+                                store_pc_exc_ret(s, tmp);
                             } else {
                                 store_reg_from_load(s, i, tmp);
                             }
-- 
2.7.4

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

* [Qemu-devel] [PULL 22/25] target-arm: Implement dummy MDCCINT_EL1
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (20 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 21/25] Fix masking of PC lower bits when doing exception returns Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 23/25] target-arm: Add trace events for the generic timers Peter Maydell
                   ` (3 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

MDCCINT_EL1 is part of the DCC debugger communication
channel between the CPU and an attached external debugger.
QEMU doesn't implement this, but since Linux may try
to access this register we need to provide at least
a dummy implementation.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1476294876-12340-2-git-send-email-peter.maydell@linaro.org
---
 target-arm/helper.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 70e2742..a65f4f2 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -4060,6 +4060,14 @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
       .cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
       .access = PL1_RW, .accessfn = access_tda,
       .type = ARM_CP_NOP },
+    /* Dummy MDCCINT_EL1, since we don't implement the Debug Communications
+     * Channel but Linux may try to access this register. The 32-bit
+     * alias is DBGDCCINT.
+     */
+    { .name = "MDCCINT_EL1", .state = ARM_CP_STATE_BOTH,
+      .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
+      .access = PL1_RW, .accessfn = access_tda,
+      .type = ARM_CP_NOP },
     REGINFO_SENTINEL
 };
 
-- 
2.7.4

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

* [Qemu-devel] [PULL 23/25] target-arm: Add trace events for the generic timers
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (21 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 22/25] target-arm: Implement dummy MDCCINT_EL1 Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 24/25] hw/intc/arm_gicv3: Fix ICC register tracepoints Peter Maydell
                   ` (2 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

Add some useful trace events for the ARM generic timers (notably
the various register writes and the resulting IRQ line state).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1476294876-12340-3-git-send-email-peter.maydell@linaro.org
---
 Makefile.objs           |  1 +
 target-arm/helper.c     | 20 ++++++++++++++++----
 target-arm/trace-events | 10 ++++++++++
 3 files changed, 27 insertions(+), 4 deletions(-)
 create mode 100644 target-arm/trace-events

diff --git a/Makefile.objs b/Makefile.objs
index 02fb8e7..69fdd48 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -155,6 +155,7 @@ trace-events-y += hw/alpha/trace-events
 trace-events-y += ui/trace-events
 trace-events-y += audio/trace-events
 trace-events-y += net/trace-events
+trace-events-y += target-arm/trace-events
 trace-events-y += target-i386/trace-events
 trace-events-y += target-sparc/trace-events
 trace-events-y += target-s390x/trace-events
diff --git a/target-arm/helper.c b/target-arm/helper.c
index a65f4f2..cb83ee2 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1,4 +1,5 @@
 #include "qemu/osdep.h"
+#include "trace.h"
 #include "cpu.h"
 #include "internals.h"
 #include "exec/gdbstub.h"
@@ -1560,10 +1561,13 @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
         /* Note that this must be unsigned 64 bit arithmetic: */
         int istatus = count - offset >= gt->cval;
         uint64_t nexttick;
+        int irqstate;
 
         gt->ctl = deposit32(gt->ctl, 2, 1, istatus);
-        qemu_set_irq(cpu->gt_timer_outputs[timeridx],
-                     (istatus && !(gt->ctl & 2)));
+
+        irqstate = (istatus && !(gt->ctl & 2));
+        qemu_set_irq(cpu->gt_timer_outputs[timeridx], irqstate);
+
         if (istatus) {
             /* Next transition is when count rolls back over to zero */
             nexttick = UINT64_MAX;
@@ -1580,11 +1584,13 @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
             nexttick = INT64_MAX / GTIMER_SCALE;
         }
         timer_mod(cpu->gt_timer[timeridx], nexttick);
+        trace_arm_gt_recalc(timeridx, irqstate, nexttick);
     } else {
         /* Timer disabled: ISTATUS and timer output always clear */
         gt->ctl &= ~4;
         qemu_set_irq(cpu->gt_timer_outputs[timeridx], 0);
         timer_del(cpu->gt_timer[timeridx]);
+        trace_arm_gt_recalc_disabled(timeridx);
     }
 }
 
@@ -1610,6 +1616,7 @@ static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
                           int timeridx,
                           uint64_t value)
 {
+    trace_arm_gt_cval_write(timeridx, value);
     env->cp15.c14_timer[timeridx].cval = value;
     gt_recalc_timer(arm_env_get_cpu(env), timeridx);
 }
@@ -1629,6 +1636,7 @@ static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
 {
     uint64_t offset = timeridx == GTIMER_VIRT ? env->cp15.cntvoff_el2 : 0;
 
+    trace_arm_gt_tval_write(timeridx, value);
     env->cp15.c14_timer[timeridx].cval = gt_get_countervalue(env) - offset +
                                          sextract64(value, 0, 32);
     gt_recalc_timer(arm_env_get_cpu(env), timeridx);
@@ -1641,6 +1649,7 @@ static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
     ARMCPU *cpu = arm_env_get_cpu(env);
     uint32_t oldval = env->cp15.c14_timer[timeridx].ctl;
 
+    trace_arm_gt_ctl_write(timeridx, value);
     env->cp15.c14_timer[timeridx].ctl = deposit64(oldval, 0, 2, value);
     if ((oldval ^ value) & 1) {
         /* Enable toggled */
@@ -1649,8 +1658,10 @@ static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
         /* IMASK toggled: don't need to recalculate,
          * just set the interrupt line based on ISTATUS
          */
-        qemu_set_irq(cpu->gt_timer_outputs[timeridx],
-                     (oldval & 4) && !(value & 2));
+        int irqstate = (oldval & 4) && !(value & 2);
+
+        trace_arm_gt_imask_toggle(timeridx, irqstate);
+        qemu_set_irq(cpu->gt_timer_outputs[timeridx], irqstate);
     }
 }
 
@@ -1715,6 +1726,7 @@ static void gt_cntvoff_write(CPUARMState *env, const ARMCPRegInfo *ri,
 {
     ARMCPU *cpu = arm_env_get_cpu(env);
 
+    trace_arm_gt_cntvoff_write(value);
     raw_write(env, ri, value);
     gt_recalc_timer(cpu, GTIMER_VIRT);
 }
diff --git a/target-arm/trace-events b/target-arm/trace-events
new file mode 100644
index 0000000..9f726bd
--- /dev/null
+++ b/target-arm/trace-events
@@ -0,0 +1,10 @@
+# See docs/tracing.txt for syntax documentation.
+
+# target-arm/helper.c
+arm_gt_recalc(int timer, int irqstate, uint64_t nexttick) "gt recalc: timer %d irqstate %d next tick %" PRIx64
+arm_gt_recalc_disabled(int timer) "gt recalc: timer %d irqstate 0 timer disabled"
+arm_gt_cval_write(int timer, uint64_t value) "gt_cval_write: timer %d value %" PRIx64
+arm_gt_tval_write(int timer, uint64_t value) "gt_tval_write: timer %d value %" PRIx64
+arm_gt_ctl_write(int timer, uint64_t value) "gt_ctl_write: timer %d value %" PRIx64
+arm_gt_imask_toggle(int timer, int irqstate) "gt_ctl_write: timer %d IMASK toggle, new irqstate %d"
+arm_gt_cntvoff_write(uint64_t value) "gt_cntvoff_write: value %" PRIx64
-- 
2.7.4

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

* [Qemu-devel] [PULL 24/25] hw/intc/arm_gicv3: Fix ICC register tracepoints
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (22 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 23/25] target-arm: Add trace events for the generic timers Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-17 18:40 ` [Qemu-devel] [PULL 25/25] hw/char/pl011: Add trace events Peter Maydell
  2016-10-18  8:25 ` [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

Fix some problems with the tracepoints for ICC register reads
and writes:
 * tracepoints for ICC_BPR<n>, ICC_AP<n>R<x>, ICC_IGRPEN<n>,
   ICC_EIOR<n> were not printing the <n> that indicated whether
   the access was to the group 0 or 1 register
 * the ICC_IGREPEN1_EL3 read function was not actually calling
   the associated tracepoint
 * the ICC_BPR<n> write function was incorrectly calling the
   tracepoint for ICC_PMR writes

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Acked-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1476294876-12340-4-git-send-email-peter.maydell@linaro.org
---
 hw/intc/arm_gicv3_cpuif.c | 23 +++++++++++++++--------
 hw/intc/trace-events      | 14 +++++++-------
 2 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
index 4633172..bca30c4 100644
--- a/hw/intc/arm_gicv3_cpuif.c
+++ b/hw/intc/arm_gicv3_cpuif.c
@@ -454,7 +454,8 @@ static void icc_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
     int irq = value & 0xffffff;
     int grp;
 
-    trace_gicv3_icc_eoir_write(gicv3_redist_affid(cs), value);
+    trace_gicv3_icc_eoir_write(ri->crm == 8 ? 0 : 1,
+                               gicv3_redist_affid(cs), value);
 
     if (ri->crm == 8) {
         /* EOIR0 */
@@ -542,7 +543,7 @@ static uint64_t icc_bpr_read(CPUARMState *env, const ARMCPRegInfo *ri)
         bpr = MIN(bpr, 7);
     }
 
-    trace_gicv3_icc_bpr_read(gicv3_redist_affid(cs), bpr);
+    trace_gicv3_icc_bpr_read(ri->crm == 8 ? 0 : 1, gicv3_redist_affid(cs), bpr);
 
     return bpr;
 }
@@ -553,7 +554,8 @@ static void icc_bpr_write(CPUARMState *env, const ARMCPRegInfo *ri,
     GICv3CPUState *cs = icc_cs_from_env(env);
     int grp = (ri->crm == 8) ? GICV3_G0 : GICV3_G1;
 
-    trace_gicv3_icc_pmr_write(gicv3_redist_affid(cs), value);
+    trace_gicv3_icc_bpr_write(ri->crm == 8 ? 0 : 1,
+                              gicv3_redist_affid(cs), value);
 
     if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
         grp = GICV3_G1NS;
@@ -591,7 +593,7 @@ static uint64_t icc_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
 
     value = cs->icc_apr[grp][regno];
 
-    trace_gicv3_icc_ap_read(regno, gicv3_redist_affid(cs), value);
+    trace_gicv3_icc_ap_read(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
     return value;
 }
 
@@ -603,7 +605,7 @@ static void icc_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
     int regno = ri->opc2 & 3;
     int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
 
-    trace_gicv3_icc_ap_write(regno, gicv3_redist_affid(cs), value);
+    trace_gicv3_icc_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
 
     if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
         grp = GICV3_G1NS;
@@ -820,7 +822,8 @@ static uint64_t icc_igrpen_read(CPUARMState *env, const ARMCPRegInfo *ri)
     }
 
     value = cs->icc_igrpen[grp];
-    trace_gicv3_icc_igrpen_read(gicv3_redist_affid(cs), value);
+    trace_gicv3_icc_igrpen_read(ri->opc2 & 1 ? 1 : 0,
+                                gicv3_redist_affid(cs), value);
     return value;
 }
 
@@ -830,7 +833,8 @@ static void icc_igrpen_write(CPUARMState *env, const ARMCPRegInfo *ri,
     GICv3CPUState *cs = icc_cs_from_env(env);
     int grp = ri->opc2 & 1 ? GICV3_G1 : GICV3_G0;
 
-    trace_gicv3_icc_igrpen_write(gicv3_redist_affid(cs), value);
+    trace_gicv3_icc_igrpen_write(ri->opc2 & 1 ? 1 : 0,
+                                 gicv3_redist_affid(cs), value);
 
     if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
         grp = GICV3_G1NS;
@@ -843,9 +847,12 @@ static void icc_igrpen_write(CPUARMState *env, const ARMCPRegInfo *ri,
 static uint64_t icc_igrpen1_el3_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     GICv3CPUState *cs = icc_cs_from_env(env);
+    uint64_t value;
 
     /* IGRPEN1_EL3 bits 0 and 1 are r/w aliases into IGRPEN1_EL1 NS and S */
-    return cs->icc_igrpen[GICV3_G1NS] | (cs->icc_igrpen[GICV3_G1] << 1);
+    value = cs->icc_igrpen[GICV3_G1NS] | (cs->icc_igrpen[GICV3_G1] << 1);
+    trace_gicv3_icc_igrpen1_el3_read(gicv3_redist_affid(cs), value);
+    return value;
 }
 
 static void icc_igrpen1_el3_write(CPUARMState *env, const ARMCPRegInfo *ri,
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index a367b46..340f617 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -85,12 +85,12 @@ gic_acknowledge_irq(int cpu, int irq) "cpu %d acknowledged irq %d"
 # hw/intc/arm_gicv3_cpuif.c
 gicv3_icc_pmr_read(uint32_t cpu, uint64_t val) "GICv3 ICC_PMR read cpu %x value 0x%" PRIx64
 gicv3_icc_pmr_write(uint32_t cpu, uint64_t val) "GICv3 ICC_PMR write cpu %x value 0x%" PRIx64
-gicv3_icc_bpr_read(uint32_t cpu, uint64_t val) "GICv3 ICC_BPR read cpu %x value 0x%" PRIx64
-gicv3_icc_bpr_write(uint32_t cpu, uint64_t val) "GICv3 ICC_BPR write cpu %x value 0x%" PRIx64
-gicv3_icc_ap_read(int regno, uint32_t cpu, uint64_t val) "GICv3 ICC_AP%dR read cpu %x value 0x%" PRIx64
-gicv3_icc_ap_write(int regno, uint32_t cpu, uint64_t val) "GICv3 ICC_AP%dR write cpu %x value 0x%" PRIx64
-gicv3_icc_igrpen_read(uint32_t cpu, uint64_t val) "GICv3 ICC_IGRPEN read cpu %x value 0x%" PRIx64
-gicv3_icc_igrpen_write(uint32_t cpu, uint64_t val) "GICv3 ICC_IGRPEN write cpu %x value 0x%" PRIx64
+gicv3_icc_bpr_read(int grp, uint32_t cpu, uint64_t val) "GICv3 ICC_BPR%d read cpu %x value 0x%" PRIx64
+gicv3_icc_bpr_write(int grp, uint32_t cpu, uint64_t val) "GICv3 ICC_BPR%d write cpu %x value 0x%" PRIx64
+gicv3_icc_ap_read(int grp, int regno, uint32_t cpu, uint64_t val) "GICv3 ICC_AP%dR%d read cpu %x value 0x%" PRIx64
+gicv3_icc_ap_write(int grp, int regno, uint32_t cpu, uint64_t val) "GICv3 ICC_AP%dR%d write cpu %x value 0x%" PRIx64
+gicv3_icc_igrpen_read(int grp, uint32_t cpu, uint64_t val) "GICv3 ICC_IGRPEN%d read cpu %x value 0x%" PRIx64
+gicv3_icc_igrpen_write(int grp, uint32_t cpu, uint64_t val) "GICv3 ICC_IGRPEN%d write cpu %x value 0x%" PRIx64
 gicv3_icc_igrpen1_el3_read(uint32_t cpu, uint64_t val) "GICv3 ICC_IGRPEN1_EL3 read cpu %x value 0x%" PRIx64
 gicv3_icc_igrpen1_el3_write(uint32_t cpu, uint64_t val) "GICv3 ICC_IGRPEN1_EL3 write cpu %x value 0x%" PRIx64
 gicv3_icc_ctlr_read(uint32_t cpu, uint64_t val) "GICv3 ICC_CTLR read cpu %x value 0x%" PRIx64
@@ -102,7 +102,7 @@ gicv3_cpuif_set_irqs(uint32_t cpuid, int fiqlevel, int irqlevel) "GICv3 CPU i/f
 gicv3_icc_generate_sgi(uint32_t cpuid, int irq, int irm, uint32_t aff, uint32_t targetlist) "GICv3 CPU i/f %x generating SGI %d IRM %d target affinity 0x%xxx targetlist 0x%x"
 gicv3_icc_iar0_read(uint32_t cpu, uint64_t val) "GICv3 ICC_IAR0 read cpu %x value 0x%" PRIx64
 gicv3_icc_iar1_read(uint32_t cpu, uint64_t val) "GICv3 ICC_IAR1 read cpu %x value 0x%" PRIx64
-gicv3_icc_eoir_write(uint32_t cpu, uint64_t val) "GICv3 ICC_EOIR write cpu %x value 0x%" PRIx64
+gicv3_icc_eoir_write(int grp, uint32_t cpu, uint64_t val) "GICv3 ICC_EOIR%d write cpu %x value 0x%" PRIx64
 gicv3_icc_hppir0_read(uint32_t cpu, uint64_t val) "GICv3 ICC_HPPIR0 read cpu %x value 0x%" PRIx64
 gicv3_icc_hppir1_read(uint32_t cpu, uint64_t val) "GICv3 ICC_HPPIR1 read cpu %x value 0x%" PRIx64
 gicv3_icc_dir_write(uint32_t cpu, uint64_t val) "GICv3 ICC_DIR write cpu %x value 0x%" PRIx64
-- 
2.7.4

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

* [Qemu-devel] [PULL 25/25] hw/char/pl011: Add trace events
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (23 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 24/25] hw/intc/arm_gicv3: Fix ICC register tracepoints Peter Maydell
@ 2016-10-17 18:40 ` Peter Maydell
  2016-10-18  8:25 ` [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-17 18:40 UTC (permalink / raw)
  To: qemu-devel

Add some trace events for the pl011 UART model.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1476294876-12340-5-git-send-email-peter.maydell@linaro.org
---
 hw/char/pl011.c      | 71 ++++++++++++++++++++++++++++++++++++----------------
 hw/char/trace-events |  9 +++++++
 2 files changed, 59 insertions(+), 21 deletions(-)

diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index 786e605..1a7911f 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -11,6 +11,7 @@
 #include "hw/sysbus.h"
 #include "sysemu/char.h"
 #include "qemu/log.h"
+#include "trace.h"
 
 #define TYPE_PL011 "pl011"
 #define PL011(obj) OBJECT_CHECK(PL011State, (obj), TYPE_PL011)
@@ -58,6 +59,7 @@ static void pl011_update(PL011State *s)
     uint32_t flags;
 
     flags = s->int_level & s->int_enabled;
+    trace_pl011_irq_state(flags != 0);
     qemu_set_irq(s->irq, flags != 0);
 }
 
@@ -66,10 +68,8 @@ static uint64_t pl011_read(void *opaque, hwaddr offset,
 {
     PL011State *s = (PL011State *)opaque;
     uint32_t c;
+    uint64_t r;
 
-    if (offset >= 0xfe0 && offset < 0x1000) {
-        return s->id[(offset - 0xfe0) >> 2];
-    }
     switch (offset >> 2) {
     case 0: /* UARTDR */
         s->flags &= ~PL011_FLAG_RXFF;
@@ -84,41 +84,62 @@ static uint64_t pl011_read(void *opaque, hwaddr offset,
         }
         if (s->read_count == s->read_trigger - 1)
             s->int_level &= ~ PL011_INT_RX;
+        trace_pl011_read_fifo(s->read_count);
         s->rsr = c >> 8;
         pl011_update(s);
         if (s->chr) {
             qemu_chr_accept_input(s->chr);
         }
-        return c;
+        r = c;
+        break;
     case 1: /* UARTRSR */
-        return s->rsr;
+        r = s->rsr;
+        break;
     case 6: /* UARTFR */
-        return s->flags;
+        r = s->flags;
+        break;
     case 8: /* UARTILPR */
-        return s->ilpr;
+        r = s->ilpr;
+        break;
     case 9: /* UARTIBRD */
-        return s->ibrd;
+        r = s->ibrd;
+        break;
     case 10: /* UARTFBRD */
-        return s->fbrd;
+        r = s->fbrd;
+        break;
     case 11: /* UARTLCR_H */
-        return s->lcr;
+        r = s->lcr;
+        break;
     case 12: /* UARTCR */
-        return s->cr;
+        r = s->cr;
+        break;
     case 13: /* UARTIFLS */
-        return s->ifl;
+        r = s->ifl;
+        break;
     case 14: /* UARTIMSC */
-        return s->int_enabled;
+        r = s->int_enabled;
+        break;
     case 15: /* UARTRIS */
-        return s->int_level;
+        r = s->int_level;
+        break;
     case 16: /* UARTMIS */
-        return s->int_level & s->int_enabled;
+        r = s->int_level & s->int_enabled;
+        break;
     case 18: /* UARTDMACR */
-        return s->dmacr;
+        r = s->dmacr;
+        break;
+    case 0x3f8 ... 0x400:
+        r = s->id[(offset - 0xfe0) >> 2];
+        break;
     default:
         qemu_log_mask(LOG_GUEST_ERROR,
                       "pl011_read: Bad offset %x\n", (int)offset);
-        return 0;
+        r = 0;
+        break;
     }
+
+    trace_pl011_read(offset, r);
+    return r;
 }
 
 static void pl011_set_read_trigger(PL011State *s)
@@ -141,6 +162,8 @@ static void pl011_write(void *opaque, hwaddr offset,
     PL011State *s = (PL011State *)opaque;
     unsigned char ch;
 
+    trace_pl011_write(offset, value);
+
     switch (offset >> 2) {
     case 0: /* UARTDR */
         /* ??? Check if transmitter is enabled.  */
@@ -207,11 +230,15 @@ static void pl011_write(void *opaque, hwaddr offset,
 static int pl011_can_receive(void *opaque)
 {
     PL011State *s = (PL011State *)opaque;
+    int r;
 
-    if (s->lcr & 0x10)
-        return s->read_count < 16;
-    else
-        return s->read_count < 1;
+    if (s->lcr & 0x10) {
+        r = s->read_count < 16;
+    } else {
+        r = s->read_count < 1;
+    }
+    trace_pl011_can_receive(s->lcr, s->read_count, r);
+    return r;
 }
 
 static void pl011_put_fifo(void *opaque, uint32_t value)
@@ -225,7 +252,9 @@ static void pl011_put_fifo(void *opaque, uint32_t value)
     s->read_fifo[slot] = value;
     s->read_count++;
     s->flags &= ~PL011_FLAG_RXFE;
+    trace_pl011_put_fifo(value, s->read_count);
     if (!(s->lcr & 0x10) || s->read_count == 16) {
+        trace_pl011_put_fifo_full();
         s->flags |= PL011_FLAG_RXFF;
     }
     if (s->read_count == s->read_trigger) {
diff --git a/hw/char/trace-events b/hw/char/trace-events
index d53577c..7fd48bb 100644
--- a/hw/char/trace-events
+++ b/hw/char/trace-events
@@ -47,3 +47,12 @@ escc_sunkbd_event_in(int ch, const char *name, int down) "QKeyCode 0x%2.2x [%s],
 escc_sunkbd_event_out(int ch) "Translated keycode 0x%2.2x"
 escc_kbd_command(int val) "Command %d"
 escc_sunmouse_event(int dx, int dy, int buttons_state) "dx=%d dy=%d buttons=%01x"
+
+# hw/char/pl011.c
+pl011_irq_state(int level) "irq state %d"
+pl011_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
+pl011_read_fifo(int read_count) "FIFO read, read_count now %d"
+pl011_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
+pl011_can_receive(uint32_t lcr, int read_count, int r) "LCR %08x read_count %d returning %d"
+pl011_put_fifo(uint32_t c, int read_count) "new char 0x%x read_count now %d"
+pl011_put_fifo_full(void) "FIFO now full, RXFF set"
-- 
2.7.4

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

* Re: [Qemu-devel] [PULL 00/25] target-arm queue
  2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
                   ` (24 preceding siblings ...)
  2016-10-17 18:40 ` [Qemu-devel] [PULL 25/25] hw/char/pl011: Add trace events Peter Maydell
@ 2016-10-18  8:25 ` Peter Maydell
  25 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2016-10-18  8:25 UTC (permalink / raw)
  To: QEMU Developers

On 17 October 2016 at 19:40, Peter Maydell <peter.maydell@linaro.org> wrote:
> Random mix of stuff here, nothing in particular
> very large. Includes a fix for the regression running
> Thumb userspace code.
>
> thanks
> -- PMM
>
>
> The following changes since commit 0975b8b823a888d474fa33821dfe84e6904db197:
>
>   Merge remote-tracking branch 'remotes/gkurz/tags/for-upstream' into staging (2016-10-17 16:17:51 +0100)
>
> are available in the git repository at:
>
>   git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20161017
>
> for you to fetch changes up to 041ac05672993ff33a15f8017c0f729ca6dfad73:
>
>   hw/char/pl011: Add trace events (2016-10-17 19:32:44 +0100)
>
> ----------------------------------------------------------------
> target-arm:
>  * target-arm: kvm: use AddressSpace-specific listener
>  * aspeed: add SMC controllers
>  * hw/arm/boot: allow using a command line specified dtb without a kernel
>  * hw/dma/pl080: Fix bad bit mask
>  * hw/intc/arm_gic_kvm: Fix build on aarch64 with some compilers
>  * hw/arm/virt: fix ACPI tables for ITS
>  * tests: add a m25p80 test
>  * tests: cleanup ptimer-test
>  * pxa2xx: Auto-assign name for i2c bus in i2c_init_bus
>  * target-arm: handle tagged addresses in A64 code
>  * target-arm: Fix masking of PC lower bits when doing exception returns
>  * target-arm: Implement dummy MDCCINT_EL1
>  * target-arm: Add trace events for the generic timers
>  * hw/intc/arm_gicv3: Fix ICC register tracepoints
>  * hw/char/pl011: Add trace events

Applied, thanks.

-- PMM

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

end of thread, other threads:[~2016-10-18  8:26 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-10-17 18:40 [Qemu-devel] [PULL 00/25] target-arm queue Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 01/25] docs/generic-loader: Update the document Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 02/25] Reducing stack frame size in stream_process_mem2s() Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 03/25] target-arm: kvm: use AddressSpace-specific listener Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 04/25] aspeed: rename the smc object to fmc Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 05/25] aspeed: move the flash module mapping address under the controller definition Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 06/25] aspeed: extend the number of host SPI controllers Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 07/25] aspeed: add support for the AST2500 SoC SMC controllers Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 08/25] aspeed: create mapping regions for the maximum number of slaves Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 09/25] aspeed: add support for the SMC segment registers Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 10/25] hw/arm/boot: allow using a command line specified dtb without a kernel Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 11/25] hw/dma/pl080: Fix bad bit mask (PL080_CONF_M1 | PL080_CONF_M1) Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 12/25] hw/intc/arm_gic_kvm: Fix build on aarch64 Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 13/25] hw/arm/virt-acpi-build: fix MADT generation Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 14/25] hw/arm/virt: no ITS on older machine types Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 15/25] tests: add a m25p80 test Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 16/25] tests: cleanup ptimer-test Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 17/25] pxa2xx: Auto-assign name for i2c bus in i2c_init_bus Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 18/25] target-arm: Infrastucture changes to enable handling of tagged address loading into PC Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 19/25] target-arm: Code changes to implement overwrite of tag field on PC load Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 20/25] target-arm: Comments added to identify cases in a switch Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 21/25] Fix masking of PC lower bits when doing exception returns Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 22/25] target-arm: Implement dummy MDCCINT_EL1 Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 23/25] target-arm: Add trace events for the generic timers Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 24/25] hw/intc/arm_gicv3: Fix ICC register tracepoints Peter Maydell
2016-10-17 18:40 ` [Qemu-devel] [PULL 25/25] hw/char/pl011: Add trace events Peter Maydell
2016-10-18  8:25 ` [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).