qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/12] target-arm queue
@ 2019-09-13 15:49 Peter Maydell
  2019-09-13 15:49 ` [Qemu-devel] [PULL 01/12] hw/gpio: Add basic Aspeed GPIO model for AST2400 and AST2500 Peter Maydell
                   ` (12 more replies)
  0 siblings, 13 replies; 25+ messages in thread
From: Peter Maydell @ 2019-09-13 15:49 UTC (permalink / raw)
  To: qemu-devel

target-arm queue: mostly aspeed changes from Cédric.

thanks
-- PMM

The following changes since commit 85182c96de61f0b600bbe834d5a23e713162e892:

  Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20190912a' into staging (2019-09-13 14:37:48 +0100)

are available in the Git repository at:

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

for you to fetch changes up to 27a296fce9821e3608d537756cffa6e43a46df3b:

  qemu-ga: Convert invocation documentation to rST (2019-09-13 16:05:01 +0100)

----------------------------------------------------------------
target-arm queue:
 * aspeed: add a GPIO controller to the SoC
 * aspeed: Various refactorings
 * aspeed: Improve DMA controller modelling
 * atomic_template: fix indentation in GEN_ATOMIC_HELPER
 * qemu-ga: Convert invocation documentation to rST

----------------------------------------------------------------
Christian Svensson (1):
      aspeed/smc: Calculate checksum on normal DMA

Cédric Le Goater (7):
      aspeed: Remove unused SoC definitions
      aspeed: Use consistent typenames
      aspeed/smc: Add support for DMAs
      aspeed/smc: Add DMA calibration settings
      aspeed/smc: Inject errors in DMA checksum
      aspeed/scu: Introduce per-SoC SCU types
      aspeed/scu: Introduce a aspeed_scu_get_apb_freq() routine

Emilio G. Cota (1):
      atomic_template: fix indentation in GEN_ATOMIC_HELPER

Peter Maydell (1):
      qemu-ga: Convert invocation documentation to rST

Rashmica Gupta (2):
      hw/gpio: Add basic Aspeed GPIO model for AST2400 and AST2500
      aspeed: add a GPIO controller to the SoC

 Makefile                      |  24 +-
 hw/gpio/Makefile.objs         |   1 +
 accel/tcg/atomic_template.h   |   2 +-
 include/hw/arm/aspeed_soc.h   |   4 +-
 include/hw/gpio/aspeed_gpio.h | 100 +++++
 include/hw/misc/aspeed_scu.h  |  21 +-
 include/hw/ssi/aspeed_smc.h   |   7 +
 hw/arm/aspeed.c               |   2 +
 hw/arm/aspeed_soc.c           |  63 ++-
 hw/gpio/aspeed_gpio.c         | 884 ++++++++++++++++++++++++++++++++++++++++++
 hw/misc/aspeed_scu.c          | 102 ++---
 hw/ssi/aspeed_smc.c           | 335 +++++++++++++++-
 hw/timer/aspeed_timer.c       |   3 +-
 MAINTAINERS                   |   2 +-
 docs/conf.py                  |  18 +-
 docs/interop/conf.py          |   7 +
 docs/interop/index.rst        |   1 +
 docs/interop/qemu-ga.rst      | 133 +++++++
 qemu-doc.texi                 |   5 -
 qemu-ga.texi                  | 137 -------
 20 files changed, 1585 insertions(+), 266 deletions(-)
 create mode 100644 include/hw/gpio/aspeed_gpio.h
 create mode 100644 hw/gpio/aspeed_gpio.c
 create mode 100644 docs/interop/qemu-ga.rst
 delete mode 100644 qemu-ga.texi


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

* [Qemu-devel] [PULL 01/12] hw/gpio: Add basic Aspeed GPIO model for AST2400 and AST2500
  2019-09-13 15:49 [Qemu-devel] [PULL 00/12] target-arm queue Peter Maydell
@ 2019-09-13 15:49 ` Peter Maydell
  2019-09-13 15:49 ` [Qemu-devel] [PULL 02/12] aspeed: add a GPIO controller to the SoC Peter Maydell
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Peter Maydell @ 2019-09-13 15:49 UTC (permalink / raw)
  To: qemu-devel

From: Rashmica Gupta <rashmica.g@gmail.com>

GPIO pins are arranged in groups of 8 pins labeled A,B,..,Y,Z,AA,AB,AC.
(Note that the ast2400 controller only goes up to group AB).
A set has four groups (except set AC which only has one) and is
referred to by the groups it is composed of (eg ABCD,EFGH,...,YZAAAB).
Each set is accessed and controlled by a bank of 14 registers.

These registers operate on a per pin level where each bit in the register
corresponds to a pin, except for the command source registers. The command
source registers operate on a per group level where bits 24, 16, 8 and 0
correspond to each group in the set.

 eg. registers for set ABCD:
 |D7...D0|C7...C0|B7...B0|A7...A0| <- GPIOs
 |31...24|23...16|15....8|7.....0| <- bit position

Note that there are a couple of groups that only have 4 pins.

