All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours)
@ 2017-07-14 10:51 Peter Maydell
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 1/9] hw/arm/mps2: Implement skeleton mps2-an385 and mps2-an511 board models Peter Maydell
                   ` (10 more replies)
  0 siblings, 11 replies; 26+ messages in thread
From: Peter Maydell @ 2017-07-14 10:51 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: patches, Philippe Mathieu-Daudé, Alistair Francis

This patchseries adds support for the ARM MPS2/MPS2+ dev board:

The MPS2 and MPS2+ dev boards are FPGA based (the 2+ has a bigger
FPGA but is otherwise the same as the 2). Since the CPU itself
and most of the devices are in the FPGA, the details of the board
as seen by the guest depend significantly on the FPGA image.

We model the following FPGA images:
 "mps2_an385" -- Cortex-M3 as documented in ARM Application Note AN385
 "mps2_an511" -- Cortex-M3 'DesignStart' as documented in AN511

They are fairly similar but differ in the details for some
peripherals.
Further info and links to all the documentation for the
board and the various FPGA images can be found here:
 https://developer.arm.com/products/system-design/development-boards/cortex-m-prototyping-system

This patchset adds the boards themselves, and the UART, timer
and system-controller devices they need. There are a number
of other devices on the board which are not yet modelled
(notably more GPIOs, a watchdog, another different kind of timer,
and a display device), but this minimal set is sufficient to
boot the "hello world" binary of the Zephyr RTOS and the
"blinky" binary of the mbed RTOS.
[To run the zephyr binary you also need this fix:
  http://patchwork.ozlabs.org/patch/782811/
 which is in the target-arm pullreq I just sent so should
 get into master in a few days.]

We can add more devices to the model later, but I figured
this was a sufficient place to start.

The underlying motivation here is that the v8M work that I
have planned will need a board, and there is a v8M FPGA
image for the MPS2 that we can use. It's also perhaps a more
useful M profile board for general purposes than the stellaris
boards (64K RAM) or the Netduino2 (128K RAM), since it has
16MB of RAM.

Changes v1->v2:
 * fixed handling of ID register arrays in uart and timer devices
 * moved variable declarations to top of function
 * removed stray braces
 * log guest error if Tx enabled with bad baudrate
 * fixed cut-n-paste error in mps2-scc.h header comment
 * added ethernet support (I actually wrote this patch earlier
   but forgot to put it in v1 ;-))
 * added MAINTAINERS file entries

Non-change:
 * I've stuck with the naming of types/files/boards in the
   first patch, because after consideration I still think
   this is the best choice overall.

Patches which still need review: 1, 2, 8, 9

I'd quite like to get this into 2.10 if possible
(softfreeze deadline rapidly approaching) so if people
have time to review before tuesday that would be great.

thanks
-- PMM

Peter Maydell (9):
  hw/arm/mps2: Implement skeleton mps2-an385 and mps2-an511 board models
  hw/char/cmsdk-apb-uart.c: Implement CMSDK APB UART
  hw/arm/mps2: Add UARTs
  hw/char/cmsdk-apb-timer: Implement CMSDK APB timer device
  hw/arm/mps2: Add timers
  hw/misc/mps2_scc: Implement MPS2 Serial Communication Controller
  hw/arm/mps2: Add SCC
  hw/arm/mps2: Add ethernet
  MAINTAINERS: Add entries for MPS2 board

 hw/arm/Makefile.objs               |   1 +
 hw/char/Makefile.objs              |   1 +
 hw/misc/Makefile.objs              |   1 +
 hw/timer/Makefile.objs             |   1 +
 include/hw/char/cmsdk-apb-uart.h   |  78 +++++++
 include/hw/misc/mps2-scc.h         |  43 ++++
 include/hw/timer/cmsdk-apb-timer.h |  59 ++++++
 hw/arm/mps2.c                      | 384 +++++++++++++++++++++++++++++++++++
 hw/char/cmsdk-apb-uart.c           | 402 +++++++++++++++++++++++++++++++++++++
 hw/misc/mps2-scc.c                 | 310 ++++++++++++++++++++++++++++
 hw/timer/cmsdk-apb-timer.c         | 253 +++++++++++++++++++++++
 MAINTAINERS                        |  14 +-
 default-configs/arm-softmmu.mak    |   6 +
 hw/char/trace-events               |   9 +
 hw/misc/trace-events               |   8 +
 hw/timer/trace-events              |   5 +
 16 files changed, 1574 insertions(+), 1 deletion(-)
 create mode 100644 include/hw/char/cmsdk-apb-uart.h
 create mode 100644 include/hw/misc/mps2-scc.h
 create mode 100644 include/hw/timer/cmsdk-apb-timer.h
 create mode 100644 hw/arm/mps2.c
 create mode 100644 hw/char/cmsdk-apb-uart.c
 create mode 100644 hw/misc/mps2-scc.c
 create mode 100644 hw/timer/cmsdk-apb-timer.c

-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 1/9] hw/arm/mps2: Implement skeleton mps2-an385 and mps2-an511 board models
  2017-07-14 10:51 [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours) Peter Maydell
@ 2017-07-14 10:51 ` Peter Maydell
  2017-07-14 14:44   ` [Qemu-devel] [Qemu-arm] " Alex Bennée
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 2/9] hw/char/cmsdk-apb-uart.c: Implement CMSDK APB UART Peter Maydell
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 26+ messages in thread
From: Peter Maydell @ 2017-07-14 10:51 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: patches, Philippe Mathieu-Daudé, Alistair Francis

Model the ARM MPS2/MPS2+ FPGA based development board.

The MPS2 and MPS2+ dev boards are FPGA based (the 2+ has a bigger
FPGA but is otherwise the same as the 2). Since the CPU itself
and most of the devices are in the FPGA, the details of the board
as seen by the guest depend significantly on the FPGA image.

We model the following FPGA images:
 "mps2_an385" -- Cortex-M3 as documented in ARM Application Note AN385
 "mps2_an511" -- Cortex-M3 'DesignStart' as documented in AN511

They are fairly similar but differ in the details for some
peripherals.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/Makefile.objs            |   1 +
 hw/arm/mps2.c                   | 271 ++++++++++++++++++++++++++++++++++++++++
 default-configs/arm-softmmu.mak |   1 +
 3 files changed, 273 insertions(+)
 create mode 100644 hw/arm/mps2.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 4c5c4ee..a2e56ec 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -18,3 +18,4 @@ obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
 obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
+obj-$(CONFIG_MPS2) += mps2.o
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
new file mode 100644
index 0000000..3dad02d
--- /dev/null
+++ b/hw/arm/mps2.c
@@ -0,0 +1,271 @@
+/*
+ * ARM V2M MPS2 board emulation.
+ *
+ * Copyright (c) 2017 Linaro Limited
+ * Written by Peter Maydell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 or
+ *  (at your option) any later version.
+ */
+
+/* The MPS2 and MPS2+ dev boards are FPGA based (the 2+ has a bigger
+ * FPGA but is otherwise the same as the 2). Since the CPU itself
+ * and most of the devices are in the FPGA, the details of the board
+ * as seen by the guest depend significantly on the FPGA image.
+ * We model the following FPGA images:
+ *  "mps2-an385" -- Cortex-M3 as documented in ARM Application Note AN385
+ *  "mps2-an511" -- Cortex-M3 'DesignStart' as documented in AN511
+ *
+ * Links to the TRM for the board itself and to the various Application
+ * Notes which document the FPGA images can be found here:
+ *   https://developer.arm.com/products/system-design/development-boards/cortex-m-prototyping-system
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "hw/arm/arm.h"
+#include "hw/arm/armv7m.h"
+#include "hw/boards.h"
+#include "exec/address-spaces.h"
+#include "hw/misc/unimp.h"
+
+typedef enum MPS2FPGAType {
+    FPGA_AN385,
+    FPGA_AN511,
+} MPS2FPGAType;
+
+typedef struct {
+    MachineClass parent;
+    MPS2FPGAType fpga_type;
+    const char *cpu_model;
+} MPS2MachineClass;
+
+typedef struct {
+    MachineState parent;
+
+    ARMv7MState armv7m;
+    MemoryRegion psram;
+    MemoryRegion ssram1;
+    MemoryRegion ssram1_m;
+    MemoryRegion ssram23;
+    MemoryRegion ssram23_m;
+    MemoryRegion blockram;
+    MemoryRegion blockram_m1;
+    MemoryRegion blockram_m2;
+    MemoryRegion blockram_m3;
+    MemoryRegion sram;
+} MPS2MachineState;
+
+#define TYPE_MPS2_MACHINE "mps2"
+#define TYPE_MPS2_AN385_MACHINE MACHINE_TYPE_NAME("mps2-an385")
+#define TYPE_MPS2_AN511_MACHINE MACHINE_TYPE_NAME("mps2-an511")
+
+#define MPS2_MACHINE(obj)                                       \
+    OBJECT_CHECK(MPS2MachineState, obj, TYPE_MPS2_MACHINE)
+#define MPS2_MACHINE_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(MPS2MachineClass, obj, TYPE_MPS2_MACHINE)
+#define MPS2_MACHINE_CLASS(klass) \
+    OBJECT_CLASS_CHECK(MPS2MachineClass, klass, TYPE_MPS2_MACHINE)
+
+/* Main SYSCLK frequency in Hz */
+#define SYSCLK_FRQ 25000000
+
+/* Initialize the auxiliary RAM region @mr and map it into
+ * the memory map at @base.
+ */
+static void make_ram(MemoryRegion *mr, const char *name,
+                     hwaddr base, hwaddr size)
+{
+    memory_region_init_ram(mr, NULL, name, size, &error_fatal);
+    vmstate_register_ram_global(mr);
+    memory_region_add_subregion(get_system_memory(), base, mr);
+}
+
+/* Create an alias of an entire original MemoryRegion @orig
+ * located at @base in the memory map.
+ */
+static void make_ram_alias(MemoryRegion *mr, const char *name,
+                           MemoryRegion *orig, hwaddr base)
+{
+    memory_region_init_alias(mr, NULL, name, orig, 0,
+                             memory_region_size(orig));
+    memory_region_add_subregion(get_system_memory(), base, mr);
+}
+
+static void mps2_common_init(MachineState *machine)
+{
+    MPS2MachineState *mms = MPS2_MACHINE(machine);
+    MPS2MachineClass *mmc = MPS2_MACHINE_GET_CLASS(machine);
+    MemoryRegion *system_memory = get_system_memory();
+    DeviceState *armv7m;
+
+    if (!machine->cpu_model) {
+        machine->cpu_model = mmc->cpu_model;
+    }
+
+    if (strcmp(machine->cpu_model, mmc->cpu_model) != 0) {
+        error_report("This board can only be used with CPU %s", mmc->cpu_model);
+        exit(1);
+    }
+
+    /* The FPGA images have an odd combination of different RAMs,
+     * because in hardware they are different implementations and
+     * connected to different buses, giving varying performance/size
+     * tradeoffs. For QEMU they're all just RAM, though. We arbitrarily
+     * call the 16MB our "system memory", as it's the largest lump.
+     *
+     * Common to both boards:
+     *  0x21000000..0x21ffffff : PSRAM (16MB)
+     * AN385 only:
+     *  0x00000000 .. 0x003fffff : ZBT SSRAM1
+     *  0x00400000 .. 0x007fffff : mirror of ZBT SSRAM1
+     *  0x20000000 .. 0x203fffff : ZBT SSRAM 2&3
+     *  0x20400000 .. 0x207fffff : mirror of ZBT SSRAM 2&3
+     *  0x01000000 .. 0x01003fff : block RAM (16K)
+     *  0x01004000 .. 0x01007fff : mirror of above
+     *  0x01008000 .. 0x0100bfff : mirror of above
+     *  0x0100c000 .. 0x0100ffff : mirror of above
+     * AN511 only:
+     *  0x00000000 .. 0x0003ffff : FPGA block RAM
+     *  0x00400000 .. 0x007fffff : ZBT SSRAM1
+     *  0x20000000 .. 0x2001ffff : SRAM
+     *  0x20400000 .. 0x207fffff : ZBT SSRAM 2&3
+     *
+     * The AN385 has a feature where the lowest 16K can be mapped
+     * either to the bottom of the ZBT SSRAM1 or to the block RAM.
+     * This is of no use for QEMU so we don't implement it (as if
+     * zbt_boot_ctrl is always zero).
+     */
+    memory_region_allocate_system_memory(&mms->psram,
+                                         NULL, "mps.ram", 0x1000000);
+    memory_region_add_subregion(system_memory, 0x21000000, &mms->psram);
+
+    switch (mmc->fpga_type) {
+    case FPGA_AN385:
+        make_ram(&mms->ssram1, "mps.ssram1", 0x0, 0x400000);
+        make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", &mms->ssram1, 0x400000);
+        make_ram(&mms->ssram23, "mps.ssram23", 0x20000000, 0x400000);
+        make_ram_alias(&mms->ssram23_m, "mps.ssram23_m",
+                       &mms->ssram23, 0x20400000);
+        make_ram(&mms->blockram, "mps.blockram", 0x01000000, 0x4000);
+        make_ram_alias(&mms->blockram_m1, "mps.blockram_m1",
+                       &mms->blockram, 0x01004000);
+        make_ram_alias(&mms->blockram_m2, "mps.blockram_m2",
+                       &mms->blockram, 0x01008000);
+        make_ram_alias(&mms->blockram_m3, "mps.blockram_m3",
+                       &mms->blockram, 0x0100c000);
+        break;
+    case FPGA_AN511:
+        make_ram(&mms->blockram, "mps.blockram", 0x0, 0x40000);
+        make_ram(&mms->ssram1, "mps.ssram1", 0x00400000, 0x00800000);
+        make_ram(&mms->sram, "mps.sram", 0x20000000, 0x20000);
+        make_ram(&mms->ssram23, "mps.ssram23", 0x20400000, 0x400000);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+
+    object_initialize(&mms->armv7m, sizeof(mms->armv7m), TYPE_ARMV7M);
+    armv7m = DEVICE(&mms->armv7m);
+    qdev_set_parent_bus(armv7m, sysbus_get_default());
+    switch (mmc->fpga_type) {
+    case FPGA_AN385:
+        qdev_prop_set_uint32(armv7m, "num-irq", 32);
+        break;
+    case FPGA_AN511:
+        qdev_prop_set_uint32(armv7m, "num-irq", 64);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    qdev_prop_set_string(armv7m, "cpu-model", machine->cpu_model);
+    object_property_set_link(OBJECT(&mms->armv7m), OBJECT(system_memory),
+                             "memory", &error_abort);
+    object_property_set_bool(OBJECT(&mms->armv7m), true, "realized",
+                             &error_fatal);
+
+    create_unimplemented_device("zbtsmram mirror", 0x00400000, 0x00400000);
+    create_unimplemented_device("RESERVED 1", 0x00800000, 0x00800000);
+    create_unimplemented_device("Block RAM", 0x01000000, 0x00010000);
+    create_unimplemented_device("RESERVED 2", 0x01010000, 0x1EFF0000);
+    create_unimplemented_device("RESERVED 3", 0x20800000, 0x00800000);
+    create_unimplemented_device("PSRAM", 0x21000000, 0x01000000);
+    /* These three ranges all cover multiple devices; we may implement
+     * some of them below (in which case the real device takes precedence
+     * over the unimplemented-region mapping).
+     */
+    create_unimplemented_device("CMSDK APB peripheral region @0x40000000",
+                                0x40000000, 0x00010000);
+    create_unimplemented_device("CMSDK peripheral region @0x40010000",
+                                0x40010000, 0x00010000);
+    create_unimplemented_device("Extra peripheral region @0x40020000",
+                                0x40020000, 0x00010000);
+    create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
+    create_unimplemented_device("Ethernet", 0x40200000, 0x00100000);
+    create_unimplemented_device("VGA", 0x41000000, 0x0200000);
+
+    system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
+
+    armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
+                       0x400000);
+}
+
+static void mps2_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+
+    mc->init = mps2_common_init;
+    mc->max_cpus = 1;
+}
+
+static void mps2_an385_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
+
+    mc->desc = "ARM MPS2 with AN385 FPGA image for Cortex-M3";
+    mmc->fpga_type = FPGA_AN385;
+    mmc->cpu_model = "cortex-m3";
+}
+
+static void mps2_an511_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
+
+    mc->desc = "ARM MPS2 with AN511 DesignStart FPGA image for Cortex-M3";
+    mmc->fpga_type = FPGA_AN511;
+    mmc->cpu_model = "cortex-m3";
+}
+
+static const TypeInfo mps2_info = {
+    .name = TYPE_MPS2_MACHINE,
+    .parent = TYPE_MACHINE,
+    .abstract = true,
+    .instance_size = sizeof(MPS2MachineState),
+    .class_size = sizeof(MPS2MachineClass),
+    .class_init = mps2_class_init,
+};
+
+static const TypeInfo mps2_an385_info = {
+    .name = TYPE_MPS2_AN385_MACHINE,
+    .parent = TYPE_MPS2_MACHINE,
+    .class_init = mps2_an385_class_init,
+};
+
+static const TypeInfo mps2_an511_info = {
+    .name = TYPE_MPS2_AN511_MACHINE,
+    .parent = TYPE_MPS2_MACHINE,
+    .class_init = mps2_an511_class_init,
+};
+
+static void mps2_machine_init(void)
+{
+    type_register_static(&mps2_info);
+    type_register_static(&mps2_an385_info);
+    type_register_static(&mps2_an511_info);
+}
+
+type_init(mps2_machine_init);
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 93e995d..bfd2a88 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -83,6 +83,7 @@ CONFIG_ONENAND=y
 CONFIG_TUSB6010=y
 CONFIG_IMX=y
 CONFIG_MAINSTONE=y
+CONFIG_MPS2=y
 CONFIG_NSERIES=y
 CONFIG_RASPI=y
 CONFIG_REALVIEW=y
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 2/9] hw/char/cmsdk-apb-uart.c: Implement CMSDK APB UART
  2017-07-14 10:51 [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours) Peter Maydell
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 1/9] hw/arm/mps2: Implement skeleton mps2-an385 and mps2-an511 board models Peter Maydell
@ 2017-07-14 10:51 ` Peter Maydell
  2017-07-14 15:32   ` [Qemu-devel] [Qemu-arm] " Alex Bennée
  2017-07-14 16:29   ` [Qemu-devel] " Philippe Mathieu-Daudé
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 3/9] hw/arm/mps2: Add UARTs Peter Maydell
                   ` (8 subsequent siblings)
  10 siblings, 2 replies; 26+ messages in thread
From: Peter Maydell @ 2017-07-14 10:51 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: patches, Philippe Mathieu-Daudé, Alistair Francis

Implement a model of the simple "APB UART" provided in
the Cortex-M System Design Kit (CMSDK).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/char/Makefile.objs            |   1 +
 include/hw/char/cmsdk-apb-uart.h |  78 ++++++++
 hw/char/cmsdk-apb-uart.c         | 402 +++++++++++++++++++++++++++++++++++++++
 default-configs/arm-softmmu.mak  |   2 +
 hw/char/trace-events             |   9 +
 5 files changed, 492 insertions(+)
 create mode 100644 include/hw/char/cmsdk-apb-uart.h
 create mode 100644 hw/char/cmsdk-apb-uart.c

diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
index 55fcb68..1bcd37e 100644
--- a/hw/char/Makefile.objs
+++ b/hw/char/Makefile.objs
@@ -19,6 +19,7 @@ obj-$(CONFIG_DIGIC) += digic-uart.o
 obj-$(CONFIG_STM32F2XX_USART) += stm32f2xx_usart.o
 obj-$(CONFIG_RASPI) += bcm2835_aux.o
 
+common-obj-$(CONFIG_CMSDK_APB_UART) += cmsdk-apb-uart.o
 common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
 common-obj-$(CONFIG_ISA_DEBUG) += debugcon.o
 common-obj-$(CONFIG_GRLIB) += grlib_apbuart.o
diff --git a/include/hw/char/cmsdk-apb-uart.h b/include/hw/char/cmsdk-apb-uart.h
new file mode 100644
index 0000000..c41fba9
--- /dev/null
+++ b/include/hw/char/cmsdk-apb-uart.h
@@ -0,0 +1,78 @@
+/*
+ * ARM CMSDK APB UART emulation
+ *
+ * Copyright (c) 2017 Linaro Limited
+ * Written by Peter Maydell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 or
+ *  (at your option) any later version.
+ */
+
+#ifndef CMSDK_APB_UART_H
+#define CMSDK_APB_UART_H
+
+#include "hw/sysbus.h"
+#include "chardev/char-fe.h"
+
+#define TYPE_CMSDK_APB_UART "cmsdk-apb-uart"
+#define CMSDK_APB_UART(obj) OBJECT_CHECK(CMSDKAPBUART, (obj), \
+                                         TYPE_CMSDK_APB_UART)
+
+typedef struct {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    MemoryRegion iomem;
+    CharBackend chr;
+    qemu_irq txint;
+    qemu_irq rxint;
+    qemu_irq txovrint;
+    qemu_irq rxovrint;
+    qemu_irq uartint;
+    guint watch_tag;
+    uint32_t pclk_frq;
+
+    uint32_t state;
+    uint32_t ctrl;
+    uint32_t intstatus;
+    uint32_t bauddiv;
+    /* This UART has no FIFO, only a 1-character buffer for each of Tx and Rx */
+    uint8_t txbuf;
+    uint8_t rxbuf;
+} CMSDKAPBUART;
+
+/**
+ * cmsdk_apb_uart_create - convenience function to create TYPE_CMSDK_APB_UART
+ * @addr: location in system memory to map registers
+ * @chr: Chardev backend to connect UART to, or NULL if no backend
+ * @pclk_frq: frequency in Hz of the PCLK clock (used for calculating baud rate)
+ */
+static inline DeviceState *cmsdk_apb_uart_create(hwaddr addr,
+                                                 qemu_irq txint,
+                                                 qemu_irq rxint,
+                                                 qemu_irq txovrint,
+                                                 qemu_irq rxovrint,
+                                                 qemu_irq uartint,
+                                                 Chardev *chr,
+                                                 uint32_t pclk_frq)
+{
+    DeviceState *dev;
+    SysBusDevice *s;
+
+    dev = qdev_create(NULL, TYPE_CMSDK_APB_UART);
+    s = SYS_BUS_DEVICE(dev);
+    qdev_prop_set_chr(dev, "chardev", chr);
+    qdev_prop_set_uint32(dev, "pclk-frq", pclk_frq);
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(s, 0, addr);
+    sysbus_connect_irq(s, 0, txint);
+    sysbus_connect_irq(s, 1, rxint);
+    sysbus_connect_irq(s, 2, txovrint);
+    sysbus_connect_irq(s, 3, rxovrint);
+    sysbus_connect_irq(s, 4, uartint);
+    return dev;
+}
+
+#endif
diff --git a/hw/char/cmsdk-apb-uart.c b/hw/char/cmsdk-apb-uart.c
new file mode 100644
index 0000000..82d2bea
--- /dev/null
+++ b/hw/char/cmsdk-apb-uart.c
@@ -0,0 +1,402 @@
+/*
+ * ARM CMSDK APB UART emulation
+ *
+ * Copyright (c) 2017 Linaro Limited
+ * Written by Peter Maydell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 or
+ *  (at your option) any later version.
+ */
+
+/* This is a model of the "APB UART" which is part of the Cortex-M
+ * System Design Kit (CMSDK) and documented in the Cortex-M System
+ * Design Kit Technical Reference Manual (ARM DDI0479C):
+ * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "trace.h"
+#include "hw/sysbus.h"
+#include "hw/registerfields.h"
+#include "chardev/char-fe.h"
+#include "chardev/char-serial.h"
+#include "hw/char/cmsdk-apb-uart.h"
+
+REG32(DATA, 0)
+REG32(STATE, 4)
+    FIELD(STATE, TXFULL, 0, 1)
+    FIELD(STATE, RXFULL, 1, 1)
+    FIELD(STATE, TXOVERRUN, 2, 1)
+    FIELD(STATE, RXOVERRUN, 3, 1)
+REG32(CTRL, 8)
+    FIELD(CTRL, TX_EN, 0, 1)
+    FIELD(CTRL, RX_EN, 1, 1)
+    FIELD(CTRL, TX_INTEN, 2, 1)
+    FIELD(CTRL, RX_INTEN, 3, 1)
+    FIELD(CTRL, TXO_INTEN, 4, 1)
+    FIELD(CTRL, RXO_INTEN, 5, 1)
+    FIELD(CTRL, HSTEST, 6, 1)
+REG32(INTSTATUS, 0xc)
+    FIELD(INTSTATUS, TX, 0, 1)
+    FIELD(INTSTATUS, RX, 1, 1)
+    FIELD(INTSTATUS, TXO, 2, 1)
+    FIELD(INTSTATUS, RXO, 3, 1)
+REG32(BAUDDIV, 0x10)
+REG32(PID4, 0xFD0)
+REG32(PID5, 0xFD4)
+REG32(PID6, 0xFD8)
+REG32(PID7, 0xFDC)
+REG32(PID0, 0xFE0)
+REG32(PID1, 0xFE4)
+REG32(PID2, 0xFE8)
+REG32(PID3, 0xFEC)
+REG32(CID0, 0xFF0)
+REG32(CID1, 0xFF4)
+REG32(CID2, 0xFF8)
+REG32(CID3, 0xFFC)
+
+/* PID/CID values */
+static const int uart_id[] = {
+    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
+    0x21, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
+    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
+};
+
+static bool uart_baudrate_ok(CMSDKAPBUART *s)
+{
+    /* The minimum permitted bauddiv setting is 16, so we just ignore
+     * settings below that (usually this means the device has just
+     * been reset and not yet programmed).
+     */
+    return s->bauddiv >= 16 && s->bauddiv <= s->pclk_frq;
+}
+
+static void uart_update_parameters(CMSDKAPBUART *s)
+{
+    QEMUSerialSetParams ssp;
+
+    /* This UART is always 8N1 but the baud rate is programmable. */
+    if (!uart_baudrate_ok(s)) {
+        return;
+    }
+
+    ssp.data_bits = 8;
+    ssp.parity = 'N';
+    ssp.stop_bits = 1;
+    ssp.speed = s->pclk_frq / s->bauddiv;
+    qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
+    trace_cmsdk_apb_uart_set_params(ssp.speed);
+}
+
+static void cmsdk_apb_uart_update(CMSDKAPBUART *s)
+{
+    /* update outbound irqs, including handling the way the rxo and txo
+     * interrupt status bits are just logical AND of the overrun bit in
+     * STATE and the overrun interrupt enable bit in CTRL.
+     */
+    uint32_t omask = (R_INTSTATUS_RXO_MASK | R_INTSTATUS_TXO_MASK);
+    s->intstatus &= ~omask;
+    s->intstatus |= (s->state & (s->ctrl >> 2) & omask);
+
+    qemu_set_irq(s->txint, !!(s->intstatus & R_INTSTATUS_TX_MASK));
+    qemu_set_irq(s->rxint, !!(s->intstatus & R_INTSTATUS_RX_MASK));
+    qemu_set_irq(s->txovrint, !!(s->intstatus & R_INTSTATUS_TXO_MASK));
+    qemu_set_irq(s->rxovrint, !!(s->intstatus & R_INTSTATUS_RXO_MASK));
+    qemu_set_irq(s->uartint, !!(s->intstatus));
+}
+
+static int uart_can_receive(void *opaque)
+{
+    CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
+
+    /* We can take a char if RX is enabled and the buffer is empty */
+    if (s->ctrl & R_CTRL_RX_EN_MASK && !(s->state & R_STATE_RXFULL_MASK)) {
+        return 1;
+    }
+    return 0;
+}
+
+static void uart_receive(void *opaque, const uint8_t *buf, int size)
+{
+    CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
+
+    trace_cmsdk_apb_uart_receive(*buf);
+
+    /* In fact uart_can_receive() ensures that we can't be
+     * called unless RX is enabled and the buffer is empty,
+     * but we include this logic as documentation of what the
+     * hardware does if a character arrives in these circumstances.
+     */
+    if (!(s->ctrl & R_CTRL_RX_EN_MASK)) {
+        /* Just drop the character on the floor */
+        return;
+    }
+
+    if (s->state & R_STATE_RXFULL_MASK) {
+        s->state |= R_STATE_RXOVERRUN_MASK;
+    }
+
+    s->rxbuf = *buf;
+    s->state |= R_STATE_RXFULL_MASK;
+    if (s->ctrl & R_CTRL_RX_INTEN_MASK) {
+        s->intstatus |= R_INTSTATUS_RX_MASK;
+    }
+    cmsdk_apb_uart_update(s);
+}
+
+static uint64_t uart_read(void *opaque, hwaddr offset, unsigned size)
+{
+    CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
+    uint64_t r;
+
+    switch (offset) {
+    case A_DATA:
+        r = s->rxbuf;
+        s->state &= ~R_STATE_RXFULL_MASK;
+        cmsdk_apb_uart_update(s);
+        break;
+    case A_STATE:
+        r = s->state;
+        break;
+    case A_CTRL:
+        r = s->ctrl;
+        break;
+    case A_INTSTATUS:
+        r = s->intstatus;
+        break;
+    case A_BAUDDIV:
+        r = s->bauddiv;
+        break;
+    case A_PID4 ... A_CID3:
+        r = uart_id[(offset - A_PID4) / 4];
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "CMSDK APB UART read: bad offset %x\n", (int) offset);
+        r = 0;
+        break;
+    }
+    trace_cmsdk_apb_uart_read(offset, r, size);
+    return r;
+}
+
+/* Try to send tx data, and arrange to be called back later if
+ * we can't (ie the char backend is busy/blocking).
+ */
+static gboolean uart_transmit(GIOChannel *chan, GIOCondition cond, void *opaque)
+{
+    CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
+    int ret;
+
+    s->watch_tag = 0;
+
+    if (!(s->ctrl & R_CTRL_TX_EN_MASK) || !(s->state & R_STATE_TXFULL_MASK)) {
+        return FALSE;
+    }
+
+    ret = qemu_chr_fe_write(&s->chr, &s->txbuf, 1);
+    if (ret <= 0) {
+        s->watch_tag = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
+                                             uart_transmit, s);
+        if (!s->watch_tag) {
+            /* Most common reason to be here is "no chardev backend":
+             * just insta-drain the buffer, so the serial output
+             * goes into a void, rather than blocking the guest.
+             */
+            goto buffer_drained;
+        }
+        /* Transmit pending */
+        trace_cmsdk_apb_uart_tx_pending();
+        return FALSE;
+    }
+
+buffer_drained:
+    /* Character successfully sent */
+    trace_cmsdk_apb_uart_tx(s->txbuf);
+    s->state &= ~R_STATE_TXFULL_MASK;
+    /* Going from TXFULL set to clear triggers the tx interrupt */
+    if (s->ctrl & R_CTRL_TX_INTEN_MASK) {
+        s->intstatus |= R_INTSTATUS_TX_MASK;
+    }
+    cmsdk_apb_uart_update(s);
+    return FALSE;
+}
+
+static void uart_cancel_transmit(CMSDKAPBUART *s)
+{
+    if (s->watch_tag) {
+        g_source_remove(s->watch_tag);
+        s->watch_tag = 0;
+    }
+}
+
+static void uart_write(void *opaque, hwaddr offset, uint64_t value,
+                       unsigned size)
+{
+    CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
+
+    trace_cmsdk_apb_uart_write(offset, value, size);
+
+    switch (offset) {
+    case A_DATA:
+        s->txbuf = value;
+        if (s->state & R_STATE_TXFULL_MASK) {
+            /* Buffer already full -- note the overrun and let the
+             * existing pending transmit callback handle the new char.
+             */
+            s->state |= R_STATE_TXOVERRUN_MASK;
+            cmsdk_apb_uart_update(s);
+        } else {
+            s->state |= R_STATE_TXFULL_MASK;
+            uart_transmit(NULL, G_IO_OUT, s);
+        }
+        break;
+    case A_STATE:
+        /* Bits 0 and 1 are read only; bits 2 and 3 are W1C */
+        s->state &= ~(value & 0xc);
+        cmsdk_apb_uart_update(s);
+        break;
+    case A_CTRL:
+        s->ctrl = value & 0x7f;
+        if ((s->ctrl & R_CTRL_TX_EN_MASK) && !uart_baudrate_ok(s)) {
+            qemu_log_mask(LOG_GUEST_ERROR,
+                          "CMSDK APB UART: Tx enabled with invalid baudrate\n");
+        }
+        cmsdk_apb_uart_update(s);
+        break;
+    case A_INTSTATUS:
+        /* All bits are W1C. Clearing the overrun interrupt bits really
+         * clears the overrun status bits in the STATE register (which
+         * is then reflected into the intstatus value by the update function).
+         */
+        s->state &= ~(value & 0xc);
+        cmsdk_apb_uart_update(s);
+        break;
+    case A_BAUDDIV:
+        s->bauddiv = value & 0xFFFFF;
+        uart_update_parameters(s);
+        break;
+    case A_PID4 ... A_CID3:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "CMSDK APB UART write: write to RO offset 0x%x\n",
+                      (int)offset);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "CMSDK APB UART write: bad offset 0x%x\n", (int) offset);
+        break;
+    }
+}
+
+static const MemoryRegionOps uart_ops = {
+    .read = uart_read,
+    .write = uart_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void cmsdk_apb_uart_reset(DeviceState *dev)
+{
+    CMSDKAPBUART *s = CMSDK_APB_UART(dev);
+
+    trace_cmsdk_apb_uart_reset();
+    uart_cancel_transmit(s);
+    s->state = 0;
+    s->ctrl = 0;
+    s->intstatus = 0;
+    s->bauddiv = 0;
+    s->txbuf = 0;
+    s->rxbuf = 0;
+}
+
+static void cmsdk_apb_uart_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    CMSDKAPBUART *s = CMSDK_APB_UART(obj);
+
+    memory_region_init_io(&s->iomem, obj, &uart_ops, s, "uart", 0x1000);
+    sysbus_init_mmio(sbd, &s->iomem);
+    sysbus_init_irq(sbd, &s->txint);
+    sysbus_init_irq(sbd, &s->rxint);
+    sysbus_init_irq(sbd, &s->txovrint);
+    sysbus_init_irq(sbd, &s->rxovrint);
+    sysbus_init_irq(sbd, &s->uartint);
+}
+
+static void cmsdk_apb_uart_realize(DeviceState *dev, Error **errp)
+{
+    CMSDKAPBUART *s = CMSDK_APB_UART(dev);
+
+    if (s->pclk_frq == 0) {
+        error_setg(errp, "CMSDK APB UART: pclk-frq property must be set");
+        return;
+    }
+
+    /* This UART has no flow control, so we do not need to register
+     * an event handler to deal with CHR_EVENT_BREAK.
+     */
+    qemu_chr_fe_set_handlers(&s->chr, uart_can_receive, uart_receive,
+                             NULL, s, NULL, true);
+}
+
+static int cmsdk_apb_uart_post_load(void *opaque, int version_id)
+{
+    CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
+
+    /* If we have a pending character, arrange to resend it. */
+    if (s->state & R_STATE_TXFULL_MASK) {
+        s->watch_tag = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
+                                             uart_transmit, s);
+    }
+    uart_update_parameters(s);
+    return 0;
+}
+
+static const VMStateDescription cmsdk_apb_uart_vmstate = {
+    .name = "cmsdk-apb-uart",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .post_load = cmsdk_apb_uart_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(state, CMSDKAPBUART),
+        VMSTATE_UINT32(ctrl, CMSDKAPBUART),
+        VMSTATE_UINT32(intstatus, CMSDKAPBUART),
+        VMSTATE_UINT32(bauddiv, CMSDKAPBUART),
+        VMSTATE_UINT8(txbuf, CMSDKAPBUART),
+        VMSTATE_UINT8(rxbuf, CMSDKAPBUART),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static Property cmsdk_apb_uart_properties[] = {
+    DEFINE_PROP_CHR("chardev", CMSDKAPBUART, chr),
+    DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBUART, pclk_frq, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void cmsdk_apb_uart_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = cmsdk_apb_uart_realize;
+    dc->vmsd = &cmsdk_apb_uart_vmstate;
+    dc->reset = cmsdk_apb_uart_reset;
+    dc->props = cmsdk_apb_uart_properties;
+}
+
+static const TypeInfo cmsdk_apb_uart_info = {
+    .name = TYPE_CMSDK_APB_UART,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(CMSDKAPBUART),
+    .instance_init = cmsdk_apb_uart_init,
+    .class_init = cmsdk_apb_uart_class_init,
+};
+
+static void cmsdk_apb_uart_register_types(void)
+{
+    type_register_static(&cmsdk_apb_uart_info);
+}
+
+type_init(cmsdk_apb_uart_register_types);
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index bfd2a88..d128e9d 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -96,6 +96,8 @@ CONFIG_STM32F2XX_ADC=y
 CONFIG_STM32F2XX_SPI=y
 CONFIG_STM32F205_SOC=y
 
+CONFIG_CMSDK_APB_UART=y
+
 CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
 
diff --git a/hw/char/trace-events b/hw/char/trace-events
index 7fd48bb..daf4ee4 100644
--- a/hw/char/trace-events
+++ b/hw/char/trace-events
@@ -56,3 +56,12 @@ pl011_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
 pl011_can_receive(uint32_t lcr, int read_count, int r) "LCR %08x read_count %d returning %d"
 pl011_put_fifo(uint32_t c, int read_count) "new char 0x%x read_count now %d"
 pl011_put_fifo_full(void) "FIFO now full, RXFF set"
+
+# hw/char/cmsdk_apb_uart.c
+cmsdk_apb_uart_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB UART read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+cmsdk_apb_uart_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB UART write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+cmsdk_apb_uart_reset(void) "CMSDK APB UART: reset"
+cmsdk_apb_uart_receive(uint8_t c) "CMSDK APB UART: got character 0x%x from backend"
+cmsdk_apb_uart_tx_pending(void) "CMSDK APB UART: character send to backend pending"
+cmsdk_apb_uart_tx(uint8_t c) "CMSDK APB UART: character 0x%x sent to backend"
+cmsdk_apb_uart_set_params(int speed) "CMSDK APB UART: params set to %d 8N1"
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 3/9] hw/arm/mps2: Add UARTs
  2017-07-14 10:51 [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours) Peter Maydell
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 1/9] hw/arm/mps2: Implement skeleton mps2-an385 and mps2-an511 board models Peter Maydell
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 2/9] hw/char/cmsdk-apb-uart.c: Implement CMSDK APB UART Peter Maydell
@ 2017-07-14 10:51 ` Peter Maydell
  2017-07-14 15:52   ` [Qemu-devel] [Qemu-arm] " Alex Bennée
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 4/9] hw/char/cmsdk-apb-timer: Implement CMSDK APB timer device Peter Maydell
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 26+ messages in thread
From: Peter Maydell @ 2017-07-14 10:51 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: patches, Philippe Mathieu-Daudé, Alistair Francis

Add the UARTs to the MPS2 board models.

Unfortunately the details of the wiring of the interrupts through
various OR gates differ between AN511 and AN385 so this can't
be purely a data-driven difference.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
---
 hw/arm/mps2.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
index 3dad02d..180c5d2 100644
--- a/hw/arm/mps2.c
+++ b/hw/arm/mps2.c
@@ -27,9 +27,12 @@
 #include "qemu/error-report.h"
 #include "hw/arm/arm.h"
 #include "hw/arm/armv7m.h"
+#include "hw/or-irq.h"
 #include "hw/boards.h"
 #include "exec/address-spaces.h"
+#include "sysemu/sysemu.h"
 #include "hw/misc/unimp.h"
+#include "hw/char/cmsdk-apb-uart.h"
 
 typedef enum MPS2FPGAType {
     FPGA_AN385,
@@ -206,6 +209,89 @@ static void mps2_common_init(MachineState *machine)
     create_unimplemented_device("Ethernet", 0x40200000, 0x00100000);
     create_unimplemented_device("VGA", 0x41000000, 0x0200000);
 
+    switch (mmc->fpga_type) {
+    case FPGA_AN385:
+    {
+        /* The overflow IRQs for UARTs 0, 1 and 2 are ORed together.
+         * Overflow for UARTs 4 and 5 doesn't trigger any interrupt.
+         */
+        Object *orgate;
+        DeviceState *orgate_dev;
+        int i;
+
+        orgate = object_new(TYPE_OR_IRQ);
+        object_property_set_int(orgate, 6, "num-lines", &error_fatal);
+        object_property_set_bool(orgate, true, "realized", &error_fatal);
+        orgate_dev = DEVICE(orgate);
+        qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
+
+        for (i = 0; i < 5; i++) {
+            hwaddr uartbase[] = {0x40004000, 0x40005000, 0x40006000,
+                                 0x40007000, 0x40009000};
+            Chardev *uartchr = i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL;
+            /* RX irq number; TX irq is always one greater */
+            int uartirq[] = {0, 2, 4, 18, 20};
+            qemu_irq txovrint = NULL, rxovrint = NULL;
+
+            if (i < 3) {
+                txovrint = qdev_get_gpio_in(orgate_dev, i * 2);
+                rxovrint = qdev_get_gpio_in(orgate_dev, i * 2 + 1);
+            }
+
+            cmsdk_apb_uart_create(uartbase[i],
+                                  qdev_get_gpio_in(armv7m, uartirq[i] + 1),
+                                  qdev_get_gpio_in(armv7m, uartirq[i]),
+                                  txovrint, rxovrint,
+                                  NULL,
+                                  uartchr, SYSCLK_FRQ);
+        }
+        break;
+    }
+    case FPGA_AN511:
+    {
+        /* The overflow IRQs for all UARTs are ORed together.
+         * Tx and Rx IRQs for each UART are ORed together.
+         */
+        Object *orgate;
+        DeviceState *orgate_dev;
+        int i;
+
+        orgate = object_new(TYPE_OR_IRQ);
+        object_property_set_int(orgate, 10, "num-lines", &error_fatal);
+        object_property_set_bool(orgate, true, "realized", &error_fatal);
+        orgate_dev = DEVICE(orgate);
+        qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
+
+        for (i = 0; i < 5; i++) {
+            /* system irq numbers for the combined tx/rx for each UART */
+            const int uart_txrx_irqno[] = {0, 2, 45, 46, 56};
+            hwaddr uartbase[] = {0x40004000, 0x40005000, 0x4002c000,
+                                 0x4002d000, 0x4002e000};
+            Chardev *uartchr = i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL;
+            Object *txrx_orgate;
+            DeviceState *txrx_orgate_dev;
+
+            txrx_orgate = object_new(TYPE_OR_IRQ);
+            object_property_set_int(txrx_orgate, 2, "num-lines", &error_fatal);
+            object_property_set_bool(txrx_orgate, true, "realized",
+                                     &error_fatal);
+            txrx_orgate_dev = DEVICE(txrx_orgate);
+            qdev_connect_gpio_out(txrx_orgate_dev, 0,
+                                  qdev_get_gpio_in(armv7m, uart_txrx_irqno[i]));
+            cmsdk_apb_uart_create(uartbase[i],
+                                  qdev_get_gpio_in(txrx_orgate_dev, 0),
+                                  qdev_get_gpio_in(txrx_orgate_dev, 1),
+                                  qdev_get_gpio_in(orgate_dev, 0),
+                                  qdev_get_gpio_in(orgate_dev, 1),
+                                  NULL,
+                                  uartchr, SYSCLK_FRQ);
+        }
+        break;
+    }
+    default:
+        g_assert_not_reached();
+    }
+
     system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
 
     armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 4/9] hw/char/cmsdk-apb-timer: Implement CMSDK APB timer device
  2017-07-14 10:51 [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours) Peter Maydell
                   ` (2 preceding siblings ...)
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 3/9] hw/arm/mps2: Add UARTs Peter Maydell
@ 2017-07-14 10:51 ` Peter Maydell
  2017-07-14 16:30   ` Philippe Mathieu-Daudé
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 5/9] hw/arm/mps2: Add timers Peter Maydell
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 26+ messages in thread
From: Peter Maydell @ 2017-07-14 10:51 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: patches, Philippe Mathieu-Daudé, Alistair Francis