There are two ways that this model deviates from the behaviour of the
actual controller:
(1) The only control source driving the GPIO pins in the model is the ARM
model (as there currently aren't models for the LPC or Coprocessor).

(2) None of the registers in the model are reset tolerant (needs
integration with the watchdog).

Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
Tested-by: Andrew Jeffery <andrew@aj.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-id: 20190904070506.1052-2-clg@kaod.org
[clg: fixed missing header files
      made use of HWADDR_PRIx to fix compilation on windows ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/gpio/Makefile.objs         |   1 +
 include/hw/gpio/aspeed_gpio.h | 100 ++++
 hw/gpio/aspeed_gpio.c         | 884 ++++++++++++++++++++++++++++++++++
 3 files changed, 985 insertions(+)
 create mode 100644 include/hw/gpio/aspeed_gpio.h
 create mode 100644 hw/gpio/aspeed_gpio.c

diff --git a/hw/gpio/Makefile.objs b/hw/gpio/Makefile.objs
index e5da0cb54fe..d305b3b24b1 100644
--- a/hw/gpio/Makefile.objs
+++ b/hw/gpio/Makefile.objs
@@ -9,3 +9,4 @@ obj-$(CONFIG_OMAP) += omap_gpio.o
 obj-$(CONFIG_IMX) += imx_gpio.o
 obj-$(CONFIG_RASPI) += bcm2835_gpio.o
 obj-$(CONFIG_NRF51_SOC) += nrf51_gpio.o
+obj-$(CONFIG_ASPEED_SOC) += aspeed_gpio.o
diff --git a/include/hw/gpio/aspeed_gpio.h b/include/hw/gpio/aspeed_gpio.h
new file mode 100644
index 00000000000..a2deac046af
--- /dev/null
+++ b/include/hw/gpio/aspeed_gpio.h
@@ -0,0 +1,100 @@
+/*
+ *  ASPEED GPIO Controller
+ *
+ *  Copyright (C) 2017-2018 IBM Corp.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#ifndef ASPEED_GPIO_H
+#define ASPEED_GPIO_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_ASPEED_GPIO "aspeed.gpio"
+#define ASPEED_GPIO(obj) OBJECT_CHECK(AspeedGPIOState, (obj), TYPE_ASPEED_GPIO)
+#define ASPEED_GPIO_CLASS(klass) \
+     OBJECT_CLASS_CHECK(AspeedGPIOClass, (klass), TYPE_ASPEED_GPIO)
+#define ASPEED_GPIO_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(AspeedGPIOClass, (obj), TYPE_ASPEED_GPIO)
+
+#define ASPEED_GPIO_MAX_NR_SETS 8
+#define ASPEED_REGS_PER_BANK 14
+#define ASPEED_GPIO_MAX_NR_REGS (ASPEED_REGS_PER_BANK * ASPEED_GPIO_MAX_NR_SETS)
+#define ASPEED_GPIO_NR_PINS 228
+#define ASPEED_GROUPS_PER_SET 4
+#define ASPEED_GPIO_NR_DEBOUNCE_REGS 3
+#define ASPEED_CHARS_PER_GROUP_LABEL 4
+
+typedef struct GPIOSets GPIOSets;
+
+typedef struct GPIOSetProperties {
+    uint32_t input;
+    uint32_t output;
+    char group_label[ASPEED_GROUPS_PER_SET][ASPEED_CHARS_PER_GROUP_LABEL];
+} GPIOSetProperties;
+
+enum GPIORegType {
+    gpio_not_a_reg,
+    gpio_reg_data_value,
+    gpio_reg_direction,
+    gpio_reg_int_enable,
+    gpio_reg_int_sens_0,
+    gpio_reg_int_sens_1,
+    gpio_reg_int_sens_2,
+    gpio_reg_int_status,
+    gpio_reg_reset_tolerant,
+    gpio_reg_debounce_1,
+    gpio_reg_debounce_2,
+    gpio_reg_cmd_source_0,
+    gpio_reg_cmd_source_1,
+    gpio_reg_data_read,
+    gpio_reg_input_mask,
+};
+
+typedef struct AspeedGPIOReg {
+    uint16_t set_idx;
+    enum GPIORegType type;
+ } AspeedGPIOReg;
+
+typedef struct  AspeedGPIOClass {
+    SysBusDevice parent_obj;
+    const GPIOSetProperties *props;
+    uint32_t nr_gpio_pins;
+    uint32_t nr_gpio_sets;
+    uint32_t gap;
+    const AspeedGPIOReg *reg_table;
+}  AspeedGPIOClass;
+
+typedef struct AspeedGPIOState {
+    /* <private> */
+    SysBusDevice parent;
+
+    /*< public >*/
+    MemoryRegion iomem;
+    int pending;
+    qemu_irq irq;
+    qemu_irq gpios[ASPEED_GPIO_NR_PINS];
+
+/* Parallel GPIO Registers */
+    uint32_t debounce_regs[ASPEED_GPIO_NR_DEBOUNCE_REGS];
+    struct GPIOSets {
+        uint32_t data_value; /* Reflects pin values */
+        uint32_t data_read; /* Contains last value written to data value */
+        uint32_t direction;
+        uint32_t int_enable;
+        uint32_t int_sens_0;
+        uint32_t int_sens_1;
+        uint32_t int_sens_2;
+        uint32_t int_status;
+        uint32_t reset_tol;
+        uint32_t cmd_source_0;
+        uint32_t cmd_source_1;
+        uint32_t debounce_1;
+        uint32_t debounce_2;
+        uint32_t input_mask;
+    } sets[ASPEED_GPIO_MAX_NR_SETS];
+} AspeedGPIOState;
+
+#endif /* _ASPEED_GPIO_H_ */
diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
new file mode 100644
index 00000000000..25fbfec3b84
--- /dev/null
+++ b/hw/gpio/aspeed_gpio.c
@@ -0,0 +1,884 @@
+/*
+ *  ASPEED GPIO Controller
+ *
+ *  Copyright (C) 2017-2019 IBM Corp.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <assert.h>
+
+#include "qemu/osdep.h"
+#include "qemu/host-utils.h"
+#include "qemu/log.h"
+#include "hw/gpio/aspeed_gpio.h"
+#include "include/hw/misc/aspeed_scu.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "hw/irq.h"
+#include "migration/vmstate.h"
+
+#define GPIOS_PER_REG 32
+#define GPIOS_PER_SET GPIOS_PER_REG
+#define GPIO_PIN_GAP_SIZE 4
+#define GPIOS_PER_GROUP 8
+#define GPIO_GROUP_SHIFT 3
+
+/* GPIO Source Types */
+#define ASPEED_CMD_SRC_MASK         0x01010101
+#define ASPEED_SOURCE_ARM           0
+#define ASPEED_SOURCE_LPC           1
+#define ASPEED_SOURCE_COPROCESSOR   2
+#define ASPEED_SOURCE_RESERVED      3
+
+/* GPIO Interrupt Triggers */
+/*
+ *  For each set of gpios there are three sensitivity registers that control
+ *  the interrupt trigger mode.
+ *
+ *  | 2 | 1 | 0 | trigger mode
+ *  -----------------------------
+ *  | 0 | 0 | 0 | falling-edge
+ *  | 0 | 0 | 1 | rising-edge
+ *  | 0 | 1 | 0 | level-low
+ *  | 0 | 1 | 1 | level-high
+ *  | 1 | X | X | dual-edge
+ */
+#define ASPEED_FALLING_EDGE 0
+#define ASPEED_RISING_EDGE  1
+#define ASPEED_LEVEL_LOW    2
+#define ASPEED_LEVEL_HIGH   3
+#define ASPEED_DUAL_EDGE    4
+
+/* GPIO Register Address Offsets */
+#define GPIO_ABCD_DATA_VALUE       (0x000 >> 2)
+#define GPIO_ABCD_DIRECTION        (0x004 >> 2)
+#define GPIO_ABCD_INT_ENABLE       (0x008 >> 2)
+#define GPIO_ABCD_INT_SENS_0       (0x00C >> 2)
+#define GPIO_ABCD_INT_SENS_1       (0x010 >> 2)
+#define GPIO_ABCD_INT_SENS_2       (0x014 >> 2)
+#define GPIO_ABCD_INT_STATUS       (0x018 >> 2)
+#define GPIO_ABCD_RESET_TOLERANT   (0x01C >> 2)
+#define GPIO_EFGH_DATA_VALUE       (0x020 >> 2)
+#define GPIO_EFGH_DIRECTION        (0x024 >> 2)
+#define GPIO_EFGH_INT_ENABLE       (0x028 >> 2)
+#define GPIO_EFGH_INT_SENS_0       (0x02C >> 2)
+#define GPIO_EFGH_INT_SENS_1       (0x030 >> 2)
+#define GPIO_EFGH_INT_SENS_2       (0x034 >> 2)
+#define GPIO_EFGH_INT_STATUS       (0x038 >> 2)
+#define GPIO_EFGH_RESET_TOLERANT   (0x03C >> 2)
+#define GPIO_ABCD_DEBOUNCE_1       (0x040 >> 2)
+#define GPIO_ABCD_DEBOUNCE_2       (0x044 >> 2)
+#define GPIO_EFGH_DEBOUNCE_1       (0x048 >> 2)
+#define GPIO_EFGH_DEBOUNCE_2       (0x04C >> 2)
+#define GPIO_DEBOUNCE_TIME_1       (0x050 >> 2)
+#define GPIO_DEBOUNCE_TIME_2       (0x054 >> 2)
+#define GPIO_DEBOUNCE_TIME_3       (0x058 >> 2)
+#define GPIO_ABCD_COMMAND_SRC_0    (0x060 >> 2)
+#define GPIO_ABCD_COMMAND_SRC_1    (0x064 >> 2)
+#define GPIO_EFGH_COMMAND_SRC_0    (0x068 >> 2)
+#define GPIO_EFGH_COMMAND_SRC_1    (0x06C >> 2)
+#define GPIO_IJKL_DATA_VALUE       (0x070 >> 2)
+#define GPIO_IJKL_DIRECTION        (0x074 >> 2)
+#define GPIO_MNOP_DATA_VALUE       (0x078 >> 2)
+#define GPIO_MNOP_DIRECTION        (0x07C >> 2)
+#define GPIO_QRST_DATA_VALUE       (0x080 >> 2)
+#define GPIO_QRST_DIRECTION        (0x084 >> 2)
+#define GPIO_UVWX_DATA_VALUE       (0x088 >> 2)
+#define GPIO_UVWX_DIRECTION        (0x08C >> 2)
+#define GPIO_IJKL_COMMAND_SRC_0    (0x090 >> 2)
+#define GPIO_IJKL_COMMAND_SRC_1    (0x094 >> 2)
+#define GPIO_IJKL_INT_ENABLE       (0x098 >> 2)
+#define GPIO_IJKL_INT_SENS_0       (0x09C >> 2)
+#define GPIO_IJKL_INT_SENS_1       (0x0A0 >> 2)
+#define GPIO_IJKL_INT_SENS_2       (0x0A4 >> 2)
+#define GPIO_IJKL_INT_STATUS       (0x0A8 >> 2)
+#define GPIO_IJKL_RESET_TOLERANT   (0x0AC >> 2)
+#define GPIO_IJKL_DEBOUNCE_1       (0x0B0 >> 2)
+#define GPIO_IJKL_DEBOUNCE_2       (0x0B4 >> 2)
+#define GPIO_IJKL_INPUT_MASK       (0x0B8 >> 2)
+#define GPIO_ABCD_DATA_READ        (0x0C0 >> 2)
+#define GPIO_EFGH_DATA_READ        (0x0C4 >> 2)
+#define GPIO_IJKL_DATA_READ        (0x0C8 >> 2)
+#define GPIO_MNOP_DATA_READ        (0x0CC >> 2)
+#define GPIO_QRST_DATA_READ        (0x0D0 >> 2)
+#define GPIO_UVWX_DATA_READ        (0x0D4 >> 2)
+#define GPIO_YZAAAB_DATA_READ      (0x0D8 >> 2)
+#define GPIO_AC_DATA_READ          (0x0DC >> 2)
+#define GPIO_MNOP_COMMAND_SRC_0    (0x0E0 >> 2)
+#define GPIO_MNOP_COMMAND_SRC_1    (0x0E4 >> 2)
+#define GPIO_MNOP_INT_ENABLE       (0x0E8 >> 2)
+#define GPIO_MNOP_INT_SENS_0       (0x0EC >> 2)
+#define GPIO_MNOP_INT_SENS_1       (0x0F0 >> 2)
+#define GPIO_MNOP_INT_SENS_2       (0x0F4 >> 2)
+#define GPIO_MNOP_INT_STATUS       (0x0F8 >> 2)
+#define GPIO_MNOP_RESET_TOLERANT   (0x0FC >> 2)
+#define GPIO_MNOP_DEBOUNCE_1       (0x100 >> 2)
+#define GPIO_MNOP_DEBOUNCE_2       (0x104 >> 2)
+#define GPIO_MNOP_INPUT_MASK       (0x108 >> 2)
+#define GPIO_QRST_COMMAND_SRC_0    (0x110 >> 2)
+#define GPIO_QRST_COMMAND_SRC_1    (0x114 >> 2)
+#define GPIO_QRST_INT_ENABLE       (0x118 >> 2)
+#define GPIO_QRST_INT_SENS_0       (0x11C >> 2)
+#define GPIO_QRST_INT_SENS_1       (0x120 >> 2)
+#define GPIO_QRST_INT_SENS_2       (0x124 >> 2)
+#define GPIO_QRST_INT_STATUS       (0x128 >> 2)
+#define GPIO_QRST_RESET_TOLERANT   (0x12C >> 2)
+#define GPIO_QRST_DEBOUNCE_1       (0x130 >> 2)
+#define GPIO_QRST_DEBOUNCE_2       (0x134 >> 2)
+#define GPIO_QRST_INPUT_MASK       (0x138 >> 2)
+#define GPIO_UVWX_COMMAND_SRC_0    (0x140 >> 2)
+#define GPIO_UVWX_COMMAND_SRC_1    (0x144 >> 2)
+#define GPIO_UVWX_INT_ENABLE       (0x148 >> 2)
+#define GPIO_UVWX_INT_SENS_0       (0x14C >> 2)
+#define GPIO_UVWX_INT_SENS_1       (0x150 >> 2)
+#define GPIO_UVWX_INT_SENS_2       (0x154 >> 2)
+#define GPIO_UVWX_INT_STATUS       (0x158 >> 2)
+#define GPIO_UVWX_RESET_TOLERANT   (0x15C >> 2)
+#define GPIO_UVWX_DEBOUNCE_1       (0x160 >> 2)
+#define GPIO_UVWX_DEBOUNCE_2       (0x164 >> 2)
+#define GPIO_UVWX_INPUT_MASK       (0x168 >> 2)
+#define GPIO_YZAAAB_COMMAND_SRC_0  (0x170 >> 2)
+#define GPIO_YZAAAB_COMMAND_SRC_1  (0x174 >> 2)
+#define GPIO_YZAAAB_INT_ENABLE     (0x178 >> 2)
+#define GPIO_YZAAAB_INT_SENS_0     (0x17C >> 2)
+#define GPIO_YZAAAB_INT_SENS_1     (0x180 >> 2)
+#define GPIO_YZAAAB_INT_SENS_2     (0x184 >> 2)
+#define GPIO_YZAAAB_INT_STATUS     (0x188 >> 2)
+#define GPIO_YZAAAB_RESET_TOLERANT (0x18C >> 2)
+#define GPIO_YZAAAB_DEBOUNCE_1     (0x190 >> 2)
+#define GPIO_YZAAAB_DEBOUNCE_2     (0x194 >> 2)
+#define GPIO_YZAAAB_INPUT_MASK     (0x198 >> 2)
+#define GPIO_AC_COMMAND_SRC_0      (0x1A0 >> 2)
+#define GPIO_AC_COMMAND_SRC_1      (0x1A4 >> 2)
+#define GPIO_AC_INT_ENABLE         (0x1A8 >> 2)
+#define GPIO_AC_INT_SENS_0         (0x1AC >> 2)
+#define GPIO_AC_INT_SENS_1         (0x1B0 >> 2)
+#define GPIO_AC_INT_SENS_2         (0x1B4 >> 2)
+#define GPIO_AC_INT_STATUS         (0x1B8 >> 2)
+#define GPIO_AC_RESET_TOLERANT     (0x1BC >> 2)
+#define GPIO_AC_DEBOUNCE_1         (0x1C0 >> 2)
+#define GPIO_AC_DEBOUNCE_2         (0x1C4 >> 2)
+#define GPIO_AC_INPUT_MASK         (0x1C8 >> 2)
+#define GPIO_ABCD_INPUT_MASK       (0x1D0 >> 2)
+#define GPIO_EFGH_INPUT_MASK       (0x1D4 >> 2)
+#define GPIO_YZAAAB_DATA_VALUE     (0x1E0 >> 2)
+#define GPIO_YZAAAB_DIRECTION      (0x1E4 >> 2)
+#define GPIO_AC_DATA_VALUE         (0x1E8 >> 2)
+#define GPIO_AC_DIRECTION          (0x1EC >> 2)
+#define GPIO_3_6V_MEM_SIZE         0x1F0
+#define GPIO_3_6V_REG_ARRAY_SIZE   (GPIO_3_6V_MEM_SIZE >> 2)
+
+static int aspeed_evaluate_irq(GPIOSets *regs, int gpio_prev_high, int gpio)
+{
+    uint32_t falling_edge = 0, rising_edge = 0;
+    uint32_t int_trigger = extract32(regs->int_sens_0, gpio, 1)
+                           | extract32(regs->int_sens_1, gpio, 1) << 1
+                           | extract32(regs->int_sens_2, gpio, 1) << 2;
+    uint32_t gpio_curr_high = extract32(regs->data_value, gpio, 1);
+    uint32_t gpio_int_enabled = extract32(regs->int_enable, gpio, 1);
+
+    if (!gpio_int_enabled) {
+        return 0;
+    }
+
+    /* Detect edges */
+    if (gpio_curr_high && !gpio_prev_high) {
+        rising_edge = 1;
+    } else if (!gpio_curr_high && gpio_prev_high) {
+        falling_edge = 1;
+    }
+
+    if (((int_trigger == ASPEED_FALLING_EDGE)  && falling_edge)  ||
+        ((int_trigger == ASPEED_RISING_EDGE)  && rising_edge)    ||
+        ((int_trigger == ASPEED_LEVEL_LOW)  && !gpio_curr_high)  ||
+        ((int_trigger == ASPEED_LEVEL_HIGH)  && gpio_curr_high)  ||
+        ((int_trigger >= ASPEED_DUAL_EDGE)  && (rising_edge || falling_edge)))
+    {
+        regs->int_status = deposit32(regs->int_status, gpio, 1, 1);
+        return 1;
+    }
+    return 0;
+}
+
+#define nested_struct_index(ta, pa, m, tb, pb) \
+        (pb - ((tb *)(((char *)pa) + offsetof(ta, m))))
+
+static ptrdiff_t aspeed_gpio_set_idx(AspeedGPIOState *s, GPIOSets *regs)
+{
+    return nested_struct_index(AspeedGPIOState, s, sets, GPIOSets, regs);
+}
+
+static void aspeed_gpio_update(AspeedGPIOState *s, GPIOSets *regs,
+                               uint32_t value)
+{
+    uint32_t input_mask = regs->input_mask;
+    uint32_t direction = regs->direction;
+    uint32_t old = regs->data_value;
+    uint32_t new = value;
+    uint32_t diff;
+    int gpio;
+
+    diff = old ^ new;
+    if (diff) {
+        for (gpio = 0; gpio < GPIOS_PER_REG; gpio++) {
+            uint32_t mask = 1 << gpio;
+
+            /* If the gpio needs to be updated... */
+            if (!(diff & mask)) {
+                continue;
+            }
+
+            /* ...and we're output or not input-masked... */
+            if (!(direction & mask) && (input_mask & mask)) {
+                continue;
+            }
+
+            /* ...then update the state. */
+            if (mask & new) {
+                regs->data_value |= mask;
+            } else {
+                regs->data_value &= ~mask;
+            }
+
+            /* If the gpio is set to output... */
+            if (direction & mask) {
+                /* ...trigger the line-state IRQ */
+                ptrdiff_t set = aspeed_gpio_set_idx(s, regs);
+                size_t offset = set * GPIOS_PER_SET + gpio;
+                qemu_set_irq(s->gpios[offset], !!(new & mask));
+            } else {
+                /* ...otherwise if we meet the line's current IRQ policy... */
+                if (aspeed_evaluate_irq(regs, old & mask, gpio)) {
+                    /* ...trigger the VIC IRQ */
+                    s->pending++;
+                }
+            }
+        }
+    }
+    qemu_set_irq(s->irq, !!(s->pending));
+}
+
+static uint32_t aspeed_adjust_pin(AspeedGPIOState *s, uint32_t pin)
+{
+    AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
+    /*
+     * The 2500 has a 4 pin gap in group AB and the 2400 has a 4 pin
+     * gap in group Y (and only four pins in AB but this is the last group so
+     * it doesn't matter).
+     */
+    if (agc->gap && pin >= agc->gap) {
+        pin += GPIO_PIN_GAP_SIZE;
+    }
+
+    return pin;
+}
+
+static bool aspeed_gpio_get_pin_level(AspeedGPIOState *s, uint32_t set_idx,
+                                      uint32_t pin)
+{
+    uint32_t reg_val;
+    uint32_t pin_mask = 1 << pin;
+
+    reg_val = s->sets[set_idx].data_value;
+
+    return !!(reg_val & pin_mask);
+}
+
+static void aspeed_gpio_set_pin_level(AspeedGPIOState *s, uint32_t set_idx,
+                                      uint32_t pin, bool level)
+{
+    uint32_t value = s->sets[set_idx].data_value;
+    uint32_t pin_mask = 1 << pin;
+
+    if (level) {
+        value |= pin_mask;
+    } else {
+        value &= !pin_mask;
+    }
+
+    aspeed_gpio_update(s, &s->sets[set_idx], value);
+}
+
+/*
+ *  | src_1 | src_2 |  source     |
+ *  |-----------------------------|
+ *  |   0   |   0   |  ARM        |
+ *  |   0   |   1   |  LPC        |
+ *  |   1   |   0   |  Coprocessor|
+ *  |   1   |   1   |  Reserved   |
+ *
+ *  Once the source of a set is programmed, corresponding bits in the
+ *  data_value, direction, interrupt [enable, sens[0-2]], reset_tol and
+ *  debounce registers can only be written by the source.
+ *
+ *  Source is ARM by default
+ *  only bits 24, 16, 8, and 0 can be set
+ *
+ *  we don't currently have a model for the LPC or Coprocessor
+ */
+static uint32_t update_value_control_source(GPIOSets *regs, uint32_t old_value,
+                                            uint32_t value)
+{
+    int i;
+    int cmd_source;
+
+    /* assume the source is always ARM for now */
+    int source = ASPEED_SOURCE_ARM;
+
+    uint32_t new_value = 0;
+
+    /* for each group in set */
+    for (i = 0; i < GPIOS_PER_REG; i += GPIOS_PER_GROUP) {
+        cmd_source = extract32(regs->cmd_source_0, i, 1)
+                | (extract32(regs->cmd_source_1, i, 1) << 1);
+
+        if (source == cmd_source) {
+            new_value |= (0xff << i) & value;
+        } else {
+            new_value |= (0xff << i) & old_value;
+        }
+    }
+    return new_value;
+}
+
+static const AspeedGPIOReg aspeed_3_6v_gpios[GPIO_3_6V_REG_ARRAY_SIZE] = {
+    /* Set ABCD */
+    [GPIO_ABCD_DATA_VALUE] =     { 0, gpio_reg_data_value },
+    [GPIO_ABCD_DIRECTION] =      { 0, gpio_reg_direction },
+    [GPIO_ABCD_INT_ENABLE] =     { 0, gpio_reg_int_enable },
+    [GPIO_ABCD_INT_SENS_0] =     { 0, gpio_reg_int_sens_0 },
+    [GPIO_ABCD_INT_SENS_1] =     { 0, gpio_reg_int_sens_1 },
+    [GPIO_ABCD_INT_SENS_2] =     { 0, gpio_reg_int_sens_2 },
+    [GPIO_ABCD_INT_STATUS] =     { 0, gpio_reg_int_status },
+    [GPIO_ABCD_RESET_TOLERANT] = { 0, gpio_reg_reset_tolerant },
+    [GPIO_ABCD_DEBOUNCE_1] =     { 0, gpio_reg_debounce_1 },
+    [GPIO_ABCD_DEBOUNCE_2] =     { 0, gpio_reg_debounce_2 },
+    [GPIO_ABCD_COMMAND_SRC_0] =  { 0, gpio_reg_cmd_source_0 },
+    [GPIO_ABCD_COMMAND_SRC_1] =  { 0, gpio_reg_cmd_source_1 },
+    [GPIO_ABCD_DATA_READ] =      { 0, gpio_reg_data_read },
+    [GPIO_ABCD_INPUT_MASK] =     { 0, gpio_reg_input_mask },
+    /* Set EFGH */
+    [GPIO_EFGH_DATA_VALUE] =     { 1, gpio_reg_data_value },
+    [GPIO_EFGH_DIRECTION] =      { 1, gpio_reg_direction },
+    [GPIO_EFGH_INT_ENABLE] =     { 1, gpio_reg_int_enable },
+    [GPIO_EFGH_INT_SENS_0] =     { 1, gpio_reg_int_sens_0 },
+    [GPIO_EFGH_INT_SENS_1] =     { 1, gpio_reg_int_sens_1 },
+    [GPIO_EFGH_INT_SENS_2] =     { 1, gpio_reg_int_sens_2 },
+    [GPIO_EFGH_INT_STATUS] =     { 1, gpio_reg_int_status },
+    [GPIO_EFGH_RESET_TOLERANT] = { 1, gpio_reg_reset_tolerant },
+    [GPIO_EFGH_DEBOUNCE_1] =     { 1, gpio_reg_debounce_1 },
+    [GPIO_EFGH_DEBOUNCE_2] =     { 1, gpio_reg_debounce_2 },
+    [GPIO_EFGH_COMMAND_SRC_0] =  { 1, gpio_reg_cmd_source_0 },
+    [GPIO_EFGH_COMMAND_SRC_1] =  { 1, gpio_reg_cmd_source_1 },
+    [GPIO_EFGH_DATA_READ] =      { 1, gpio_reg_data_read },
+    [GPIO_EFGH_INPUT_MASK] =     { 1, gpio_reg_input_mask },
+    /* Set IJKL */
+    [GPIO_IJKL_DATA_VALUE] =     { 2, gpio_reg_data_value },
+    [GPIO_IJKL_DIRECTION] =      { 2, gpio_reg_direction },
+    [GPIO_IJKL_INT_ENABLE] =     { 2, gpio_reg_int_enable },
+    [GPIO_IJKL_INT_SENS_0] =     { 2, gpio_reg_int_sens_0 },
+    [GPIO_IJKL_INT_SENS_1] =     { 2, gpio_reg_int_sens_1 },
+    [GPIO_IJKL_INT_SENS_2] =     { 2, gpio_reg_int_sens_2 },
+    [GPIO_IJKL_INT_STATUS] =     { 2, gpio_reg_int_status },
+    [GPIO_IJKL_RESET_TOLERANT] = { 2, gpio_reg_reset_tolerant },
+    [GPIO_IJKL_DEBOUNCE_1] =     { 2, gpio_reg_debounce_1 },
+    [GPIO_IJKL_DEBOUNCE_2] =     { 2, gpio_reg_debounce_2 },
+    [GPIO_IJKL_COMMAND_SRC_0] =  { 2, gpio_reg_cmd_source_0 },
+    [GPIO_IJKL_COMMAND_SRC_1] =  { 2, gpio_reg_cmd_source_1 },
+    [GPIO_IJKL_DATA_READ] =      { 2, gpio_reg_data_read },
+    [GPIO_IJKL_INPUT_MASK] =     { 2, gpio_reg_input_mask },
+    /* Set MNOP */
+    [GPIO_MNOP_DATA_VALUE] =     { 3, gpio_reg_data_value },
+    [GPIO_MNOP_DIRECTION] =      { 3, gpio_reg_direction },
+    [GPIO_MNOP_INT_ENABLE] =     { 3, gpio_reg_int_enable },
+    [GPIO_MNOP_INT_SENS_0] =     { 3, gpio_reg_int_sens_0 },
+    [GPIO_MNOP_INT_SENS_1] =     { 3, gpio_reg_int_sens_1 },
+    [GPIO_MNOP_INT_SENS_2] =     { 3, gpio_reg_int_sens_2 },
+    [GPIO_MNOP_INT_STATUS] =     { 3, gpio_reg_int_status },
+    [GPIO_MNOP_RESET_TOLERANT] = { 3, gpio_reg_reset_tolerant },
+    [GPIO_MNOP_DEBOUNCE_1] =     { 3, gpio_reg_debounce_1 },
+    [GPIO_MNOP_DEBOUNCE_2] =     { 3, gpio_reg_debounce_2 },
+    [GPIO_MNOP_COMMAND_SRC_0] =  { 3, gpio_reg_cmd_source_0 },
+    [GPIO_MNOP_COMMAND_SRC_1] =  { 3, gpio_reg_cmd_source_1 },
+    [GPIO_MNOP_DATA_READ] =      { 3, gpio_reg_data_read },
+    [GPIO_MNOP_INPUT_MASK] =     { 3, gpio_reg_input_mask },
+    /* Set QRST */
+    [GPIO_QRST_DATA_VALUE] =     { 4, gpio_reg_data_value },
+    [GPIO_QRST_DIRECTION] =      { 4, gpio_reg_direction },
+    [GPIO_QRST_INT_ENABLE] =     { 4, gpio_reg_int_enable },
+    [GPIO_QRST_INT_SENS_0] =     { 4, gpio_reg_int_sens_0 },
+    [GPIO_QRST_INT_SENS_1] =     { 4, gpio_reg_int_sens_1 },
+    [GPIO_QRST_INT_SENS_2] =     { 4, gpio_reg_int_sens_2 },
+    [GPIO_QRST_INT_STATUS] =     { 4, gpio_reg_int_status },
+    [GPIO_QRST_RESET_TOLERANT] = { 4, gpio_reg_reset_tolerant },
+    [GPIO_QRST_DEBOUNCE_1] =     { 4, gpio_reg_debounce_1 },
+    [GPIO_QRST_DEBOUNCE_2] =     { 4, gpio_reg_debounce_2 },
+    [GPIO_QRST_COMMAND_SRC_0] =  { 4, gpio_reg_cmd_source_0 },
+    [GPIO_QRST_COMMAND_SRC_1] =  { 4, gpio_reg_cmd_source_1 },
+    [GPIO_QRST_DATA_READ] =      { 4, gpio_reg_data_read },
+    [GPIO_QRST_INPUT_MASK] =     { 4, gpio_reg_input_mask },
+    /* Set UVWX */
+    [GPIO_UVWX_DATA_VALUE] =     { 5, gpio_reg_data_value },
+    [GPIO_UVWX_DIRECTION] =      { 5, gpio_reg_direction },
+    [GPIO_UVWX_INT_ENABLE] =     { 5, gpio_reg_int_enable },
+    [GPIO_UVWX_INT_SENS_0] =     { 5, gpio_reg_int_sens_0 },
+    [GPIO_UVWX_INT_SENS_1] =     { 5, gpio_reg_int_sens_1 },
+    [GPIO_UVWX_INT_SENS_2] =     { 5, gpio_reg_int_sens_2 },
+    [GPIO_UVWX_INT_STATUS] =     { 5, gpio_reg_int_status },
+    [GPIO_UVWX_RESET_TOLERANT] = { 5, gpio_reg_reset_tolerant },
+    [GPIO_UVWX_DEBOUNCE_1] =     { 5, gpio_reg_debounce_1 },
+    [GPIO_UVWX_DEBOUNCE_2] =     { 5, gpio_reg_debounce_2 },
+    [GPIO_UVWX_COMMAND_SRC_0] =  { 5, gpio_reg_cmd_source_0 },
+    [GPIO_UVWX_COMMAND_SRC_1] =  { 5, gpio_reg_cmd_source_1 },
+    [GPIO_UVWX_DATA_READ] =      { 5, gpio_reg_data_read },
+    [GPIO_UVWX_INPUT_MASK] =     { 5, gpio_reg_input_mask },
+    /* Set YZAAAB */
+    [GPIO_YZAAAB_DATA_VALUE] =     { 6, gpio_reg_data_value },
+    [GPIO_YZAAAB_DIRECTION] =      { 6, gpio_reg_direction },
+    [GPIO_YZAAAB_INT_ENABLE] =     { 6, gpio_reg_int_enable },
+    [GPIO_YZAAAB_INT_SENS_0] =     { 6, gpio_reg_int_sens_0 },
+    [GPIO_YZAAAB_INT_SENS_1] =     { 6, gpio_reg_int_sens_1 },
+    [GPIO_YZAAAB_INT_SENS_2] =     { 6, gpio_reg_int_sens_2 },
+    [GPIO_YZAAAB_INT_STATUS] =     { 6, gpio_reg_int_status },
+    [GPIO_YZAAAB_RESET_TOLERANT] = { 6, gpio_reg_reset_tolerant },
+    [GPIO_YZAAAB_DEBOUNCE_1] =     { 6, gpio_reg_debounce_1 },
+    [GPIO_YZAAAB_DEBOUNCE_2] =     { 6, gpio_reg_debounce_2 },
+    [GPIO_YZAAAB_COMMAND_SRC_0] =  { 6, gpio_reg_cmd_source_0 },
+    [GPIO_YZAAAB_COMMAND_SRC_1] =  { 6, gpio_reg_cmd_source_1 },
+    [GPIO_YZAAAB_DATA_READ] =      { 6, gpio_reg_data_read },
+    [GPIO_YZAAAB_INPUT_MASK] =     { 6, gpio_reg_input_mask },
+    /* Set AC  (ast2500 only) */
+    [GPIO_AC_DATA_VALUE] =         { 7, gpio_reg_data_value },
+    [GPIO_AC_DIRECTION] =          { 7, gpio_reg_direction },
+    [GPIO_AC_INT_ENABLE] =         { 7, gpio_reg_int_enable },
+    [GPIO_AC_INT_SENS_0] =         { 7, gpio_reg_int_sens_0 },
+    [GPIO_AC_INT_SENS_1] =         { 7, gpio_reg_int_sens_1 },
+    [GPIO_AC_INT_SENS_2] =         { 7, gpio_reg_int_sens_2 },
+    [GPIO_AC_INT_STATUS] =         { 7, gpio_reg_int_status },
+    [GPIO_AC_RESET_TOLERANT] =     { 7, gpio_reg_reset_tolerant },
+    [GPIO_AC_DEBOUNCE_1] =         { 7, gpio_reg_debounce_1 },
+    [GPIO_AC_DEBOUNCE_2] =         { 7, gpio_reg_debounce_2 },
+    [GPIO_AC_COMMAND_SRC_0] =      { 7, gpio_reg_cmd_source_0 },
+    [GPIO_AC_COMMAND_SRC_1] =      { 7, gpio_reg_cmd_source_1 },
+    [GPIO_AC_DATA_READ] =          { 7, gpio_reg_data_read },
+    [GPIO_AC_INPUT_MASK] =         { 7, gpio_reg_input_mask },
+};
+
+static uint64_t aspeed_gpio_read(void *opaque, hwaddr offset, uint32_t size)
+{
+    AspeedGPIOState *s = ASPEED_GPIO(opaque);
+    AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
+    uint64_t idx = -1;
+    const AspeedGPIOReg *reg;
+    GPIOSets *set;
+
+    idx = offset >> 2;
+    if (idx >= GPIO_DEBOUNCE_TIME_1 && idx <= GPIO_DEBOUNCE_TIME_3) {
+        idx -= GPIO_DEBOUNCE_TIME_1;
+        return (uint64_t) s->debounce_regs[idx];
+    }
+
+    reg = &agc->reg_table[idx];
+    if (reg->set_idx >= agc->nr_gpio_sets) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%"
+                      HWADDR_PRIx"\n", __func__, offset);
+        return 0;
+    }
+
+    set = &s->sets[reg->set_idx];
+    switch (reg->type) {
+    case gpio_reg_data_value:
+        return set->data_value;
+    case gpio_reg_direction:
+        return set->direction;
+    case gpio_reg_int_enable:
+        return set->int_enable;
+    case gpio_reg_int_sens_0:
+        return set->int_sens_0;
+    case gpio_reg_int_sens_1:
+        return set->int_sens_1;
+    case gpio_reg_int_sens_2:
+        return set->int_sens_2;
+    case gpio_reg_int_status:
+        return set->int_status;
+    case gpio_reg_reset_tolerant:
+        return set->reset_tol;
+    case gpio_reg_debounce_1:
+        return set->debounce_1;
+    case gpio_reg_debounce_2:
+        return set->debounce_2;
+    case gpio_reg_cmd_source_0:
+        return set->cmd_source_0;
+    case gpio_reg_cmd_source_1:
+        return set->cmd_source_1;
+    case gpio_reg_data_read:
+        return set->data_read;
+    case gpio_reg_input_mask:
+        return set->input_mask;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%"
+                      HWADDR_PRIx"\n", __func__, offset);
+        return 0;
+    };
+}
+
+static void aspeed_gpio_write(void *opaque, hwaddr offset, uint64_t data,
+                              uint32_t size)
+{
+    AspeedGPIOState *s = ASPEED_GPIO(opaque);
+    AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
+    const GPIOSetProperties *props;
+    uint64_t idx = -1;
+    const AspeedGPIOReg *reg;
+    GPIOSets *set;
+    uint32_t cleared;
+
+    idx = offset >> 2;
+    if (idx >= GPIO_DEBOUNCE_TIME_1 && idx <= GPIO_DEBOUNCE_TIME_3) {
+        idx -= GPIO_DEBOUNCE_TIME_1;
+        s->debounce_regs[idx] = (uint32_t) data;
+        return;
+    }
+
+    reg = &agc->reg_table[idx];
+    if (reg->set_idx >= agc->nr_gpio_sets) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: no setter for offset 0x%"
+                      HWADDR_PRIx"\n", __func__, offset);
+        return;
+    }
+
+    set = &s->sets[reg->set_idx];
+    props = &agc->props[reg->set_idx];
+
+    switch (reg->type) {
+    case gpio_reg_data_value:
+        data &= props->output;
+        data = update_value_control_source(set, set->data_value, data);
+        set->data_read = data;
+        aspeed_gpio_update(s, set, data);
+        return;
+    case gpio_reg_direction:
+        /*
+         *   where data is the value attempted to be written to the pin:
+         *    pin type      | input mask | output mask | expected value
+         *    ------------------------------------------------------------
+         *   bidirectional  |   1       |   1        |  data
+         *   input only     |   1       |   0        |   0
+         *   output only    |   0       |   1        |   1
+         *   no pin / gap   |   0       |   0        |   0
+         *
+         *  which is captured by:
+         *  data = ( data | ~input) & output;
+         */
+        data = (data | ~props->input) & props->output;
+        set->direction = update_value_control_source(set, set->direction, data);
+        break;
+    case gpio_reg_int_enable:
+        set->int_enable = update_value_control_source(set, set->int_enable,
+                                                      data);
+        break;
+    case gpio_reg_int_sens_0:
+        set->int_sens_0 = update_value_control_source(set, set->int_sens_0,
+                                                      data);
+        break;
+    case gpio_reg_int_sens_1:
+        set->int_sens_1 = update_value_control_source(set, set->int_sens_1,
+                                                      data);
+        break;
+    case gpio_reg_int_sens_2:
+        set->int_sens_2 = update_value_control_source(set, set->int_sens_2,
+                                                      data);
+        break;
+    case gpio_reg_int_status:
+        cleared = ctpop32(data & set->int_status);
+        if (s->pending && cleared) {
+            assert(s->pending >= cleared);
+            s->pending -= cleared;
+        }
+        set->int_status &= ~data;
+        break;
+    case gpio_reg_reset_tolerant:
+        set->reset_tol = update_value_control_source(set, set->reset_tol,
+                                                     data);
+        return;
+    case gpio_reg_debounce_1:
+        set->debounce_1 = update_value_control_source(set, set->debounce_1,
+                                                      data);
+        return;
+    case gpio_reg_debounce_2:
+        set->debounce_2 = update_value_control_source(set, set->debounce_2,
+                                                      data);
+        return;
+    case gpio_reg_cmd_source_0:
+        set->cmd_source_0 = data & ASPEED_CMD_SRC_MASK;
+        return;
+    case gpio_reg_cmd_source_1:
+        set->cmd_source_1 = data & ASPEED_CMD_SRC_MASK;
+        return;
+    case gpio_reg_data_read:
+        /* Read only register */
+        return;
+    case gpio_reg_input_mask:
+        /*
+         * feeds into interrupt generation
+         * 0: read from data value reg will be updated
+         * 1: read from data value reg will not be updated
+         */
+         set->input_mask = data & props->input;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: no setter for offset 0x%"
+                      HWADDR_PRIx"\n", __func__, offset);
+        return;
+    }
+    aspeed_gpio_update(s, set, set->data_value);
+    return;
+}
+
+static int get_set_idx(AspeedGPIOState *s, const char *group, int *group_idx)
+{
+    AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
+    int set_idx, g_idx = *group_idx;
+
+    for (set_idx = 0; set_idx < agc->nr_gpio_sets; set_idx++) {
+        const GPIOSetProperties *set_props = &agc->props[set_idx];
+        for (g_idx = 0; g_idx < ASPEED_GROUPS_PER_SET; g_idx++) {
+            if (!strncmp(group, set_props->group_label[g_idx], strlen(group))) {
+                *group_idx = g_idx;
+                return set_idx;
+            }
+        }
+    }
+    return -1;
+}
+
+static void aspeed_gpio_get_pin(Object *obj, Visitor *v, const char *name,
+                                void *opaque, Error **errp)
+{
+    int pin = 0xfff;
+    bool level = true;
+    char group[3];
+    AspeedGPIOState *s = ASPEED_GPIO(obj);
+    int set_idx, group_idx = 0;
+
+    if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) {
+        error_setg(errp, "%s: error reading %s", __func__, name);
+        return;
+    }
+    set_idx = get_set_idx(s, group, &group_idx);
+    if (set_idx == -1) {
+        error_setg(errp, "%s: invalid group %s", __func__, group);
+        return;
+    }
+    pin =  pin + group_idx * GPIOS_PER_GROUP;
+    level = aspeed_gpio_get_pin_level(s, set_idx, pin);
+    visit_type_bool(v, name, &level, errp);
+}
+
+static void aspeed_gpio_set_pin(Object *obj, Visitor *v, const char *name,
+                               void *opaque, Error **errp)
+{
+    Error *local_err = NULL;
+    bool level;
+    int pin = 0xfff;
+    char group[3];
+    AspeedGPIOState *s = ASPEED_GPIO(obj);
+    int set_idx, group_idx = 0;
+
+    visit_type_bool(v, name, &level, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) {
+        error_setg(errp, "%s: error reading %s", __func__, name);
+        return;
+    }
+    set_idx = get_set_idx(s, group, &group_idx);
+    if (set_idx == -1) {
+        error_setg(errp, "%s: invalid group %s", __func__, group);
+        return;
+    }
+    pin =  pin + group_idx * GPIOS_PER_GROUP;
+    aspeed_gpio_set_pin_level(s, set_idx, pin, level);
+}
+
+/****************** Setup functions ******************/
+static const GPIOSetProperties ast2400_set_props[] = {
+    [0] = {0xffffffff,  0xffffffff,  {"A", "B", "C", "D"} },
+    [1] = {0xffffffff,  0xffffffff,  {"E", "F", "G", "H"} },
+    [2] = {0xffffffff,  0xffffffff,  {"I", "J", "K", "L"} },
+    [3] = {0xffffffff,  0xffffffff,  {"M", "N", "O", "P"} },
+    [4] = {0xffffffff,  0xffffffff,  {"Q", "R", "S", "T"} },
+    [5] = {0xffffffff,  0x0000ffff,  {"U", "V", "W", "X"} },
+    [6] = {0x0000000f,  0x0fffff0f,  {"Y", "Z", "AA", "AB"} },
+};
+
+static const GPIOSetProperties ast2500_set_props[] = {
+    [0] = {0xffffffff,  0xffffffff,  {"A", "B", "C", "D"} },
+    [1] = {0xffffffff,  0xffffffff,  {"E", "F", "G", "H"} },
+    [2] = {0xffffffff,  0xffffffff,  {"I", "J", "K", "L"} },
+    [3] = {0xffffffff,  0xffffffff,  {"M", "N", "O", "P"} },
+    [4] = {0xffffffff,  0xffffffff,  {"Q", "R", "S", "T"} },
+    [5] = {0xffffffff,  0x0000ffff,  {"U", "V", "W", "X"} },
+    [6] = {0xffffff0f,  0x0fffff0f,  {"Y", "Z", "AA", "AB"} },
+    [7] = {0x000000ff,  0x000000ff,  {"AC"} },
+};
+
+static const MemoryRegionOps aspeed_gpio_ops = {
+    .read       = aspeed_gpio_read,
+    .write      = aspeed_gpio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid.min_access_size = 4,
+    .valid.max_access_size = 4,
+};
+
+static void aspeed_gpio_reset(DeviceState *dev)
+{
+    AspeedGPIOState *s = ASPEED_GPIO(dev);
+
+    /* TODO: respect the reset tolerance registers */
+    memset(s->sets, 0, sizeof(s->sets));
+}
+
+static void aspeed_gpio_realize(DeviceState *dev, Error **errp)
+{
+    AspeedGPIOState *s = ASPEED_GPIO(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
+    int pin;
+
+    /* Interrupt parent line */
+    sysbus_init_irq(sbd, &s->irq);
+
+    /* Individual GPIOs */
+    for (pin = 0; pin < agc->nr_gpio_pins; pin++) {
+        sysbus_init_irq(sbd, &s->gpios[pin]);
+    }
+
+    memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_gpio_ops, s,
+            TYPE_ASPEED_GPIO, GPIO_3_6V_MEM_SIZE);
+
+    sysbus_init_mmio(sbd, &s->iomem);
+}
+
+static void aspeed_gpio_init(Object *obj)
+{
+    AspeedGPIOState *s = ASPEED_GPIO(obj);
+    AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
+    int pin;
+
+    for (pin = 0; pin < agc->nr_gpio_pins; pin++) {
+        char *name;
+        int set_idx = pin / GPIOS_PER_SET;
+        int pin_idx = aspeed_adjust_pin(s, pin) - (set_idx * GPIOS_PER_SET);
+        int group_idx = pin_idx >> GPIO_GROUP_SHIFT;
+        const GPIOSetProperties *props = &agc->props[set_idx];
+
+        name = g_strdup_printf("gpio%s%d", props->group_label[group_idx],
+                               pin_idx % GPIOS_PER_GROUP);
+        object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
+                            aspeed_gpio_set_pin, NULL, NULL, NULL);
+    }
+}
+
+static const VMStateDescription vmstate_gpio_regs = {
+    .name = TYPE_ASPEED_GPIO"/regs",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(data_value,   GPIOSets),
+        VMSTATE_UINT32(data_read,    GPIOSets),
+        VMSTATE_UINT32(direction,    GPIOSets),
+        VMSTATE_UINT32(int_enable,   GPIOSets),
+        VMSTATE_UINT32(int_sens_0,   GPIOSets),
+        VMSTATE_UINT32(int_sens_1,   GPIOSets),
+        VMSTATE_UINT32(int_sens_2,   GPIOSets),
+        VMSTATE_UINT32(int_status,   GPIOSets),
+        VMSTATE_UINT32(reset_tol,    GPIOSets),
+        VMSTATE_UINT32(cmd_source_0, GPIOSets),
+        VMSTATE_UINT32(cmd_source_1, GPIOSets),
+        VMSTATE_UINT32(debounce_1,   GPIOSets),
+        VMSTATE_UINT32(debounce_2,   GPIOSets),
+        VMSTATE_UINT32(input_mask,   GPIOSets),
+        VMSTATE_END_OF_LIST(),
+    }
+};
+
+static const VMStateDescription vmstate_aspeed_gpio = {
+    .name = TYPE_ASPEED_GPIO,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_STRUCT_ARRAY(sets, AspeedGPIOState, ASPEED_GPIO_MAX_NR_SETS,
+                             1, vmstate_gpio_regs, GPIOSets),
+        VMSTATE_UINT32_ARRAY(debounce_regs, AspeedGPIOState,
+                             ASPEED_GPIO_NR_DEBOUNCE_REGS),
+        VMSTATE_END_OF_LIST(),
+   }
+};
+
+static void aspeed_gpio_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = aspeed_gpio_realize;
+    dc->reset = aspeed_gpio_reset;
+    dc->desc = "Aspeed GPIO Controller";
+    dc->vmsd = &vmstate_aspeed_gpio;
+}
+
+static void aspeed_gpio_ast2400_class_init(ObjectClass *klass, void *data)
+{
+    AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
+
+    agc->props = ast2400_set_props;
+    agc->nr_gpio_pins = 216;
+    agc->nr_gpio_sets = 7;
+    agc->gap = 196;
+    agc->reg_table = aspeed_3_6v_gpios;
+}
+
+static void aspeed_gpio_2500_class_init(ObjectClass *klass, void *data)
+{
+    AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
+
+    agc->props = ast2500_set_props;
+    agc->nr_gpio_pins = 228;
+    agc->nr_gpio_sets = 8;
+    agc->gap = 220;
+    agc->reg_table = aspeed_3_6v_gpios;
+}
+
+static const TypeInfo aspeed_gpio_info = {
+    .name           = TYPE_ASPEED_GPIO,
+    .parent         = TYPE_SYS_BUS_DEVICE,
+    .instance_size  = sizeof(AspeedGPIOState),
+    .class_size     = sizeof(AspeedGPIOClass),
+    .class_init     = aspeed_gpio_class_init,
+    .abstract       = true,
+};
+
+static const TypeInfo aspeed_gpio_ast2400_info = {
+    .name           = TYPE_ASPEED_GPIO "-ast2400",
+    .parent         = TYPE_ASPEED_GPIO,
+    .class_init     = aspeed_gpio_ast2400_class_init,
+    .instance_init  = aspeed_gpio_init,
+};
+
+static const TypeInfo aspeed_gpio_ast2500_info = {
+    .name           = TYPE_ASPEED_GPIO "-ast2500",
+    .parent         = TYPE_ASPEED_GPIO,
+    .class_init     = aspeed_gpio_2500_class_init,
+    .instance_init  = aspeed_gpio_init,
+};
+
+static void aspeed_gpio_register_types(void)
+{
+    type_register_static(&aspeed_gpio_info);
+    type_register_static(&aspeed_gpio_ast2400_info);
+    type_register_static(&aspeed_gpio_ast2500_info);
+}
+
+type_init(aspeed_gpio_register_types);
-- 
2.20.1



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