Implement a model of the simple timer device found in the CMSDK.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/timer/Makefile.objs             |   1 +
 include/hw/timer/cmsdk-apb-timer.h |  59 +++++++++
 hw/timer/cmsdk-apb-timer.c         | 253 +++++++++++++++++++++++++++++++++++++
 default-configs/arm-softmmu.mak    |   1 +
 hw/timer/trace-events              |   5 +
 5 files changed, 319 insertions(+)
 create mode 100644 include/hw/timer/cmsdk-apb-timer.h
 create mode 100644 hw/timer/cmsdk-apb-timer.c

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index dd6f27e..15cce1c 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -41,3 +41,4 @@ common-obj-$(CONFIG_STM32F2XX_TIMER) += stm32f2xx_timer.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
 
 common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
+common-obj-$(CONFIG_CMSDK_APB_TIMER) += cmsdk-apb-timer.o
diff --git a/include/hw/timer/cmsdk-apb-timer.h b/include/hw/timer/cmsdk-apb-timer.h
new file mode 100644
index 0000000..f21686d
--- /dev/null
+++ b/include/hw/timer/cmsdk-apb-timer.h
@@ -0,0 +1,59 @@
+/*
+ * ARM CMSDK APB timer emulation
+ *
+ * Copyright (c) 2017 Linaro Limited
+ * Written by Peter Maydell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 or
+ *  (at your option) any later version.
+ */
+
+#ifndef CMSDK_APB_TIMER_H
+#define CMSDK_APB_TIMER_H
+
+#include "hw/sysbus.h"
+#include "hw/ptimer.h"
+
+#define TYPE_CMSDK_APB_TIMER "cmsdk-apb-timer"
+#define CMSDK_APB_TIMER(obj) OBJECT_CHECK(CMSDKAPBTIMER, (obj), \
+                                         TYPE_CMSDK_APB_TIMER)
+
+typedef struct {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    MemoryRegion iomem;
+    qemu_irq timerint;
+    uint32_t pclk_frq;
+    struct ptimer_state *timer;
+
+    uint32_t ctrl;
+    uint32_t value;
+    uint32_t reload;
+    uint32_t intstatus;
+} CMSDKAPBTIMER;
+
+/**
+ * cmsdk_apb_timer_create - convenience function to create TYPE_CMSDK_APB_TIMER
+ * @addr: location in system memory to map registers
+ * @pclk_frq: frequency in Hz of the PCLK clock (used for calculating baud rate)
+ */
+static inline DeviceState *cmsdk_apb_timer_create(hwaddr addr,
+                                                 qemu_irq timerint,
+                                                 uint32_t pclk_frq)
+{
+    DeviceState *dev;
+    SysBusDevice *s;
+
+    dev = qdev_create(NULL, TYPE_CMSDK_APB_TIMER);
+    s = SYS_BUS_DEVICE(dev);
+    qdev_prop_set_uint32(dev, "pclk-frq", pclk_frq);
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(s, 0, addr);
+    sysbus_connect_irq(s, 0, timerint);
+    return dev;
+}
+
+#endif
diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c
new file mode 100644
index 0000000..9878746
--- /dev/null
+++ b/hw/timer/cmsdk-apb-timer.c
@@ -0,0 +1,253 @@
+/*
+ * ARM CMSDK APB timer emulation
+ *
+ * Copyright (c) 2017 Linaro Limited
+ * Written by Peter Maydell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 or
+ *  (at your option) any later version.
+ */
+
+/* This is a model of the "APB timer" which is part of the Cortex-M
+ * System Design Kit (CMSDK) and documented in the Cortex-M System
+ * Design Kit Technical Reference Manual (ARM DDI0479C):
+ * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
+ *
+ * The hardware has an EXTIN input wire, which can be configured
+ * by the guest to act either as a 'timer enable' (timer does not run
+ * when EXTIN is low), or as a 'timer clock' (timer runs at frequency
+ * of EXTIN clock, not PCLK frequency). We don't model this.
+ *
+ * The documentation is not very clear about the exact behaviour;
+ * we choose to implement that the interrupt is triggered when
+ * the counter goes from 1 to 0, that the counter then holds at 0
+ * for one clock cycle before reloading from the RELOAD register,
+ * and that if the RELOAD register is 0 this does not cause an
+ * interrupt (as there is no further 1->0 transition).
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/main-loop.h"
+#include "qapi/error.h"
+#include "trace.h"
+#include "hw/sysbus.h"
+#include "hw/registerfields.h"
+#include "hw/timer/cmsdk-apb-timer.h"
+
+REG32(CTRL, 0)
+    FIELD(CTRL, EN, 0, 1)
+    FIELD(CTRL, SELEXTEN, 1, 1)
+    FIELD(CTRL, SELEXTCLK, 2, 1)
+    FIELD(CTRL, IRQEN, 3, 1)
+REG32(VALUE, 4)
+REG32(RELOAD, 8)
+REG32(INTSTATUS, 0xc)
+    FIELD(INTSTATUS, IRQ, 0, 1)
+REG32(PID4, 0xFD0)
+REG32(PID5, 0xFD4)
+REG32(PID6, 0xFD8)
+REG32(PID7, 0xFDC)
+REG32(PID0, 0xFE0)
+REG32(PID1, 0xFE4)
+REG32(PID2, 0xFE8)
+REG32(PID3, 0xFEC)
+REG32(CID0, 0xFF0)
+REG32(CID1, 0xFF4)
+REG32(CID2, 0xFF8)
+REG32(CID3, 0xFFC)
+
+/* PID/CID values */
+static const int timer_id[] = {
+    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
+    0x22, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
+    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
+};
+
+static void cmsdk_apb_timer_update(CMSDKAPBTIMER *s)
+{
+    qemu_set_irq(s->timerint, !!(s->intstatus & R_INTSTATUS_IRQ_MASK));
+}
+
+static uint64_t cmsdk_apb_timer_read(void *opaque, hwaddr offset, unsigned size)
+{
+    CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);
+    uint64_t r;
+
+    switch (offset) {
+    case A_CTRL:
+        r = s->ctrl;
+        break;
+    case A_VALUE:
+        r = ptimer_get_count(s->timer);
+        break;
+    case A_RELOAD:
+        r = ptimer_get_limit(s->timer);
+        break;
+    case A_INTSTATUS:
+        r = s->intstatus;
+        break;
+    case A_PID4 ... A_CID3:
+        r = timer_id[(offset - A_PID4) / 4];
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "CMSDK APB timer read: bad offset %x\n", (int) offset);
+        r = 0;
+        break;
+    }
+    trace_cmsdk_apb_timer_read(offset, r, size);
+    return r;
+}
+
+static void cmsdk_apb_timer_write(void *opaque, hwaddr offset, uint64_t value,
+                                  unsigned size)
+{
+    CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);
+
+    trace_cmsdk_apb_timer_write(offset, value, size);
+
+    switch (offset) {
+    case A_CTRL:
+        if (value & 6) {
+            /* Bits [1] and [2] enable using EXTIN as either clock or
+             * an enable line. We don't model this.
+             */
+            qemu_log_mask(LOG_UNIMP,
+                          "CMSDK APB timer: EXTIN input not supported\n");
+        }
+        s->ctrl = value & 0xf;
+        if (s->ctrl & R_CTRL_EN_MASK) {
+            ptimer_run(s->timer, 0);
+        } else {
+            ptimer_stop(s->timer);
+        }
+        break;
+    case A_RELOAD:
+        /* Writing to reload also sets the current timer value */
+        ptimer_set_limit(s->timer, value, 1);
+        break;
+    case A_VALUE:
+        ptimer_set_count(s->timer, value);
+        break;
+    case A_INTSTATUS:
+        /* Just one bit, which is W1C. */
+        value &= 1;
+        s->intstatus &= ~value;
+        cmsdk_apb_timer_update(s);
+        break;
+    case A_PID4 ... A_CID3:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "CMSDK APB timer write: write to RO offset 0x%x\n",
+                      (int)offset);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "CMSDK APB timer write: bad offset 0x%x\n", (int) offset);
+        break;
+    }
+}
+
+static const MemoryRegionOps cmsdk_apb_timer_ops = {
+    .read = cmsdk_apb_timer_read,
+    .write = cmsdk_apb_timer_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void cmsdk_apb_timer_tick(void *opaque)
+{
+    CMSDKAPBTIMER *s = CMSDK_APB_TIMER(opaque);
+
+    if (s->ctrl & R_CTRL_IRQEN_MASK) {
+        s->intstatus |= R_INTSTATUS_IRQ_MASK;
+        cmsdk_apb_timer_update(s);
+    }
+}
+
+static void cmsdk_apb_timer_reset(DeviceState *dev)
+{
+    CMSDKAPBTIMER *s = CMSDK_APB_TIMER(dev);
+
+    trace_cmsdk_apb_timer_reset();
+    s->ctrl = 0;
+    s->intstatus = 0;
+    ptimer_stop(s->timer);
+    /* Set the limit and the count */
+    ptimer_set_limit(s->timer, 0, 1);
+}
+
+static void cmsdk_apb_timer_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    CMSDKAPBTIMER *s = CMSDK_APB_TIMER(obj);
+
+    memory_region_init_io(&s->iomem, obj, &cmsdk_apb_timer_ops,
+                          s, "cmsdk-apb-timer", 0x1000);
+    sysbus_init_mmio(sbd, &s->iomem);
+    sysbus_init_irq(sbd, &s->timerint);
+}
+
+static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
+{
+    CMSDKAPBTIMER *s = CMSDK_APB_TIMER(dev);
+    QEMUBH *bh;
+
+    if (s->pclk_frq == 0) {
+        error_setg(errp, "CMSDK APB timer: pclk-frq property must be set");
+        return;
+    }
+
+    bh = qemu_bh_new(cmsdk_apb_timer_tick, s);
+    s->timer = ptimer_init(bh,
+                           PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD |
+                           PTIMER_POLICY_NO_IMMEDIATE_TRIGGER |
+                           PTIMER_POLICY_NO_IMMEDIATE_RELOAD |
+                           PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
+
+    ptimer_set_freq(s->timer, s->pclk_frq);
+}
+
+static const VMStateDescription cmsdk_apb_timer_vmstate = {
+    .name = "cmsdk-apb-timer",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_PTIMER(timer, CMSDKAPBTIMER),
+        VMSTATE_UINT32(ctrl, CMSDKAPBTIMER),
+        VMSTATE_UINT32(value, CMSDKAPBTIMER),
+        VMSTATE_UINT32(reload, CMSDKAPBTIMER),
+        VMSTATE_UINT32(intstatus, CMSDKAPBTIMER),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static Property cmsdk_apb_timer_properties[] = {
+    DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBTIMER, pclk_frq, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void cmsdk_apb_timer_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = cmsdk_apb_timer_realize;
+    dc->vmsd = &cmsdk_apb_timer_vmstate;
+    dc->reset = cmsdk_apb_timer_reset;
+    dc->props = cmsdk_apb_timer_properties;
+}
+
+static const TypeInfo cmsdk_apb_timer_info = {
+    .name = TYPE_CMSDK_APB_TIMER,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(CMSDKAPBTIMER),
+    .instance_init = cmsdk_apb_timer_init,
+    .class_init = cmsdk_apb_timer_class_init,
+};
+
+static void cmsdk_apb_timer_register_types(void)
+{
+    type_register_static(&cmsdk_apb_timer_info);
+}
+
+type_init(cmsdk_apb_timer_register_types);
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index d128e9d..c75f52c 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -96,6 +96,7 @@ CONFIG_STM32F2XX_ADC=y
 CONFIG_STM32F2XX_SPI=y
 CONFIG_STM32F205_SOC=y
 
+CONFIG_CMSDK_APB_TIMER=y
 CONFIG_CMSDK_APB_UART=y
 
 CONFIG_VERSATILE_PCI=y
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
index d17cfe6..fd8196b 100644
--- a/hw/timer/trace-events
+++ b/hw/timer/trace-events
@@ -55,3 +55,8 @@ systick_reload(void) "systick reload"
 systick_timer_tick(void) "systick reload"
 systick_read(uint64_t addr, uint32_t value, unsigned size) "systick read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
 systick_write(uint64_t addr, uint32_t value, unsigned size) "systick write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
+
+# hw/char/cmsdk_apb_timer.c
+cmsdk_apb_timer_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB timer read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+cmsdk_apb_timer_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB timer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+cmsdk_apb_timer_reset(void) "CMSDK APB timer: reset"
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 5/9] hw/arm/mps2: Add timers
  2017-07-14 10:51 [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours) Peter Maydell
                   ` (3 preceding siblings ...)
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 4/9] hw/char/cmsdk-apb-timer: Implement CMSDK APB timer device Peter Maydell
@ 2017-07-14 10:51 ` Peter Maydell
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 6/9] hw/misc/mps2_scc: Implement MPS2 Serial Communication Controller Peter Maydell
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Peter Maydell @ 2017-07-14 10:51 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: patches, Philippe Mathieu-Daudé, Alistair Francis

Add the CMSDK APB timers to the MPS2 board.

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

diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
index 180c5d2..0de0ffcb 100644
--- a/hw/arm/mps2.c
+++ b/hw/arm/mps2.c
@@ -33,6 +33,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/misc/unimp.h"
 #include "hw/char/cmsdk-apb-uart.h"
+#include "hw/timer/cmsdk-apb-timer.h"
 
 typedef enum MPS2FPGAType {
     FPGA_AN385,
@@ -292,6 +293,9 @@ static void mps2_common_init(MachineState *machine)
         g_assert_not_reached();
     }
 
+    cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
+    cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
+
     system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
 
     armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 6/9] hw/misc/mps2_scc: Implement MPS2 Serial Communication Controller
  2017-07-14 10:51 [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours) Peter Maydell
                   ` (4 preceding siblings ...)
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 5/9] hw/arm/mps2: Add timers Peter Maydell
@ 2017-07-14 10:51 ` Peter Maydell
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 7/9] hw/arm/mps2: Add SCC Peter Maydell
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Peter Maydell @ 2017-07-14 10:51 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: patches, Philippe Mathieu-Daudé, Alistair Francis

Implement a model of the Serial Communication Controller (SCC) found
in MPS2 FPGA images.

The primary purpose of this device is to communicate with the
Motherboard Configuration Controller (MCC) which is located on
the MPS board itself, outside the FPGA image. This is used
for programming the MPS clock generators. The SCC also has
some basic ID registers and an output for the board LEDs.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/misc/Makefile.objs           |   1 +
 include/hw/misc/mps2-scc.h      |  43 ++++++
 hw/misc/mps2-scc.c              | 310 ++++++++++++++++++++++++++++++++++++++++
 default-configs/arm-softmmu.mak |   2 +
 hw/misc/trace-events            |   8 ++
 5 files changed, 364 insertions(+)
 create mode 100644 include/hw/misc/mps2-scc.h
 create mode 100644 hw/misc/mps2-scc.c

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 7e373db..3b91d32 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -52,6 +52,7 @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
 obj-$(CONFIG_MIPS_CPS) += mips_cmgcr.o
 obj-$(CONFIG_MIPS_CPS) += mips_cpc.o
 obj-$(CONFIG_MIPS_ITU) += mips_itu.o
+obj-$(CONFIG_MPS2_SCC) += mps2-scc.o
 
 obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
new file mode 100644
index 0000000..7045473
--- /dev/null
+++ b/include/hw/misc/mps2-scc.h
@@ -0,0 +1,43 @@
+/*
+ * ARM MPS2 SCC emulation
+ *
+ * Copyright (c) 2017 Linaro Limited
+ * Written by Peter Maydell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 or
+ *  (at your option) any later version.
+ */
+
+#ifndef MPS2_SCC_H
+#define MPS2_SCC_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_MPS2_SCC "mps2-scc"
+#define MPS2_SCC(obj) OBJECT_CHECK(MPS2SCC, (obj), TYPE_MPS2_SCC)
+
+#define NUM_OSCCLK 3
+
+typedef struct {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    MemoryRegion iomem;
+
+    uint32_t cfg0;
+    uint32_t cfg1;
+    uint32_t cfg4;
+    uint32_t cfgdata_rtn;
+    uint32_t cfgdata_out;
+    uint32_t cfgctrl;
+    uint32_t cfgstat;
+    uint32_t dll;
+    uint32_t aid;
+    uint32_t id;
+    uint32_t oscclk[NUM_OSCCLK];
+    uint32_t oscclk_reset[NUM_OSCCLK];
+} MPS2SCC;
+
+#endif
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
new file mode 100644
index 0000000..cc58d26
--- /dev/null
+++ b/hw/misc/mps2-scc.c
@@ -0,0 +1,310 @@
+/*
+ * ARM MPS2 SCC emulation
+ *
+ * Copyright (c) 2017 Linaro Limited
+ * Written by Peter Maydell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 or
+ *  (at your option) any later version.
+ */
+
+/* This is a model of the SCC (Serial Communication Controller)
+ * found in the FPGA images of MPS2 development boards.
+ *
+ * Documentation of it can be found in the MPS2 TRM:
+ * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.100112_0100_03_en/index.html
+ * and also in the Application Notes documenting individual FPGA images.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "trace.h"
+#include "hw/sysbus.h"
+#include "hw/registerfields.h"
+#include "hw/misc/mps2-scc.h"
+
+REG32(CFG0, 0)
+REG32(CFG1, 4)
+REG32(CFG3, 0xc)
+REG32(CFG4, 0x10)
+REG32(CFGDATA_RTN, 0xa0)
+REG32(CFGDATA_OUT, 0xa4)
+REG32(CFGCTRL, 0xa8)
+    FIELD(CFGCTRL, DEVICE, 0, 12)
+    FIELD(CFGCTRL, RES1, 12, 8)
+    FIELD(CFGCTRL, FUNCTION, 20, 6)
+    FIELD(CFGCTRL, RES2, 26, 4)
+    FIELD(CFGCTRL, WRITE, 30, 1)
+    FIELD(CFGCTRL, START, 31, 1)
+REG32(CFGSTAT, 0xac)
+    FIELD(CFGSTAT, DONE, 0, 1)
+    FIELD(CFGSTAT, ERROR, 1, 1)
+REG32(DLL, 0x100)
+REG32(AID, 0xFF8)
+REG32(ID, 0xFFC)
+
+/* Handle a write via the SYS_CFG channel to the specified function/device.
+ * Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
+ */
+static bool scc_cfg_write(MPS2SCC *s, unsigned function,
+                          unsigned device, uint32_t value)
+{
+    trace_mps2_scc_cfg_write(function, device, value);
+
+    if (function != 1 || device >= NUM_OSCCLK) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "MPS2 SCC config write: bad function %d device %d\n",
+                      function, device);
+        return false;
+    }
+
+    s->oscclk[device] = value;
+    return true;
+}
+
+/* Handle a read via the SYS_CFG channel to the specified function/device.
+ * Return false on error (reported to guest via SYS_CFGCTRL ERROR bit),
+ * or set *value on success.
+ */
+static bool scc_cfg_read(MPS2SCC *s, unsigned function,
+                         unsigned device, uint32_t *value)
+{
+    if (function != 1 || device >= NUM_OSCCLK) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "MPS2 SCC config read: bad function %d device %d\n",
+                      function, device);
+        return false;
+    }
+
+    *value = s->oscclk[device];
+
+    trace_mps2_scc_cfg_read(function, device, *value);
+    return true;
+}
+
+static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
+{
+    MPS2SCC *s = MPS2_SCC(opaque);
+    uint64_t r;
+
+    switch (offset) {
+    case A_CFG0:
+        r = s->cfg0;
+        break;
+    case A_CFG1:
+        r = s->cfg1;
+        break;
+    case A_CFG3:
+        /* These are user-settable DIP switches on the board. We don't
+         * model that, so just return zeroes.
+         */
+        r = 0;
+        break;
+    case A_CFG4:
+        r = s->cfg4;
+        break;
+    case A_CFGDATA_RTN:
+        r = s->cfgdata_rtn;
+        break;
+    case A_CFGDATA_OUT:
+        r = s->cfgdata_out;
+        break;
+    case A_CFGCTRL:
+        r = s->cfgctrl;
+        break;
+    case A_CFGSTAT:
+        r = s->cfgstat;
+        break;
+    case A_DLL:
+        r = s->dll;
+        break;
+    case A_AID:
+        r = s->aid;
+        break;
+    case A_ID:
+        r = s->id;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "MPS2 SCC read: bad offset %x\n", (int) offset);
+        r = 0;
+        break;
+    }
+
+    trace_mps2_scc_read(offset, r, size);
+    return r;
+}
+
+static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
+                           unsigned size)
+{
+    MPS2SCC *s = MPS2_SCC(opaque);
+
+    trace_mps2_scc_write(offset, value, size);
+
+    switch (offset) {
+    case A_CFG0:
+        /* TODO on some boards bit 0 controls RAM remapping */
+        s->cfg0 = value;
+        break;
+    case A_CFG1:
+        /* CFG1 bits [7:0] control the board LEDs. We don't currently have
+         * a mechanism for displaying this graphically, so use a trace event.
+         */
+        trace_mps2_scc_leds(value & 0x80 ? '*' : '.',
+                            value & 0x40 ? '*' : '.',
+                            value & 0x20 ? '*' : '.',
+                            value & 0x10 ? '*' : '.',
+                            value & 0x08 ? '*' : '.',
+                            value & 0x04 ? '*' : '.',
+                            value & 0x02 ? '*' : '.',
+                            value & 0x01 ? '*' : '.');
+        s->cfg1 = value;
+        break;
+    case A_CFGDATA_OUT:
+        s->cfgdata_out = value;
+        break;
+    case A_CFGCTRL:
+        /* Writing to CFGCTRL clears SYS_CFGSTAT */
+        s->cfgstat = 0;
+        s->cfgctrl = value & ~(R_CFGCTRL_RES1_MASK |
+                               R_CFGCTRL_RES2_MASK |
+                               R_CFGCTRL_START_MASK);
+
+        if (value & R_CFGCTRL_START_MASK) {
+            /* Start bit set -- do a read or write (instantaneously) */
+            int device = extract32(s->cfgctrl, R_CFGCTRL_DEVICE_SHIFT,
+                                   R_CFGCTRL_DEVICE_LENGTH);
+            int function = extract32(s->cfgctrl, R_CFGCTRL_FUNCTION_SHIFT,
+                                     R_CFGCTRL_FUNCTION_LENGTH);
+
+            s->cfgstat = R_CFGSTAT_DONE_MASK;
+            if (s->cfgctrl & R_CFGCTRL_WRITE_MASK) {
+                if (!scc_cfg_write(s, function, device, s->cfgdata_out)) {
+                    s->cfgstat |= R_CFGSTAT_ERROR_MASK;
+                }
+            } else {
+                uint32_t result;
+                if (!scc_cfg_read(s, function, device, &result)) {
+                    s->cfgstat |= R_CFGSTAT_ERROR_MASK;
+                } else {
+                    s->cfgdata_rtn = result;
+                }
+            }
+        }
+        break;
+    case A_DLL:
+        /* DLL stands for Digital Locked Loop.
+         * Bits [31:24] (DLL_LOCK_MASK) are writable, and indicate a
+         * mask of which of the DLL_LOCKED bits [16:23] should be ORed
+         * together to determine the ALL_UNMASKED_DLLS_LOCKED bit [0].
+         * For QEMU, our DLLs are always locked, so we can leave bit 0
+         * as 1 always and don't need to recalculate it.
+         */
+        s->dll = deposit32(s->dll, 24, 8, extract32(value, 24, 8));
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "MPS2 SCC write: bad offset 0x%x\n", (int) offset);
+        break;
+    }
+}
+
+static const MemoryRegionOps mps2_scc_ops = {
+    .read = mps2_scc_read,
+    .write = mps2_scc_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void mps2_scc_reset(DeviceState *dev)
+{
+    MPS2SCC *s = MPS2_SCC(dev);
+    int i;
+
+    trace_mps2_scc_reset();
+    s->cfg0 = 0;
+    s->cfg1 = 0;
+    s->cfgdata_rtn = 0;
+    s->cfgdata_out = 0;
+    s->cfgctrl = 0x100000;
+    s->cfgstat = 0;
+    s->dll = 0xffff0001;
+    for (i = 0; i < NUM_OSCCLK; i++) {
+        s->oscclk[i] = s->oscclk_reset[i];
+    }
+}
+
+static void mps2_scc_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    MPS2SCC *s = MPS2_SCC(obj);
+
+    memory_region_init_io(&s->iomem, obj, &mps2_scc_ops, s, "mps2-scc", 0x1000);
+    sysbus_init_mmio(sbd, &s->iomem);
+}
+
+static void mps2_scc_realize(DeviceState *dev, Error **errp)
+{
+}
+
+static const VMStateDescription mps2_scc_vmstate = {
+    .name = "mps2-scc",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(cfg0, MPS2SCC),
+        VMSTATE_UINT32(cfg1, MPS2SCC),
+        VMSTATE_UINT32(cfgdata_rtn, MPS2SCC),
+        VMSTATE_UINT32(cfgdata_out, MPS2SCC),
+        VMSTATE_UINT32(cfgctrl, MPS2SCC),
+        VMSTATE_UINT32(cfgstat, MPS2SCC),
+        VMSTATE_UINT32(dll, MPS2SCC),
+        VMSTATE_UINT32_ARRAY(oscclk, MPS2SCC, NUM_OSCCLK),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static Property mps2_scc_properties[] = {
+    /* Values for various read-only ID registers (which are specific
+     * to the board model or FPGA image)
+     */
+    DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, aid, 0),
+    DEFINE_PROP_UINT32("scc-aid", MPS2SCC, aid, 0),
+    DEFINE_PROP_UINT32("scc-id", MPS2SCC, aid, 0),
+    /* These are the initial settings for the source clocks on the board.
+     * In hardware they can be configured via a config file read by the
+     * motherboard configuration controller to suit the FPGA image.
+     * These default values are used by most of the standard FPGA images.
+     */
+    DEFINE_PROP_UINT32("oscclk0", MPS2SCC, oscclk_reset[0], 50000000),
+    DEFINE_PROP_UINT32("oscclk1", MPS2SCC, oscclk_reset[1], 24576000),
+    DEFINE_PROP_UINT32("oscclk2", MPS2SCC, oscclk_reset[2], 25000000),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void mps2_scc_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = mps2_scc_realize;
+    dc->vmsd = &mps2_scc_vmstate;
+    dc->reset = mps2_scc_reset;
+    dc->props = mps2_scc_properties;
+}
+
+static const TypeInfo mps2_scc_info = {
+    .name = TYPE_MPS2_SCC,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MPS2SCC),
+    .instance_init = mps2_scc_init,
+    .class_init = mps2_scc_class_init,
+};
+
+static void mps2_scc_register_types(void)
+{
+    type_register_static(&mps2_scc_info);
+}
+
+type_init(mps2_scc_register_types);
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index c75f52c..bbdd3c1 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -99,6 +99,8 @@ CONFIG_STM32F205_SOC=y
 CONFIG_CMSDK_APB_TIMER=y
 CONFIG_CMSDK_APB_UART=y
 
+CONFIG_MPS2_SCC=y
+
 CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
 
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 0cc556c..28b8cd1 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -53,3 +53,11 @@ milkymist_pfpu_pulse_irq(void) "Pulse IRQ"
 
 # hw/misc/aspeed_scu.c
 aspeed_scu_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
+
+# hw/misc/mps2_scc.c
+mps2_scc_read(uint64_t offset, uint64_t data, unsigned size) "MPS2 SCC read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+mps2_scc_write(uint64_t offset, uint64_t data, unsigned size) "MPS2 SCC write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+mps2_scc_reset(void) "MPS2 SCC: reset"
+mps2_scc_leds(char led7, char led6, char led5, char led4, char led3, char led2, char led1, char led0) "MPS2 SCC LEDs: %c%c%c%c%c%c%c%c"
+mps2_scc_cfg_write(unsigned function, unsigned device, uint32_t value) "MPS2 SCC config write: function %d device %d data 0x%" PRIx32
+mps2_scc_cfg_read(unsigned function, unsigned device, uint32_t value) "MPS2 SCC config read: function %d device %d data 0x%" PRIx32
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 7/9] hw/arm/mps2: Add SCC
  2017-07-14 10:51 [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours) Peter Maydell
                   ` (5 preceding siblings ...)
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 6/9] hw/misc/mps2_scc: Implement MPS2 Serial Communication Controller Peter Maydell
@ 2017-07-14 10:51 ` Peter Maydell
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 8/9] hw/arm/mps2: Add ethernet Peter Maydell
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Peter Maydell @ 2017-07-14 10:51 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: patches, Philippe Mathieu-Daudé, Alistair Francis

Add the SCC to the MPS2 board models.

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

diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
index 0de0ffcb..bdc631a 100644
--- a/hw/arm/mps2.c
+++ b/hw/arm/mps2.c
@@ -34,6 +34,7 @@
 #include "hw/misc/unimp.h"
 #include "hw/char/cmsdk-apb-uart.h"
 #include "hw/timer/cmsdk-apb-timer.h"