* [Qemu-devel] [PULL 02/12] aspeed: add a GPIO controller to the SoC
  2019-09-13 15:49 [Qemu-devel] [PULL 00/12] target-arm queue Peter Maydell
  2019-09-13 15:49 ` [Qemu-devel] [PULL 01/12] hw/gpio: Add basic Aspeed GPIO model for AST2400 and AST2500 Peter Maydell
@ 2019-09-13 15:49 ` Peter Maydell
  2019-09-13 15:49 ` [Qemu-devel] [PULL 03/12] aspeed: Remove unused SoC definitions Peter Maydell
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Peter Maydell @ 2019-09-13 15:49 UTC (permalink / raw)
  To: qemu-devel

From: Rashmica Gupta <rashmica.g@gmail.com>

Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-id: 20190904070506.1052-3-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/aspeed_soc.h |  3 +++
 hw/arm/aspeed_soc.c         | 17 +++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index 976fd6be93f..a56effebc16 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -23,6 +23,7 @@
 #include "hw/watchdog/wdt_aspeed.h"
 #include "hw/net/ftgmac100.h"
 #include "target/arm/cpu.h"
+#include "hw/gpio/aspeed_gpio.h"
 
 #define ASPEED_SPIS_NUM  2
 #define ASPEED_WDTS_NUM  3
@@ -48,6 +49,7 @@ typedef struct AspeedSoCState {
     AspeedSDMCState sdmc;
     AspeedWDTState wdt[ASPEED_WDTS_NUM];
     FTGMAC100State ftgmac100[ASPEED_MACS_NUM];
+    AspeedGPIOState gpio;
 } AspeedSoCState;
 
 #define TYPE_ASPEED_SOC "aspeed-soc"
@@ -61,6 +63,7 @@ typedef struct AspeedSoCInfo {
     int spis_num;
     const char *fmc_typename;
     const char **spi_typename;
+    const char *gpio_typename;
     int wdts_num;
     const int *irqmap;
     const hwaddr *memmap;
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 9ee81048326..04480875d0d 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -125,6 +125,7 @@ static const AspeedSoCInfo aspeed_socs[] = {
         .spis_num     = 1,
         .fmc_typename = "aspeed.smc.fmc",
         .spi_typename = aspeed_soc_ast2400_typenames,
+        .gpio_typename = "aspeed.gpio-ast2400",
         .wdts_num     = 2,
         .irqmap       = aspeed_soc_ast2400_irqmap,
         .memmap       = aspeed_soc_ast2400_memmap,
@@ -137,6 +138,7 @@ static const AspeedSoCInfo aspeed_socs[] = {
         .spis_num     = 1,
         .fmc_typename = "aspeed.smc.fmc",
         .spi_typename = aspeed_soc_ast2400_typenames,
+        .gpio_typename = "aspeed.gpio-ast2400",
         .wdts_num     = 2,
         .irqmap       = aspeed_soc_ast2400_irqmap,
         .memmap       = aspeed_soc_ast2400_memmap,
@@ -149,6 +151,7 @@ static const AspeedSoCInfo aspeed_socs[] = {
         .spis_num     = 1,
         .fmc_typename = "aspeed.smc.fmc",
         .spi_typename = aspeed_soc_ast2400_typenames,
+        .gpio_typename = "aspeed.gpio-ast2400",
         .wdts_num     = 2,
         .irqmap       = aspeed_soc_ast2400_irqmap,
         .memmap       = aspeed_soc_ast2400_memmap,
@@ -161,6 +164,7 @@ static const AspeedSoCInfo aspeed_socs[] = {
         .spis_num     = 2,
         .fmc_typename = "aspeed.smc.ast2500-fmc",
         .spi_typename = aspeed_soc_ast2500_typenames,
+        .gpio_typename = "aspeed.gpio-ast2500",
         .wdts_num     = 3,
         .irqmap       = aspeed_soc_ast2500_irqmap,
         .memmap       = aspeed_soc_ast2500_memmap,
@@ -247,6 +251,9 @@ static void aspeed_soc_init(Object *obj)
 
     sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma),
                           TYPE_ASPEED_XDMA);
+
+    sysbus_init_child_obj(obj, "gpio", OBJECT(&s->gpio), sizeof(s->gpio),
+                          sc->info->gpio_typename);
 }
 
 static void aspeed_soc_realize(DeviceState *dev, Error **errp)
@@ -426,6 +433,16 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
                     sc->info->memmap[ASPEED_XDMA]);
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0,
                        aspeed_soc_get_irq(s, ASPEED_XDMA));
+
+    /* GPIO */
+    object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->info->memmap[ASPEED_GPIO]);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0,
+                       aspeed_soc_get_irq(s, ASPEED_GPIO));
 }
 static Property aspeed_soc_properties[] = {
     DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0),
-- 
2.20.1



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

* [Qemu-devel] [PULL 03/12] aspeed: Remove unused SoC definitions
  2019-09-13 15:49 [Qemu-devel] [PULL 00/12] target-arm queue Peter Maydell
  2019-09-13 15:49 ` [Qemu-devel] [PULL 01/12] hw/gpio: Add basic Aspeed GPIO model for AST2400 and AST2500 Peter Maydell
  2019-09-13 15:49 ` [Qemu-devel] [PULL 02/12] aspeed: add a GPIO controller to the SoC Peter Maydell
@ 2019-09-13 15:49 ` Peter Maydell
  2019-09-13 15:49 ` [Qemu-devel] [PULL 04/12] aspeed: Use consistent typenames Peter Maydell
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Peter Maydell @ 2019-09-13 15:49 UTC (permalink / raw)
  To: qemu-devel

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

There are no QEMU Aspeed machines using the SoCs "ast2400-a0" or
"ast2400".

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-id: 20190904070506.1052-4-clg@kaod.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/aspeed_soc.c | 26 --------------------------
 1 file changed, 26 deletions(-)

diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 04480875d0d..3aa73d2438e 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -118,19 +118,6 @@ static const char *aspeed_soc_ast2500_typenames[] = {
 
 static const AspeedSoCInfo aspeed_socs[] = {
     {
-        .name         = "ast2400-a0",
-        .cpu_type     = ARM_CPU_TYPE_NAME("arm926"),
-        .silicon_rev  = AST2400_A0_SILICON_REV,
-        .sram_size    = 0x8000,
-        .spis_num     = 1,
-        .fmc_typename = "aspeed.smc.fmc",
-        .spi_typename = aspeed_soc_ast2400_typenames,
-        .gpio_typename = "aspeed.gpio-ast2400",
-        .wdts_num     = 2,
-        .irqmap       = aspeed_soc_ast2400_irqmap,
-        .memmap       = aspeed_soc_ast2400_memmap,
-        .num_cpus     = 1,
-    }, {
         .name         = "ast2400-a1",
         .cpu_type     = ARM_CPU_TYPE_NAME("arm926"),
         .silicon_rev  = AST2400_A1_SILICON_REV,
@@ -143,19 +130,6 @@ static const AspeedSoCInfo aspeed_socs[] = {
         .irqmap       = aspeed_soc_ast2400_irqmap,
         .memmap       = aspeed_soc_ast2400_memmap,
         .num_cpus     = 1,
-    }, {
-        .name         = "ast2400",
-        .cpu_type     = ARM_CPU_TYPE_NAME("arm926"),
-        .silicon_rev  = AST2400_A0_SILICON_REV,
-        .sram_size    = 0x8000,
-        .spis_num     = 1,
-        .fmc_typename = "aspeed.smc.fmc",
-        .spi_typename = aspeed_soc_ast2400_typenames,
-        .gpio_typename = "aspeed.gpio-ast2400",
-        .wdts_num     = 2,
-        .irqmap       = aspeed_soc_ast2400_irqmap,
-        .memmap       = aspeed_soc_ast2400_memmap,
-        .num_cpus     = 1,
     }, {
         .name         = "ast2500-a1",
         .cpu_type     = ARM_CPU_TYPE_NAME("arm1176"),
-- 
2.20.1



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

* [Qemu-devel] [PULL 04/12] aspeed: Use consistent typenames
  2019-09-13 15:49 [Qemu-devel] [PULL 00/12] target-arm queue Peter Maydell
                   ` (2 preceding siblings ...)
  2019-09-13 15:49 ` [Qemu-devel] [PULL 03/12] aspeed: Remove unused SoC definitions Peter Maydell
@ 2019-09-13 15:49 ` Peter Maydell
  2019-09-13 15:49 ` [Qemu-devel] [PULL 05/12] aspeed/smc: Add support for DMAs Peter Maydell
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Peter Maydell @ 2019-09-13 15:49 UTC (permalink / raw)
  To: qemu-devel

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

Improve the naming of the different controller models to ease their
generation when initializing the SoC. The rename of the SMC types is
breaking migration compatibility.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-id: 20190904070506.1052-5-clg@kaod.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/aspeed_soc.h |  3 ---
 hw/arm/aspeed_soc.c         | 25 ++++++++++++-------------
 hw/ssi/aspeed_smc.c         | 12 ++++++------
 3 files changed, 18 insertions(+), 22 deletions(-)

diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index a56effebc16..ab5052b12cb 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -61,9 +61,6 @@ typedef struct AspeedSoCInfo {
     uint32_t silicon_rev;
     uint64_t sram_size;
     int spis_num;
-    const char *fmc_typename;
-    const char **spi_typename;
-    const char *gpio_typename;
     int wdts_num;
     const int *irqmap;
     const hwaddr *memmap;
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 3aa73d2438e..25dbc409d35 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -112,10 +112,6 @@ static const int aspeed_soc_ast2400_irqmap[] = {
 
 #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
 
-static const char *aspeed_soc_ast2400_typenames[] = { "aspeed.smc.spi" };
-static const char *aspeed_soc_ast2500_typenames[] = {
-    "aspeed.smc.ast2500-spi1", "aspeed.smc.ast2500-spi2" };
-
 static const AspeedSoCInfo aspeed_socs[] = {
     {
         .name         = "ast2400-a1",
@@ -123,9 +119,6 @@ static const AspeedSoCInfo aspeed_socs[] = {
         .silicon_rev  = AST2400_A1_SILICON_REV,
         .sram_size    = 0x8000,
         .spis_num     = 1,
-        .fmc_typename = "aspeed.smc.fmc",
-        .spi_typename = aspeed_soc_ast2400_typenames,
-        .gpio_typename = "aspeed.gpio-ast2400",
         .wdts_num     = 2,
         .irqmap       = aspeed_soc_ast2400_irqmap,
         .memmap       = aspeed_soc_ast2400_memmap,
@@ -136,9 +129,6 @@ static const AspeedSoCInfo aspeed_socs[] = {
         .silicon_rev  = AST2500_A1_SILICON_REV,
         .sram_size    = 0x9000,
         .spis_num     = 2,
-        .fmc_typename = "aspeed.smc.ast2500-fmc",
-        .spi_typename = aspeed_soc_ast2500_typenames,
-        .gpio_typename = "aspeed.gpio-ast2500",
         .wdts_num     = 3,
         .irqmap       = aspeed_soc_ast2500_irqmap,
         .memmap       = aspeed_soc_ast2500_memmap,
@@ -158,6 +148,12 @@ static void aspeed_soc_init(Object *obj)
     AspeedSoCState *s = ASPEED_SOC(obj);
     AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
     int i;
+    char socname[8];
+    char typename[64];
+
+    if (sscanf(sc->info->name, "%7s", socname) != 1) {
+        g_assert_not_reached();
+    }
 
     for (i = 0; i < sc->info->num_cpus; i++) {
         object_initialize_child(obj, "cpu[*]", OBJECT(&s->cpu[i]),
@@ -190,14 +186,16 @@ static void aspeed_soc_init(Object *obj)
     sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c),
                           TYPE_ASPEED_I2C);
 
+    snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
     sysbus_init_child_obj(obj, "fmc", OBJECT(&s->fmc), sizeof(s->fmc),
-                          sc->info->fmc_typename);
+                          typename);
     object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
                               &error_abort);
 
     for (i = 0; i < sc->info->spis_num; i++) {
+        snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
         sysbus_init_child_obj(obj, "spi[*]", OBJECT(&s->spi[i]),
-                              sizeof(s->spi[i]), sc->info->spi_typename[i]);
+                              sizeof(s->spi[i]), typename);
     }
 
     sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc),
@@ -226,8 +224,9 @@ static void aspeed_soc_init(Object *obj)
     sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma),
                           TYPE_ASPEED_XDMA);
 
+    snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
     sysbus_init_child_obj(obj, "gpio", OBJECT(&s->gpio), sizeof(s->gpio),
-                          sc->info->gpio_typename);
+                          typename);
 }
 
 static void aspeed_soc_realize(DeviceState *dev, Error **errp)
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 9f3cff5fb6f..f4f7c181830 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -190,7 +190,7 @@ static const AspeedSegments aspeed_segments_ast2500_spi2[] = {
 
 static const AspeedSMCController controllers[] = {
     {
-        .name              = "aspeed.smc.smc",
+        .name              = "aspeed.smc-ast2400",
         .r_conf            = R_CONF,
         .r_ce_ctrl         = R_CE_CTRL,
         .r_ctrl0           = R_CTRL0,
@@ -203,7 +203,7 @@ static const AspeedSMCController controllers[] = {
         .has_dma           = false,
         .nregs             = ASPEED_SMC_R_SMC_MAX,
     }, {
-        .name              = "aspeed.smc.fmc",
+        .name              = "aspeed.fmc-ast2400",
         .r_conf            = R_CONF,
         .r_ce_ctrl         = R_CE_CTRL,
         .r_ctrl0           = R_CTRL0,
@@ -216,7 +216,7 @@ static const AspeedSMCController controllers[] = {
         .has_dma           = true,
         .nregs             = ASPEED_SMC_R_MAX,
     }, {
-        .name              = "aspeed.smc.spi",
+        .name              = "aspeed.spi1-ast2400",
         .r_conf            = R_SPI_CONF,
         .r_ce_ctrl         = 0xff,
         .r_ctrl0           = R_SPI_CTRL0,
@@ -229,7 +229,7 @@ static const AspeedSMCController controllers[] = {
         .has_dma           = false,
         .nregs             = ASPEED_SMC_R_SPI_MAX,
     }, {
-        .name              = "aspeed.smc.ast2500-fmc",
+        .name              = "aspeed.fmc-ast2500",
         .r_conf            = R_CONF,
         .r_ce_ctrl         = R_CE_CTRL,
         .r_ctrl0           = R_CTRL0,
@@ -242,7 +242,7 @@ static const AspeedSMCController controllers[] = {
         .has_dma           = true,
         .nregs             = ASPEED_SMC_R_MAX,
     }, {
-        .name              = "aspeed.smc.ast2500-spi1",
+        .name              = "aspeed.spi1-ast2500",
         .r_conf            = R_CONF,
         .r_ce_ctrl         = R_CE_CTRL,
         .r_ctrl0           = R_CTRL0,
@@ -255,7 +255,7 @@ static const AspeedSMCController controllers[] = {
         .has_dma           = false,
         .nregs             = ASPEED_SMC_R_MAX,
     }, {
-        .name              = "aspeed.smc.ast2500-spi2",
+        .name              = "aspeed.spi2-ast2500",
         .r_conf            = R_CONF,
         .r_ce_ctrl         = R_CE_CTRL,
         .r_ctrl0           = R_CTRL0,
-- 
2.20.1



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

* [Qemu-devel] [PULL 05/12] aspeed/smc: Add support for DMAs
  2019-09-13 15:49 [Qemu-devel] [PULL 00/12] target-arm queue Peter Maydell
                   ` (3 preceding siblings ...)
  2019-09-13 15:49 ` [Qemu-devel] [PULL 04/12] aspeed: Use consistent typenames Peter Maydell
@ 2019-09-13 15:49 ` Peter Maydell
  2019-09-13 15:49 ` [Qemu-devel] [PULL 06/12] aspeed/smc: Add DMA calibration settings Peter Maydell
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Peter Maydell @ 2019-09-13 15:49 UTC (permalink / raw)
  To: qemu-devel

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

The FMC controller on the Aspeed SoCs support DMA to access the flash
modules. It can operate in a normal mode, to copy to or from the flash
module mapping window, or in a checksum calculation mode, to evaluate
the best clock settings for reads.

The model introduces two custom address spaces for DMAs: one for the
AHB window of the FMC flash devices and one for the DRAM. The latter
is populated using a "dram" link set from the machine with the RAM
container region.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Acked-by: Joel Stanley <joel@jms.id.au>
Message-id: 20190904070506.1052-6-clg@kaod.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/ssi/aspeed_smc.h |   6 +
 hw/arm/aspeed.c             |   2 +
 hw/arm/aspeed_soc.c         |   2 +
 hw/ssi/aspeed_smc.c         | 222 +++++++++++++++++++++++++++++++++++-
 4 files changed, 226 insertions(+), 6 deletions(-)

diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
index aa07dac4fe3..32ce6916f6c 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -46,6 +46,8 @@ typedef struct AspeedSMCController {
     hwaddr flash_window_base;
     uint32_t flash_window_size;
     bool has_dma;
+    hwaddr dma_flash_mask;
+    hwaddr dma_dram_mask;
     uint32_t nregs;
 } AspeedSMCController;
 
@@ -101,6 +103,10 @@ typedef struct AspeedSMCState {
     /* for DMA support */
     uint64_t sdram_base;
 
+    AddressSpace flash_as;
+    MemoryRegion *dram_mr;
+    AddressSpace dram_as;
+
     AspeedSMCFlash *flashes;
 
     uint8_t snoop_index;
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 13e208c78cc..aa72be309da 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -190,6 +190,8 @@ static void aspeed_board_init(MachineState *machine,
                             &error_abort);
     object_property_set_int(OBJECT(&bmc->soc), machine->smp.cpus, "num-cpus",
                             &error_abort);
+    object_property_set_link(OBJECT(&bmc->soc), OBJECT(&bmc->ram_container),
+                             "dram", &error_abort);
     if (machine->kernel_filename) {
         /*
          * When booting with a -kernel command line there is no u-boot
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 25dbc409d35..da508c99c33 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -191,6 +191,8 @@ static void aspeed_soc_init(Object *obj)
                           typename);
     object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
                               &error_abort);
+    object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
+                              &error_abort);
 
     for (i = 0; i < sc->info->spis_num; i++) {
         snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index f4f7c181830..c1a45c10dc1 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -28,6 +28,8 @@
 #include "qemu/log.h"
 #include "qemu/module.h"
 #include "qemu/error-report.h"
+#include "qapi/error.h"
+#include "exec/address-spaces.h"
 
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
@@ -112,8 +114,8 @@
 #define   DMA_CTRL_FREQ_SHIFT   4
 #define   DMA_CTRL_MODE         (1 << 3)
 #define   DMA_CTRL_CKSUM        (1 << 2)
-#define   DMA_CTRL_DIR          (1 << 1)
-#define   DMA_CTRL_EN           (1 << 0)
+#define   DMA_CTRL_WRITE        (1 << 1)
+#define   DMA_CTRL_ENABLE       (1 << 0)
 
 /* DMA Flash Side Address */
 #define R_DMA_FLASH_ADDR  (0x84 / 4)
@@ -145,6 +147,24 @@
 #define ASPEED_SOC_SPI_FLASH_BASE   0x30000000
 #define ASPEED_SOC_SPI2_FLASH_BASE  0x38000000
 
+/*
+ * DMA DRAM addresses should be 4 bytes aligned and the valid address
+ * range is 0x40000000 - 0x5FFFFFFF (AST2400)
+ *          0x80000000 - 0xBFFFFFFF (AST2500)
+ *
+ * DMA flash addresses should be 4 bytes aligned and the valid address
+ * range is 0x20000000 - 0x2FFFFFFF.
+ *
+ * DMA length is from 4 bytes to 32MB
+ *   0: 4 bytes
+ *   0x7FFFFF: 32M bytes
+ */
+#define DMA_DRAM_ADDR(s, val)   ((s)->sdram_base | \
+                                 ((val) & (s)->ctrl->dma_dram_mask))
+#define DMA_FLASH_ADDR(s, val)  ((s)->ctrl->flash_window_base | \
+                                ((val) & (s)->ctrl->dma_flash_mask))
+#define DMA_LENGTH(val)         ((val) & 0x01FFFFFC)
+
 /* Flash opcodes. */
 #define SPI_OP_READ       0x03    /* Read data bytes (low frequency) */
 
@@ -214,6 +234,8 @@ static const AspeedSMCController controllers[] = {
         .flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
         .flash_window_size = 0x10000000,
         .has_dma           = true,
+        .dma_flash_mask    = 0x0FFFFFFC,
+        .dma_dram_mask     = 0x1FFFFFFC,
         .nregs             = ASPEED_SMC_R_MAX,
     }, {
         .name              = "aspeed.spi1-ast2400",
@@ -240,6 +262,8 @@ static const AspeedSMCController controllers[] = {
         .flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
         .flash_window_size = 0x10000000,
         .has_dma           = true,
+        .dma_flash_mask    = 0x0FFFFFFC,
+        .dma_dram_mask     = 0x3FFFFFFC,
         .nregs             = ASPEED_SMC_R_MAX,
     }, {
         .name              = "aspeed.spi1-ast2500",
@@ -732,9 +756,6 @@ static void aspeed_smc_reset(DeviceState *d)
 
     memset(s->regs, 0, sizeof s->regs);
 
-    /* Pretend DMA is done (u-boot initialization) */
-    s->regs[R_INTR_CTRL] = INTR_CTRL_DMA_STATUS;
-
     /* Unselect all slaves */
     for (i = 0; i < s->num_cs; ++i) {
         s->regs[s->r_ctrl0 + i] |= CTRL_CE_STOP_ACTIVE;
@@ -775,6 +796,11 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
         addr == s->r_ce_ctrl ||
         addr == R_INTR_CTRL ||
         addr == R_DUMMY_DATA ||
+        (s->ctrl->has_dma && addr == R_DMA_CTRL) ||
+        (s->ctrl->has_dma && addr == R_DMA_FLASH_ADDR) ||
+        (s->ctrl->has_dma && addr == R_DMA_DRAM_ADDR) ||
+        (s->ctrl->has_dma && addr == R_DMA_LEN) ||
+        (s->ctrl->has_dma && addr == R_DMA_CHECKSUM) ||
         (addr >= R_SEG_ADDR0 && addr < R_SEG_ADDR0 + s->ctrl->max_slaves) ||
         (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->ctrl->max_slaves)) {
         return s->regs[addr];
@@ -785,6 +811,149 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
     }
 }
 
+/*
+ * Accumulate the result of the reads to provide a checksum that will
+ * be used to validate the read timing settings.
+ */
+static void aspeed_smc_dma_checksum(AspeedSMCState *s)
+{
+    MemTxResult result;
+    uint32_t data;
+
+    if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: invalid direction for DMA checksum\n",  __func__);
+        return;
+    }
+
+    while (s->regs[R_DMA_LEN]) {
+        data = address_space_ldl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
+                                    MEMTXATTRS_UNSPECIFIED, &result);
+        if (result != MEMTX_OK) {
+            qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash read failed @%08x\n",
+                          __func__, s->regs[R_DMA_FLASH_ADDR]);
+            return;
+        }
+
+        /*
+         * When the DMA is on-going, the DMA registers are updated
+         * with the current working addresses and length.
+         */
+        s->regs[R_DMA_CHECKSUM] += data;
+        s->regs[R_DMA_FLASH_ADDR] += 4;
+        s->regs[R_DMA_LEN] -= 4;
+    }
+}
+
+static void aspeed_smc_dma_rw(AspeedSMCState *s)
+{
+    MemTxResult result;
+    uint32_t data;
+
+    while (s->regs[R_DMA_LEN]) {
+        if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
+            data = address_space_ldl_le(&s->dram_as, s->regs[R_DMA_DRAM_ADDR],
+                                        MEMTXATTRS_UNSPECIFIED, &result);
+            if (result != MEMTX_OK) {
+                qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM read failed @%08x\n",
+                              __func__, s->regs[R_DMA_DRAM_ADDR]);
+                return;
+            }
+
+            address_space_stl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
+                                 data, MEMTXATTRS_UNSPECIFIED, &result);
+            if (result != MEMTX_OK) {
+                qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash write failed @%08x\n",
+                              __func__, s->regs[R_DMA_FLASH_ADDR]);
+                return;
+            }
+        } else {
+            data = address_space_ldl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
+                                        MEMTXATTRS_UNSPECIFIED, &result);
+            if (result != MEMTX_OK) {
+                qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash read failed @%08x\n",
+                              __func__, s->regs[R_DMA_FLASH_ADDR]);
+                return;
+            }
+
+            address_space_stl_le(&s->dram_as, s->regs[R_DMA_DRAM_ADDR],
+                                 data, MEMTXATTRS_UNSPECIFIED, &result);
+            if (result != MEMTX_OK) {
+                qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM write failed @%08x\n",
+                              __func__, s->regs[R_DMA_DRAM_ADDR]);
+                return;
+            }
+        }
+
+        /*
+         * When the DMA is on-going, the DMA registers are updated
+         * with the current working addresses and length.
+         */
+        s->regs[R_DMA_FLASH_ADDR] += 4;
+        s->regs[R_DMA_DRAM_ADDR] += 4;
+        s->regs[R_DMA_LEN] -= 4;
+    }
+}
+
+static void aspeed_smc_dma_stop(AspeedSMCState *s)
+{
+    /*
+     * When the DMA is disabled, INTR_CTRL_DMA_STATUS=0 means the
+     * engine is idle
+     */
+    s->regs[R_INTR_CTRL] &= ~INTR_CTRL_DMA_STATUS;
+    s->regs[R_DMA_CHECKSUM] = 0;
+
+    /*
+     * Lower the DMA irq in any case. The IRQ control register could
+     * have been cleared before disabling the DMA.
+     */
+    qemu_irq_lower(s->irq);
+}
+
+/*
+ * When INTR_CTRL_DMA_STATUS=1, the DMA has completed and a new DMA
+ * can start even if the result of the previous was not collected.
+ */
+static bool aspeed_smc_dma_in_progress(AspeedSMCState *s)
+{
+    return s->regs[R_DMA_CTRL] & DMA_CTRL_ENABLE &&
+        !(s->regs[R_INTR_CTRL] & INTR_CTRL_DMA_STATUS);
+}
+
+static void aspeed_smc_dma_done(AspeedSMCState *s)
+{
+    s->regs[R_INTR_CTRL] |= INTR_CTRL_DMA_STATUS;
+    if (s->regs[R_INTR_CTRL] & INTR_CTRL_DMA_EN) {
+        qemu_irq_raise(s->irq);
+    }
+}
+
+static void aspeed_smc_dma_ctrl(AspeedSMCState *s, uint64_t dma_ctrl)
+{
+    if (!(dma_ctrl & DMA_CTRL_ENABLE)) {
+        s->regs[R_DMA_CTRL] = dma_ctrl;
+
+        aspeed_smc_dma_stop(s);
+        return;
+    }
+
+    if (aspeed_smc_dma_in_progress(s)) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA in progress\n",  __func__);
+        return;
+    }
+
+    s->regs[R_DMA_CTRL] = dma_ctrl;
+
+    if (s->regs[R_DMA_CTRL] & DMA_CTRL_CKSUM) {
+        aspeed_smc_dma_checksum(s);
+    } else {
+        aspeed_smc_dma_rw(s);
+    }
+
+    aspeed_smc_dma_done(s);
+}
+
 static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
                              unsigned int size)
 {
@@ -810,6 +979,16 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
         }
     } else if (addr == R_DUMMY_DATA) {
         s->regs[addr] = value & 0xff;
+    } else if (addr == R_INTR_CTRL) {
+        s->regs[addr] = value;
+    } else if (s->ctrl->has_dma && addr == R_DMA_CTRL) {
+        aspeed_smc_dma_ctrl(s, value);
+    } else if (s->ctrl->has_dma && addr == R_DMA_DRAM_ADDR) {
+        s->regs[addr] = DMA_DRAM_ADDR(s, value);
+    } else if (s->ctrl->has_dma && addr == R_DMA_FLASH_ADDR) {
+        s->regs[addr] = DMA_FLASH_ADDR(s, value);
+    } else if (s->ctrl->has_dma && addr == R_DMA_LEN) {
+        s->regs[addr] = DMA_LENGTH(value);
     } else {
         qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
                       __func__, addr);
@@ -824,6 +1003,28 @@ static const MemoryRegionOps aspeed_smc_ops = {
     .valid.unaligned = true,
 };
 
+
+/*
+ * Initialize the custom address spaces for DMAs
+ */
+static void aspeed_smc_dma_setup(AspeedSMCState *s, Error **errp)
+{
+    char *name;
+
+    if (!s->dram_mr) {
+        error_setg(errp, TYPE_ASPEED_SMC ": 'dram' link not set");
+        return;
+    }
+
+    name = g_strdup_printf("%s-dma-flash", s->ctrl->name);
+    address_space_init(&s->flash_as, &s->mmio_flash, name);
+    g_free(name);
+
+    name = g_strdup_printf("%s-dma-dram", s->ctrl->name);
+    address_space_init(&s->dram_as, s->dram_mr, name);
+    g_free(name);
+}
+
 static void aspeed_smc_realize(DeviceState *dev, Error **errp)
 {
     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
@@ -849,10 +1050,12 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
         s->num_cs = s->ctrl->max_slaves;
     }
 
+    /* DMA irq. Keep it first for the initialization in the SoC */
+    sysbus_init_irq(sbd, &s->irq);
+
     s->spi = ssi_create_bus(dev, "spi");
 
     /* Setup cs_lines for slaves */
-    sysbus_init_irq(sbd, &s->irq);
     s->cs_lines = g_new0(qemu_irq, s->num_cs);
     ssi_auto_connect_slaves(dev, s->cs_lines, s->spi);
 
@@ -899,6 +1102,11 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
         memory_region_add_subregion(&s->mmio_flash, offset, &fl->mmio);
         offset += fl->size;
     }
+
+    /* DMA support */
+    if (s->ctrl->has_dma) {
+        aspeed_smc_dma_setup(s, errp);
+    }
 }
 
 static const VMStateDescription vmstate_aspeed_smc = {
@@ -916,6 +1124,8 @@ static const VMStateDescription vmstate_aspeed_smc = {
 static Property aspeed_smc_properties[] = {
     DEFINE_PROP_UINT32("num-cs", AspeedSMCState, num_cs, 1),
     DEFINE_PROP_UINT64("sdram-base", AspeedSMCState, sdram_base, 0),
+    DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr,
+                     TYPE_MEMORY_REGION, MemoryRegion *),
     DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.20.1



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

* [Qemu-devel] [PULL 06/12] aspeed/smc: Add DMA calibration settings
  2019-09-13 15:49 [Qemu-devel] [PULL 00/12] target-arm queue Peter Maydell
                   ` (4 preceding siblings ...)
  2019-09-13 15:49 ` [Qemu-devel] [PULL 05/12] aspeed/smc: Add support for DMAs Peter Maydell
@ 2019-09-13 15:49 ` Peter Maydell
  2019-09-13 15:49 ` [Qemu-devel] [PULL 07/12] aspeed/smc: Inject errors in DMA checksum Peter Maydell
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Peter Maydell @ 2019-09-13 15:49 UTC (permalink / raw)
  To: qemu-devel

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

When doing calibration, the SPI clock rate in the CE0 Control Register
and the read delay cycles in the Read Timing Compensation Register are
set using bit[11:4] of the DMA Control Register.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Acked-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20190904070506.1052-7-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/ssi/aspeed_smc.c | 64 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index c1a45c10dc1..7a0cd7607fd 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -77,6 +77,10 @@
 #define   CTRL_CMD_MASK            0xff
 #define   CTRL_DUMMY_HIGH_SHIFT    14
 #define   CTRL_AST2400_SPI_4BYTE   (1 << 13)
+#define CE_CTRL_CLOCK_FREQ_SHIFT   8
+#define CE_CTRL_CLOCK_FREQ_MASK    0xf
+#define CE_CTRL_CLOCK_FREQ(div)                                         \
+    (((div) & CE_CTRL_CLOCK_FREQ_MASK) << CE_CTRL_CLOCK_FREQ_SHIFT)
 #define   CTRL_DUMMY_LOW_SHIFT     6 /* 2 bits [7:6] */
 #define   CTRL_CE_STOP_ACTIVE      (1 << 2)
 #define   CTRL_CMD_MODE_MASK       0x3
@@ -112,7 +116,7 @@
 #define   DMA_CTRL_DELAY_SHIFT  8
 #define   DMA_CTRL_FREQ_MASK    0xf
 #define   DMA_CTRL_FREQ_SHIFT   4
-#define   DMA_CTRL_MODE         (1 << 3)
+#define   DMA_CTRL_CALIB        (1 << 3)
 #define   DMA_CTRL_CKSUM        (1 << 2)
 #define   DMA_CTRL_WRITE        (1 << 1)
 #define   DMA_CTRL_ENABLE       (1 << 0)
@@ -811,6 +815,60 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
     }
 }
 
+static uint8_t aspeed_smc_hclk_divisor(uint8_t hclk_mask)
+{
+    /* HCLK/1 .. HCLK/16 */
+    const uint8_t hclk_divisors[] = {
+        15, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 0
+    };
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(hclk_divisors); i++) {
+        if (hclk_mask == hclk_divisors[i]) {
+            return i + 1;
+        }
+    }
+
+    qemu_log_mask(LOG_GUEST_ERROR, "invalid HCLK mask %x", hclk_mask);
+    return 0;
+}
+
+/*
+ * When doing calibration, the SPI clock rate in the CE0 Control
+ * Register and the read delay cycles in the Read Timing Compensation
+ * Register are set using bit[11:4] of the DMA Control Register.
+ */
+static void aspeed_smc_dma_calibration(AspeedSMCState *s)
+{
+    uint8_t delay =
+        (s->regs[R_DMA_CTRL] >> DMA_CTRL_DELAY_SHIFT) & DMA_CTRL_DELAY_MASK;
+    uint8_t hclk_mask =
+        (s->regs[R_DMA_CTRL] >> DMA_CTRL_FREQ_SHIFT) & DMA_CTRL_FREQ_MASK;
+    uint8_t hclk_div = aspeed_smc_hclk_divisor(hclk_mask);
+    uint32_t hclk_shift = (hclk_div - 1) << 2;
+    uint8_t cs;
+
+    /*
+     * The Read Timing Compensation Register values apply to all CS on
+     * the SPI bus and only HCLK/1 - HCLK/5 can have tunable delays
+     */
+    if (hclk_div && hclk_div < 6) {
+        s->regs[s->r_timings] &= ~(0xf << hclk_shift);
+        s->regs[s->r_timings] |= delay << hclk_shift;
+    }
+
+    /*
+     * TODO: compute the CS from the DMA address and the segment
+     * registers. This is not really a problem for now because the
+     * Timing Register values apply to all CS and software uses CS0 to
+     * do calibration.
+     */
+    cs = 0;
+    s->regs[s->r_ctrl0 + cs] &=
+        ~(CE_CTRL_CLOCK_FREQ_MASK << CE_CTRL_CLOCK_FREQ_SHIFT);
+    s->regs[s->r_ctrl0 + cs] |= CE_CTRL_CLOCK_FREQ(hclk_div);
+}
+
 /*
  * Accumulate the result of the reads to provide a checksum that will
  * be used to validate the read timing settings.
@@ -826,6 +884,10 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
         return;
     }
 
+    if (s->regs[R_DMA_CTRL] & DMA_CTRL_CALIB) {
+        aspeed_smc_dma_calibration(s);
+    }
+
     while (s->regs[R_DMA_LEN]) {
         data = address_space_ldl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
                                     MEMTXATTRS_UNSPECIFIED, &result);
-- 
2.20.1



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

* [Qemu-devel] [PULL 07/12] aspeed/smc: Inject errors in DMA checksum
  2019-09-13 15:49 [Qemu-devel] [PULL 00/12] target-arm queue Peter Maydell
                   ` (5 preceding siblings ...)
  2019-09-13 15:49 ` [Qemu-devel] [PULL 06/12] aspeed/smc: Add DMA calibration settings Peter Maydell
@ 2019-09-13 15:49 ` Peter Maydell
  2019-09-13 15:49 ` [Qemu-devel] [PULL 08/12] aspeed/smc: Calculate checksum on normal DMA Peter Maydell
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Peter Maydell @ 2019-09-13 15:49 UTC (permalink / raw)
  To: qemu-devel

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

Emulate read errors in the DMA Checksum Register for high frequencies
and optimistic settings of the Read Timing Compensation Register. This
will help in tuning the SPI timing calibration algorithm. Errors are
only injected when the property "inject_failure" is set to true as
suggested by Philippe.

The values below are those to expect from the first flash device of
the FMC controller of a palmetto-bmc machine.

Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Message-id: 20190904070506.1052-8-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/ssi/aspeed_smc.h |  1 +
 hw/ssi/aspeed_smc.c         | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
index 32ce6916f6c..5176ff6bf95 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -88,6 +88,7 @@ typedef struct AspeedSMCState {
 
     uint32_t num_cs;
     qemu_irq *cs_lines;
+    bool inject_failure;
 
     SSIBus *spi;
 
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 7a0cd7607fd..5c3436db5e8 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -869,6 +869,36 @@ static void aspeed_smc_dma_calibration(AspeedSMCState *s)
     s->regs[s->r_ctrl0 + cs] |= CE_CTRL_CLOCK_FREQ(hclk_div);
 }
 
+/*
+ * Emulate read errors in the DMA Checksum Register for high
+ * frequencies and optimistic settings of the Read Timing Compensation
+ * Register. This will help in tuning the SPI timing calibration
+ * algorithm.
+ */
+static bool aspeed_smc_inject_read_failure(AspeedSMCState *s)
+{
+    uint8_t delay =
+        (s->regs[R_DMA_CTRL] >> DMA_CTRL_DELAY_SHIFT) & DMA_CTRL_DELAY_MASK;
+    uint8_t hclk_mask =
+        (s->regs[R_DMA_CTRL] >> DMA_CTRL_FREQ_SHIFT) & DMA_CTRL_FREQ_MASK;
+
+    /*
+     * Typical values of a palmetto-bmc machine.
+     */
+    switch (aspeed_smc_hclk_divisor(hclk_mask)) {
+    case 4 ... 16:
+        return false;
+    case 3: /* at least one HCLK cycle delay */
+        return (delay & 0x7) < 1;
+    case 2: /* at least two HCLK cycle delay */
+        return (delay & 0x7) < 2;
+    case 1: /* (> 100MHz) is above the max freq of the controller */
+        return true;
+    default:
+        g_assert_not_reached();
+    }
+}
+
 /*
  * Accumulate the result of the reads to provide a checksum that will
  * be used to validate the read timing settings.
@@ -905,6 +935,11 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
         s->regs[R_DMA_FLASH_ADDR] += 4;
         s->regs[R_DMA_LEN] -= 4;
     }
+
+    if (s->inject_failure && aspeed_smc_inject_read_failure(s)) {
+        s->regs[R_DMA_CHECKSUM] = 0xbadc0de;
+    }
+
 }
 
 static void aspeed_smc_dma_rw(AspeedSMCState *s)
@@ -1185,6 +1220,7 @@ static const VMStateDescription vmstate_aspeed_smc = {
 
 static Property aspeed_smc_properties[] = {
     DEFINE_PROP_UINT32("num-cs", AspeedSMCState, num_cs, 1),
+    DEFINE_PROP_BOOL("inject-failure", AspeedSMCState, inject_failure, false),
     DEFINE_PROP_UINT64("sdram-base", AspeedSMCState, sdram_base, 0),
     DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr,
                      TYPE_MEMORY_REGION, MemoryRegion *),
-- 
2.20.1



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

* [Qemu-devel] [PULL 08/12] aspeed/smc: Calculate checksum on normal DMA
  2019-09-13 15:49 [Qemu-devel] [PULL 00/12] target-arm queue Peter Maydell
                   ` (6 preceding siblings ...)
  2019-09-13 15:49 ` [Qemu-devel] [PULL 07/12] aspeed/smc: Inject errors in DMA checksum Peter Maydell
@ 2019-09-13 15:49 ` Peter Maydell
  2019-09-13 15:49 ` [Qemu-devel] [PULL 09/12] aspeed/scu: Introduce per-SoC SCU types Peter Maydell
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Peter Maydell @ 2019-09-13 15:49 UTC (permalink / raw)
  To: qemu-devel

From: Christian Svensson <bluecmd@google.com>

This patch adds the missing checksum calculation on normal DMA transfer.
According to the datasheet this is how the SMC should behave.

Verified on AST1250 that the hardware matches the behaviour.

Signed-off-by: Christian Svensson <bluecmd@google.com>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-id: 20190904070506.1052-9-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/ssi/aspeed_smc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 5c3436db5e8..9ffc7e01179 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -989,6 +989,7 @@ static void aspeed_smc_dma_rw(AspeedSMCState *s)
         s->regs[R_DMA_FLASH_ADDR] += 4;
         s->regs[R_DMA_DRAM_ADDR] += 4;
         s->regs[R_DMA_LEN] -= 4;
+        s->regs[R_DMA_CHECKSUM] += data;
     }
 }
 
-- 
2.20.1



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

* [Qemu-devel] [PULL 09/12] aspeed/scu: Introduce per-SoC SCU types
  2019-09-13 15:49 [Qemu-devel] [PULL 00/12] target-arm queue Peter Maydell
                   ` (7 preceding siblings ...)
  2019-09-13 15:49 ` [Qemu-devel] [PULL 08/12] aspeed/smc: Calculate checksum on normal DMA Peter Maydell
@ 2019-09-13 15:49 ` Peter Maydell
  2019-09-13 15:49 ` [Qemu-devel] [PULL 10/12] aspeed/scu: Introduce a aspeed_scu_get_apb_freq() routine Peter Maydell
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Peter Maydell @ 2019-09-13 15:49 UTC (permalink / raw)
  To: qemu-devel

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

and use a class AspeedSCUClass to define each SoC characteristics.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-id: 20190904070506.1052-10-clg@kaod.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/misc/aspeed_scu.h | 15 +++++++
 hw/arm/aspeed_soc.c          |  3 +-
 hw/misc/aspeed_scu.c         | 83 ++++++++++++++++++++----------------
 3 files changed, 64 insertions(+), 37 deletions(-)

diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h
index 38996adc59f..90dd4dadede 100644
--- a/include/hw/misc/aspeed_scu.h
+++ b/include/hw/misc/aspeed_scu.h
@@ -15,6 +15,8 @@
 
 #define TYPE_ASPEED_SCU "aspeed.scu"
 #define ASPEED_SCU(obj) OBJECT_CHECK(AspeedSCUState, (obj), TYPE_ASPEED_SCU)
+#define TYPE_ASPEED_2400_SCU TYPE_ASPEED_SCU "-ast2400"
+#define TYPE_ASPEED_2500_SCU TYPE_ASPEED_SCU "-ast2500"
 
 #define ASPEED_SCU_NR_REGS (0x1A8 >> 2)
 
@@ -45,6 +47,19 @@ typedef struct AspeedSCUState {
 
 extern bool is_supported_silicon_rev(uint32_t silicon_rev);
 
+#define ASPEED_SCU_CLASS(klass) \
+     OBJECT_CLASS_CHECK(AspeedSCUClass, (klass), TYPE_ASPEED_SCU)
+#define ASPEED_SCU_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(AspeedSCUClass, (obj), TYPE_ASPEED_SCU)
+
+typedef struct  AspeedSCUClass {
+    SysBusDeviceClass parent_class;
+
+    const uint32_t *resets;
+    uint32_t (*calc_hpll)(AspeedSCUState *s);
+    uint32_t apb_divider;
+}  AspeedSCUClass;
+
 #define ASPEED_SCU_PROT_KEY      0x1688A8A8
 
 /*
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index da508c99c33..cf1d0cf921b 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -161,8 +161,9 @@ static void aspeed_soc_init(Object *obj)
                                 &error_abort, NULL);
     }
 
+    snprintf(typename, sizeof(typename), "aspeed.scu-%s", socname);
     sysbus_init_child_obj(obj, "scu", OBJECT(&s->scu), sizeof(s->scu),
-                          TYPE_ASPEED_SCU);
+                          typename);
     qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev",
                          sc->info->silicon_rev);
     object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index 268cb24e565..d284458b9b3 100644
--- a/hw/misc/aspeed_scu.c
+++ b/hw/misc/aspeed_scu.c
@@ -166,23 +166,10 @@ static uint32_t aspeed_scu_get_random(void)
 
 static void aspeed_scu_set_apb_freq(AspeedSCUState *s)
 {
-    uint32_t apb_divider;
-
-    switch (s->silicon_rev) {
-    case AST2400_A0_SILICON_REV:
-    case AST2400_A1_SILICON_REV:
-        apb_divider = 2;
-        break;
-    case AST2500_A0_SILICON_REV:
-    case AST2500_A1_SILICON_REV:
-        apb_divider = 4;
-        break;
-    default:
-        g_assert_not_reached();
-    }
+    AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
 
     s->apb_freq = s->hpll / (SCU_CLK_GET_PCLK_DIV(s->regs[CLK_SEL]) + 1)
-        / apb_divider;
+        / asc->apb_divider;
 }
 
 static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
@@ -303,7 +290,7 @@ static const uint32_t hpll_ast2400_freqs[][4] = {
     { 400, 375, 350, 425 }, /* 25MHz */
 };
 
-static uint32_t aspeed_scu_calc_hpll_ast2400(AspeedSCUState *s)
+static uint32_t aspeed_2400_scu_calc_hpll(AspeedSCUState *s)
 {
     uint32_t hpll_reg = s->regs[HPLL_PARAM];
     uint8_t freq_select;
@@ -334,7 +321,7 @@ static uint32_t aspeed_scu_calc_hpll_ast2400(AspeedSCUState *s)
     return hpll_ast2400_freqs[clk_25m_in][freq_select] * 1000000;
 }
 
-static uint32_t aspeed_scu_calc_hpll_ast2500(AspeedSCUState *s)
+static uint32_t aspeed_2500_scu_calc_hpll(AspeedSCUState *s)
 {
     uint32_t hpll_reg   = s->regs[HPLL_PARAM];
     uint32_t multiplier = 1;
@@ -357,25 +344,9 @@ static uint32_t aspeed_scu_calc_hpll_ast2500(AspeedSCUState *s)
 static void aspeed_scu_reset(DeviceState *dev)
 {
     AspeedSCUState *s = ASPEED_SCU(dev);
-    const uint32_t *reset;
-    uint32_t (*calc_hpll)(AspeedSCUState *s);
+    AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(dev);
 
-    switch (s->silicon_rev) {
-    case AST2400_A0_SILICON_REV:
-    case AST2400_A1_SILICON_REV:
-        reset = ast2400_a0_resets;
-        calc_hpll = aspeed_scu_calc_hpll_ast2400;
-        break;
-    case AST2500_A0_SILICON_REV:
-    case AST2500_A1_SILICON_REV:
-        reset = ast2500_a1_resets;
-        calc_hpll = aspeed_scu_calc_hpll_ast2500;
-        break;
-    default:
-        g_assert_not_reached();
-    }
-
-    memcpy(s->regs, reset, sizeof(s->regs));
+    memcpy(s->regs, asc->resets, sizeof(s->regs));
     s->regs[SILICON_REV] = s->silicon_rev;
     s->regs[HW_STRAP1] = s->hw_strap1;
     s->regs[HW_STRAP2] = s->hw_strap2;
@@ -385,7 +356,7 @@ static void aspeed_scu_reset(DeviceState *dev)
      * All registers are set. Now compute the frequencies of the main clocks
      */
     s->clkin = aspeed_scu_get_clkin(s);
-    s->hpll = calc_hpll(s);
+    s->hpll = asc->calc_hpll(s);
     aspeed_scu_set_apb_freq(s);
 }
 
@@ -459,11 +430,51 @@ static const TypeInfo aspeed_scu_info = {
     .parent = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(AspeedSCUState),
     .class_init = aspeed_scu_class_init,
+    .class_size    = sizeof(AspeedSCUClass),
+    .abstract      = true,
+};
+
+static void aspeed_2400_scu_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    AspeedSCUClass *asc = ASPEED_SCU_CLASS(klass);
+
+    dc->desc = "ASPEED 2400 System Control Unit";
+    asc->resets = ast2400_a0_resets;
+    asc->calc_hpll = aspeed_2400_scu_calc_hpll;
+    asc->apb_divider = 2;
+}
+
+static const TypeInfo aspeed_2400_scu_info = {
+    .name = TYPE_ASPEED_2400_SCU,
+    .parent = TYPE_ASPEED_SCU,
+    .instance_size = sizeof(AspeedSCUState),
+    .class_init = aspeed_2400_scu_class_init,
+};
+
+static void aspeed_2500_scu_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    AspeedSCUClass *asc = ASPEED_SCU_CLASS(klass);
+
+    dc->desc = "ASPEED 2500 System Control Unit";
+    asc->resets = ast2500_a1_resets;
+    asc->calc_hpll = aspeed_2500_scu_calc_hpll;
+    asc->apb_divider = 4;
+}
+
+static const TypeInfo aspeed_2500_scu_info = {
+    .name = TYPE_ASPEED_2500_SCU,
+    .parent = TYPE_ASPEED_SCU,
+    .instance_size = sizeof(AspeedSCUState),
+    .class_init = aspeed_2500_scu_class_init,
 };
 
 static void aspeed_scu_register_types(void)
 {
     type_register_static(&aspeed_scu_info);
+    type_register_static(&aspeed_2400_scu_info);
+    type_register_static(&aspeed_2500_scu_info);
 }
 
 type_init(aspeed_scu_register_types);
-- 
2.20.1



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

* [Qemu-devel] [PULL 10/12] aspeed/scu: Introduce a aspeed_scu_get_apb_freq() routine
  2019-09-13 15:49 [Qemu-devel] [PULL 00/12] target-arm queue Peter Maydell
                   ` (8 preceding siblings ...)
  2019-09-13 15:49 ` [Qemu-devel] [PULL 09/12] aspeed/scu: Introduce per-SoC SCU types Peter Maydell
@ 2019-09-13 15:49 ` Peter Maydell
  2019-09-13 15:49 ` [Qemu-devel] [PULL 11/12] atomic_template: fix indentation in GEN_ATOMIC_HELPER Peter Maydell
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Peter Maydell @ 2019-09-13 15:49 UTC (permalink / raw)
  To: qemu-devel

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

The APB frequency can be calculated directly when needed from the
HPLL_PARAM and CLK_SEL register values. This removes useless state in
the model.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-id: 20190904070506.1052-11-clg@kaod.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/misc/aspeed_scu.h |  8 +++-----
 hw/misc/aspeed_scu.c         | 25 +++++++++----------------
 hw/timer/aspeed_timer.c      |  3 ++-
 3 files changed, 14 insertions(+), 22 deletions(-)

diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h
index 90dd4dadede..239e94fe2c4 100644
--- a/include/hw/misc/aspeed_scu.h
+++ b/include/hw/misc/aspeed_scu.h
@@ -32,10 +32,6 @@ typedef struct AspeedSCUState {
     uint32_t hw_strap1;
     uint32_t hw_strap2;
     uint32_t hw_prot_key;
-
-    uint32_t clkin;
-    uint32_t hpll;
-    uint32_t apb_freq;
 } AspeedSCUState;
 
 #define AST2400_A0_SILICON_REV   0x02000303U
@@ -56,12 +52,14 @@ typedef struct  AspeedSCUClass {
     SysBusDeviceClass parent_class;
 
     const uint32_t *resets;
-    uint32_t (*calc_hpll)(AspeedSCUState *s);
+    uint32_t (*calc_hpll)(AspeedSCUState *s, uint32_t hpll_reg);
     uint32_t apb_divider;
 }  AspeedSCUClass;
 
 #define ASPEED_SCU_PROT_KEY      0x1688A8A8
 
+uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s);
+
 /*
  * Extracted from Aspeed SDK v00.03.21. Fixes and extra definitions
  * were added.
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index d284458b9b3..620b25c2047 100644
--- a/hw/misc/aspeed_scu.c
+++ b/hw/misc/aspeed_scu.c
@@ -164,11 +164,12 @@ static uint32_t aspeed_scu_get_random(void)
     return num;
 }
 
-static void aspeed_scu_set_apb_freq(AspeedSCUState *s)
+uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s)
 {
     AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
+    uint32_t hpll = asc->calc_hpll(s, s->regs[HPLL_PARAM]);
 
-    s->apb_freq = s->hpll / (SCU_CLK_GET_PCLK_DIV(s->regs[CLK_SEL]) + 1)
+    return hpll / (SCU_CLK_GET_PCLK_DIV(s->regs[CLK_SEL]) + 1)
         / asc->apb_divider;
 }
 
@@ -228,7 +229,6 @@ static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
         return;
     case CLK_SEL:
         s->regs[reg] = data;
-        aspeed_scu_set_apb_freq(s);
         break;
     case HW_STRAP1:
         if (ASPEED_IS_AST2500(s->regs[SILICON_REV])) {
@@ -290,11 +290,11 @@ static const uint32_t hpll_ast2400_freqs[][4] = {
     { 400, 375, 350, 425 }, /* 25MHz */
 };
 
-static uint32_t aspeed_2400_scu_calc_hpll(AspeedSCUState *s)
+static uint32_t aspeed_2400_scu_calc_hpll(AspeedSCUState *s, uint32_t hpll_reg)
 {
-    uint32_t hpll_reg = s->regs[HPLL_PARAM];
     uint8_t freq_select;
     bool clk_25m_in;
+    uint32_t clkin = aspeed_scu_get_clkin(s);
 
     if (hpll_reg & SCU_AST2400_H_PLL_OFF) {
         return 0;
@@ -311,7 +311,7 @@ static uint32_t aspeed_2400_scu_calc_hpll(AspeedSCUState *s)
             multiplier = (2 - od) * ((n + 2) / (d + 1));
         }
 
-        return s->clkin * multiplier;
+        return clkin * multiplier;
     }
 
     /* HW strapping */
@@ -321,10 +321,10 @@ static uint32_t aspeed_2400_scu_calc_hpll(AspeedSCUState *s)
     return hpll_ast2400_freqs[clk_25m_in][freq_select] * 1000000;
 }
 
-static uint32_t aspeed_2500_scu_calc_hpll(AspeedSCUState *s)
+static uint32_t aspeed_2500_scu_calc_hpll(AspeedSCUState *s, uint32_t hpll_reg)
 {
-    uint32_t hpll_reg   = s->regs[HPLL_PARAM];
     uint32_t multiplier = 1;
+    uint32_t clkin = aspeed_scu_get_clkin(s);
 
     if (hpll_reg & SCU_H_PLL_OFF) {
         return 0;
@@ -338,7 +338,7 @@ static uint32_t aspeed_2500_scu_calc_hpll(AspeedSCUState *s)
         multiplier = ((m + 1) / (n + 1)) / (p + 1);
     }
 
-    return s->clkin * multiplier;
+    return clkin * multiplier;
 }
 
 static void aspeed_scu_reset(DeviceState *dev)
@@ -351,13 +351,6 @@ static void aspeed_scu_reset(DeviceState *dev)
     s->regs[HW_STRAP1] = s->hw_strap1;
     s->regs[HW_STRAP2] = s->hw_strap2;
     s->regs[PROT_KEY] = s->hw_prot_key;
-
-    /*
-     * All registers are set. Now compute the frequencies of the main clocks
-     */
-    s->clkin = aspeed_scu_get_clkin(s);
-    s->hpll = asc->calc_hpll(s);
-    aspeed_scu_set_apb_freq(s);
 }
 
 static uint32_t aspeed_silicon_revs[] = {
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
index 59c2bbeee60..2bda826882d 100644
--- a/hw/timer/aspeed_timer.c
+++ b/hw/timer/aspeed_timer.c
@@ -93,7 +93,8 @@ static inline uint32_t calculate_rate(struct AspeedTimer *t)
 {
     AspeedTimerCtrlState *s = timer_to_ctrl(t);
 
-    return timer_external_clock(t) ? TIMER_CLOCK_EXT_HZ : s->scu->apb_freq;
+    return timer_external_clock(t) ? TIMER_CLOCK_EXT_HZ :
+        aspeed_scu_get_apb_freq(s->scu);
 }
 
 static inline uint32_t calculate_ticks(struct AspeedTimer *t, uint64_t now_ns)
-- 
2.20.1



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

* [Qemu-devel] [PULL 11/12] atomic_template: fix indentation in GEN_ATOMIC_HELPER
  2019-09-13 15:49 [Qemu-devel] [PULL 00/12] target-arm queue Peter Maydell
                   ` (9 preceding siblings ...)
  2019-09-13 15:49 ` [Qemu-devel] [PULL 10/12] aspeed/scu: Introduce a aspeed_scu_get_apb_freq() routine Peter Maydell
@ 2019-09-13 15:49 ` Peter Maydell
  2019-09-13 15:49 ` [Qemu-devel] [PULL 12/12] qemu-ga: Convert invocation documentation to rST Peter Maydell
  2019-09-16 12:21 ` [Qemu-devel] [PULL 00/12] target-arm queue Peter Maydell
  12 siblings, 0 replies; 25+ messages in thread
From: Peter Maydell @ 2019-09-13 15:49 UTC (permalink / raw)
  To: qemu-devel

From: "Emilio G. Cota" <cota@braap.org>

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Emilio G. Cota <cota@braap.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 accel/tcg/atomic_template.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h
index df9c8388178..287433d809b 100644
--- a/accel/tcg/atomic_template.h
+++ b/accel/tcg/atomic_template.h
@@ -149,7 +149,7 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr,
 
 #define GEN_ATOMIC_HELPER(X)                                        \
 ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr,       \
-                 ABI_TYPE val EXTRA_ARGS)                           \
+                        ABI_TYPE val EXTRA_ARGS)                    \
 {                                                                   \
     ATOMIC_MMU_DECLS;                                               \
     DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;                           \
-- 
2.20.1



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

* [Qemu-devel] [PULL 12/12] qemu-ga: Convert invocation documentation to rST
  2019-09-13 15:49 [Qemu-devel] [PULL 00/12] target-arm queue Peter Maydell
                   ` (10 preceding siblings ...)
  2019-09-13 15:49 ` [Qemu-devel] [PULL 11/12] atomic_template: fix indentation in GEN_ATOMIC_HELPER Peter Maydell
@ 2019-09-13 15:49 ` Peter Maydell
  2019-09-19  1:25   ` Eric Blake
  2019-09-16 12:21 ` [Qemu-devel] [PULL 00/12] target-arm queue Peter Maydell
  12 siblings, 1 reply; 25+ messages in thread
From: Peter Maydell @ 2019-09-13 15:49 UTC (permalink / raw)
  To: qemu-devel

The qemu-ga documentation is currently in qemu-ga.texi in
Texinfo format, which we present to the user as:
 * a qemu-ga manpage
 * a section of the main qemu-doc HTML documentation

Convert the documentation to rST format, and present it to
the user as:
 * a qemu-ga manpage
 * part of the interop/ Sphinx manual

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Tested-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Message-id: 20190905131040.8350-1-peter.maydell@linaro.org
---
 Makefile                 |  24 ++++---
 MAINTAINERS              |   2 +-
 docs/conf.py             |  18 ++---
 docs/interop/conf.py     |   7 ++
 docs/interop/index.rst   |   1 +
 docs/interop/qemu-ga.rst | 133 +++++++++++++++++++++++++++++++++++++
 qemu-doc.texi            |   5 --
 qemu-ga.texi             | 137 ---------------------------------------
 8 files changed, 166 insertions(+), 161 deletions(-)
 create mode 100644 docs/interop/qemu-ga.rst
 delete mode 100644 qemu-ga.texi

diff --git a/Makefile b/Makefile
index b3528617e48..111082ce545 100644
--- a/Makefile
+++ b/Makefile
@@ -325,7 +325,7 @@ endif
 endif
 
 ifdef BUILD_DOCS
-DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1 qemu-nbd.8 qemu-ga.8
+DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1 qemu-nbd.8 docs/interop/qemu-ga.8
 DOCS+=docs/interop/qemu-qmp-ref.html docs/interop/qemu-qmp-ref.txt docs/interop/qemu-qmp-ref.7
 DOCS+=docs/interop/qemu-ga-ref.html docs/interop/qemu-ga-ref.txt docs/interop/qemu-ga-ref.7
 DOCS+=docs/qemu-block-drivers.7
@@ -783,10 +783,11 @@ DESCS=
 endif
 
 # Note that we manually filter-out the non-Sphinx documentation which
-# is currently built into the docs/interop directory in the build tree.
+# is currently built into the docs/interop directory in the build tree,
+# and also any sphinx-built manpages.
 define install-manual =
 for d in $$(cd $(MANUAL_BUILDDIR) && find $1 -type d); do $(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)/$$d"; done
-for f in $$(cd $(MANUAL_BUILDDIR) && find $1 -type f -a '!' '(' -name 'qemu-*-qapi.*' -o -name 'qemu-*-ref.*' ')' ); do $(INSTALL_DATA) "$(MANUAL_BUILDDIR)/$$f" "$(DESTDIR)$(qemu_docdir)/$$f"; done
+for f in $$(cd $(MANUAL_BUILDDIR) && find $1 -type f -a '!' '(' -name '*.[0-9]' -o -name 'qemu-*-qapi.*' -o -name 'qemu-*-ref.*' ')' ); do $(INSTALL_DATA) "$(MANUAL_BUILDDIR)/$$f" "$(DESTDIR)$(qemu_docdir)/$$f"; done
 endef
 
 # Note that we deliberately do not install the "devel" manual: it is
@@ -818,7 +819,7 @@ ifdef CONFIG_TRACE_SYSTEMTAP
 	$(INSTALL_DATA) scripts/qemu-trace-stap.1 "$(DESTDIR)$(mandir)/man1"
 endif
 ifneq (,$(findstring qemu-ga,$(TOOLS)))
-	$(INSTALL_DATA) qemu-ga.8 "$(DESTDIR)$(mandir)/man8"
+	$(INSTALL_DATA) docs/interop/qemu-ga.8 "$(DESTDIR)$(mandir)/man8"
 	$(INSTALL_DATA) docs/interop/qemu-ga-ref.html "$(DESTDIR)$(qemu_docdir)"
 	$(INSTALL_DATA) docs/interop/qemu-ga-ref.txt "$(DESTDIR)$(qemu_docdir)"
 	$(INSTALL_DATA) docs/interop/qemu-ga-ref.7 "$(DESTDIR)$(mandir)/man7"
@@ -977,18 +978,22 @@ docs/version.texi: $(SRC_PATH)/VERSION config-host.mak
 sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html $(MANUAL_BUILDDIR)/interop/index.html $(MANUAL_BUILDDIR)/specs/index.html
 
 # Canned command to build a single manual
-build-manual = $(call quiet-command,sphinx-build $(if $(V),,-q) -W -n -b html -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1 $(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1")
+# Arguments: $1 = manual name, $2 = Sphinx builder ('html' or 'man')
+build-manual = $(call quiet-command,CONFDIR="$(qemu_confdir)" sphinx-build $(if $(V),,-q) -W -n -b $2 -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1 $(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1")
 # We assume all RST files in the manual's directory are used in it
 manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst) $(SRC_PATH)/docs/$1/conf.py $(SRC_PATH)/docs/conf.py
 
 $(MANUAL_BUILDDIR)/devel/index.html: $(call manual-deps,devel)
-	$(call build-manual,devel)
+	$(call build-manual,devel,html)
 
 $(MANUAL_BUILDDIR)/interop/index.html: $(call manual-deps,interop)
-	$(call build-manual,interop)
+	$(call build-manual,interop,html)
 
 $(MANUAL_BUILDDIR)/specs/index.html: $(call manual-deps,specs)
-	$(call build-manual,specs)
+	$(call build-manual,specs,html)
+
+$(MANUAL_BUILDDIR)/interop/qemu-ga.8: $(call manual-deps,interop)
+	$(call build-manual,interop,man)
 
 qemu-options.texi: $(SRC_PATH)/qemu-options.hx $(SRC_PATH)/scripts/hxtool
 	$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@,"GEN","$@")
@@ -1013,7 +1018,6 @@ qemu.1: qemu-option-trace.texi
 qemu-img.1: qemu-img.texi qemu-option-trace.texi qemu-img-cmds.texi
 fsdev/virtfs-proxy-helper.1: fsdev/virtfs-proxy-helper.texi
 qemu-nbd.8: qemu-nbd.texi qemu-option-trace.texi
-qemu-ga.8: qemu-ga.texi
 docs/qemu-block-drivers.7: docs/qemu-block-drivers.texi
 docs/qemu-cpu-models.7: docs/qemu-cpu-models.texi
 scripts/qemu-trace-stap.1: scripts/qemu-trace-stap.texi
@@ -1026,7 +1030,7 @@ txt: qemu-doc.txt docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt
 qemu-doc.html qemu-doc.info qemu-doc.pdf qemu-doc.txt: \
 	qemu-img.texi qemu-nbd.texi qemu-options.texi \
 	qemu-tech.texi qemu-option-trace.texi \
-	qemu-deprecated.texi qemu-monitor.texi qemu-img-cmds.texi qemu-ga.texi \
+	qemu-deprecated.texi qemu-monitor.texi qemu-img-cmds.texi \
 	qemu-monitor-info.texi docs/qemu-block-drivers.texi \
 	docs/qemu-cpu-models.texi docs/security.texi
 
diff --git a/MAINTAINERS b/MAINTAINERS
index 50eaf005f40..f0e30b5248c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2040,7 +2040,7 @@ QEMU Guest Agent
 M: Michael Roth <mdroth@linux.vnet.ibm.com>
 S: Maintained
 F: qga/
-F: qemu-ga.texi
+F: docs/interop/qemu-ga.rst
 F: scripts/qemu-guest-agent/
 F: tests/test-qga.c
 F: docs/interop/qemu-ga-ref.texi
diff --git a/docs/conf.py b/docs/conf.py
index e46b299b71f..b7edb0666b5 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -115,6 +115,14 @@ todo_include_todos = False
 # with "option::" in the document being processed. Turn that off.
 suppress_warnings = ["ref.option"]
 
+# The rst_epilog fragment is effectively included in every rST file.
+# We use it to define substitutions based on build config that
+# can then be used in the documentation. The fallback if the
+# environment variable is not set is for the benefit of readthedocs
+# style document building; our Makefile always sets the variable.
+confdir = os.getenv('CONFDIR', "/etc/qemu")
+rst_epilog = ".. |CONFDIR| replace:: ``" + confdir + "``\n"
+
 # -- Options for HTML output ----------------------------------------------
 
 # The theme to use for HTML and HTML Help pages.  See the documentation for
@@ -192,14 +200,8 @@ latex_documents = [
 
 
 # -- Options for manual page output ---------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
-    (master_doc, 'qemu', u'QEMU Documentation',
-     [author], 1)
-]
-
+# Individual manual/conf.py can override this to create man pages
+man_pages = []
 
 # -- Options for Texinfo output -------------------------------------------
 
diff --git a/docs/interop/conf.py b/docs/interop/conf.py
index cf3c69d4a7e..e87b8c22bec 100644
--- a/docs/interop/conf.py
+++ b/docs/interop/conf.py
@@ -13,3 +13,10 @@ exec(compile(open(parent_config, "rb").read(), parent_config, 'exec'))
 # This slightly misuses the 'description', but is the best way to get
 # the manual title to appear in the sidebar.
 html_theme_options['description'] = u'System Emulation Management and Interoperability Guide'
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('qemu-ga', 'qemu-ga', u'QEMU Guest Agent',
+     ['Michael Roth <mdroth@linux.vnet.ibm.com>'], 8)
+]
diff --git a/docs/interop/index.rst b/docs/interop/index.rst
index b4bfcab4171..3e33fb59332 100644
--- a/docs/interop/index.rst
+++ b/docs/interop/index.rst
@@ -15,5 +15,6 @@ Contents:
    bitmaps
    live-block-operations
    pr-helper
+   qemu-ga
    vhost-user
    vhost-user-gpu
diff --git a/docs/interop/qemu-ga.rst b/docs/interop/qemu-ga.rst
new file mode 100644
index 00000000000..1313a4ae1c9
--- /dev/null
+++ b/docs/interop/qemu-ga.rst
@@ -0,0 +1,133 @@
+QEMU Guest Agent
+================
+
+Synopsis
+--------
+
+**qemu-ga** [*OPTIONS*]
+
+Description
+-----------
+
+The QEMU Guest Agent is a daemon intended to be run within virtual
+machines. It allows the hypervisor host to perform various operations
+in the guest, such as:
+
+- get information from the guest
+- set the guest's system time
+- read/write a file
+- sync and freeze the filesystems
+- suspend the guest
+- reconfigure guest local processors
+- set user's password
+- ...
+
+qemu-ga will read a system configuration file on startup (located at
+|CONFDIR|\ ``/qemu-ga.conf`` by default), then parse remaining
+configuration options on the command line. For the same key, the last
+option wins, but the lists accumulate (see below for configuration
+file format).
+
+Options
+-------
+
+.. program:: qemu-ga
+
+.. option:: -m, --method=METHOD
+
+  Transport method: one of ``unix-listen``, ``virtio-serial``, or
+  ``isa-serial`` (``virtio-serial`` is the default).
+
+.. option:: -p, --path=PATH
+
+  Device/socket path (the default for virtio-serial is
+  ``/dev/virtio-ports/org.qemu.guest_agent.0``,
+  the default for isa-serial is ``/dev/ttyS0``)
+
+.. option:: -l, --logfile=PATH
+
+  Set log file path (default is stderr).
+
+.. option:: -f, --pidfile=PATH
+
+  Specify pid file (default is ``/var/run/qemu-ga.pid``).
+
+.. option:: -F, --fsfreeze-hook=PATH
+
+  Enable fsfreeze hook. Accepts an optional argument that specifies
+  script to run on freeze/thaw. Script will be called with
+  'freeze'/'thaw' arguments accordingly (default is
+  |CONFDIR|\ ``/fsfreeze-hook``). If using -F with an argument, do
+  not follow -F with a space (for example:
+  ``-F/var/run/fsfreezehook.sh``).
+
+.. option:: -t, --statedir=PATH
+
+  Specify the directory to store state information (absolute paths only,
+  default is ``/var/run``).
+
+.. option:: -v, --verbose
+
+  Log extra debugging information.
+
+.. option:: -V, --version
+
+  Print version information and exit.
+
+.. option:: -d, --daemon
+
+  Daemonize after startup (detach from terminal).
+
+.. option:: -b, --blacklist=LIST
+
+  Comma-separated list of RPCs to disable (no spaces, ``?`` to list
+  available RPCs).
+
+.. option:: -D, --dump-conf
+
+  Dump the configuration in a format compatible with ``qemu-ga.conf``
+  and exit.
+
+.. option:: -h, --help
+
+  Display this help and exit.
+
+Files
+-----
+
+
+The syntax of the ``qemu-ga.conf`` configuration file follows the
+Desktop Entry Specification, here is a quick summary: it consists of
+groups of key-value pairs, interspersed with comments.
+
+::
+
+    # qemu-ga configuration sample
+    [general]
+    daemonize = 0
+    pidfile = /var/run/qemu-ga.pid
+    verbose = 0
+    method = virtio-serial
+    path = /dev/virtio-ports/org.qemu.guest_agent.0
+    statedir = /var/run
+
+The list of keys follows the command line options:
+
+=============  ===========
+Key             Key type
+=============  ===========
+daemon         boolean
+method         string
+path           string
+logfile        string
+pidfile        string
+fsfreeze-hook  string
+statedir       string
+verbose        boolean
+blacklist      string list
+=============  ===========
+
+See also
+--------
+
+:manpage:`qemu(1)`
diff --git a/qemu-doc.texi b/qemu-doc.texi
index b47e89cfca6..2ba6c90c083 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -2535,11 +2535,6 @@ so should only be used with trusted guest OS.
 
 @c man end
 
-@node QEMU Guest Agent
-@chapter QEMU Guest Agent invocation
-
-@include qemu-ga.texi
-
 @node QEMU User space emulator
 @chapter QEMU User space emulator
 
diff --git a/qemu-ga.texi b/qemu-ga.texi
deleted file mode 100644
index f00ad830f28..00000000000
--- a/qemu-ga.texi
+++ /dev/null
@@ -1,137 +0,0 @@
-@example
-@c man begin SYNOPSIS
-@command{qemu-ga} [@var{OPTIONS}]
-@c man end
-@end example
-
-@c man begin DESCRIPTION
-
-The QEMU Guest Agent is a daemon intended to be run within virtual
-machines. It allows the hypervisor host to perform various operations
-in the guest, such as:
-
-@itemize
-@item
-get information from the guest
-@item
-set the guest's system time
-@item
-read/write a file
-@item
-sync and freeze the filesystems
-@item
-suspend the guest
-@item
-reconfigure guest local processors
-@item
-set user's password
-@item
-...
-@end itemize
-
-qemu-ga will read a system configuration file on startup (located at
-@file{@value{CONFDIR}/qemu-ga.conf} by default), then parse remaining
-configuration options on the command line. For the same key, the last
-option wins, but the lists accumulate (see below for configuration
-file format).
-
-@c man end
-
-@c man begin OPTIONS
-@table @option
-@item -m, --method=@var{method}
-  Transport method: one of @samp{unix-listen}, @samp{virtio-serial}, or
-  @samp{isa-serial} (@samp{virtio-serial} is the default).
-
-@item -p, --path=@var{path}
-  Device/socket path (the default for virtio-serial is
-  @samp{/dev/virtio-ports/org.qemu.guest_agent.0},
-  the default for isa-serial is @samp{/dev/ttyS0})
-
-@item -l, --logfile=@var{path}
-  Set log file path (default is stderr).
-
-@item -f, --pidfile=@var{path}
-  Specify pid file (default is @samp{/var/run/qemu-ga.pid}).
-
-@item -F, --fsfreeze-hook=@var{path}
-  Enable fsfreeze hook. Accepts an optional argument that specifies
-  script to run on freeze/thaw. Script will be called with
-  'freeze'/'thaw' arguments accordingly (default is
-  @samp{@value{CONFDIR}/fsfreeze-hook}). If using -F with an argument, do
-  not follow -F with a space (for example:
-  @samp{-F/var/run/fsfreezehook.sh}).
-
-@item -t, --statedir=@var{path}
-  Specify the directory to store state information (absolute paths only,
-  default is @samp{/var/run}).
-
-@item -v, --verbose
-  Log extra debugging information.
-
-@item -V, --version
-  Print version information and exit.
-
-@item -d, --daemon
-  Daemonize after startup (detach from terminal).
-
-@item -b, --blacklist=@var{list}
-  Comma-separated list of RPCs to disable (no spaces, @samp{?} to list
-  available RPCs).
-
-@item -D, --dump-conf
-  Dump the configuration in a format compatible with @file{qemu-ga.conf}
-  and exit.
-
-@item -h, --help
-  Display this help and exit.
-@end table
-
-@c man end
-
-@c man begin FILES
-
-The syntax of the @file{qemu-ga.conf} configuration file follows the
-Desktop Entry Specification, here is a quick summary: it consists of
-groups of key-value pairs, interspersed with comments.
-
-@example
-# qemu-ga configuration sample
-[general]
-daemonize = 0
-pidfile = /var/run/qemu-ga.pid
-verbose = 0
-method = virtio-serial
-path = /dev/virtio-ports/org.qemu.guest_agent.0
-statedir = /var/run
-@end example
-
-The list of keys follows the command line options:
-@table @option
-@item daemon= boolean
-@item method= string
-@item path= string
-@item logfile= string
-@item pidfile= string
-@item fsfreeze-hook= string
-@item statedir= string
-@item verbose= boolean
-@item blacklist= string list
-@end table
-
-@c man end
-
-@ignore
-
-@setfilename qemu-ga
-@settitle QEMU Guest Agent
-
-@c man begin AUTHOR
-Michael Roth <mdroth@linux.vnet.ibm.com>
-@c man end
-
-@c man begin SEEALSO
-qemu(1)
-@c man end
-
-@end ignore
-- 
2.20.1



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

* Re: [Qemu-devel] [PULL 00/12] target-arm queue
  2019-09-13 15:49 [Qemu-devel] [PULL 00/12] target-arm queue Peter Maydell
                   ` (11 preceding siblings ...)
  2019-09-13 15:49 ` [Qemu-devel] [PULL 12/12] qemu-ga: Convert invocation documentation to rST Peter Maydell
@ 2019-09-16 12:21 ` Peter Maydell
  12 siblings, 0 replies; 25+ messages in thread
From: Peter Maydell @ 2019-09-16 12:21 UTC (permalink / raw)
  To: QEMU Developers

On Fri, 13 Sep 2019 at 16:49, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> target-arm queue: mostly aspeed changes from Cédric.
>
> thanks
> -- PMM
>
> The following changes since commit 85182c96de61f0b600bbe834d5a23e713162e892:
>
>   Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20190912a' into staging (2019-09-13 14:37:48 +0100)
>
> are available in the Git repository at:
>
>   https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190913
>
> for you to fetch changes up to 27a296fce9821e3608d537756cffa6e43a46df3b:
>
>   qemu-ga: Convert invocation documentation to rST (2019-09-13 16:05:01 +0100)
>
> ----------------------------------------------------------------
> target-arm queue:
>  * aspeed: add a GPIO controller to the SoC
>  * aspeed: Various refactorings
>  * aspeed: Improve DMA controller modelling
>  * atomic_template: fix indentation in GEN_ATOMIC_HELPER
>  * qemu-ga: Convert invocation documentation to rST
>
> ----------------------------------------------------------------


Applied, thanks.

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

-- PMM


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

* Re: [Qemu-devel] [PULL 12/12] qemu-ga: Convert invocation documentation to rST
  2019-09-13 15:49 ` [Qemu-devel] [PULL 12/12] qemu-ga: Convert invocation documentation to rST Peter Maydell
@ 2019-09-19  1:25   ` Eric Blake
  2019-09-19 10:25     ` Alex Bennée
  2019-09-19 12:00     ` Peter Maydell
  0 siblings, 2 replies; 25+ messages in thread
From: Eric Blake @ 2019-09-19  1:25 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel


[-- Attachment #1.1: Type: text/plain, Size: 1173 bytes --]

On 9/13/19 10:49 AM, Peter Maydell wrote:
> The qemu-ga documentation is currently in qemu-ga.texi in
> Texinfo format, which we present to the user as:
>  * a qemu-ga manpage
>  * a section of the main qemu-doc HTML documentation
> 
> Convert the documentation to rST format, and present it to
> the user as:
>  * a qemu-ga manpage
>  * part of the interop/ Sphinx manual
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
> Tested-by: Michael Roth <mdroth@linux.vnet.ibm.com>
> Message-id: 20190905131040.8350-1-peter.maydell@linaro.org
> ---

In an incremental build on Fedora 30, I'm now seeing:

	CHK version_gen.h
  GEN     docs/interop/qemu-ga.8
No filename or title
make: *** [/home/eblake/qemu/rules.mak:394: docs/interop/qemu-ga.8]
Error 255

and suspect this patch introduced it.  It may be that I just need to
nuke intermediate artifacts rather than an actual problem with the
patch, but I'd welcome help in identifying the problem.


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


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

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

* Re: [Qemu-devel] [PULL 12/12] qemu-ga: Convert invocation documentation to rST
  2019-09-19  1:25   ` Eric Blake
@ 2019-09-19 10:25     ` Alex Bennée
  2019-09-19 12:00     ` Peter Maydell
  1 sibling, 0 replies; 25+ messages in thread
From: Alex Bennée @ 2019-09-19 10:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell


Eric Blake <eblake@redhat.com> writes:

> On 9/13/19 10:49 AM, Peter Maydell wrote:
>> The qemu-ga documentation is currently in qemu-ga.texi in
>> Texinfo format, which we present to the user as:
>>  * a qemu-ga manpage
>>  * a section of the main qemu-doc HTML documentation
>>
>> Convert the documentation to rST format, and present it to
>> the user as:
>>  * a qemu-ga manpage
>>  * part of the interop/ Sphinx manual
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
>> Tested-by: Michael Roth <mdroth@linux.vnet.ibm.com>
>> Message-id: 20190905131040.8350-1-peter.maydell@linaro.org
>> ---
>
> In an incremental build on Fedora 30, I'm now seeing:
>
> 	CHK version_gen.h
>   GEN     docs/interop/qemu-ga.8
> No filename or title
> make: *** [/home/eblake/qemu/rules.mak:394: docs/interop/qemu-ga.8]
> Error 255
>
> and suspect this patch introduced it.  It may be that I just need to
> nuke intermediate artifacts rather than an actual problem with the
> patch, but I'd welcome help in identifying the problem.

It did - it's also the commit that has broken shippable builds. Once I
reverted they started working again. However I'm finding it hard to
trigger in the same containers on my setup so I'm confused as to how it
breaks.

--
Alex Bennée


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

* Re: [Qemu-devel] [PULL 12/12] qemu-ga: Convert invocation documentation to rST
  2019-09-19  1:25   ` Eric Blake
  2019-09-19 10:25     ` Alex Bennée
@ 2019-09-19 12:00     ` Peter Maydell
  2019-09-19 13:27       ` Eric Blake
  2019-09-19 14:00       ` Alex Bennée
  1 sibling, 2 replies; 25+ messages in thread
From: Peter Maydell @ 2019-09-19 12:00 UTC (permalink / raw)
  To: Eric Blake; +Cc: QEMU Developers

On Thu, 19 Sep 2019 at 02:25, Eric Blake <eblake@redhat.com> wrote:
>
> On 9/13/19 10:49 AM, Peter Maydell wrote:
> > The qemu-ga documentation is currently in qemu-ga.texi in
> > Texinfo format, which we present to the user as:
> >  * a qemu-ga manpage
> >  * a section of the main qemu-doc HTML documentation
> >
> > Convert the documentation to rST format, and present it to
> > the user as:
> >  * a qemu-ga manpage
> >  * part of the interop/ Sphinx manual
> >
> > Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> > Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
> > Tested-by: Michael Roth <mdroth@linux.vnet.ibm.com>
> > Message-id: 20190905131040.8350-1-peter.maydell@linaro.org
> > ---
>
> In an incremental build on Fedora 30, I'm now seeing:
>
>         CHK version_gen.h
>   GEN     docs/interop/qemu-ga.8
> No filename or title
> make: *** [/home/eblake/qemu/rules.mak:394: docs/interop/qemu-ga.8]
> Error 255
>
> and suspect this patch introduced it.  It may be that I just need to
> nuke intermediate artifacts rather than an actual problem with the
> patch, but I'd welcome help in identifying the problem.

If you build with V=1 what does it say it's doing?

thanks
-- PMM


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

* Re: [Qemu-devel] [PULL 12/12] qemu-ga: Convert invocation documentation to rST
  2019-09-19 12:00     ` Peter Maydell
@ 2019-09-19 13:27       ` Eric Blake
  2019-09-19 13:35         ` Peter Maydell
  2019-09-19 14:00       ` Alex Bennée
  1 sibling, 1 reply; 25+ messages in thread
From: Eric Blake @ 2019-09-19 13:27 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers


[-- Attachment #1.1: Type: text/plain, Size: 1135 bytes --]

On 9/19/19 7:00 AM, Peter Maydell wrote:

>> In an incremental build on Fedora 30, I'm now seeing:
>>
>>         CHK version_gen.h
>>   GEN     docs/interop/qemu-ga.8
>> No filename or title
>> make: *** [/home/eblake/qemu/rules.mak:394: docs/interop/qemu-ga.8]
>> Error 255
>>
>> and suspect this patch introduced it.  It may be that I just need to
>> nuke intermediate artifacts rather than an actual problem with the
>> patch, but I'd welcome help in identifying the problem.
> 
> If you build with V=1 what does it say it's doing?

make[1]: Leaving directory '/home/eblake/qemu/dtc'
perl -Ww -- /home/eblake/qemu/scripts/texi2pod.pl -I docs -I scripts -I
docs/interop -DVERSION="4.1.50" -DCONFDIR="/usr/local/etc/qemu"
scripts/texi2pod.pl docs/interop/qemu-ga.8.pod && pod2man --utf8
--section=8 --center=" " --release=" " docs/interop/qemu-ga.8.pod >
docs/interop/qemu-ga.8
No filename or title
make: *** [/home/eblake/qemu/rules.mak:394: docs/interop/qemu-ga.8]
Error 255

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


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

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

* Re: [Qemu-devel] [PULL 12/12] qemu-ga: Convert invocation documentation to rST
  2019-09-19 13:27       ` Eric Blake
@ 2019-09-19 13:35         ` Peter Maydell
  2019-09-19 13:54           ` Eric Blake
  0 siblings, 1 reply; 25+ messages in thread
From: Peter Maydell @ 2019-09-19 13:35 UTC (permalink / raw)
  To: Eric Blake; +Cc: QEMU Developers

On Thu, 19 Sep 2019 at 14:27, Eric Blake <eblake@redhat.com> wrote:
>
> On 9/19/19 7:00 AM, Peter Maydell wrote:
>
> >> In an incremental build on Fedora 30, I'm now seeing:
> >>
> >>         CHK version_gen.h
> >>   GEN     docs/interop/qemu-ga.8
> >> No filename or title
> >> make: *** [/home/eblake/qemu/rules.mak:394: docs/interop/qemu-ga.8]
> >> Error 255
> >>
> >> and suspect this patch introduced it.  It may be that I just need to
> >> nuke intermediate artifacts rather than an actual problem with the
> >> patch, but I'd welcome help in identifying the problem.
> >
> > If you build with V=1 what does it say it's doing?
>
> make[1]: Leaving directory '/home/eblake/qemu/dtc'
> perl -Ww -- /home/eblake/qemu/scripts/texi2pod.pl -I docs -I scripts -I
> docs/interop -DVERSION="4.1.50" -DCONFDIR="/usr/local/etc/qemu"
> scripts/texi2pod.pl docs/interop/qemu-ga.8.pod && pod2man --utf8
> --section=8 --center=" " --release=" " docs/interop/qemu-ga.8.pod >
> docs/interop/qemu-ga.8
> No filename or title
> make: *** [/home/eblake/qemu/rules.mak:394: docs/interop/qemu-ga.8]
> Error 255

Do you have sphinx installed on this machine? I'm wondering
if the problem here is that we have disabled the sphinx build
runes but are then falling back to the "try to make any %.8
via the TEXI2MAN rule in rules.mak" [*]. On the other hand
docs/interop/qemu-ga.8 is only put into DOCS if BUILD_DOCS is
set, which should only happen if sphinx is available.

[*] these rules are a bit bogus, because I think they will apply even
if there's no other rule saying 'foo.8 depends on something.texi',
and then as you can see in your command line we end up running
texi2pod with an empty "$<" rather than passing it a texi file.

thanks
-- PMM


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

* Re: [Qemu-devel] [PULL 12/12] qemu-ga: Convert invocation documentation to rST
  2019-09-19 13:35         ` Peter Maydell
@ 2019-09-19 13:54           ` Eric Blake
  2019-09-19 15:22             ` Peter Maydell
  0 siblings, 1 reply; 25+ messages in thread
From: Eric Blake @ 2019-09-19 13:54 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers


[-- Attachment #1.1: Type: text/plain, Size: 2154 bytes --]

On 9/19/19 8:35 AM, Peter Maydell wrote:
> On Thu, 19 Sep 2019 at 14:27, Eric Blake <eblake@redhat.com> wrote:
>>
>> On 9/19/19 7:00 AM, Peter Maydell wrote:
>>
>>>> In an incremental build on Fedora 30, I'm now seeing:
>>>>
>>>>         CHK version_gen.h
>>>>   GEN     docs/interop/qemu-ga.8
>>>> No filename or title
>>>> make: *** [/home/eblake/qemu/rules.mak:394: docs/interop/qemu-ga.8]
>>>> Error 255
>>>>
>>>> and suspect this patch introduced it.  It may be that I just need to
>>>> nuke intermediate artifacts rather than an actual problem with the
>>>> patch, but I'd welcome help in identifying the problem.
>>>
>>> If you build with V=1 what does it say it's doing?
>>
>> make[1]: Leaving directory '/home/eblake/qemu/dtc'
>> perl -Ww -- /home/eblake/qemu/scripts/texi2pod.pl -I docs -I scripts -I
>> docs/interop -DVERSION="4.1.50" -DCONFDIR="/usr/local/etc/qemu"
>> scripts/texi2pod.pl docs/interop/qemu-ga.8.pod && pod2man --utf8
>> --section=8 --center=" " --release=" " docs/interop/qemu-ga.8.pod >
>> docs/interop/qemu-ga.8
>> No filename or title
>> make: *** [/home/eblake/qemu/rules.mak:394: docs/interop/qemu-ga.8]
>> Error 255
> 
> Do you have sphinx installed on this machine?

Not yet.

/me goes and installs sphinx-2.2.11-12.fc30.x86_64

Nope, problem is still happening even after rerunning ./configure


> I'm wondering
> if the problem here is that we have disabled the sphinx build
> runes but are then falling back to the "try to make any %.8
> via the TEXI2MAN rule in rules.mak" [*]. On the other hand
> docs/interop/qemu-ga.8 is only put into DOCS if BUILD_DOCS is
> set, which should only happen if sphinx is available.
> 
> [*] these rules are a bit bogus, because I think they will apply even
> if there's no other rule saying 'foo.8 depends on something.texi',
> and then as you can see in your command line we end up running
> texi2pod with an empty "$<" rather than passing it a texi file.

Okay, that's something to play with.


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


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

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

* Re: [Qemu-devel] [PULL 12/12] qemu-ga: Convert invocation documentation to rST
  2019-09-19 12:00     ` Peter Maydell
  2019-09-19 13:27       ` Eric Blake
@ 2019-09-19 14:00       ` Alex Bennée
  1 sibling, 0 replies; 25+ messages in thread
From: Alex Bennée @ 2019-09-19 14:00 UTC (permalink / raw)
  To: qemu-devel


Peter Maydell <peter.maydell@linaro.org> writes:

> On Thu, 19 Sep 2019 at 02:25, Eric Blake <eblake@redhat.com> wrote:
>>
>> On 9/13/19 10:49 AM, Peter Maydell wrote:
>> > The qemu-ga documentation is currently in qemu-ga.texi in
>> > Texinfo format, which we present to the user as:
>> >  * a qemu-ga manpage
>> >  * a section of the main qemu-doc HTML documentation
>> >
>> > Convert the documentation to rST format, and present it to
>> > the user as:
>> >  * a qemu-ga manpage
>> >  * part of the interop/ Sphinx manual
>> >
>> > Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> > Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
>> > Tested-by: Michael Roth <mdroth@linux.vnet.ibm.com>
>> > Message-id: 20190905131040.8350-1-peter.maydell@linaro.org
>> > ---
>>
>> In an incremental build on Fedora 30, I'm now seeing:
>>
>>         CHK version_gen.h
>>   GEN     docs/interop/qemu-ga.8
>> No filename or title
>> make: *** [/home/eblake/qemu/rules.mak:394: docs/interop/qemu-ga.8]
>> Error 255
>>
>> and suspect this patch introduced it.  It may be that I just need to
>> nuke intermediate artifacts rather than an actual problem with the
>> patch, but I'd welcome help in identifying the problem.
>
> If you build with V=1 what does it say it's doing?

This is what shippable shows:

make -I/root/src/github.com/stsquad/qemu/dtc VPATH=/root/src/github.com/stsquad/qemu/dtc -C dtc V="1" LIBFDT_srcdir=/root/src/github.com/stsquad/qemu/dtc/libfdt CPPFLAGS="-I/root/src/github.com/stsquad/qemu/dtc -I/root/src/github.com/stsquad/qemu/dtc -I/root/src/github.com/stsquad/qemu/dtc/libfdt" CFLAGS="-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g  -I/usr/include/pixman-1 -I/root/src/github.com/stsquad/qemu/dtc/libfdt -Werror  -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -fPIE -DPIE -m64 -mcx16 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv -std=gnu99  -Wendif-labels -Wno-shift-negative-value -Wno-missing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-strong -I/usr/include/p11-kit-1    -I/usr/include/libpng16  -I/usr/include/spice-server -I/usr/include/spice-1 -I/root/src/github.com/stsquad/qemu/capstone/include -I/root/src/github.com/stsquad/qemu/tests" LDFLAGS="-Wl,--warn-common -Wl,-z,relro -Wl,-z,now -pie -m64 -g " ARFLAGS="rv" CC="cc" AR="ar" LD="ld"  BUILD_DIR=/root/src/github.com/stsquad/qemu libfdt/libfdt.a
if ! cmp -s qemu-version.h qemu-version.h.tmp; then mv qemu-version.h.tmp qemu-version.h; else rm qemu-version.h.tmp; fi
make[1]: Entering directory '/root/src/github.com/stsquad/qemu/dtc'
make[1]: Entering directory '/root/src/github.com/stsquad/qemu/slirp'
make -C /root/src/github.com/stsquad/qemu/capstone CAPSTONE_SHARED=no BUILDDIR="/root/src/github.com/stsquad/qemu/capstone" CC="cc" AR="ar" LD="ld" RANLIB="ranlib" CFLAGS="-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g -I/usr/include/pixman-1 -I/root/src/github.com/stsquad/qemu/dtc/libfdt -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -fPIE -DPIE -m64 -mcx16 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -fno-strict-aliasing -fno-common -fwrapv -std=gnu99 -fstack-protector-strong -I/usr/include/p11-kit-1 -I/usr/include/libpng16 -I/usr/include/spice-server -I/usr/include/spice-1 -I/root/src/github.com/stsquad/qemu/capstone/include -I/root/src/github.com/stsquad/qemu/tests -DCAPSTONE_USE_SYS_DYN_MEM -DCAPSTONE_HAS_ARM -DCAPSTONE_HAS_ARM64 -DCAPSTONE_HAS_POWERPC -DCAPSTONE_HAS_X86"  BUILD_DIR=/root/src/github.com/stsquad/qemu /root/src/github.com/stsquad/qemu/capstone/libcapstone.a
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/root/src/github.com/stsquad/qemu/slirp'
make[1]: Entering directory '/root/src/github.com/stsquad/qemu/capstone'
set -e; echo '	CHK version_gen.h'; mkdir -p ./; 	(echo "#define DTC_VERSION \"DTC 1.4.7\""; ) < Makefile > version_gen.h.tmp; if [ -r version_gen.h ] && cmp -s version_gen.h version_gen.h.tmp; then rm -f version_gen.h.tmp; else echo '	UPD version_gen.h'; mv -f version_gen.h.tmp version_gen.h; fi;
	CHK version_gen.h
make[1]: '/root/src/github.com/stsquad/qemu/capstone/libcapstone.a' is up to date.
make[1]: Leaving directory '/root/src/github.com/stsquad/qemu/capstone'
make[1]: 'libfdt/libfdt.a' is up to date.
make[1]: Leaving directory '/root/src/github.com/stsquad/qemu/dtc'
cc -iquote /root/src/github.com/stsquad/qemu/tests/qemu-iotests -iquote tests/qemu-iotests -iquote /root/src/github.com/stsquad/qemu/tcg -iquote /root/src/github.com/stsquad/qemu/tcg/i386 -I/root/src/github.com/stsquad/qemu/linux-headers -I/root/src/github.com/stsquad/qemu/linux-headers -iquote . -iquote /root/src/github.com/stsquad/qemu -iquote /root/src/github.com/stsquad/qemu/accel/tcg -iquote /root/src/github.com/stsquad/qemu/include -I/usr/include/pixman-1 -I/root/src/github.com/stsquad/qemu/dtc/libfdt -Werror  -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -fPIE -DPIE -m64 -mcx16 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv -std=gnu99  -Wendif-labels -Wno-shift-negative-value -Wno-missing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-strong -I/usr/include/p11-kit-1    -I/usr/include/libpng16  -I/usr/include/spice-server -I/usr/include/spice-1 -I/root/src/github.com/stsquad/qemu/capstone/include -I/root/src/github.com/stsquad/qemu/tests -MMD -MP -MT tests/qemu-iotests/socket_scm_helper.o -MF tests/qemu-iotests/socket_scm_helper.d -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g   -c -o tests/qemu-iotests/socket_scm_helper.o tests/qemu-iotests/socket_scm_helper.c
( echo "@set VERSION 4.1.50" && echo "@set CONFDIR /usr/local/etc/qemu" )> docs/version.texi
sh /root/src/github.com/stsquad/qemu/scripts/hxtool -t < /root/src/github.com/stsquad/qemu/qemu-options.hx > qemu-options.texi
sh /root/src/github.com/stsquad/qemu/scripts/hxtool -t < /root/src/github.com/stsquad/qemu/hmp-commands.hx > qemu-monitor.texi
sh /root/src/github.com/stsquad/qemu/scripts/hxtool -t < /root/src/github.com/stsquad/qemu/qemu-img-cmds.hx > qemu-img-cmds.texi
sh /root/src/github.com/stsquad/qemu/scripts/hxtool -t < /root/src/github.com/stsquad/qemu/hmp-commands-info.hx > qemu-monitor-info.texi
perl -Ww -- /root/src/github.com/stsquad/qemu/scripts/texi2pod.pl -I docs -I . -I . -DVERSION="4.1.50" -DCONFDIR="/usr/local/etc/qemu" qemu-img.texi qemu-img.1.pod && pod2man --utf8 --section=1 --center=" " --release=" " qemu-img.1.pod > qemu-img.1
perl -Ww -- /root/src/github.com/stsquad/qemu/scripts/texi2pod.pl -I docs -I . -I . -DVERSION="4.1.50" -DCONFDIR="/usr/local/etc/qemu" qemu-nbd.texi qemu-nbd.8.pod && pod2man --utf8 --section=8 --center=" " --release=" " qemu-nbd.8.pod > qemu-nbd.8
perl -Ww -- /root/src/github.com/stsquad/qemu/scripts/texi2pod.pl -I docs -I scripts -I docs/interop -DVERSION="4.1.50" -DCONFDIR="/usr/local/etc/qemu" scripts/texi2pod.pl docs/interop/qemu-ga.8.pod && pod2man --utf8 --section=8 --center=" " --release=" " docs/interop/qemu-ga.8.pod > docs/interop/qemu-ga.8
python3 -B /root/src/github.com/stsquad/qemu/scripts/qapi-gen.py -o qga/qapi-generated -p "qga-" /root/src/github.com/stsquad/qemu/qga/qapi-schema.json
No filename or title
/root/src/github.com/stsquad/qemu/rules.mak:394: recipe for target 'docs/interop/qemu-ga.8' failed
make: *** [docs/interop/qemu-ga.8] Error 255
make: *** Waiting for unfinished jobs....

--
Alex Bennée


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

* Re: [Qemu-devel] [PULL 12/12] qemu-ga: Convert invocation documentation to rST
  2019-09-19 13:54           ` Eric Blake
@ 2019-09-19 15:22             ` Peter Maydell
  2019-09-19 15:37               ` Eric Blake
  0 siblings, 1 reply; 25+ messages in thread
From: Peter Maydell @ 2019-09-19 15:22 UTC (permalink / raw)
  To: Eric Blake; +Cc: Alex Bennée, QEMU Developers

On Thu, 19 Sep 2019 at 14:54, Eric Blake <eblake@redhat.com> wrote:
>
> On 9/19/19 8:35 AM, Peter Maydell wrote:
> > On Thu, 19 Sep 2019 at 14:27, Eric Blake <eblake@redhat.com> wrote:
> >>
> >> On 9/19/19 7:00 AM, Peter Maydell wrote:
> >>
> >>>> In an incremental build on Fedora 30, I'm now seeing:
> >>>>
> >>>>         CHK version_gen.h
> >>>>   GEN     docs/interop/qemu-ga.8
> >>>> No filename or title
> >>>> make: *** [/home/eblake/qemu/rules.mak:394: docs/interop/qemu-ga.8]
> >>>> Error 255
> >>>>
> >>>> and suspect this patch introduced it.  It may be that I just need to
> >>>> nuke intermediate artifacts rather than an actual problem with the
> >>>> patch, but I'd welcome help in identifying the problem.
> >>>
> >>> If you build with V=1 what does it say it's doing?
> >>
> >> make[1]: Leaving directory '/home/eblake/qemu/dtc'
> >> perl -Ww -- /home/eblake/qemu/scripts/texi2pod.pl -I docs -I scripts -I
> >> docs/interop -DVERSION="4.1.50" -DCONFDIR="/usr/local/etc/qemu"
> >> scripts/texi2pod.pl docs/interop/qemu-ga.8.pod && pod2man --utf8
> >> --section=8 --center=" " --release=" " docs/interop/qemu-ga.8.pod >
> >> docs/interop/qemu-ga.8
> >> No filename or title
> >> make: *** [/home/eblake/qemu/rules.mak:394: docs/interop/qemu-ga.8]
> >> Error 255
> >
> > Do you have sphinx installed on this machine?
>
> Not yet.
>
> /me goes and installs sphinx-2.2.11-12.fc30.x86_64
>
> Nope, problem is still happening even after rerunning ./configure

Alex looked at this and suggests the problem is probably because
you're doing an in-tree build. Sphinx insists that it can't build
output files into the source tree, so we have a thing where we
set MANUAL_BUILDDIR to docs/built if we're doing an in-tree build.
But the filename we add to DOCS is just "docs/interop/qemu-ga.8"
so for an in-tree build the sphinx rule won't match it, and
the install rune won't find it either.

If that's the cause I think this untested fix should help:

diff --git a/Makefile b/Makefile
index 111082ce545..8d9dcb3aa4a 100644
--- a/Makefile
+++ b/Makefile
@@ -325,7 +325,7 @@ endif
 endif

 ifdef BUILD_DOCS
-DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1 qemu-nbd.8
docs/interop/qemu-ga.8
+DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1 qemu-nbd.8
$(MANUAL_BUILDDIR)/interop/qemu-ga.8
 DOCS+=docs/interop/qemu-qmp-ref.html docs/interop/qemu-qmp-ref.txt
docs/interop/qemu-qmp-ref.7
 DOCS+=docs/interop/qemu-ga-ref.html docs/interop/qemu-ga-ref.txt
docs/interop/qemu-ga-ref.7
 DOCS+=docs/qemu-block-drivers.7
@@ -819,7 +819,7 @@ ifdef CONFIG_TRACE_SYSTEMTAP
        $(INSTALL_DATA) scripts/qemu-trace-stap.1 "$(DESTDIR)$(mandir)/man1"
 endif
 ifneq (,$(findstring qemu-ga,$(TOOLS)))
-       $(INSTALL_DATA) docs/interop/qemu-ga.8 "$(DESTDIR)$(mandir)/man8"
+       $(INSTALL_DATA) $(MANUAL_BUILDDIR)/interop/qemu-ga.8
"$(DESTDIR)$(mandir)/man8"
        $(INSTALL_DATA) docs/interop/qemu-ga-ref.html "$(DESTDIR)$(qemu_docdir)"
        $(INSTALL_DATA) docs/interop/qemu-ga-ref.txt "$(DESTDIR)$(qemu_docdir)"
        $(INSTALL_DATA) docs/interop/qemu-ga-ref.7 "$(DESTDIR)$(mandir)/man7"


thanks
-- PMM


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

* Re: [Qemu-devel] [PULL 12/12] qemu-ga: Convert invocation documentation to rST
  2019-09-19 15:22             ` Peter Maydell
@ 2019-09-19 15:37               ` Eric Blake
  2019-09-19 15:39                 ` Peter Maydell
  0 siblings, 1 reply; 25+ messages in thread
From: Eric Blake @ 2019-09-19 15:37 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Alex Bennée, QEMU Developers


[-- Attachment #1.1: Type: text/plain, Size: 1996 bytes --]

On 9/19/19 10:22 AM, Peter Maydell wrote:

> Alex looked at this and suggests the problem is probably because
> you're doing an in-tree build.

Bingo.  I thought we wanted to get rid of that, though.  What's the
status on forcing out-of-tree builds?  (I'll adapt, but only once
patches are in that force me to).

> Sphinx insists that it can't build
> output files into the source tree, so we have a thing where we
> set MANUAL_BUILDDIR to docs/built if we're doing an in-tree build.
> But the filename we add to DOCS is just "docs/interop/qemu-ga.8"
> so for an in-tree build the sphinx rule won't match it, and
> the install rune won't find it either.
> 
> If that's the cause I think this untested fix should help:
> 
> diff --git a/Makefile b/Makefile
> index 111082ce545..8d9dcb3aa4a 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -325,7 +325,7 @@ endif
>  endif
> 

[1]

>  ifdef BUILD_DOCS
> -DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1 qemu-nbd.8
> docs/interop/qemu-ga.8
> +DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1 qemu-nbd.8
> $(MANUAL_BUILDDIR)/interop/qemu-ga.8

Not quite. This occurs prior to the line defining MANUAL_BUILDDIR,
resulting in:

  GEN     /interop/qemu-ga.8
opening "/interop": No such file or directory

But hoisting the following text up to point [1] makes the build complete
with sphinx installed.  Progress!

> # Sphinx does not allow building manuals into the same directory as
> # the source files, so if we're doing an in-tree QEMU build we must
> # build the manuals into a subdirectory (and then install them from
> # there for 'make install'). For an out-of-tree build we can just
> # use the docs/ subdirectory in the build tree as normal.
> ifeq ($(realpath $(SRC_PATH)),$(realpath .))
> MANUAL_BUILDDIR := docs/built
> else
> MANUAL_BUILDDIR := docs
> endif
-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org


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

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

* Re: [Qemu-devel] [PULL 12/12] qemu-ga: Convert invocation documentation to rST
  2019-09-19 15:37               ` Eric Blake
@ 2019-09-19 15:39                 ` Peter Maydell
  2019-10-12 13:59                   ` Eduardo Habkost
  0 siblings, 1 reply; 25+ messages in thread
From: Peter Maydell @ 2019-09-19 15:39 UTC (permalink / raw)
  To: Eric Blake; +Cc: Alex Bennée, QEMU Developers

On Thu, 19 Sep 2019 at 16:37, Eric Blake <eblake@redhat.com> wrote:
>
> On 9/19/19 10:22 AM, Peter Maydell wrote:
>
> > Alex looked at this and suggests the problem is probably because
> > you're doing an in-tree build.
>
> Bingo.  I thought we wanted to get rid of that, though.  What's the
> status on forcing out-of-tree builds?  (I'll adapt, but only once
> patches are in that force me to).

I think the general consensus was that it would probably
be a good idea, but nobody's actually written any code :-)
(Among other things, various bits of CI infra, probably
the tests/vm code, etc, need updating to not try to do
an in-tree build.)

thanks
-- PMM


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

* Re: [Qemu-devel] [PULL 12/12] qemu-ga: Convert invocation documentation to rST
  2019-09-19 15:39                 ` Peter Maydell
@ 2019-10-12 13:59                   ` Eduardo Habkost
  0 siblings, 0 replies; 25+ messages in thread
From: Eduardo Habkost @ 2019-10-12 13:59 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Alex Bennée, QEMU Developers

On Thu, Sep 19, 2019 at 04:39:00PM +0100, Peter Maydell wrote:
> On Thu, 19 Sep 2019 at 16:37, Eric Blake <eblake@redhat.com> wrote:
> >
> > On 9/19/19 10:22 AM, Peter Maydell wrote:
> >
> > > Alex looked at this and suggests the problem is probably because
> > > you're doing an in-tree build.
> >
> > Bingo.  I thought we wanted to get rid of that, though.  What's the
> > status on forcing out-of-tree builds?  (I'll adapt, but only once
> > patches are in that force me to).
> 
> I think the general consensus was that it would probably
> be a good idea, but nobody's actually written any code :-)
> (Among other things, various bits of CI infra, probably
> the tests/vm code, etc, need updating to not try to do
> an in-tree build.)

We have another issue introduced by this patch and not fixed yet,
caused by this sphinx-build bug:
https://github.com/sphinx-doc/sphinx/issues/2946

We're triggering that bug because the interop/index.html and
interop/qemu-ga.8 rules are using the same doctree cache
directory.

-- 
Eduardo


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

end of thread, other threads:[~2019-10-12 13:59 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-13 15:49 [Qemu-devel] [PULL 00/12] target-arm queue Peter Maydell
2019-09-13 15:49 ` [Qemu-devel] [PULL 01/12] hw/gpio: Add basic Aspeed GPIO model for AST2400 and AST2500 Peter Maydell
2019-09-13 15:49 ` [Qemu-devel] [PULL 02/12] aspeed: add a GPIO controller to the SoC Peter Maydell
2019-09-13 15:49 ` [Qemu-devel] [PULL 03/12] aspeed: Remove unused SoC definitions Peter Maydell
2019-09-13 15:49 ` [Qemu-devel] [PULL 04/12] aspeed: Use consistent typenames Peter Maydell
2019-09-13 15:49 ` [Qemu-devel] [PULL 05/12] aspeed/smc: Add support for DMAs Peter Maydell
2019-09-13 15:49 ` [Qemu-devel] [PULL 06/12] aspeed/smc: Add DMA calibration settings Peter Maydell
2019-09-13 15:49 ` [Qemu-devel] [PULL 07/12] aspeed/smc: Inject errors in DMA checksum Peter Maydell
2019-09-13 15:49 ` [Qemu-devel] [PULL 08/12] aspeed/smc: Calculate checksum on normal DMA Peter Maydell
2019-09-13 15:49 ` [Qemu-devel] [PULL 09/12] aspeed/scu: Introduce per-SoC SCU types Peter Maydell
2019-09-13 15:49 ` [Qemu-devel] [PULL 10/12] aspeed/scu: Introduce a aspeed_scu_get_apb_freq() routine Peter Maydell
2019-09-13 15:49 ` [Qemu-devel] [PULL 11/12] atomic_template: fix indentation in GEN_ATOMIC_HELPER Peter Maydell
2019-09-13 15:49 ` [Qemu-devel] [PULL 12/12] qemu-ga: Convert invocation documentation to rST Peter Maydell
2019-09-19  1:25   ` Eric Blake
2019-09-19 10:25     ` Alex Bennée
2019-09-19 12:00     ` Peter Maydell
2019-09-19 13:27       ` Eric Blake
2019-09-19 13:35         ` Peter Maydell
2019-09-19 13:54           ` Eric Blake
2019-09-19 15:22             ` Peter Maydell
2019-09-19 15:37               ` Eric Blake
2019-09-19 15:39                 ` Peter Maydell
2019-10-12 13:59                   ` Eduardo Habkost
2019-09-19 14:00       ` Alex Bennée
2019-09-16 12:21 ` [Qemu-devel] [PULL 00/12] 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).