+#include "hw/misc/mps2-scc.h"
 
 typedef enum MPS2FPGAType {
     FPGA_AN385,
@@ -44,6 +45,7 @@ typedef struct {
     MachineClass parent;
     MPS2FPGAType fpga_type;
     const char *cpu_model;
+    uint32_t scc_id;
 } MPS2MachineClass;
 
 typedef struct {
@@ -60,6 +62,7 @@ typedef struct {
     MemoryRegion blockram_m2;
     MemoryRegion blockram_m3;
     MemoryRegion sram;
+    MPS2SCC scc;
 } MPS2MachineState;
 
 #define TYPE_MPS2_MACHINE "mps2"
@@ -103,7 +106,7 @@ static void mps2_common_init(MachineState *machine)
     MPS2MachineState *mms = MPS2_MACHINE(machine);
     MPS2MachineClass *mmc = MPS2_MACHINE_GET_CLASS(machine);
     MemoryRegion *system_memory = get_system_memory();
-    DeviceState *armv7m;
+    DeviceState *armv7m, *sccdev;
 
     if (!machine->cpu_model) {
         machine->cpu_model = mmc->cpu_model;
@@ -296,6 +299,16 @@ static void mps2_common_init(MachineState *machine)
     cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
     cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
 
+    object_initialize(&mms->scc, sizeof(mms->scc), TYPE_MPS2_SCC);
+    sccdev = DEVICE(&mms->scc);
+    qdev_set_parent_bus(armv7m, sysbus_get_default());
+    qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
+    qdev_prop_set_uint32(sccdev, "scc-aid", 0x02000008);
+    qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
+    object_property_set_bool(OBJECT(&mms->scc), true, "realized",
+                             &error_fatal);
+    sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
+
     system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
 
     armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
@@ -318,6 +331,7 @@ static void mps2_an385_class_init(ObjectClass *oc, void *data)
     mc->desc = "ARM MPS2 with AN385 FPGA image for Cortex-M3";
     mmc->fpga_type = FPGA_AN385;
     mmc->cpu_model = "cortex-m3";
+    mmc->scc_id = 0x41040000 | (385 << 4);
 }
 
 static void mps2_an511_class_init(ObjectClass *oc, void *data)
@@ -328,6 +342,7 @@ static void mps2_an511_class_init(ObjectClass *oc, void *data)
     mc->desc = "ARM MPS2 with AN511 DesignStart FPGA image for Cortex-M3";
     mmc->fpga_type = FPGA_AN511;
     mmc->cpu_model = "cortex-m3";
+    mmc->scc_id = 0x4104000 | (511 << 4);
 }
 
 static const TypeInfo mps2_info = {
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 8/9] hw/arm/mps2: Add ethernet
  2017-07-14 10:51 [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours) Peter Maydell
                   ` (6 preceding siblings ...)
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 7/9] hw/arm/mps2: Add SCC Peter Maydell
@ 2017-07-14 10:51 ` Peter Maydell
  2017-07-14 16:17   ` [Qemu-devel] [Qemu-arm] " Alex Bennée
  2017-07-14 16:23   ` [Qemu-devel] " Philippe Mathieu-Daudé
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 9/9] MAINTAINERS: Add entries for MPS2 board Peter Maydell
                   ` (2 subsequent siblings)
  10 siblings, 2 replies; 26+ messages in thread
From: Peter Maydell @ 2017-07-14 10:51 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: patches, Philippe Mathieu-Daudé, Alistair Francis

The MPS2 FPGA images support ethernet via a LAN9220. We use
QEMU's LAN9118 model, which is software compatible except
that it is missing the checksum-offload feature.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/mps2.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
index bdc631a..6adfb22 100644
--- a/hw/arm/mps2.c
+++ b/hw/arm/mps2.c
@@ -35,6 +35,8 @@
 #include "hw/char/cmsdk-apb-uart.h"
 #include "hw/timer/cmsdk-apb-timer.h"
 #include "hw/misc/mps2-scc.h"
+#include "hw/devices.h"
+#include "net/net.h"
 
 typedef enum MPS2FPGAType {
     FPGA_AN385,
@@ -210,7 +212,6 @@ static void mps2_common_init(MachineState *machine)
     create_unimplemented_device("Extra peripheral region @0x40020000",
                                 0x40020000, 0x00010000);
     create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
-    create_unimplemented_device("Ethernet", 0x40200000, 0x00100000);
     create_unimplemented_device("VGA", 0x41000000, 0x0200000);
 
     switch (mmc->fpga_type) {
@@ -309,6 +310,13 @@ static void mps2_common_init(MachineState *machine)
                              &error_fatal);
     sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
 
+    /* In hardware this is a LAN9220; the LAN9118 is software compatible
+     * except that it doesn't support the checksum-offload feature.
+     */
+    lan9118_init(&nd_table[0], 0x40200000,
+                 qdev_get_gpio_in(armv7m,
+                                  mmc->fpga_type == FPGA_AN385 ? 13 : 47));
+
     system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
 
     armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 9/9] MAINTAINERS: Add entries for MPS2 board
  2017-07-14 10:51 [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours) Peter Maydell
                   ` (7 preceding siblings ...)
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 8/9] hw/arm/mps2: Add ethernet Peter Maydell
@ 2017-07-14 10:51 ` Peter Maydell
  2017-07-14 16:18   ` [Qemu-devel] [Qemu-arm] " Alex Bennée
  2017-07-14 16:24   ` [Qemu-devel] " Philippe Mathieu-Daudé
  2017-07-14 12:16 ` [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours) no-reply
  2017-07-14 16:08 ` no-reply
  10 siblings, 2 replies; 26+ messages in thread
From: Peter Maydell @ 2017-07-14 10:51 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: patches, Philippe Mathieu-Daudé, Alistair Francis

Add entries to the MAINTAINERS file for the new MPS2
board and devices.

Since the CMSDK devices are not specific to the MPS2 board,
extend the existing 'PrimeCell' section to cover CMSDK
devices as well; in both cases these are devices implemented
by ARM and provided as RTL that may be used in multiple
SoCs and boards.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 MAINTAINERS | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9529c94..10f5cd6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -380,7 +380,7 @@ F: hw/*/allwinner*
 F: include/hw/*/allwinner*
 F: hw/arm/cubieboard.c
 
-ARM PrimeCell
+ARM PrimeCell and CMSDK devices
 M: Peter Maydell <peter.maydell@linaro.org>
 L: qemu-arm@nongnu.org
 S: Maintained
@@ -394,6 +394,10 @@ F: hw/intc/pl190.c
 F: hw/sd/pl181.c
 F: hw/timer/pl031.c
 F: include/hw/arm/primecell.h
+F: hw/timer/cmsdk-apb-timer.c
+F: include/hw/timer/cmsdk-apb-timer.h
+F: hw/char/cmsdk-apb-uart.c
+F: include/hw/char/cmsdk-apb-uart.h
 
 ARM cores
 M: Peter Maydell <peter.maydell@linaro.org>
@@ -455,6 +459,14 @@ S: Maintained
 F: hw/arm/integratorcp.c
 F: hw/misc/arm_integrator_debug.c
 
+MPS2
+M: Peter Maydell <peter.maydell@linaro.org>
+L: qemu-arm@nongnu.org
+S: Maintained
+F: hw/arm/mps2.c
+F: hw/misc/mps2-scc.c
+F: include/hw/misc/mps2-scc.h
+
 Musicpal
 M: Jan Kiszka <jan.kiszka@web.de>
 L: qemu-arm@nongnu.org
-- 
2.7.4

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

* Re: [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours)
  2017-07-14 10:51 [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours) Peter Maydell
                   ` (8 preceding siblings ...)
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 9/9] MAINTAINERS: Add entries for MPS2 board Peter Maydell
@ 2017-07-14 12:16 ` no-reply
  2017-07-14 16:08 ` no-reply
  10 siblings, 0 replies; 26+ messages in thread
From: no-reply @ 2017-07-14 12:16 UTC (permalink / raw)
  To: peter.maydell
  Cc: famz, qemu-arm, qemu-devel, alistair.francis, f4bug, patches

Hi,

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

Type: series
Message-id: 1500029487-14822-1-git-send-email-peter.maydell@linaro.org
Subject: [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours)

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

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

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

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

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
f3b7511 MAINTAINERS: Add entries for MPS2 board
7b2658f hw/arm/mps2: Add ethernet
62c2290 hw/arm/mps2: Add SCC
ef531fe hw/misc/mps2_scc: Implement MPS2 Serial Communication Controller
1410c25 hw/arm/mps2: Add timers
be73385 hw/char/cmsdk-apb-timer: Implement CMSDK APB timer device
fe7d5af hw/arm/mps2: Add UARTs
d9f622a hw/char/cmsdk-apb-uart.c: Implement CMSDK APB UART
1d6f3c6 hw/arm/mps2: Implement skeleton mps2-an385 and mps2-an511 board models

=== OUTPUT BEGIN ===
Checking PATCH 1/9: hw/arm/mps2: Implement skeleton mps2-an385 and mps2-an511 board models...
ERROR: line over 90 characters
#72: FILE: hw/arm/mps2.c:22:
+ *   https://developer.arm.com/products/system-design/development-boards/cortex-m-prototyping-system

total: 1 errors, 0 warnings, 282 lines checked

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

Checking PATCH 2/9: hw/char/cmsdk-apb-uart.c: Implement CMSDK APB UART...
ERROR: line over 90 characters
#57: FILE: hw/char/cmsdk-apb-uart.c:15:
+ * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit

total: 1 errors, 0 warnings, 507 lines checked

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

Checking PATCH 3/9: hw/arm/mps2: Add UARTs...
Checking PATCH 4/9: hw/char/cmsdk-apb-timer: Implement CMSDK APB timer device...
ERROR: line over 90 characters
#56: FILE: hw/timer/cmsdk-apb-timer.c:15:
+ * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit

total: 1 errors, 0 warnings, 331 lines checked

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

Checking PATCH 5/9: hw/arm/mps2: Add timers...
Checking PATCH 6/9: hw/misc/mps2_scc: Implement MPS2 Serial Communication Controller...
ERROR: line over 90 characters
#69: FILE: hw/misc/mps2-scc.c:16:
+ * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.100112_0100_03_en/index.html

ERROR: spaces required around that '*' (ctx:WxV)
#104: FILE: hw/misc/mps2-scc.c:51:
+static bool scc_cfg_write(MPS2SCC *s, unsigned function,
                                   ^

total: 2 errors, 0 warnings, 379 lines checked

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

Checking PATCH 7/9: hw/arm/mps2: Add SCC...
Checking PATCH 8/9: hw/arm/mps2: Add ethernet...
Checking PATCH 9/9: MAINTAINERS: Add entries for MPS2 board...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH v2 1/9] hw/arm/mps2: Implement skeleton mps2-an385 and mps2-an511 board models
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 1/9] hw/arm/mps2: Implement skeleton mps2-an385 and mps2-an511 board models Peter Maydell
@ 2017-07-14 14:44   ` Alex Bennée
  0 siblings, 0 replies; 26+ messages in thread
From: Alex Bennée @ 2017-07-14 14:44 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-arm, qemu-devel, Alistair Francis,
	Philippe Mathieu-Daudé,
	patches


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

> Model the ARM MPS2/MPS2+ FPGA based development board.
>
> The MPS2 and MPS2+ dev boards are FPGA based (the 2+ has a bigger
> FPGA but is otherwise the same as the 2). Since the CPU itself
> and most of the devices are in the FPGA, the details of the board
> as seen by the guest depend significantly on the FPGA image.
>
> We model the following FPGA images:
>  "mps2_an385" -- Cortex-M3 as documented in ARM Application Note AN385
>  "mps2_an511" -- Cortex-M3 'DesignStart' as documented in AN511
>
> They are fairly similar but differ in the details for some
> peripherals.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>


> ---
>  hw/arm/Makefile.objs            |   1 +
>  hw/arm/mps2.c                   | 271 ++++++++++++++++++++++++++++++++++++++++
>  default-configs/arm-softmmu.mak |   1 +
>  3 files changed, 273 insertions(+)
>  create mode 100644 hw/arm/mps2.c
>
> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
> index 4c5c4ee..a2e56ec 100644
> --- a/hw/arm/Makefile.objs
> +++ b/hw/arm/Makefile.objs
> @@ -18,3 +18,4 @@ obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
>  obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
>  obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
>  obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
> +obj-$(CONFIG_MPS2) += mps2.o
> diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
> new file mode 100644
> index 0000000..3dad02d
> --- /dev/null
> +++ b/hw/arm/mps2.c
> @@ -0,0 +1,271 @@
> +/*
> + * ARM V2M MPS2 board emulation.
> + *
> + * Copyright (c) 2017 Linaro Limited
> + * Written by Peter Maydell
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2 or
> + *  (at your option) any later version.
> + */
> +
> +/* The MPS2 and MPS2+ dev boards are FPGA based (the 2+ has a bigger
> + * FPGA but is otherwise the same as the 2). Since the CPU itself
> + * and most of the devices are in the FPGA, the details of the board
> + * as seen by the guest depend significantly on the FPGA image.
> + * We model the following FPGA images:
> + *  "mps2-an385" -- Cortex-M3 as documented in ARM Application Note AN385
> + *  "mps2-an511" -- Cortex-M3 'DesignStart' as documented in AN511
> + *
> + * Links to the TRM for the board itself and to the various Application
> + * Notes which document the FPGA images can be found here:
> + *   https://developer.arm.com/products/system-design/development-boards/cortex-m-prototyping-system
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "qemu/error-report.h"
> +#include "hw/arm/arm.h"
> +#include "hw/arm/armv7m.h"
> +#include "hw/boards.h"
> +#include "exec/address-spaces.h"
> +#include "hw/misc/unimp.h"
> +
> +typedef enum MPS2FPGAType {
> +    FPGA_AN385,
> +    FPGA_AN511,
> +} MPS2FPGAType;
> +
> +typedef struct {
> +    MachineClass parent;
> +    MPS2FPGAType fpga_type;
> +    const char *cpu_model;
> +} MPS2MachineClass;
> +
> +typedef struct {
> +    MachineState parent;
> +
> +    ARMv7MState armv7m;
> +    MemoryRegion psram;
> +    MemoryRegion ssram1;
> +    MemoryRegion ssram1_m;
> +    MemoryRegion ssram23;
> +    MemoryRegion ssram23_m;
> +    MemoryRegion blockram;
> +    MemoryRegion blockram_m1;
> +    MemoryRegion blockram_m2;
> +    MemoryRegion blockram_m3;
> +    MemoryRegion sram;
> +} MPS2MachineState;
> +
> +#define TYPE_MPS2_MACHINE "mps2"
> +#define TYPE_MPS2_AN385_MACHINE MACHINE_TYPE_NAME("mps2-an385")
> +#define TYPE_MPS2_AN511_MACHINE MACHINE_TYPE_NAME("mps2-an511")
> +
> +#define MPS2_MACHINE(obj)                                       \
> +    OBJECT_CHECK(MPS2MachineState, obj, TYPE_MPS2_MACHINE)
> +#define MPS2_MACHINE_GET_CLASS(obj) \
> +    OBJECT_GET_CLASS(MPS2MachineClass, obj, TYPE_MPS2_MACHINE)
> +#define MPS2_MACHINE_CLASS(klass) \
> +    OBJECT_CLASS_CHECK(MPS2MachineClass, klass, TYPE_MPS2_MACHINE)
> +
> +/* Main SYSCLK frequency in Hz */
> +#define SYSCLK_FRQ 25000000
> +
> +/* Initialize the auxiliary RAM region @mr and map it into
> + * the memory map at @base.
> + */
> +static void make_ram(MemoryRegion *mr, const char *name,
> +                     hwaddr base, hwaddr size)
> +{
> +    memory_region_init_ram(mr, NULL, name, size, &error_fatal);
> +    vmstate_register_ram_global(mr);
> +    memory_region_add_subregion(get_system_memory(), base, mr);
> +}
> +
> +/* Create an alias of an entire original MemoryRegion @orig
> + * located at @base in the memory map.
> + */
> +static void make_ram_alias(MemoryRegion *mr, const char *name,
> +                           MemoryRegion *orig, hwaddr base)
> +{
> +    memory_region_init_alias(mr, NULL, name, orig, 0,
> +                             memory_region_size(orig));
> +    memory_region_add_subregion(get_system_memory(), base, mr);
> +}
> +
> +static void mps2_common_init(MachineState *machine)
> +{
> +    MPS2MachineState *mms = MPS2_MACHINE(machine);
> +    MPS2MachineClass *mmc = MPS2_MACHINE_GET_CLASS(machine);
> +    MemoryRegion *system_memory = get_system_memory();
> +    DeviceState *armv7m;
> +
> +    if (!machine->cpu_model) {
> +        machine->cpu_model = mmc->cpu_model;
> +    }
> +
> +    if (strcmp(machine->cpu_model, mmc->cpu_model) != 0) {
> +        error_report("This board can only be used with CPU %s", mmc->cpu_model);
> +        exit(1);
> +    }
> +
> +    /* The FPGA images have an odd combination of different RAMs,
> +     * because in hardware they are different implementations and
> +     * connected to different buses, giving varying performance/size
> +     * tradeoffs. For QEMU they're all just RAM, though. We arbitrarily
> +     * call the 16MB our "system memory", as it's the largest lump.
> +     *
> +     * Common to both boards:
> +     *  0x21000000..0x21ffffff : PSRAM (16MB)
> +     * AN385 only:
> +     *  0x00000000 .. 0x003fffff : ZBT SSRAM1
> +     *  0x00400000 .. 0x007fffff : mirror of ZBT SSRAM1
> +     *  0x20000000 .. 0x203fffff : ZBT SSRAM 2&3
> +     *  0x20400000 .. 0x207fffff : mirror of ZBT SSRAM 2&3
> +     *  0x01000000 .. 0x01003fff : block RAM (16K)
> +     *  0x01004000 .. 0x01007fff : mirror of above
> +     *  0x01008000 .. 0x0100bfff : mirror of above
> +     *  0x0100c000 .. 0x0100ffff : mirror of above
> +     * AN511 only:
> +     *  0x00000000 .. 0x0003ffff : FPGA block RAM
> +     *  0x00400000 .. 0x007fffff : ZBT SSRAM1
> +     *  0x20000000 .. 0x2001ffff : SRAM
> +     *  0x20400000 .. 0x207fffff : ZBT SSRAM 2&3
> +     *
> +     * The AN385 has a feature where the lowest 16K can be mapped
> +     * either to the bottom of the ZBT SSRAM1 or to the block RAM.
> +     * This is of no use for QEMU so we don't implement it (as if
> +     * zbt_boot_ctrl is always zero).
> +     */
> +    memory_region_allocate_system_memory(&mms->psram,
> +                                         NULL, "mps.ram", 0x1000000);
> +    memory_region_add_subregion(system_memory, 0x21000000, &mms->psram);
> +
> +    switch (mmc->fpga_type) {
> +    case FPGA_AN385:
> +        make_ram(&mms->ssram1, "mps.ssram1", 0x0, 0x400000);
> +        make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", &mms->ssram1, 0x400000);
> +        make_ram(&mms->ssram23, "mps.ssram23", 0x20000000, 0x400000);
> +        make_ram_alias(&mms->ssram23_m, "mps.ssram23_m",
> +                       &mms->ssram23, 0x20400000);
> +        make_ram(&mms->blockram, "mps.blockram", 0x01000000, 0x4000);
> +        make_ram_alias(&mms->blockram_m1, "mps.blockram_m1",
> +                       &mms->blockram, 0x01004000);
> +        make_ram_alias(&mms->blockram_m2, "mps.blockram_m2",
> +                       &mms->blockram, 0x01008000);
> +        make_ram_alias(&mms->blockram_m3, "mps.blockram_m3",
> +                       &mms->blockram, 0x0100c000);
> +        break;
> +    case FPGA_AN511:
> +        make_ram(&mms->blockram, "mps.blockram", 0x0, 0x40000);
> +        make_ram(&mms->ssram1, "mps.ssram1", 0x00400000, 0x00800000);
> +        make_ram(&mms->sram, "mps.sram", 0x20000000, 0x20000);
> +        make_ram(&mms->ssram23, "mps.ssram23", 0x20400000, 0x400000);
> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }
> +
> +    object_initialize(&mms->armv7m, sizeof(mms->armv7m), TYPE_ARMV7M);
> +    armv7m = DEVICE(&mms->armv7m);
> +    qdev_set_parent_bus(armv7m, sysbus_get_default());
> +    switch (mmc->fpga_type) {
> +    case FPGA_AN385:
> +        qdev_prop_set_uint32(armv7m, "num-irq", 32);
> +        break;
> +    case FPGA_AN511:
> +        qdev_prop_set_uint32(armv7m, "num-irq", 64);
> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }
> +    qdev_prop_set_string(armv7m, "cpu-model", machine->cpu_model);
> +    object_property_set_link(OBJECT(&mms->armv7m), OBJECT(system_memory),
> +                             "memory", &error_abort);
> +    object_property_set_bool(OBJECT(&mms->armv7m), true, "realized",
> +                             &error_fatal);
> +
> +    create_unimplemented_device("zbtsmram mirror", 0x00400000, 0x00400000);
> +    create_unimplemented_device("RESERVED 1", 0x00800000, 0x00800000);
> +    create_unimplemented_device("Block RAM", 0x01000000, 0x00010000);
> +    create_unimplemented_device("RESERVED 2", 0x01010000, 0x1EFF0000);
> +    create_unimplemented_device("RESERVED 3", 0x20800000, 0x00800000);
> +    create_unimplemented_device("PSRAM", 0x21000000, 0x01000000);
> +    /* These three ranges all cover multiple devices; we may implement
> +     * some of them below (in which case the real device takes precedence
> +     * over the unimplemented-region mapping).
> +     */
> +    create_unimplemented_device("CMSDK APB peripheral region @0x40000000",
> +                                0x40000000, 0x00010000);
> +    create_unimplemented_device("CMSDK peripheral region @0x40010000",
> +                                0x40010000, 0x00010000);
> +    create_unimplemented_device("Extra peripheral region @0x40020000",
> +                                0x40020000, 0x00010000);
> +    create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
> +    create_unimplemented_device("Ethernet", 0x40200000, 0x00100000);
> +    create_unimplemented_device("VGA", 0x41000000, 0x0200000);
> +
> +    system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
> +
> +    armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
> +                       0x400000);
> +}
> +
> +static void mps2_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +
> +    mc->init = mps2_common_init;
> +    mc->max_cpus = 1;
> +}
> +
> +static void mps2_an385_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
> +
> +    mc->desc = "ARM MPS2 with AN385 FPGA image for Cortex-M3";
> +    mmc->fpga_type = FPGA_AN385;
> +    mmc->cpu_model = "cortex-m3";
> +}
> +
> +static void mps2_an511_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
> +
> +    mc->desc = "ARM MPS2 with AN511 DesignStart FPGA image for Cortex-M3";
> +    mmc->fpga_type = FPGA_AN511;
> +    mmc->cpu_model = "cortex-m3";
> +}
> +
> +static const TypeInfo mps2_info = {
> +    .name = TYPE_MPS2_MACHINE,
> +    .parent = TYPE_MACHINE,
> +    .abstract = true,
> +    .instance_size = sizeof(MPS2MachineState),
> +    .class_size = sizeof(MPS2MachineClass),
> +    .class_init = mps2_class_init,
> +};
> +
> +static const TypeInfo mps2_an385_info = {
> +    .name = TYPE_MPS2_AN385_MACHINE,
> +    .parent = TYPE_MPS2_MACHINE,
> +    .class_init = mps2_an385_class_init,
> +};
> +
> +static const TypeInfo mps2_an511_info = {
> +    .name = TYPE_MPS2_AN511_MACHINE,
> +    .parent = TYPE_MPS2_MACHINE,
> +    .class_init = mps2_an511_class_init,
> +};
> +
> +static void mps2_machine_init(void)
> +{
> +    type_register_static(&mps2_info);
> +    type_register_static(&mps2_an385_info);
> +    type_register_static(&mps2_an511_info);
> +}
> +
> +type_init(mps2_machine_init);
> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
> index 93e995d..bfd2a88 100644
> --- a/default-configs/arm-softmmu.mak
> +++ b/default-configs/arm-softmmu.mak
> @@ -83,6 +83,7 @@ CONFIG_ONENAND=y
>  CONFIG_TUSB6010=y
>  CONFIG_IMX=y
>  CONFIG_MAINSTONE=y
> +CONFIG_MPS2=y
>  CONFIG_NSERIES=y
>  CONFIG_RASPI=y
>  CONFIG_REALVIEW=y


--
Alex Bennée

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH v2 2/9] hw/char/cmsdk-apb-uart.c: Implement CMSDK APB UART
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 2/9] hw/char/cmsdk-apb-uart.c: Implement CMSDK APB UART Peter Maydell
@ 2017-07-14 15:32   ` Alex Bennée
  2017-07-14 15:45     ` Peter Maydell
  2017-07-14 16:29   ` [Qemu-devel] " Philippe Mathieu-Daudé
  1 sibling, 1 reply; 26+ messages in thread
From: Alex Bennée @ 2017-07-14 15:32 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-arm, qemu-devel, Alistair Francis,
	Philippe Mathieu-Daudé,
	patches


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

> Implement a model of the simple "APB UART" provided in
> the Cortex-M System Design Kit (CMSDK).
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

This fails to compile, I think since
81517ba37a6cec59f92396b4722861868eb0a500 change the API for
qemu_chr_fe_set_handlers.

> ---
>  hw/char/Makefile.objs            |   1 +
>  include/hw/char/cmsdk-apb-uart.h |  78 ++++++++
>  hw/char/cmsdk-apb-uart.c         | 402 +++++++++++++++++++++++++++++++++++++++
>  default-configs/arm-softmmu.mak  |   2 +
>  hw/char/trace-events             |   9 +
>  5 files changed, 492 insertions(+)
>  create mode 100644 include/hw/char/cmsdk-apb-uart.h
>  create mode 100644 hw/char/cmsdk-apb-uart.c
>
> diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
> index 55fcb68..1bcd37e 100644
> --- a/hw/char/Makefile.objs
> +++ b/hw/char/Makefile.objs
> @@ -19,6 +19,7 @@ obj-$(CONFIG_DIGIC) += digic-uart.o
>  obj-$(CONFIG_STM32F2XX_USART) += stm32f2xx_usart.o
>  obj-$(CONFIG_RASPI) += bcm2835_aux.o
>
> +common-obj-$(CONFIG_CMSDK_APB_UART) += cmsdk-apb-uart.o
>  common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
>  common-obj-$(CONFIG_ISA_DEBUG) += debugcon.o
>  common-obj-$(CONFIG_GRLIB) += grlib_apbuart.o
> diff --git a/include/hw/char/cmsdk-apb-uart.h b/include/hw/char/cmsdk-apb-uart.h
> new file mode 100644
> index 0000000..c41fba9
> --- /dev/null
> +++ b/include/hw/char/cmsdk-apb-uart.h
> @@ -0,0 +1,78 @@
> +/*
> + * ARM CMSDK APB UART emulation
> + *
> + * Copyright (c) 2017 Linaro Limited
> + * Written by Peter Maydell
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2 or
> + *  (at your option) any later version.
> + */
> +
> +#ifndef CMSDK_APB_UART_H
> +#define CMSDK_APB_UART_H
> +
> +#include "hw/sysbus.h"
> +#include "chardev/char-fe.h"
> +
> +#define TYPE_CMSDK_APB_UART "cmsdk-apb-uart"
> +#define CMSDK_APB_UART(obj) OBJECT_CHECK(CMSDKAPBUART, (obj), \
> +                                         TYPE_CMSDK_APB_UART)
> +
> +typedef struct {
> +    /*< private >*/
> +    SysBusDevice parent_obj;
> +
> +    /*< public >*/
> +    MemoryRegion iomem;
> +    CharBackend chr;
> +    qemu_irq txint;
> +    qemu_irq rxint;
> +    qemu_irq txovrint;
> +    qemu_irq rxovrint;
> +    qemu_irq uartint;
> +    guint watch_tag;
> +    uint32_t pclk_frq;
> +
> +    uint32_t state;
> +    uint32_t ctrl;
> +    uint32_t intstatus;
> +    uint32_t bauddiv;
> +    /* This UART has no FIFO, only a 1-character buffer for each of Tx and Rx */
> +    uint8_t txbuf;
> +    uint8_t rxbuf;
> +} CMSDKAPBUART;
> +
> +/**
> + * cmsdk_apb_uart_create - convenience function to create TYPE_CMSDK_APB_UART
> + * @addr: location in system memory to map registers
> + * @chr: Chardev backend to connect UART to, or NULL if no backend
> + * @pclk_frq: frequency in Hz of the PCLK clock (used for calculating baud rate)
> + */
> +static inline DeviceState *cmsdk_apb_uart_create(hwaddr addr,
> +                                                 qemu_irq txint,
> +                                                 qemu_irq rxint,
> +                                                 qemu_irq txovrint,
> +                                                 qemu_irq rxovrint,
> +                                                 qemu_irq uartint,
> +                                                 Chardev *chr,
> +                                                 uint32_t pclk_frq)
> +{
> +    DeviceState *dev;
> +    SysBusDevice *s;
> +
> +    dev = qdev_create(NULL, TYPE_CMSDK_APB_UART);
> +    s = SYS_BUS_DEVICE(dev);
> +    qdev_prop_set_chr(dev, "chardev", chr);
> +    qdev_prop_set_uint32(dev, "pclk-frq", pclk_frq);
> +    qdev_init_nofail(dev);
> +    sysbus_mmio_map(s, 0, addr);
> +    sysbus_connect_irq(s, 0, txint);
> +    sysbus_connect_irq(s, 1, rxint);
> +    sysbus_connect_irq(s, 2, txovrint);
> +    sysbus_connect_irq(s, 3, rxovrint);
> +    sysbus_connect_irq(s, 4, uartint);
> +    return dev;
> +}
> +
> +#endif
> diff --git a/hw/char/cmsdk-apb-uart.c b/hw/char/cmsdk-apb-uart.c
> new file mode 100644
> index 0000000..82d2bea
> --- /dev/null
> +++ b/hw/char/cmsdk-apb-uart.c
> @@ -0,0 +1,402 @@
> +/*
> + * ARM CMSDK APB UART emulation
> + *
> + * Copyright (c) 2017 Linaro Limited
> + * Written by Peter Maydell
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2 or
> + *  (at your option) any later version.
> + */
> +
> +/* This is a model of the "APB UART" which is part of the Cortex-M
> + * System Design Kit (CMSDK) and documented in the Cortex-M System
> + * Design Kit Technical Reference Manual (ARM DDI0479C):
> + * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "qapi/error.h"
> +#include "trace.h"
> +#include "hw/sysbus.h"
> +#include "hw/registerfields.h"
> +#include "chardev/char-fe.h"
> +#include "chardev/char-serial.h"
> +#include "hw/char/cmsdk-apb-uart.h"
> +
> +REG32(DATA, 0)
> +REG32(STATE, 4)
> +    FIELD(STATE, TXFULL, 0, 1)
> +    FIELD(STATE, RXFULL, 1, 1)
> +    FIELD(STATE, TXOVERRUN, 2, 1)
> +    FIELD(STATE, RXOVERRUN, 3, 1)
> +REG32(CTRL, 8)
> +    FIELD(CTRL, TX_EN, 0, 1)
> +    FIELD(CTRL, RX_EN, 1, 1)
> +    FIELD(CTRL, TX_INTEN, 2, 1)
> +    FIELD(CTRL, RX_INTEN, 3, 1)
> +    FIELD(CTRL, TXO_INTEN, 4, 1)
> +    FIELD(CTRL, RXO_INTEN, 5, 1)
> +    FIELD(CTRL, HSTEST, 6, 1)
> +REG32(INTSTATUS, 0xc)
> +    FIELD(INTSTATUS, TX, 0, 1)
> +    FIELD(INTSTATUS, RX, 1, 1)
> +    FIELD(INTSTATUS, TXO, 2, 1)
> +    FIELD(INTSTATUS, RXO, 3, 1)
> +REG32(BAUDDIV, 0x10)
> +REG32(PID4, 0xFD0)
> +REG32(PID5, 0xFD4)
> +REG32(PID6, 0xFD8)
> +REG32(PID7, 0xFDC)
> +REG32(PID0, 0xFE0)
> +REG32(PID1, 0xFE4)
> +REG32(PID2, 0xFE8)
> +REG32(PID3, 0xFEC)
> +REG32(CID0, 0xFF0)
> +REG32(CID1, 0xFF4)
> +REG32(CID2, 0xFF8)
> +REG32(CID3, 0xFFC)
> +
> +/* PID/CID values */
> +static const int uart_id[] = {
> +    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
> +    0x21, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
> +    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
> +};
> +
> +static bool uart_baudrate_ok(CMSDKAPBUART *s)
> +{
> +    /* The minimum permitted bauddiv setting is 16, so we just ignore
> +     * settings below that (usually this means the device has just
> +     * been reset and not yet programmed).
> +     */
> +    return s->bauddiv >= 16 && s->bauddiv <= s->pclk_frq;
> +}
> +
> +static void uart_update_parameters(CMSDKAPBUART *s)
> +{
> +    QEMUSerialSetParams ssp;
> +
> +    /* This UART is always 8N1 but the baud rate is programmable. */
> +    if (!uart_baudrate_ok(s)) {
> +        return;
> +    }
> +
> +    ssp.data_bits = 8;
> +    ssp.parity = 'N';
> +    ssp.stop_bits = 1;
> +    ssp.speed = s->pclk_frq / s->bauddiv;
> +    qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
> +    trace_cmsdk_apb_uart_set_params(ssp.speed);
> +}
> +
> +static void cmsdk_apb_uart_update(CMSDKAPBUART *s)
> +{
> +    /* update outbound irqs, including handling the way the rxo and txo
> +     * interrupt status bits are just logical AND of the overrun bit in
> +     * STATE and the overrun interrupt enable bit in CTRL.
> +     */
> +    uint32_t omask = (R_INTSTATUS_RXO_MASK | R_INTSTATUS_TXO_MASK);
> +    s->intstatus &= ~omask;
> +    s->intstatus |= (s->state & (s->ctrl >> 2) & omask);
> +
> +    qemu_set_irq(s->txint, !!(s->intstatus & R_INTSTATUS_TX_MASK));
> +    qemu_set_irq(s->rxint, !!(s->intstatus & R_INTSTATUS_RX_MASK));
> +    qemu_set_irq(s->txovrint, !!(s->intstatus & R_INTSTATUS_TXO_MASK));
> +    qemu_set_irq(s->rxovrint, !!(s->intstatus & R_INTSTATUS_RXO_MASK));
> +    qemu_set_irq(s->uartint, !!(s->intstatus));

If we updated qemu_set_irq to take a bool instead of int would the !!
hack no longer be needed?

> +}
> +
> +static int uart_can_receive(void *opaque)
> +{
> +    CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
> +
> +    /* We can take a char if RX is enabled and the buffer is empty */
> +    if (s->ctrl & R_CTRL_RX_EN_MASK && !(s->state & R_STATE_RXFULL_MASK)) {
> +        return 1;
> +    }
> +    return 0;
> +}
> +
> +static void uart_receive(void *opaque, const uint8_t *buf, int size)
> +{
> +    CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
> +
> +    trace_cmsdk_apb_uart_receive(*buf);
> +
> +    /* In fact uart_can_receive() ensures that we can't be
> +     * called unless RX is enabled and the buffer is empty,
> +     * but we include this logic as documentation of what the
> +     * hardware does if a character arrives in these circumstances.
> +     */
> +    if (!(s->ctrl & R_CTRL_RX_EN_MASK)) {
> +        /* Just drop the character on the floor */
> +        return;
> +    }
> +
> +    if (s->state & R_STATE_RXFULL_MASK) {
> +        s->state |= R_STATE_RXOVERRUN_MASK;
> +    }
> +
> +    s->rxbuf = *buf;
> +    s->state |= R_STATE_RXFULL_MASK;
> +    if (s->ctrl & R_CTRL_RX_INTEN_MASK) {
> +        s->intstatus |= R_INTSTATUS_RX_MASK;
> +    }
> +    cmsdk_apb_uart_update(s);
> +}
> +
> +static uint64_t uart_read(void *opaque, hwaddr offset, unsigned size)
> +{
> +    CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
> +    uint64_t r;
> +
> +    switch (offset) {
> +    case A_DATA:
> +        r = s->rxbuf;
> +        s->state &= ~R_STATE_RXFULL_MASK;
> +        cmsdk_apb_uart_update(s);
> +        break;
> +    case A_STATE:
> +        r = s->state;
> +        break;
> +    case A_CTRL:
> +        r = s->ctrl;
> +        break;
> +    case A_INTSTATUS:
> +        r = s->intstatus;
> +        break;
> +    case A_BAUDDIV:
> +        r = s->bauddiv;
> +        break;
> +    case A_PID4 ... A_CID3:
> +        r = uart_id[(offset - A_PID4) / 4];
> +        break;
> +    default:
> +        qemu_log_mask(LOG_GUEST_ERROR,
> +                      "CMSDK APB UART read: bad offset %x\n", (int) offset);
> +        r = 0;
> +        break;
> +    }
> +    trace_cmsdk_apb_uart_read(offset, r, size);
> +    return r;
> +}
> +
> +/* Try to send tx data, and arrange to be called back later if
> + * we can't (ie the char backend is busy/blocking).
> + */
> +static gboolean uart_transmit(GIOChannel *chan, GIOCondition cond, void *opaque)
> +{
> +    CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
> +    int ret;
> +
> +    s->watch_tag = 0;
> +
> +    if (!(s->ctrl & R_CTRL_TX_EN_MASK) || !(s->state & R_STATE_TXFULL_MASK)) {
> +        return FALSE;
> +    }
> +
> +    ret = qemu_chr_fe_write(&s->chr, &s->txbuf, 1);
> +    if (ret <= 0) {
> +        s->watch_tag = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
> +                                             uart_transmit, s);
> +        if (!s->watch_tag) {
> +            /* Most common reason to be here is "no chardev backend":
> +             * just insta-drain the buffer, so the serial output
> +             * goes into a void, rather than blocking the guest.
> +             */
> +            goto buffer_drained;
> +        }
> +        /* Transmit pending */
> +        trace_cmsdk_apb_uart_tx_pending();
> +        return FALSE;
> +    }
> +
> +buffer_drained:
> +    /* Character successfully sent */
> +    trace_cmsdk_apb_uart_tx(s->txbuf);
> +    s->state &= ~R_STATE_TXFULL_MASK;
> +    /* Going from TXFULL set to clear triggers the tx interrupt */
> +    if (s->ctrl & R_CTRL_TX_INTEN_MASK) {
> +        s->intstatus |= R_INTSTATUS_TX_MASK;
> +    }
> +    cmsdk_apb_uart_update(s);
> +    return FALSE;
> +}
> +
> +static void uart_cancel_transmit(CMSDKAPBUART *s)
> +{
> +    if (s->watch_tag) {
> +        g_source_remove(s->watch_tag);
> +        s->watch_tag = 0;
> +    }
> +}
> +
> +static void uart_write(void *opaque, hwaddr offset, uint64_t value,
> +                       unsigned size)
> +{
> +    CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
> +
> +    trace_cmsdk_apb_uart_write(offset, value, size);
> +
> +    switch (offset) {
> +    case A_DATA:
> +        s->txbuf = value;
> +        if (s->state & R_STATE_TXFULL_MASK) {
> +            /* Buffer already full -- note the overrun and let the
> +             * existing pending transmit callback handle the new char.
> +             */
> +            s->state |= R_STATE_TXOVERRUN_MASK;
> +            cmsdk_apb_uart_update(s);
> +        } else {
> +            s->state |= R_STATE_TXFULL_MASK;
> +            uart_transmit(NULL, G_IO_OUT, s);
> +        }
> +        break;
> +    case A_STATE:
> +        /* Bits 0 and 1 are read only; bits 2 and 3 are W1C */
> +        s->state &= ~(value & 0xc);

I guess:
          s->state &= ~(value & (R_STATE_TXOVERRUN_MASK | R_STATE_RXOVERRUN_MASK));

maybe a little too verbose.

> +        cmsdk_apb_uart_update(s);
> +        break;
> +    case A_CTRL:
> +        s->ctrl = value & 0x7f;
> +        if ((s->ctrl & R_CTRL_TX_EN_MASK) && !uart_baudrate_ok(s)) {
> +            qemu_log_mask(LOG_GUEST_ERROR,
> +                          "CMSDK APB UART: Tx enabled with invalid baudrate\n");
> +        }
> +        cmsdk_apb_uart_update(s);
> +        break;
> +    case A_INTSTATUS:
> +        /* All bits are W1C. Clearing the overrun interrupt bits really
> +         * clears the overrun status bits in the STATE register (which
> +         * is then reflected into the intstatus value by the update function).
> +         */
> +        s->state &= ~(value & 0xc);
> +        cmsdk_apb_uart_update(s);
> +        break;
> +    case A_BAUDDIV:
> +        s->bauddiv = value & 0xFFFFF;
> +        uart_update_parameters(s);
> +        break;
> +    case A_PID4 ... A_CID3:
> +        qemu_log_mask(LOG_GUEST_ERROR,
> +                      "CMSDK APB UART write: write to RO offset 0x%x\n",
> +                      (int)offset);
> +        break;
> +    default:
> +        qemu_log_mask(LOG_GUEST_ERROR,
> +                      "CMSDK APB UART write: bad offset 0x%x\n", (int) offset);
> +        break;
> +    }
> +}
> +
> +static const MemoryRegionOps uart_ops = {
> +    .read = uart_read,
> +    .write = uart_write,
> +    .endianness = DEVICE_LITTLE_ENDIAN,
> +};
> +
> +static void cmsdk_apb_uart_reset(DeviceState *dev)
> +{
> +    CMSDKAPBUART *s = CMSDK_APB_UART(dev);
> +
> +    trace_cmsdk_apb_uart_reset();
> +    uart_cancel_transmit(s);
> +    s->state = 0;
> +    s->ctrl = 0;
> +    s->intstatus = 0;
> +    s->bauddiv = 0;
> +    s->txbuf = 0;
> +    s->rxbuf = 0;
> +}
> +
> +static void cmsdk_apb_uart_init(Object *obj)
> +{
> +    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
> +    CMSDKAPBUART *s = CMSDK_APB_UART(obj);
> +
> +    memory_region_init_io(&s->iomem, obj, &uart_ops, s, "uart", 0x1000);
> +    sysbus_init_mmio(sbd, &s->iomem);
> +    sysbus_init_irq(sbd, &s->txint);
> +    sysbus_init_irq(sbd, &s->rxint);
> +    sysbus_init_irq(sbd, &s->txovrint);
> +    sysbus_init_irq(sbd, &s->rxovrint);
> +    sysbus_init_irq(sbd, &s->uartint);
> +}
> +
> +static void cmsdk_apb_uart_realize(DeviceState *dev, Error **errp)
> +{
> +    CMSDKAPBUART *s = CMSDK_APB_UART(dev);
> +
> +    if (s->pclk_frq == 0) {
> +        error_setg(errp, "CMSDK APB UART: pclk-frq property must be set");
> +        return;
> +    }
> +
> +    /* This UART has no flow control, so we do not need to register
> +     * an event handler to deal with CHR_EVENT_BREAK.
> +     */
> +    qemu_chr_fe_set_handlers(&s->chr, uart_can_receive, uart_receive,
> +                             NULL, s, NULL, true);

I think this is now:

    qemu_chr_fe_set_handlers(&s->chr, uart_can_receive, uart_receive,
                             NULL, NULL, s, NULL, true);


> +}
> +
> +static int cmsdk_apb_uart_post_load(void *opaque, int version_id)
> +{
> +    CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
> +
> +    /* If we have a pending character, arrange to resend it. */
> +    if (s->state & R_STATE_TXFULL_MASK) {
> +        s->watch_tag = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
> +                                             uart_transmit, s);
> +    }
> +    uart_update_parameters(s);
> +    return 0;
> +}
> +
> +static const VMStateDescription cmsdk_apb_uart_vmstate = {
> +    .name = "cmsdk-apb-uart",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .post_load = cmsdk_apb_uart_post_load,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_UINT32(state, CMSDKAPBUART),
> +        VMSTATE_UINT32(ctrl, CMSDKAPBUART),
> +        VMSTATE_UINT32(intstatus, CMSDKAPBUART),
> +        VMSTATE_UINT32(bauddiv, CMSDKAPBUART),
> +        VMSTATE_UINT8(txbuf, CMSDKAPBUART),
> +        VMSTATE_UINT8(rxbuf, CMSDKAPBUART),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
> +static Property cmsdk_apb_uart_properties[] = {
> +    DEFINE_PROP_CHR("chardev", CMSDKAPBUART, chr),
> +    DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBUART, pclk_frq, 0),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void cmsdk_apb_uart_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    dc->realize = cmsdk_apb_uart_realize;
> +    dc->vmsd = &cmsdk_apb_uart_vmstate;
> +    dc->reset = cmsdk_apb_uart_reset;
> +    dc->props = cmsdk_apb_uart_properties;
> +}
> +
> +static const TypeInfo cmsdk_apb_uart_info = {
> +    .name = TYPE_CMSDK_APB_UART,
> +    .parent = TYPE_SYS_BUS_DEVICE,
> +    .instance_size = sizeof(CMSDKAPBUART),
> +    .instance_init = cmsdk_apb_uart_init,
> +    .class_init = cmsdk_apb_uart_class_init,
> +};
> +
> +static void cmsdk_apb_uart_register_types(void)
> +{
> +    type_register_static(&cmsdk_apb_uart_info);
> +}
> +
> +type_init(cmsdk_apb_uart_register_types);
> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
> index bfd2a88..d128e9d 100644
> --- a/default-configs/arm-softmmu.mak
> +++ b/default-configs/arm-softmmu.mak
> @@ -96,6 +96,8 @@ CONFIG_STM32F2XX_ADC=y
>  CONFIG_STM32F2XX_SPI=y
>  CONFIG_STM32F205_SOC=y
>
> +CONFIG_CMSDK_APB_UART=y
> +
>  CONFIG_VERSATILE_PCI=y
>  CONFIG_VERSATILE_I2C=y
>
> diff --git a/hw/char/trace-events b/hw/char/trace-events
> index 7fd48bb..daf4ee4 100644
> --- a/hw/char/trace-events
> +++ b/hw/char/trace-events
> @@ -56,3 +56,12 @@ pl011_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
>  pl011_can_receive(uint32_t lcr, int read_count, int r) "LCR %08x read_count %d returning %d"
>  pl011_put_fifo(uint32_t c, int read_count) "new char 0x%x read_count now %d"
>  pl011_put_fifo_full(void) "FIFO now full, RXFF set"
> +
> +# hw/char/cmsdk_apb_uart.c
> +cmsdk_apb_uart_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB UART read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
> +cmsdk_apb_uart_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB UART write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
> +cmsdk_apb_uart_reset(void) "CMSDK APB UART: reset"
> +cmsdk_apb_uart_receive(uint8_t c) "CMSDK APB UART: got character 0x%x from backend"
> +cmsdk_apb_uart_tx_pending(void) "CMSDK APB UART: character send to backend pending"
> +cmsdk_apb_uart_tx(uint8_t c) "CMSDK APB UART: character 0x%x sent to backend"
> +cmsdk_apb_uart_set_params(int speed) "CMSDK APB UART: params set to %d 8N1"


--
Alex Bennée

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH v2 2/9] hw/char/cmsdk-apb-uart.c: Implement CMSDK APB UART
  2017-07-14 15:32   ` [Qemu-devel] [Qemu-arm] " Alex Bennée
@ 2017-07-14 15:45     ` Peter Maydell
  2017-07-14 16:11       ` Alex Bennée
  0 siblings, 1 reply; 26+ messages in thread
From: Peter Maydell @ 2017-07-14 15:45 UTC (permalink / raw)
  To: Alex Bennée
  Cc: qemu-arm, QEMU Developers, Alistair Francis,
	Philippe Mathieu-Daudé,
	patches

On 14 July 2017 at 16:32, Alex Bennée <alex.bennee@linaro.org> wrote:
>
> Peter Maydell <peter.maydell@linaro.org> writes:
>
>> Implement a model of the simple "APB UART" provided in
>> the Cortex-M System Design Kit (CMSDK).
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>
> This fails to compile, I think since
> 81517ba37a6cec59f92396b4722861868eb0a500 change the API for
> qemu_chr_fe_set_handlers.

>> +static void cmsdk_apb_uart_update(CMSDKAPBUART *s)
>> +{
>> +    /* update outbound irqs, including handling the way the rxo and txo
>> +     * interrupt status bits are just logical AND of the overrun bit in
>> +     * STATE and the overrun interrupt enable bit in CTRL.
>> +     */
>> +    uint32_t omask = (R_INTSTATUS_RXO_MASK | R_INTSTATUS_TXO_MASK);
>> +    s->intstatus &= ~omask;
>> +    s->intstatus |= (s->state & (s->ctrl >> 2) & omask);
>> +
>> +    qemu_set_irq(s->txint, !!(s->intstatus & R_INTSTATUS_TX_MASK));
>> +    qemu_set_irq(s->rxint, !!(s->intstatus & R_INTSTATUS_RX_MASK));
>> +    qemu_set_irq(s->txovrint, !!(s->intstatus & R_INTSTATUS_TXO_MASK));
>> +    qemu_set_irq(s->rxovrint, !!(s->intstatus & R_INTSTATUS_RXO_MASK));
>> +    qemu_set_irq(s->uartint, !!(s->intstatus));
>
> If we updated qemu_set_irq to take a bool instead of int would the !!
> hack no longer be needed?

I am fairly sure we have a few places that utilize the ability
to send an integer down the qemu_irq channel.

>> +    case A_STATE:
>> +        /* Bits 0 and 1 are read only; bits 2 and 3 are W1C */
>> +        s->state &= ~(value & 0xc);
>
> I guess:
>           s->state &= ~(value & (R_STATE_TXOVERRUN_MASK | R_STATE_RXOVERRUN_MASK));
>
> maybe a little too verbose.

Well, it probably ought to use the bit mask names, yes.

>> +static void cmsdk_apb_uart_realize(DeviceState *dev, Error **errp)
>> +{
>> +    CMSDKAPBUART *s = CMSDK_APB_UART(dev);
>> +
>> +    if (s->pclk_frq == 0) {
>> +        error_setg(errp, "CMSDK APB UART: pclk-frq property must be set");
>> +        return;
>> +    }
>> +
>> +    /* This UART has no flow control, so we do not need to register
>> +     * an event handler to deal with CHR_EVENT_BREAK.
>> +     */
>> +    qemu_chr_fe_set_handlers(&s->chr, uart_can_receive, uart_receive,
>> +                             NULL, s, NULL, true);
>
> I think this is now:
>
>     qemu_chr_fe_set_handlers(&s->chr, uart_can_receive, uart_receive,
>                              NULL, NULL, s, NULL, true);

Yes. It looks like we don't have to support backend swaps
(only hw/char/serial.c and virtio-console have support for that),
so just the extra NULL argument will do fine.

I propose to just fix both these nits in target-arm rather
than resend.

thanks
-- PMM

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH v2 3/9] hw/arm/mps2: Add UARTs
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 3/9] hw/arm/mps2: Add UARTs Peter Maydell
@ 2017-07-14 15:52   ` Alex Bennée
  2017-07-14 16:07     ` Peter Maydell
  0 siblings, 1 reply; 26+ messages in thread
From: Alex Bennée @ 2017-07-14 15:52 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-arm, qemu-devel, Alistair Francis,
	Philippe Mathieu-Daudé,
	patches


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

> Add the UARTs to the MPS2 board models.
>
> Unfortunately the details of the wiring of the interrupts through
> various OR gates differ between AN511 and AN385 so this can't
> be purely a data-driven difference.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
> ---
>  hw/arm/mps2.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 86 insertions(+)
>
> diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
> index 3dad02d..180c5d2 100644
> --- a/hw/arm/mps2.c
> +++ b/hw/arm/mps2.c
> @@ -27,9 +27,12 @@
>  #include "qemu/error-report.h"
>  #include "hw/arm/arm.h"
>  #include "hw/arm/armv7m.h"
> +#include "hw/or-irq.h"
>  #include "hw/boards.h"
>  #include "exec/address-spaces.h"
> +#include "sysemu/sysemu.h"
>  #include "hw/misc/unimp.h"
> +#include "hw/char/cmsdk-apb-uart.h"
>
>  typedef enum MPS2FPGAType {
>      FPGA_AN385,
> @@ -206,6 +209,89 @@ static void mps2_common_init(MachineState *machine)
>      create_unimplemented_device("Ethernet", 0x40200000, 0x00100000);
>      create_unimplemented_device("VGA", 0x41000000, 0x0200000);
>
> +    switch (mmc->fpga_type) {
> +    case FPGA_AN385:
> +    {
> +        /* The overflow IRQs for UARTs 0, 1 and 2 are ORed together.
> +         * Overflow for UARTs 4 and 5 doesn't trigger any interrupt.
> +         */
> +        Object *orgate;
> +        DeviceState *orgate_dev;
> +        int i;
> +
> +        orgate = object_new(TYPE_OR_IRQ);
> +        object_property_set_int(orgate, 6, "num-lines", &error_fatal);
> +        object_property_set_bool(orgate, true, "realized", &error_fatal);
> +        orgate_dev = DEVICE(orgate);
> +        qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
> +
> +        for (i = 0; i < 5; i++) {
> +            hwaddr uartbase[] = {0x40004000, 0x40005000, 0x40006000,
> +                                 0x40007000, 0x40009000};

I would expect these to be something like:

  static hwaddr an385_uartbase[] = {0x40004000, 0x40005000, 0x40006000,
                                    0x40007000, 0x40009000};
  static hwaddr an511_uartbase[] = {0x40004000, 0x40005000, 0x4002c000,
                                    0x4002d000, 0x4002e000};

to save the compiler from filling in the table every loop. Not that it
makes much different for an init routine.

> +            Chardev *uartchr = i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL;
> +            /* RX irq number; TX irq is always one greater */
> +            int uartirq[] = {0, 2, 4, 18, 20};

At the very least you an move uartbase and uartirq into the case block
so it is not being pointlessly rebuilt each loop.

> +            qemu_irq txovrint = NULL, rxovrint = NULL;
> +
> +            if (i < 3) {
> +                txovrint = qdev_get_gpio_in(orgate_dev, i * 2);
> +                rxovrint = qdev_get_gpio_in(orgate_dev, i * 2 + 1);
> +            }
> +
> +            cmsdk_apb_uart_create(uartbase[i],
> +                                  qdev_get_gpio_in(armv7m, uartirq[i] + 1),
> +                                  qdev_get_gpio_in(armv7m, uartirq[i]),
> +                                  txovrint, rxovrint,
> +                                  NULL,
> +                                  uartchr, SYSCLK_FRQ);
> +        }
> +        break;
> +    }
> +    case FPGA_AN511:
> +    {
> +        /* The overflow IRQs for all UARTs are ORed together.
> +         * Tx and Rx IRQs for each UART are ORed together.
> +         */
> +        Object *orgate;
> +        DeviceState *orgate_dev;
> +        int i;
> +
> +        orgate = object_new(TYPE_OR_IRQ);
> +        object_property_set_int(orgate, 10, "num-lines", &error_fatal);
> +        object_property_set_bool(orgate, true, "realized", &error_fatal);
> +        orgate_dev = DEVICE(orgate);
> +        qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
> +
> +        for (i = 0; i < 5; i++) {
> +            /* system irq numbers for the combined tx/rx for each UART */
> +            const int uart_txrx_irqno[] = {0, 2, 45, 46, 56};
> +            hwaddr uartbase[] = {0x40004000, 0x40005000, 0x4002c000,
> +                                 0x4002d000, 0x4002e000};

Ditto. I see irqno is const here.

> +            Chardev *uartchr = i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL;
> +            Object *txrx_orgate;
> +            DeviceState *txrx_orgate_dev;
> +
> +            txrx_orgate = object_new(TYPE_OR_IRQ);
> +            object_property_set_int(txrx_orgate, 2, "num-lines", &error_fatal);
> +            object_property_set_bool(txrx_orgate, true, "realized",
> +                                     &error_fatal);
> +            txrx_orgate_dev = DEVICE(txrx_orgate);
> +            qdev_connect_gpio_out(txrx_orgate_dev, 0,
> +                                  qdev_get_gpio_in(armv7m, uart_txrx_irqno[i]));
> +            cmsdk_apb_uart_create(uartbase[i],
> +                                  qdev_get_gpio_in(txrx_orgate_dev, 0),
> +                                  qdev_get_gpio_in(txrx_orgate_dev, 1),
> +                                  qdev_get_gpio_in(orgate_dev, 0),
> +                                  qdev_get_gpio_in(orgate_dev, 1),
> +                                  NULL,
> +                                  uartchr, SYSCLK_FRQ);
> +        }
> +        break;
> +    }
> +    default:
> +        g_assert_not_reached();
> +    }
> +
>      system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
>
>      armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,


--
Alex Bennée

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH v2 3/9] hw/arm/mps2: Add UARTs
  2017-07-14 15:52   ` [Qemu-devel] [Qemu-arm] " Alex Bennée
@ 2017-07-14 16:07     ` Peter Maydell
  2017-07-14 16:35       ` Alex Bennée
  0 siblings, 1 reply; 26+ messages in thread
From: Peter Maydell @ 2017-07-14 16:07 UTC (permalink / raw)
  To: Alex Bennée
  Cc: qemu-arm, QEMU Developers, Alistair Francis,
	Philippe Mathieu-Daudé,
	patches

On 14 July 2017 at 16:52, Alex Bennée <alex.bennee@linaro.org> wrote:
>
> Peter Maydell <peter.maydell@linaro.org> writes:
>
>> Add the UARTs to the MPS2 board models.
>>
>> Unfortunately the details of the wiring of the interrupts through
>> various OR gates differ between AN511 and AN385 so this can't
>> be purely a data-driven difference.
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
>> ---
>>  hw/arm/mps2.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 86 insertions(+)
>>
>> diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
>> index 3dad02d..180c5d2 100644
>> --- a/hw/arm/mps2.c
>> +++ b/hw/arm/mps2.c
>> @@ -27,9 +27,12 @@
>>  #include "qemu/error-report.h"
>>  #include "hw/arm/arm.h"
>>  #include "hw/arm/armv7m.h"
>> +#include "hw/or-irq.h"
>>  #include "hw/boards.h"
>>  #include "exec/address-spaces.h"
>> +#include "sysemu/sysemu.h"
>>  #include "hw/misc/unimp.h"
>> +#include "hw/char/cmsdk-apb-uart.h"
>>
>>  typedef enum MPS2FPGAType {
>>      FPGA_AN385,
>> @@ -206,6 +209,89 @@ static void mps2_common_init(MachineState *machine)
>>      create_unimplemented_device("Ethernet", 0x40200000, 0x00100000);
>>      create_unimplemented_device("VGA", 0x41000000, 0x0200000);
>>
>> +    switch (mmc->fpga_type) {
>> +    case FPGA_AN385:
>> +    {
>> +        /* The overflow IRQs for UARTs 0, 1 and 2 are ORed together.
>> +         * Overflow for UARTs 4 and 5 doesn't trigger any interrupt.
>> +         */
>> +        Object *orgate;
>> +        DeviceState *orgate_dev;
>> +        int i;
>> +
>> +        orgate = object_new(TYPE_OR_IRQ);
>> +        object_property_set_int(orgate, 6, "num-lines", &error_fatal);
>> +        object_property_set_bool(orgate, true, "realized", &error_fatal);
>> +        orgate_dev = DEVICE(orgate);
>> +        qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
>> +
>> +        for (i = 0; i < 5; i++) {
>> +            hwaddr uartbase[] = {0x40004000, 0x40005000, 0x40006000,
>> +                                 0x40007000, 0x40009000};
>
> I would expect these to be something like:
>
>   static hwaddr an385_uartbase[] = {0x40004000, 0x40005000, 0x40006000,
>                                     0x40007000, 0x40009000};
>   static hwaddr an511_uartbase[] = {0x40004000, 0x40005000, 0x4002c000,
>                                     0x4002d000, 0x4002e000};
>
> to save the compiler from filling in the table every loop. Not that it
> makes much different for an init routine.

I'm slightly surprised the compiler can't tell that these
are never written and emit the same code for all of them,
but yeah, let's just 'static const' all of them.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours)
  2017-07-14 10:51 [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours) Peter Maydell
                   ` (9 preceding siblings ...)
  2017-07-14 12:16 ` [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours) no-reply
@ 2017-07-14 16:08 ` no-reply
  10 siblings, 0 replies; 26+ messages in thread
From: no-reply @ 2017-07-14 16:08 UTC (permalink / raw)
  To: peter.maydell
  Cc: famz, qemu-arm, qemu-devel, alistair.francis, f4bug, patches

Hi,

This series failed automatic build test. Please find the testing commands and
their output below. If you have docker installed, you can probably reproduce it
locally.

Type: series
Message-id: 1500029487-14822-1-git-send-email-peter.maydell@linaro.org
Subject: [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours)

=== TEST SCRIPT BEGIN ===
#!/bin/bash
set -e
git submodule update --init dtc
# Let docker tests dump environment info
export SHOW_ENV=1
export J=8
time make docker-test-quick@centos6
time make docker-test-build@min-glib
time make docker-test-mingw@fedora
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]      patchew/1500025208-14827-1-git-send-email-mark.cave-ayland@ilande.co.uk -> patchew/1500025208-14827-1-git-send-email-mark.cave-ayland@ilande.co.uk
 * [new tag]         patchew/1500046217-24597-1-git-send-email-mst@redhat.com -> patchew/1500046217-24597-1-git-send-email-mst@redhat.com
 * [new tag]         patchew/20170714152820.24034-1-dgilbert@redhat.com -> patchew/20170714152820.24034-1-dgilbert@redhat.com
 * [new tag]         patchew/20170714153749.25132-1-pbutsykin@virtuozzo.com -> patchew/20170714153749.25132-1-pbutsykin@virtuozzo.com
Switched to a new branch 'test'
bd82167 MAINTAINERS: Add entries for MPS2 board
9809359 hw/arm/mps2: Add ethernet
d826b97 hw/arm/mps2: Add SCC
8eecac7 hw/misc/mps2_scc: Implement MPS2 Serial Communication Controller
a1522d1 hw/arm/mps2: Add timers
01557be hw/char/cmsdk-apb-timer: Implement CMSDK APB timer device
8118bd5 hw/arm/mps2: Add UARTs
1cc3b5e hw/char/cmsdk-apb-uart.c: Implement CMSDK APB UART
198c710 hw/arm/mps2: Implement skeleton mps2-an385 and mps2-an511 board models

=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into '/var/tmp/patchew-tester-tmp-32l_mal7/src/dtc'...
Submodule path 'dtc': checked out '558cd81bdd432769b59bff01240c44f82cfb1a9d'
  BUILD   centos6
make[1]: Entering directory '/var/tmp/patchew-tester-tmp-32l_mal7/src'
  ARCHIVE qemu.tgz
  ARCHIVE dtc.tgz
  COPY    RUNNER
    RUN test-quick in qemu:centos6 
Packages installed:
SDL-devel-1.2.14-7.el6_7.1.x86_64
bison-2.4.1-5.el6.x86_64
ccache-3.1.6-2.el6.x86_64
epel-release-6-8.noarch
flex-2.5.35-9.el6.x86_64
gcc-4.4.7-18.el6.x86_64
git-1.7.1-8.el6.x86_64
glib2-devel-2.28.8-9.el6.x86_64
libfdt-devel-1.4.0-1.el6.x86_64
make-3.81-23.el6.x86_64
package g++ is not installed
pixman-devel-0.32.8-1.el6.x86_64
tar-1.23-15.el6_8.x86_64
zlib-devel-1.2.3-29.el6.x86_64

Environment variables:
PACKAGES=libfdt-devel ccache     tar git make gcc g++ flex bison     zlib-devel glib2-devel SDL-devel pixman-devel     epel-release
HOSTNAME=acc80caef856
TERM=xterm
MAKEFLAGS= -j8
HISTSIZE=1000
J=8
USER=root
CCACHE_DIR=/var/tmp/ccache
EXTRA_CONFIGURE_OPTS=
V=
SHOW_ENV=1
MAIL=/var/spool/mail/root
PATH=/usr/lib/ccache:/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
LANG=en_US.UTF-8
TARGET_LIST=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
TEST_DIR=/tmp/qemu-test
LOGNAME=root
LESSOPEN=||/usr/bin/lesspipe.sh %s
FEATURES= dtc
DEBUG=
G_BROKEN_FILENAMES=1
CCACHE_HASHDIR=
_=/usr/bin/env

Configure options:
--enable-werror --target-list=x86_64-softmmu,aarch64-softmmu --prefix=/var/tmp/qemu-build/install
No C++ compiler available; disabling C++ specific optional code
Install prefix    /var/tmp/qemu-build/install
BIOS directory    /var/tmp/qemu-build/install/share/qemu
binary directory  /var/tmp/qemu-build/install/bin
library directory /var/tmp/qemu-build/install/lib
module directory  /var/tmp/qemu-build/install/lib/qemu
libexec directory /var/tmp/qemu-build/install/libexec
include directory /var/tmp/qemu-build/install/include
config directory  /var/tmp/qemu-build/install/etc
local state directory   /var/tmp/qemu-build/install/var
Manual directory  /var/tmp/qemu-build/install/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path       /tmp/qemu-test/src
C compiler        cc
Host C compiler   cc
C++ compiler      
Objective-C compiler cc
ARFLAGS           rv
CFLAGS            -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g 
QEMU_CFLAGS       -I/usr/include/pixman-1   -I$(SRC_PATH)/dtc/libfdt -pthread -I/usr/include/glib-2.0 -I/usr/lib64/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  -Wendif-labels -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-all
LDFLAGS           -Wl,--warn-common -Wl,-z,relro -Wl,-z,now -pie -m64 -g 
make              make
install           install
python            python -B
smbd              /usr/sbin/smbd
module support    no
host CPU          x86_64
host big endian   no
target list       x86_64-softmmu aarch64-softmmu
gprof enabled     no
sparse enabled    no
strip binaries    yes
profiler          no
static build      no
pixman            system
SDL support       yes (1.2.14)
GTK support       no 
GTK GL support    no
VTE support       no 
TLS priority      NORMAL
GNUTLS support    no
GNUTLS rnd        no
libgcrypt         no
libgcrypt kdf     no
nettle            no 
nettle kdf        no
libtasn1          no
curses support    no
virgl support     no
curl support      no
mingw32 support   no
Audio drivers     oss
Block whitelist (rw) 
Block whitelist (ro) 
VirtFS support    no
VNC support       yes
VNC SASL support  no
VNC JPEG support  no
VNC PNG support   no
xen support       no
brlapi support    no
bluez  support    no
Documentation     no
PIE               yes
vde support       no
netmap support    no
Linux AIO support no
ATTR/XATTR support yes
Install blobs     yes
KVM support       yes
HAX support       no
TCG support       yes
TCG debug enabled no
TCG interpreter   no
RDMA support      no
fdt support       yes
preadv support    yes
fdatasync         yes
madvise           yes
posix_madvise     yes
libcap-ng support no
vhost-net support yes
vhost-scsi support yes
vhost-vsock support yes
Trace backends    log
spice support     no 
rbd support       no
xfsctl support    no
smartcard support no
libusb            no
usb net redir     no
OpenGL support    no
OpenGL dmabufs    no
libiscsi support  no
libnfs support    no
build guest agent yes
QGA VSS support   no
QGA w32 disk info no
QGA MSI support   no
seccomp support   no
coroutine backend ucontext
coroutine pool    yes
debug stack usage no
GlusterFS support no
gcov              gcov
gcov enabled      no
TPM support       yes
libssh2 support   no
TPM passthrough   yes
QOM debugging     yes
Live block migration yes
lzo support       no
snappy support    no
bzip2 support     no
NUMA host support no
tcmalloc support  no
jemalloc support  no
avx2 optimization no
replication support yes
VxHS block device no
  GEN     x86_64-softmmu/config-devices.mak.tmp
  GEN     aarch64-softmmu/config-devices.mak.tmp
mkdir -p dtc/libfdt
mkdir -p dtc/tests
  GEN     config-host.h
  GEN     qemu-options.def
  GEN     qapi-visit.h
  GEN     qmp-commands.h
  GEN     qapi-types.h
  GEN     qapi-event.h
  GEN     x86_64-softmmu/config-devices.mak
  GEN     aarch64-softmmu/config-devices.mak
  GEN     qmp-marshal.c
  GEN     qapi-types.c
  GEN     qapi-visit.c
  GEN     qapi-event.c
  GEN     qmp-introspect.h
  GEN     qmp-introspect.c
  GEN     trace/generated-tcg-tracers.h
  GEN     trace/generated-helpers-wrappers.h
  GEN     trace/generated-helpers.h
  GEN     trace/generated-helpers.c
  GEN     module_block.h
  GEN     tests/test-qapi-types.h
  GEN     tests/test-qapi-visit.h
  GEN     tests/test-qmp-commands.h
  GEN     tests/test-qapi-event.h
  GEN     tests/test-qmp-introspect.h
  GEN     trace-root.h
  GEN     util/trace.h
  GEN     crypto/trace.h
  GEN     io/trace.h
  GEN     migration/trace.h
  GEN     block/trace.h
  GEN     chardev/trace.h
  GEN     hw/block/trace.h
  GEN     hw/block/dataplane/trace.h
  GEN     hw/char/trace.h
  GEN     hw/intc/trace.h
  GEN     hw/net/trace.h
  GEN     hw/virtio/trace.h
  GEN     hw/audio/trace.h
  GEN     hw/misc/trace.h
  GEN     hw/usb/trace.h
  GEN     hw/scsi/trace.h
  GEN     hw/nvram/trace.h
  GEN     hw/display/trace.h
  GEN     hw/input/trace.h
  GEN     hw/timer/trace.h
  GEN     hw/dma/trace.h
  GEN     hw/sparc/trace.h
  GEN     hw/sd/trace.h
  GEN     hw/isa/trace.h
  GEN     hw/mem/trace.h
  GEN     hw/i386/trace.h
  GEN     hw/i386/xen/trace.h
  GEN     hw/9pfs/trace.h
  GEN     hw/ppc/trace.h
  GEN     hw/pci/trace.h
  GEN     hw/s390x/trace.h
  GEN     hw/vfio/trace.h
  GEN     hw/acpi/trace.h
  GEN     hw/arm/trace.h
  GEN     hw/alpha/trace.h
  GEN     hw/xen/trace.h
  GEN     ui/trace.h
  GEN     audio/trace.h
  GEN     net/trace.h
  GEN     target/arm/trace.h
  GEN     target/i386/trace.h
  GEN     target/mips/trace.h
  GEN     target/sparc/trace.h
  GEN     target/s390x/trace.h
  GEN     target/ppc/trace.h
  GEN     qom/trace.h
  GEN     linux-user/trace.h
  GEN     qapi/trace.h
  GEN     accel/tcg/trace.h
  GEN     accel/kvm/trace.h
  GEN     trace-root.c
  GEN     nbd/trace.h
  GEN     util/trace.c
  GEN     crypto/trace.c
  GEN     io/trace.c
  GEN     migration/trace.c
  GEN     block/trace.c
  GEN     chardev/trace.c
  GEN     hw/block/trace.c
  GEN     hw/block/dataplane/trace.c
  GEN     hw/char/trace.c
  GEN     hw/intc/trace.c
  GEN     hw/net/trace.c
  GEN     hw/virtio/trace.c
  GEN     hw/audio/trace.c
  GEN     hw/misc/trace.c
  GEN     hw/usb/trace.c
  GEN     hw/scsi/trace.c
  GEN     hw/nvram/trace.c
  GEN     hw/display/trace.c
  GEN     hw/input/trace.c
  GEN     hw/timer/trace.c
  GEN     hw/dma/trace.c
  GEN     hw/sparc/trace.c
  GEN     hw/sd/trace.c
  GEN     hw/isa/trace.c
  GEN     hw/mem/trace.c
  GEN     hw/i386/trace.c
  GEN     hw/i386/xen/trace.c
  GEN     hw/9pfs/trace.c
  GEN     hw/ppc/trace.c
  GEN     hw/pci/trace.c
  GEN     hw/s390x/trace.c
  GEN     hw/vfio/trace.c
  GEN     hw/acpi/trace.c
  GEN     hw/arm/trace.c
  GEN     hw/alpha/trace.c
  GEN     hw/xen/trace.c
  GEN     ui/trace.c
  GEN     audio/trace.c
  GEN     net/trace.c
  GEN     target/arm/trace.c
  GEN     target/i386/trace.c
  GEN     target/mips/trace.c
  GEN     target/sparc/trace.c
  GEN     target/s390x/trace.c
  GEN     target/ppc/trace.c
  GEN     qom/trace.c
  GEN     linux-user/trace.c
  GEN     qapi/trace.c
  GEN     accel/tcg/trace.c
  GEN     accel/kvm/trace.c
  GEN     nbd/trace.c
  GEN     config-all-devices.mak
	 DEP /tmp/qemu-test/src/dtc/tests/trees.S
	 DEP /tmp/qemu-test/src/dtc/tests/dumptrees.c
	 DEP /tmp/qemu-test/src/dtc/tests/testutils.c
	 DEP /tmp/qemu-test/src/dtc/tests/value-labels.c
	 DEP /tmp/qemu-test/src/dtc/tests/asm_tree_dump.c
	 DEP /tmp/qemu-test/src/dtc/tests/truncated_property.c
	 DEP /tmp/qemu-test/src/dtc/tests/overlay_bad_fixup.c
	 DEP /tmp/qemu-test/src/dtc/tests/check_path.c
	 DEP /tmp/qemu-test/src/dtc/tests/overlay.c
	 DEP /tmp/qemu-test/src/dtc/tests/subnode_iterate.c
	 DEP /tmp/qemu-test/src/dtc/tests/property_iterate.c
	 DEP /tmp/qemu-test/src/dtc/tests/integer-expressions.c
	 DEP /tmp/qemu-test/src/dtc/tests/utilfdt_test.c
	 DEP /tmp/qemu-test/src/dtc/tests/path_offset_aliases.c
	 DEP /tmp/qemu-test/src/dtc/tests/add_subnode_with_nops.c
	 DEP /tmp/qemu-test/src/dtc/tests/dtbs_equal_unordered.c
	 DEP /tmp/qemu-test/src/dtc/tests/dtb_reverse.c
	 DEP /tmp/qemu-test/src/dtc/tests/dtbs_equal_ordered.c
	 DEP /tmp/qemu-test/src/dtc/tests/extra-terminating-null.c
	 DEP /tmp/qemu-test/src/dtc/tests/incbin.c
	 DEP /tmp/qemu-test/src/dtc/tests/boot-cpuid.c
	 DEP /tmp/qemu-test/src/dtc/tests/phandle_format.c
	 DEP /tmp/qemu-test/src/dtc/tests/path-references.c
	 DEP /tmp/qemu-test/src/dtc/tests/references.c
	 DEP /tmp/qemu-test/src/dtc/tests/string_escapes.c
	 DEP /tmp/qemu-test/src/dtc/tests/propname_escapes.c
	 DEP /tmp/qemu-test/src/dtc/tests/appendprop2.c
	 DEP /tmp/qemu-test/src/dtc/tests/appendprop1.c
	 DEP /tmp/qemu-test/src/dtc/tests/del_node.c
	 DEP /tmp/qemu-test/src/dtc/tests/del_property.c
	 DEP /tmp/qemu-test/src/dtc/tests/setprop.c
	 DEP /tmp/qemu-test/src/dtc/tests/set_name.c
	 DEP /tmp/qemu-test/src/dtc/tests/rw_tree1.c
	 DEP /tmp/qemu-test/src/dtc/tests/open_pack.c
	 DEP /tmp/qemu-test/src/dtc/tests/nopulate.c
	 DEP /tmp/qemu-test/src/dtc/tests/mangle-layout.c
	 DEP /tmp/qemu-test/src/dtc/tests/move_and_save.c
	 DEP /tmp/qemu-test/src/dtc/tests/sw_tree1.c
	 DEP /tmp/qemu-test/src/dtc/tests/nop_node.c
	 DEP /tmp/qemu-test/src/dtc/tests/nop_property.c
	 DEP /tmp/qemu-test/src/dtc/tests/setprop_inplace.c
	 DEP /tmp/qemu-test/src/dtc/tests/stringlist.c
	 DEP /tmp/qemu-test/src/dtc/tests/addr_size_cells.c
	 DEP /tmp/qemu-test/src/dtc/tests/notfound.c
	 DEP /tmp/qemu-test/src/dtc/tests/sized_cells.c
	 DEP /tmp/qemu-test/src/dtc/tests/char_literal.c
	 DEP /tmp/qemu-test/src/dtc/tests/get_alias.c
	 DEP /tmp/qemu-test/src/dtc/tests/node_offset_by_compatible.c
	 DEP /tmp/qemu-test/src/dtc/tests/node_check_compatible.c
	 DEP /tmp/qemu-test/src/dtc/tests/node_offset_by_phandle.c
	 DEP /tmp/qemu-test/src/dtc/tests/node_offset_by_prop_value.c
	 DEP /tmp/qemu-test/src/dtc/tests/parent_offset.c
	 DEP /tmp/qemu-test/src/dtc/tests/supernode_atdepth_offset.c
	 DEP /tmp/qemu-test/src/dtc/tests/get_path.c
	 DEP /tmp/qemu-test/src/dtc/tests/get_phandle.c
	 DEP /tmp/qemu-test/src/dtc/tests/getprop.c
	 DEP /tmp/qemu-test/src/dtc/tests/path_offset.c
	 DEP /tmp/qemu-test/src/dtc/tests/get_name.c
	 DEP /tmp/qemu-test/src/dtc/tests/subnode_offset.c
	 DEP /tmp/qemu-test/src/dtc/tests/find_property.c
	 DEP /tmp/qemu-test/src/dtc/tests/root_node.c
	 DEP /tmp/qemu-test/src/dtc/tests/get_mem_rsv.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt_overlay.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt_addresses.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt_empty_tree.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt_strerror.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt_rw.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt_sw.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt_wip.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt_ro.c
	 DEP /tmp/qemu-test/src/dtc/util.c
	 DEP /tmp/qemu-test/src/dtc/fdtput.c
	 DEP /tmp/qemu-test/src/dtc/fdtget.c
	 DEP /tmp/qemu-test/src/dtc/fdtdump.c
	 LEX convert-dtsv0-lexer.lex.c
	 DEP /tmp/qemu-test/src/dtc/srcpos.c
	 BISON dtc-parser.tab.c
	 LEX dtc-lexer.lex.c
	 DEP /tmp/qemu-test/src/dtc/treesource.c
	 DEP /tmp/qemu-test/src/dtc/livetree.c
	 DEP /tmp/qemu-test/src/dtc/fstree.c
	 DEP /tmp/qemu-test/src/dtc/flattree.c
	 DEP /tmp/qemu-test/src/dtc/dtc.c
	 DEP /tmp/qemu-test/src/dtc/data.c
	 DEP /tmp/qemu-test/src/dtc/checks.c
	 DEP convert-dtsv0-lexer.lex.c
	 DEP dtc-parser.tab.c
	 DEP dtc-lexer.lex.c
	CHK version_gen.h
	UPD version_gen.h
	 DEP /tmp/qemu-test/src/dtc/util.c
	 CC libfdt/fdt.o
	 CC libfdt/fdt_ro.o
	 CC libfdt/fdt_wip.o
	 CC libfdt/fdt_rw.o
	 CC libfdt/fdt_strerror.o
	 CC libfdt/fdt_sw.o
	 CC libfdt/fdt_empty_tree.o
	 CC libfdt/fdt_addresses.o
	 CC libfdt/fdt_overlay.o
	 AR libfdt/libfdt.a
ar: creating libfdt/libfdt.a
a - libfdt/fdt.o
a - libfdt/fdt_ro.o
a - libfdt/fdt_wip.o
a - libfdt/fdt_sw.o
a - libfdt/fdt_rw.o
a - libfdt/fdt_strerror.o
a - libfdt/fdt_empty_tree.o
a - libfdt/fdt_addresses.o
a - libfdt/fdt_overlay.o
  CC      tests/qemu-iotests/socket_scm_helper.o
  GEN     qga/qapi-generated/qga-qapi-types.h
  GEN     qga/qapi-generated/qga-qapi-visit.h
  GEN     qga/qapi-generated/qga-qapi-visit.c
  GEN     qga/qapi-generated/qga-qapi-types.c
  GEN     qga/qapi-generated/qga-qmp-commands.h
  GEN     qga/qapi-generated/qga-qmp-marshal.c
  CC      qmp-introspect.o
  CC      qapi-types.o
  CC      qapi-visit.o
  CC      qapi-event.o
  CC      qapi/qapi-visit-core.o
  CC      qapi/qapi-dealloc-visitor.o
  CC      qapi/qobject-input-visitor.o
  CC      qapi/qobject-output-visitor.o
  CC      qapi/qmp-registry.o
  CC      qapi/qmp-dispatch.o
  CC      qapi/string-input-visitor.o
  CC      qapi/string-output-visitor.o
  CC      qapi/opts-visitor.o
  CC      qapi/qapi-clone-visitor.o
  CC      qapi/qmp-event.o
  CC      qapi/qapi-util.o
  CC      qobject/qnull.o
  CC      qobject/qnum.o
  CC      qobject/qstring.o
  CC      qobject/qdict.o
  CC      qobject/qlist.o
  CC      qobject/qjson.o
  CC      qobject/qbool.o
  CC      qobject/qobject.o
  CC      qobject/json-lexer.o
  CC      qobject/json-streamer.o
  CC      qobject/json-parser.o
  CC      trace/control.o
  CC      trace/qmp.o
  CC      util/osdep.o
  CC      util/cutils.o
  CC      util/unicode.o
  CC      util/qemu-timer-common.o
  CC      util/bufferiszero.o
  CC      util/lockcnt.o
  CC      util/aiocb.o
  CC      util/async.o
  CC      util/thread-pool.o
  CC      util/qemu-timer.o
  CC      util/main-loop.o
  CC      util/iohandler.o
  CC      util/aio-posix.o
  CC      util/compatfd.o
  CC      util/event_notifier-posix.o
  CC      util/mmap-alloc.o
  CC      util/oslib-posix.o
  CC      util/qemu-openpty.o
  CC      util/qemu-thread-posix.o
  CC      util/memfd.o
  CC      util/envlist.o
  CC      util/path.o
  CC      util/module.o
  CC      util/host-utils.o
  CC      util/bitmap.o
  CC      util/bitops.o
  CC      util/hbitmap.o
  CC      util/fifo8.o
  CC      util/acl.o
  CC      util/cacheinfo.o
  CC      util/error.o
  CC      util/qemu-error.o
  CC      util/id.o
  CC      util/iov.o
  CC      util/qemu-config.o
  CC      util/qemu-sockets.o
  CC      util/uri.o
  CC      util/notify.o
  CC      util/qemu-option.o
  CC      util/qemu-progress.o
  CC      util/keyval.o
  CC      util/hexdump.o
  CC      util/crc32c.o
  CC      util/uuid.o
  CC      util/throttle.o
  CC      util/getauxval.o
  CC      util/readline.o
  CC      util/rcu.o
  CC      util/qemu-coroutine.o
  CC      util/qemu-coroutine-lock.o
  CC      util/qemu-coroutine-io.o
  CC      util/qemu-coroutine-sleep.o
  CC      util/coroutine-ucontext.o
  CC      util/buffer.o
  CC      util/timed-average.o
  CC      util/base64.o
  CC      util/log.o
  CC      util/qdist.o
  CC      util/qht.o
  CC      util/range.o
  CC      util/stats64.o
  CC      util/systemd.o
  CC      trace-root.o
  CC      util/trace.o
  CC      crypto/trace.o
  CC      io/trace.o
  CC      migration/trace.o
  CC      block/trace.o
  CC      chardev/trace.o
  CC      hw/block/trace.o
  CC      hw/block/dataplane/trace.o
  CC      hw/char/trace.o
  CC      hw/intc/trace.o
  CC      hw/net/trace.o
  CC      hw/virtio/trace.o
  CC      hw/audio/trace.o
  CC      hw/misc/trace.o
  CC      hw/usb/trace.o
  CC      hw/scsi/trace.o
  CC      hw/nvram/trace.o
  CC      hw/display/trace.o
  CC      hw/input/trace.o
  CC      hw/timer/trace.o
  CC      hw/dma/trace.o
  CC      hw/sparc/trace.o
  CC      hw/sd/trace.o
  CC      hw/isa/trace.o
  CC      hw/mem/trace.o
  CC      hw/i386/trace.o
  CC      hw/i386/xen/trace.o
  CC      hw/9pfs/trace.o
  CC      hw/pci/trace.o
  CC      hw/ppc/trace.o
  CC      hw/s390x/trace.o
  CC      hw/vfio/trace.o
  CC      hw/acpi/trace.o
  CC      hw/arm/trace.o
  CC      hw/alpha/trace.o
  CC      hw/xen/trace.o
  CC      ui/trace.o
  CC      audio/trace.o
  CC      net/trace.o
  CC      target/arm/trace.o
  CC      target/i386/trace.o
  CC      target/mips/trace.o
  CC      target/sparc/trace.o
  CC      target/s390x/trace.o
  CC      target/ppc/trace.o
  CC      qom/trace.o
  CC      linux-user/trace.o
  CC      qapi/trace.o
  CC      accel/tcg/trace.o
  CC      accel/kvm/trace.o
  CC      nbd/trace.o
  CC      crypto/pbkdf-stub.o
  CC      stubs/arch-query-cpu-def.o
  CC      stubs/arch-query-cpu-model-expansion.o
  CC      stubs/arch-query-cpu-model-comparison.o
  CC      stubs/arch-query-cpu-model-baseline.o
  CC      stubs/bdrv-next-monitor-owned.o
  CC      stubs/blk-commit-all.o
  CC      stubs/blockdev-close-all-bdrv-states.o
  CC      stubs/clock-warp.o
  CC      stubs/cpu-get-clock.o
  CC      stubs/cpu-get-icount.o
  CC      stubs/dump.o
  CC      stubs/error-printf.o
  CC      stubs/fdset.o
  CC      stubs/gdbstub.o
  CC      stubs/get-vm-name.o
  CC      stubs/iothread.o
  CC      stubs/is-daemonized.o
  CC      stubs/iothread-lock.o
  CC      stubs/machine-init-done.o
  CC      stubs/migr-blocker.o
  CC      stubs/monitor.o
  CC      stubs/notify-event.o
  CC      stubs/qtest.o
  CC      stubs/replay.o
  CC      stubs/runstate-check.o
  CC      stubs/set-fd-handler.o
  CC      stubs/slirp.o
  CC      stubs/sysbus.o
  CC      stubs/trace-control.o
  CC      stubs/uuid.o
  CC      stubs/vm-stop.o
  CC      stubs/vmstate.o
  CC      stubs/qmp_pc_dimm_device_list.o
  CC      stubs/target-monitor-defs.o
  CC      stubs/target-get-monitor-def.o
  CC      stubs/pc_madt_cpu_entry.o
  CC      stubs/vmgenid.o
  CC      stubs/xen-common.o
  CC      stubs/xen-hvm.o
  CC      contrib/ivshmem-client/ivshmem-client.o
  CC      contrib/ivshmem-client/main.o
  CC      contrib/ivshmem-server/ivshmem-server.o
  CC      contrib/ivshmem-server/main.o
  CC      qemu-nbd.o
  CC      block.o
  CC      blockjob.o
  CC      qemu-io-cmds.o
  CC      replication.o
  CC      block/raw-format.o
  CC      block/qcow.o
  CC      block/vdi.o
  CC      block/vmdk.o
  CC      block/cloop.o
  CC      block/bochs.o
  CC      block/vpc.o
  CC      block/vvfat.o
  CC      block/qcow2-refcount.o
  CC      block/dmg.o
  CC      block/qcow2-cluster.o
  CC      block/qcow2.o
  CC      block/qcow2-snapshot.o
  CC      block/qcow2-cache.o
  CC      block/qcow2-bitmap.o
  CC      block/qed.o
  CC      block/qed-l2-cache.o
  CC      block/qed-table.o
  CC      block/qed-cluster.o
  CC      block/qed-check.o
  CC      block/vhdx.o
  CC      block/vhdx-endian.o
  CC      block/vhdx-log.o
  CC      block/quorum.o
  CC      block/parallels.o
  CC      block/blkdebug.o
  CC      block/blkverify.o
  CC      block/blkreplay.o
  CC      block/block-backend.o
  CC      block/snapshot.o
  CC      block/qapi.o
  CC      block/file-posix.o
  CC      block/null.o
  CC      block/mirror.o
  CC      block/commit.o
  CC      block/io.o
  CC      block/throttle-groups.o
  CC      block/nbd.o
  CC      block/nbd-client.o
  CC      block/sheepdog.o
  CC      block/accounting.o
  CC      block/dirty-bitmap.o
  CC      block/write-threshold.o
  CC      block/backup.o
  CC      block/replication.o
  CC      block/crypto.o
  CC      nbd/server.o
  CC      nbd/client.o
  CC      nbd/common.o
  CC      crypto/init.o
  CC      crypto/hash.o
  CC      crypto/hash-glib.o
  CC      crypto/hmac.o
  CC      crypto/hmac-glib.o
  CC      crypto/aes.o
  CC      crypto/desrfb.o
  CC      crypto/cipher.o
  CC      crypto/tlscreds.o
  CC      crypto/tlscredsanon.o
  CC      crypto/tlscredsx509.o
  CC      crypto/tlssession.o
  CC      crypto/secret.o
  CC      crypto/random-platform.o
  CC      crypto/ivgen.o
  CC      crypto/pbkdf.o
  CC      crypto/ivgen-essiv.o
  CC      crypto/ivgen-plain.o
  CC      crypto/ivgen-plain64.o
  CC      crypto/afsplit.o
  CC      crypto/xts.o
  CC      crypto/block.o
  CC      crypto/block-luks.o
  CC      crypto/block-qcow.o
  CC      io/channel.o
  CC      io/channel-buffer.o
  CC      io/channel-command.o
  CC      io/channel-socket.o
  CC      io/channel-file.o
  CC      io/channel-tls.o
  CC      io/channel-watch.o
  CC      io/channel-websock.o
  CC      io/channel-util.o
  CC      io/dns-resolver.o
  CC      io/task.o
  CC      qom/object.o
  CC      qom/container.o
  CC      qom/qom-qobject.o
  CC      qom/object_interfaces.o
  GEN     qemu-img-cmds.h
  CC      qemu-io.o
  CC      qemu-bridge-helper.o
  CC      blockdev.o
  CC      blockdev-nbd.o
  CC      bootdevice.o
  CC      iothread.o
  CC      qdev-monitor.o
  CC      device-hotplug.o
  CC      os-posix.o
  CC      bt-host.o
  CC      bt-vhci.o
  CC      dma-helpers.o
  CC      vl.o
  CC      tpm.o
  CC      device_tree.o
  CC      qmp-marshal.o
  CC      qmp.o
  CC      hmp.o
  CC      cpus-common.o
  CC      audio/audio.o
  CC      audio/noaudio.o
  CC      audio/wavaudio.o
  CC      audio/mixeng.o
  CC      audio/sdlaudio.o
  CC      audio/ossaudio.o
  CC      audio/wavcapture.o
  CC      backends/rng.o
  CC      backends/rng-egd.o
  CC      backends/rng-random.o
  CC      backends/tpm.o
  CC      backends/hostmem.o
  CC      backends/hostmem-ram.o
  CC      backends/hostmem-file.o
  CC      backends/cryptodev.o
  CC      backends/cryptodev-builtin.o
  CC      block/stream.o
  CC      chardev/msmouse.o
  CC      chardev/wctablet.o
  CC      chardev/testdev.o
  CC      disas/arm.o
  CC      disas/i386.o
  CC      fsdev/qemu-fsdev-dummy.o
  CC      fsdev/qemu-fsdev-opts.o
  CC      fsdev/qemu-fsdev-throttle.o
  CC      hw/acpi/core.o
  CC      hw/acpi/piix4.o
  CC      hw/acpi/pcihp.o
  CC      hw/acpi/ich9.o
  CC      hw/acpi/tco.o
  CC      hw/acpi/cpu_hotplug.o
  CC      hw/acpi/memory_hotplug.o
  CC      hw/acpi/cpu.o
  CC      hw/acpi/nvdimm.o
  CC      hw/acpi/vmgenid.o
  CC      hw/acpi/acpi_interface.o
  CC      hw/acpi/bios-linker-loader.o
  CC      hw/acpi/aml-build.o
  CC      hw/acpi/ipmi.o
  CC      hw/acpi/acpi-stub.o
  CC      hw/acpi/ipmi-stub.o
  CC      hw/audio/sb16.o
  CC      hw/audio/ac97.o
  CC      hw/audio/es1370.o
  CC      hw/audio/fmopl.o
  CC      hw/audio/adlib.o
  CC      hw/audio/gus.o
  CC      hw/audio/gusemu_hal.o
  CC      hw/audio/gusemu_mixer.o
  CC      hw/audio/cs4231a.o
  CC      hw/audio/intel-hda.o
  CC      hw/audio/hda-codec.o
  CC      hw/audio/pcspk.o
  CC      hw/audio/wm8750.o
  CC      hw/audio/pl041.o
  CC      hw/audio/lm4549.o
  CC      hw/audio/marvell_88w8618.o
  CC      hw/audio/soundhw.o
  CC      hw/block/block.o
  CC      hw/block/cdrom.o
  CC      hw/block/hd-geometry.o
  CC      hw/block/fdc.o
  CC      hw/block/m25p80.o
  CC      hw/block/nand.o
  CC      hw/block/pflash_cfi02.o
  CC      hw/block/pflash_cfi01.o
  CC      hw/block/ecc.o
  CC      hw/block/onenand.o
  CC      hw/block/nvme.o
  CC      hw/bt/core.o
  CC      hw/bt/l2cap.o
  CC      hw/bt/sdp.o
  CC      hw/bt/hci.o
  CC      hw/bt/hid.o
  CC      hw/bt/hci-csr.o
  CC      hw/char/ipoctal232.o
  CC      hw/char/parallel.o
  CC      hw/char/pl011.o
  CC      hw/char/serial.o
  CC      hw/char/serial-isa.o
  CC      hw/char/serial-pci.o
  CC      hw/char/virtio-console.o
  CC      hw/char/cadence_uart.o
  CC      hw/char/cmsdk-apb-uart.o
  CC      hw/char/debugcon.o
  CC      hw/char/imx_serial.o
/tmp/qemu-test/src/hw/char/cmsdk-apb-uart.c: In function ‘cmsdk_apb_uart_realize’:
/tmp/qemu-test/src/hw/char/cmsdk-apb-uart.c:341: warning: passing argument 5 of ‘qemu_chr_fe_set_handlers’ from incompatible pointer type
/tmp/qemu-test/src/include/chardev/char-fe.h:88: note: expected ‘int (*)(void *)’ but argument is of type ‘struct CMSDKAPBUART *’
/tmp/qemu-test/src/hw/char/cmsdk-apb-uart.c:341: warning: passing argument 7 of ‘qemu_chr_fe_set_handlers’ makes pointer from integer without a cast
/tmp/qemu-test/src/include/chardev/char-fe.h:88: note: expected ‘struct GMainContext *’ but argument is of type ‘int’
/tmp/qemu-test/src/hw/char/cmsdk-apb-uart.c:341: error: too few arguments to function ‘qemu_chr_fe_set_handlers’
make: *** [hw/char/cmsdk-apb-uart.o] Error 1
make: *** Waiting for unfinished jobs....
tests/docker/Makefile.include:122: recipe for target 'docker-run' failed
make[1]: *** [docker-run] Error 2
make[1]: Leaving directory '/var/tmp/patchew-tester-tmp-32l_mal7/src'
tests/docker/Makefile.include:153: recipe for target 'docker-run-test-quick@centos6' failed
make: *** [docker-run-test-quick@centos6] Error 2
=== OUTPUT END ===

Test command exited with code: 2


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH v2 2/9] hw/char/cmsdk-apb-uart.c: Implement CMSDK APB UART
  2017-07-14 15:45     ` Peter Maydell
@ 2017-07-14 16:11       ` Alex Bennée
  0 siblings, 0 replies; 26+ messages in thread
From: Alex Bennée @ 2017-07-14 16:11 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-arm, QEMU Developers, Alistair Francis,
	Philippe Mathieu-Daudé,
	patches


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

> On 14 July 2017 at 16:32, Alex Bennée <alex.bennee@linaro.org> wrote:
>>
>> Peter Maydell <peter.maydell@linaro.org> writes:
>>
>>> Implement a model of the simple "APB UART" provided in
>>> the Cortex-M System Design Kit (CMSDK).
>>>
>>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>>
>> This fails to compile, I think since
>> 81517ba37a6cec59f92396b4722861868eb0a500 change the API for
>> qemu_chr_fe_set_handlers.
>
>>> +static void cmsdk_apb_uart_update(CMSDKAPBUART *s)
>>> +{
>>> +    /* update outbound irqs, including handling the way the rxo and txo
>>> +     * interrupt status bits are just logical AND of the overrun bit in
>>> +     * STATE and the overrun interrupt enable bit in CTRL.
>>> +     */
>>> +    uint32_t omask = (R_INTSTATUS_RXO_MASK | R_INTSTATUS_TXO_MASK);
>>> +    s->intstatus &= ~omask;
>>> +    s->intstatus |= (s->state & (s->ctrl >> 2) & omask);
>>> +
>>> +    qemu_set_irq(s->txint, !!(s->intstatus & R_INTSTATUS_TX_MASK));
>>> +    qemu_set_irq(s->rxint, !!(s->intstatus & R_INTSTATUS_RX_MASK));
>>> +    qemu_set_irq(s->txovrint, !!(s->intstatus & R_INTSTATUS_TXO_MASK));
>>> +    qemu_set_irq(s->rxovrint, !!(s->intstatus & R_INTSTATUS_RXO_MASK));
>>> +    qemu_set_irq(s->uartint, !!(s->intstatus));
>>
>> If we updated qemu_set_irq to take a bool instead of int would the !!
>> hack no longer be needed?
>
> I am fairly sure we have a few places that utilize the ability
> to send an integer down the qemu_irq channel.
>
>>> +    case A_STATE:
>>> +        /* Bits 0 and 1 are read only; bits 2 and 3 are W1C */
>>> +        s->state &= ~(value & 0xc);
>>
>> I guess:
>>           s->state &= ~(value & (R_STATE_TXOVERRUN_MASK | R_STATE_RXOVERRUN_MASK));
>>
>> maybe a little too verbose.
>
> Well, it probably ought to use the bit mask names, yes.
>
>>> +static void cmsdk_apb_uart_realize(DeviceState *dev, Error **errp)
>>> +{
>>> +    CMSDKAPBUART *s = CMSDK_APB_UART(dev);
>>> +
>>> +    if (s->pclk_frq == 0) {
>>> +        error_setg(errp, "CMSDK APB UART: pclk-frq property must be set");
>>> +        return;
>>> +    }
>>> +
>>> +    /* This UART has no flow control, so we do not need to register
>>> +     * an event handler to deal with CHR_EVENT_BREAK.
>>> +     */
>>> +    qemu_chr_fe_set_handlers(&s->chr, uart_can_receive, uart_receive,
>>> +                             NULL, s, NULL, true);
>>
>> I think this is now:
>>
>>     qemu_chr_fe_set_handlers(&s->chr, uart_can_receive, uart_receive,
>>                              NULL, NULL, s, NULL, true);
>
> Yes. It looks like we don't have to support backend swaps
> (only hw/char/serial.c and virtio-console have support for that),
> so just the extra NULL argument will do fine.
>
> I propose to just fix both these nits in target-arm rather
> than resend.

Sure.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

>
> thanks
> -- PMM


--
Alex Bennée

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH v2 8/9] hw/arm/mps2: Add ethernet
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 8/9] hw/arm/mps2: Add ethernet Peter Maydell
@ 2017-07-14 16:17   ` Alex Bennée
  2017-07-14 16:23   ` [Qemu-devel] " Philippe Mathieu-Daudé
  1 sibling, 0 replies; 26+ messages in thread
From: Alex Bennée @ 2017-07-14 16:17 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-arm, qemu-devel, Alistair Francis,
	Philippe Mathieu-Daudé,
	patches


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

> The MPS2 FPGA images support ethernet via a LAN9220. We use
> QEMU's LAN9118 model, which is software compatible except
> that it is missing the checksum-offload feature.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/arm/mps2.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
> index bdc631a..6adfb22 100644
> --- a/hw/arm/mps2.c
> +++ b/hw/arm/mps2.c
> @@ -35,6 +35,8 @@
>  #include "hw/char/cmsdk-apb-uart.h"
>  #include "hw/timer/cmsdk-apb-timer.h"
>  #include "hw/misc/mps2-scc.h"
> +#include "hw/devices.h"
> +#include "net/net.h"
>
>  typedef enum MPS2FPGAType {
>      FPGA_AN385,
> @@ -210,7 +212,6 @@ static void mps2_common_init(MachineState *machine)
>      create_unimplemented_device("Extra peripheral region @0x40020000",
>                                  0x40020000, 0x00010000);
>      create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
> -    create_unimplemented_device("Ethernet", 0x40200000, 0x00100000);
>      create_unimplemented_device("VGA", 0x41000000, 0x0200000);
>
>      switch (mmc->fpga_type) {
> @@ -309,6 +310,13 @@ static void mps2_common_init(MachineState *machine)
>                               &error_fatal);
>      sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
>
> +    /* In hardware this is a LAN9220; the LAN9118 is software compatible
> +     * except that it doesn't support the checksum-offload feature.
> +     */
> +    lan9118_init(&nd_table[0], 0x40200000,
> +                 qdev_get_gpio_in(armv7m,
> +                                  mmc->fpga_type == FPGA_AN385 ? 13 : 47));
> +

As the lan9118 model will log guest errors if the software tries to
access the csum feature I guess thats OK.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>


>      system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
>
>      armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,


--
Alex Bennée

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH v2 9/9] MAINTAINERS: Add entries for MPS2 board
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 9/9] MAINTAINERS: Add entries for MPS2 board Peter Maydell
@ 2017-07-14 16:18   ` Alex Bennée
  2017-07-14 16:24   ` [Qemu-devel] " Philippe Mathieu-Daudé
  1 sibling, 0 replies; 26+ messages in thread
From: Alex Bennée @ 2017-07-14 16:18 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-arm, qemu-devel, Alistair Francis,
	Philippe Mathieu-Daudé,
	patches


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

> Add entries to the MAINTAINERS file for the new MPS2
> board and devices.
>
> Since the CMSDK devices are not specific to the MPS2 board,
> extend the existing 'PrimeCell' section to cover CMSDK
> devices as well; in both cases these are devices implemented
> by ARM and provided as RTL that may be used in multiple
> SoCs and boards.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

> ---
>  MAINTAINERS | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 9529c94..10f5cd6 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -380,7 +380,7 @@ F: hw/*/allwinner*
>  F: include/hw/*/allwinner*
>  F: hw/arm/cubieboard.c
>
> -ARM PrimeCell
> +ARM PrimeCell and CMSDK devices
>  M: Peter Maydell <peter.maydell@linaro.org>
>  L: qemu-arm@nongnu.org
>  S: Maintained
> @@ -394,6 +394,10 @@ F: hw/intc/pl190.c
>  F: hw/sd/pl181.c
>  F: hw/timer/pl031.c
>  F: include/hw/arm/primecell.h
> +F: hw/timer/cmsdk-apb-timer.c
> +F: include/hw/timer/cmsdk-apb-timer.h
> +F: hw/char/cmsdk-apb-uart.c
> +F: include/hw/char/cmsdk-apb-uart.h
>
>  ARM cores
>  M: Peter Maydell <peter.maydell@linaro.org>
> @@ -455,6 +459,14 @@ S: Maintained
>  F: hw/arm/integratorcp.c
>  F: hw/misc/arm_integrator_debug.c
>
> +MPS2
> +M: Peter Maydell <peter.maydell@linaro.org>
> +L: qemu-arm@nongnu.org
> +S: Maintained
> +F: hw/arm/mps2.c
> +F: hw/misc/mps2-scc.c
> +F: include/hw/misc/mps2-scc.h
> +
>  Musicpal
>  M: Jan Kiszka <jan.kiszka@web.de>
>  L: qemu-arm@nongnu.org


--
Alex Bennée

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

* Re: [Qemu-devel] [PATCH v2 8/9] hw/arm/mps2: Add ethernet
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 8/9] hw/arm/mps2: Add ethernet Peter Maydell
  2017-07-14 16:17   ` [Qemu-devel] [Qemu-arm] " Alex Bennée
@ 2017-07-14 16:23   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 26+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-07-14 16:23 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches, Alistair Francis

On 07/14/2017 07:51 AM, Peter Maydell wrote:
> The MPS2 FPGA images support ethernet via a LAN9220. We use
> QEMU's LAN9118 model, which is software compatible except
> that it is missing the checksum-offload feature.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

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

> ---
>   hw/arm/mps2.c | 10 +++++++++-
>   1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
> index bdc631a..6adfb22 100644
> --- a/hw/arm/mps2.c
> +++ b/hw/arm/mps2.c
> @@ -35,6 +35,8 @@
>   #include "hw/char/cmsdk-apb-uart.h"
>   #include "hw/timer/cmsdk-apb-timer.h"
>   #include "hw/misc/mps2-scc.h"
> +#include "hw/devices.h"
> +#include "net/net.h"
>   
>   typedef enum MPS2FPGAType {
>       FPGA_AN385,
> @@ -210,7 +212,6 @@ static void mps2_common_init(MachineState *machine)
>       create_unimplemented_device("Extra peripheral region @0x40020000",
>                                   0x40020000, 0x00010000);
>       create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
> -    create_unimplemented_device("Ethernet", 0x40200000, 0x00100000);
>       create_unimplemented_device("VGA", 0x41000000, 0x0200000);
>   
>       switch (mmc->fpga_type) {
> @@ -309,6 +310,13 @@ static void mps2_common_init(MachineState *machine)
>                                &error_fatal);
>       sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
>   
> +    /* In hardware this is a LAN9220; the LAN9118 is software compatible
> +     * except that it doesn't support the checksum-offload feature.
> +     */
> +    lan9118_init(&nd_table[0], 0x40200000,
> +                 qdev_get_gpio_in(armv7m,
> +                                  mmc->fpga_type == FPGA_AN385 ? 13 : 47));
> +
>       system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
>   
>       armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
> 

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

* Re: [Qemu-devel] [PATCH v2 9/9] MAINTAINERS: Add entries for MPS2 board
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 9/9] MAINTAINERS: Add entries for MPS2 board Peter Maydell
  2017-07-14 16:18   ` [Qemu-devel] [Qemu-arm] " Alex Bennée
@ 2017-07-14 16:24   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 26+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-07-14 16:24 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches, Alistair Francis

On 07/14/2017 07:51 AM, Peter Maydell wrote:
> Add entries to the MAINTAINERS file for the new MPS2
> board and devices.
> 
> Since the CMSDK devices are not specific to the MPS2 board,
> extend the existing 'PrimeCell' section to cover CMSDK
> devices as well; in both cases these are devices implemented
> by ARM and provided as RTL that may be used in multiple
> SoCs and boards.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

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

> ---
>   MAINTAINERS | 14 +++++++++++++-
>   1 file changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 9529c94..10f5cd6 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -380,7 +380,7 @@ F: hw/*/allwinner*
>   F: include/hw/*/allwinner*
>   F: hw/arm/cubieboard.c
>   
> -ARM PrimeCell
> +ARM PrimeCell and CMSDK devices
>   M: Peter Maydell <peter.maydell@linaro.org>
>   L: qemu-arm@nongnu.org
>   S: Maintained
> @@ -394,6 +394,10 @@ F: hw/intc/pl190.c
>   F: hw/sd/pl181.c
>   F: hw/timer/pl031.c
>   F: include/hw/arm/primecell.h
> +F: hw/timer/cmsdk-apb-timer.c
> +F: include/hw/timer/cmsdk-apb-timer.h
> +F: hw/char/cmsdk-apb-uart.c
> +F: include/hw/char/cmsdk-apb-uart.h
>   
>   ARM cores
>   M: Peter Maydell <peter.maydell@linaro.org>
> @@ -455,6 +459,14 @@ S: Maintained
>   F: hw/arm/integratorcp.c
>   F: hw/misc/arm_integrator_debug.c
>   
> +MPS2
> +M: Peter Maydell <peter.maydell@linaro.org>
> +L: qemu-arm@nongnu.org
> +S: Maintained
> +F: hw/arm/mps2.c
> +F: hw/misc/mps2-scc.c
> +F: include/hw/misc/mps2-scc.h
> +
>   Musicpal
>   M: Jan Kiszka <jan.kiszka@web.de>
>   L: qemu-arm@nongnu.org
> 

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

* Re: [Qemu-devel] [PATCH v2 2/9] hw/char/cmsdk-apb-uart.c: Implement CMSDK APB UART
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 2/9] hw/char/cmsdk-apb-uart.c: Implement CMSDK APB UART Peter Maydell
  2017-07-14 15:32   ` [Qemu-devel] [Qemu-arm] " Alex Bennée
@ 2017-07-14 16:29   ` Philippe Mathieu-Daudé
  2017-07-14 16:31     ` Peter Maydell
  1 sibling, 1 reply; 26+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-07-14 16:29 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches, Alistair Francis

Hi Peter,

On 07/14/2017 07:51 AM, Peter Maydell wrote:
> Implement a model of the simple "APB UART" provided in
> the Cortex-M System Design Kit (CMSDK).
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>   hw/char/Makefile.objs            |   1 +
>   include/hw/char/cmsdk-apb-uart.h |  78 ++++++++
>   hw/char/cmsdk-apb-uart.c         | 402 +++++++++++++++++++++++++++++++++++++++
>   default-configs/arm-softmmu.mak  |   2 +
>   hw/char/trace-events             |   9 +
>   5 files changed, 492 insertions(+)
>   create mode 100644 include/hw/char/cmsdk-apb-uart.h
>   create mode 100644 hw/char/cmsdk-apb-uart.c
> 
> diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
> index 55fcb68..1bcd37e 100644
> --- a/hw/char/Makefile.objs
> +++ b/hw/char/Makefile.objs
> @@ -19,6 +19,7 @@ obj-$(CONFIG_DIGIC) += digic-uart.o
>   obj-$(CONFIG_STM32F2XX_USART) += stm32f2xx_usart.o
>   obj-$(CONFIG_RASPI) += bcm2835_aux.o
>   
> +common-obj-$(CONFIG_CMSDK_APB_UART) += cmsdk-apb-uart.o
>   common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
>   common-obj-$(CONFIG_ISA_DEBUG) += debugcon.o
>   common-obj-$(CONFIG_GRLIB) += grlib_apbuart.o
[...]> diff --git a/default-configs/arm-softmmu.mak 
b/default-configs/arm-softmmu.mak
> index bfd2a88..d128e9d 100644
> --- a/default-configs/arm-softmmu.mak
> +++ b/default-configs/arm-softmmu.mak
> @@ -96,6 +96,8 @@ CONFIG_STM32F2XX_ADC=y
>   CONFIG_STM32F2XX_SPI=y
>   CONFIG_STM32F205_SOC=y
>   
> +CONFIG_CMSDK_APB_UART=y

I'd prefer:

CONFIG_CMSDK_APB_UART=$(CONFIG_MPS2)

> +
>   CONFIG_VERSATILE_PCI=y
>   CONFIG_VERSATILE_I2C=y
[...]

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

* Re: [Qemu-devel] [PATCH v2 4/9] hw/char/cmsdk-apb-timer: Implement CMSDK APB timer device
  2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 4/9] hw/char/cmsdk-apb-timer: Implement CMSDK APB timer device Peter Maydell
@ 2017-07-14 16:30   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 26+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-07-14 16:30 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: patches, Alistair Francis

On 07/14/2017 07:51 AM, Peter Maydell wrote:
> Implement a model of the simple timer device found in the CMSDK.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>   hw/timer/Makefile.objs             |   1 +
>   include/hw/timer/cmsdk-apb-timer.h |  59 +++++++++
>   hw/timer/cmsdk-apb-timer.c         | 253 +++++++++++++++++++++++++++++++++++++
>   default-configs/arm-softmmu.mak    |   1 +
>   hw/timer/trace-events              |   5 +
>   5 files changed, 319 insertions(+)
>   create mode 100644 include/hw/timer/cmsdk-apb-timer.h
>   create mode 100644 hw/timer/cmsdk-apb-timer.c
> 
> diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
> index dd6f27e..15cce1c 100644
> --- a/hw/timer/Makefile.objs
> +++ b/hw/timer/Makefile.objs
> @@ -41,3 +41,4 @@ common-obj-$(CONFIG_STM32F2XX_TIMER) += stm32f2xx_timer.o
>   common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
>   
>   common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
> +common-obj-$(CONFIG_CMSDK_APB_TIMER) += cmsdk-apb-timer.o
[...]
> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
> index d128e9d..c75f52c 100644
> --- a/default-configs/arm-softmmu.mak
> +++ b/default-configs/arm-softmmu.mak
> @@ -96,6 +96,7 @@ CONFIG_STM32F2XX_ADC=y
>   CONFIG_STM32F2XX_SPI=y
>   CONFIG_STM32F205_SOC=y
>   
> +CONFIG_CMSDK_APB_TIMER=y

and here:

CONFIG_CMSDK_APB_TIMER=$(CONFIG_MPS2)

>   CONFIG_CMSDK_APB_UART=y
>   
>   CONFIG_VERSATILE_PCI=y
[...]

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

* Re: [Qemu-devel] [PATCH v2 2/9] hw/char/cmsdk-apb-uart.c: Implement CMSDK APB UART
  2017-07-14 16:29   ` [Qemu-devel] " Philippe Mathieu-Daudé
@ 2017-07-14 16:31     ` Peter Maydell
  0 siblings, 0 replies; 26+ messages in thread
From: Peter Maydell @ 2017-07-14 16:31 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: qemu-arm, QEMU Developers, patches, Alistair Francis

On 14 July 2017 at 17:29, Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
> Hi Peter,
>
> On 07/14/2017 07:51 AM, Peter Maydell wrote:
>>
>> Implement a model of the simple "APB UART" provided in
>> the Cortex-M System Design Kit (CMSDK).
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> ---
>>   hw/char/Makefile.objs            |   1 +
>>   include/hw/char/cmsdk-apb-uart.h |  78 ++++++++
>>   hw/char/cmsdk-apb-uart.c         | 402
>> +++++++++++++++++++++++++++++++++++++++
>>   default-configs/arm-softmmu.mak  |   2 +
>>   hw/char/trace-events             |   9 +
>>   5 files changed, 492 insertions(+)
>>   create mode 100644 include/hw/char/cmsdk-apb-uart.h
>>   create mode 100644 hw/char/cmsdk-apb-uart.c
>>
>> diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
>> index 55fcb68..1bcd37e 100644
>> --- a/hw/char/Makefile.objs
>> +++ b/hw/char/Makefile.objs
>> @@ -19,6 +19,7 @@ obj-$(CONFIG_DIGIC) += digic-uart.o
>>   obj-$(CONFIG_STM32F2XX_USART) += stm32f2xx_usart.o
>>   obj-$(CONFIG_RASPI) += bcm2835_aux.o
>>   +common-obj-$(CONFIG_CMSDK_APB_UART) += cmsdk-apb-uart.o
>>   common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
>>   common-obj-$(CONFIG_ISA_DEBUG) += debugcon.o
>>   common-obj-$(CONFIG_GRLIB) += grlib_apbuart.o
>
> [...]> diff --git a/default-configs/arm-softmmu.mak
> b/default-configs/arm-softmmu.mak
>>
>> index bfd2a88..d128e9d 100644
>> --- a/default-configs/arm-softmmu.mak
>> +++ b/default-configs/arm-softmmu.mak
>> @@ -96,6 +96,8 @@ CONFIG_STM32F2XX_ADC=y
>>   CONFIG_STM32F2XX_SPI=y
>>   CONFIG_STM32F205_SOC=y
>>   +CONFIG_CMSDK_APB_UART=y
>
>
> I'd prefer:
>
> CONFIG_CMSDK_APB_UART=$(CONFIG_MPS2)

That would just need changing when we add the next
board that uses this UART. None of the other config switches
in this file set themselves based on a board config switch.

thanks
-- PMM

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

* Re: [Qemu-devel] [Qemu-arm] [PATCH v2 3/9] hw/arm/mps2: Add UARTs
  2017-07-14 16:07     ` Peter Maydell
@ 2017-07-14 16:35       ` Alex Bennée
  0 siblings, 0 replies; 26+ messages in thread
From: Alex Bennée @ 2017-07-14 16:35 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-arm, QEMU Developers, Alistair Francis,
	Philippe Mathieu-Daudé,
	patches


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

> On 14 July 2017 at 16:52, Alex Bennée <alex.bennee@linaro.org> wrote:
>>
>> Peter Maydell <peter.maydell@linaro.org> writes:
>>
>>> Add the UARTs to the MPS2 board models.
>>>
>>> Unfortunately the details of the wiring of the interrupts through
>>> various OR gates differ between AN511 and AN385 so this can't
>>> be purely a data-driven difference.
>>>
>>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>>> Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
>>> ---
>>>  hw/arm/mps2.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>  1 file changed, 86 insertions(+)
>>>
>>> diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
>>> index 3dad02d..180c5d2 100644
>>> --- a/hw/arm/mps2.c
>>> +++ b/hw/arm/mps2.c
>>> @@ -27,9 +27,12 @@
>>>  #include "qemu/error-report.h"
>>>  #include "hw/arm/arm.h"
>>>  #include "hw/arm/armv7m.h"
>>> +#include "hw/or-irq.h"
>>>  #include "hw/boards.h"
>>>  #include "exec/address-spaces.h"
>>> +#include "sysemu/sysemu.h"
>>>  #include "hw/misc/unimp.h"
>>> +#include "hw/char/cmsdk-apb-uart.h"
>>>
>>>  typedef enum MPS2FPGAType {
>>>      FPGA_AN385,
>>> @@ -206,6 +209,89 @@ static void mps2_common_init(MachineState *machine)
>>>      create_unimplemented_device("Ethernet", 0x40200000, 0x00100000);
>>>      create_unimplemented_device("VGA", 0x41000000, 0x0200000);
>>>
>>> +    switch (mmc->fpga_type) {
>>> +    case FPGA_AN385:
>>> +    {
>>> +        /* The overflow IRQs for UARTs 0, 1 and 2 are ORed together.
>>> +         * Overflow for UARTs 4 and 5 doesn't trigger any interrupt.
>>> +         */
>>> +        Object *orgate;
>>> +        DeviceState *orgate_dev;
>>> +        int i;
>>> +
>>> +        orgate = object_new(TYPE_OR_IRQ);
>>> +        object_property_set_int(orgate, 6, "num-lines", &error_fatal);
>>> +        object_property_set_bool(orgate, true, "realized", &error_fatal);
>>> +        orgate_dev = DEVICE(orgate);
>>> +        qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
>>> +
>>> +        for (i = 0; i < 5; i++) {
>>> +            hwaddr uartbase[] = {0x40004000, 0x40005000, 0x40006000,
>>> +                                 0x40007000, 0x40009000};
>>
>> I would expect these to be something like:
>>
>>   static hwaddr an385_uartbase[] = {0x40004000, 0x40005000, 0x40006000,
>>                                     0x40007000, 0x40009000};
>>   static hwaddr an511_uartbase[] = {0x40004000, 0x40005000, 0x4002c000,
>>                                     0x4002d000, 0x4002e000};
>>
>> to save the compiler from filling in the table every loop. Not that it
>> makes much different for an init routine.
>
> I'm slightly surprised the compiler can't tell that these
> are never written and emit the same code for all of them,
> but yeah, let's just 'static const' all of them.

I was just curious so I objdumped - maybe we should poke our TCWG
friends ;-)

--
Alex Bennée

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

end of thread, other threads:[~2017-07-14 16:35 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-14 10:51 [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours) Peter Maydell
2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 1/9] hw/arm/mps2: Implement skeleton mps2-an385 and mps2-an511 board models Peter Maydell
2017-07-14 14:44   ` [Qemu-devel] [Qemu-arm] " Alex Bennée
2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 2/9] hw/char/cmsdk-apb-uart.c: Implement CMSDK APB UART Peter Maydell
2017-07-14 15:32   ` [Qemu-devel] [Qemu-arm] " Alex Bennée
2017-07-14 15:45     ` Peter Maydell
2017-07-14 16:11       ` Alex Bennée
2017-07-14 16:29   ` [Qemu-devel] " Philippe Mathieu-Daudé
2017-07-14 16:31     ` Peter Maydell
2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 3/9] hw/arm/mps2: Add UARTs Peter Maydell
2017-07-14 15:52   ` [Qemu-devel] [Qemu-arm] " Alex Bennée
2017-07-14 16:07     ` Peter Maydell
2017-07-14 16:35       ` Alex Bennée
2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 4/9] hw/char/cmsdk-apb-timer: Implement CMSDK APB timer device Peter Maydell
2017-07-14 16:30   ` Philippe Mathieu-Daudé
2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 5/9] hw/arm/mps2: Add timers Peter Maydell
2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 6/9] hw/misc/mps2_scc: Implement MPS2 Serial Communication Controller Peter Maydell
2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 7/9] hw/arm/mps2: Add SCC Peter Maydell
2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 8/9] hw/arm/mps2: Add ethernet Peter Maydell
2017-07-14 16:17   ` [Qemu-devel] [Qemu-arm] " Alex Bennée
2017-07-14 16:23   ` [Qemu-devel] " Philippe Mathieu-Daudé
2017-07-14 10:51 ` [Qemu-devel] [PATCH v2 9/9] MAINTAINERS: Add entries for MPS2 board Peter Maydell
2017-07-14 16:18   ` [Qemu-devel] [Qemu-arm] " Alex Bennée
2017-07-14 16:24   ` [Qemu-devel] " Philippe Mathieu-Daudé
2017-07-14 12:16 ` [Qemu-devel] [PATCH v2 0/9] ARM: implement MPS2 board (with 2 FPGA flavours) no-reply
2017-07-14 16:08 ` no-reply

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