Skip to contentSkip to conversation

Update the Netduino 2 Machine

PATCH Superseded Alistair Francis 2 participants 9 messages Aug 3, 2016 – Sep 11, 2016 Arm STM32

v6 of 8 Superseded Latest is v8 →

lore
Share & tools
lore
#0 lore raw

v6 cover Update the Netduino 2 Machine

This patchset continues with the Netduino 2 and STM32F205 SoC work.

This patch series makes a small change to the STM32F2xx SoC to tidy up the code.

Next a feature is added to the STM32F2xx timer to display the PWM duty cycle, when debugging is enabled.

Then the STM32F2xx SPI and ADC devices are added and connected to the STM32F205 SoC.

Finally the maintainers file is updated to add myself as the maintainer for the Netdunio 2 and STM32F2xx.

V6:
- Add vmstate to the new OR IRQ device
V5:
- Add a irq ORing function
V4:
- Add VMState to the new devices
- Remove rand() function
V3:
- Rebase
V2:
- Update based on Peter C's coments
- Rebase
- Create an ADC folder for the ADC device

Alistair Francis (8):
STM32F205: Remove the individual device variables
STM32F2xx: Display PWM duty cycle from timer
STM32F2xx: Add the ADC device
STM32F2xx: Add the SPI device
irq: Add a new irq device that allows the ORing of lines
STM32F205: Connect the ADC devices
STM32F205: Connect the SPI devices
MAINTAINERS: Add Alistair to the maintainers list

 MAINTAINERS                     |  15 ++
 default-configs/arm-softmmu.mak |   2 +
 hw/Makefile.objs                |   1 +
 hw/adc/Makefile.objs            |   1 +
 hw/adc/stm32f2xx_adc.c          | 306 ++++++++++++++++++++++++++++++++++++++++
 hw/arm/stm32f205_soc.c          |  82 ++++++++---
 hw/core/Makefile.objs           |   1 +
 hw/core/irq.c                   |   1 +
 hw/core/or-irq.c                | 102 ++++++++++++++
 hw/ssi/Makefile.objs            |   1 +
 hw/ssi/stm32f2xx_spi.c          | 225 +++++++++++++++++++++++++++++
 hw/timer/stm32f2xx_timer.c      |   9 ++
 include/hw/adc/stm32f2xx_adc.h  |  87 ++++++++++++
 include/hw/arm/stm32f205_soc.h  |   6 +
 include/hw/irq.h                |  15 ++
 include/hw/ssi/stm32f2xx_spi.h  |  72 ++++++++++
 16 files changed, 908 insertions(+), 18 deletions(-)
 create mode 100644 hw/adc/Makefile.objs
 create mode 100644 hw/adc/stm32f2xx_adc.c
 create mode 100644 hw/core/or-irq.c
 create mode 100644 hw/ssi/stm32f2xx_spi.c
 create mode 100644 include/hw/adc/stm32f2xx_adc.h
 create mode 100644 include/hw/ssi/stm32f2xx_spi.h
Signature · 1 line
2.7.4
#1 lore raw

PATCH v6 1/8 STM32F205: Remove the individual device variables

Cleanup the individual DeviceState and SysBusDevice variables to re-use the same variable for each device.

---

 hw/arm/stm32f205_soc.c | 35 +++++++++++++++++------------------
 1 file changed, 17 insertions(+), 18 deletions(-)
hw/arm/stm32f205_soc.c +17 -18
index de26b8c..5b6fa3b 100644
@@ -62,8 +62,8 @@ static void stm32f205_soc_initfn(Object *obj)
 static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
 {
     STM32F205State *s = STM32F205_SOC(dev_soc);
-    DeviceState *syscfgdev, *usartdev, *timerdev, *nvic;
-    SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev;
+    DeviceState *dev, *nvic;
+    SysBusDevice *busdev;
     Error *err = NULL;
     int i;
 
@@ -94,44 +94,43 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
                        s->kernel_filename, s->cpu_model);
 
     /* System configuration controller */
-    syscfgdev = DEVICE(&s->syscfg);
+    dev = DEVICE(&s->syscfg);
     object_property_set_bool(OBJECT(&s->syscfg), true, "realized", &err);
     if (err != NULL) {
         error_propagate(errp, err);
         return;
     }
-    syscfgbusdev = SYS_BUS_DEVICE(syscfgdev);
-    sysbus_mmio_map(syscfgbusdev, 0, 0x40013800);
-    sysbus_connect_irq(syscfgbusdev, 0, qdev_get_gpio_in(nvic, 71));
+    busdev = SYS_BUS_DEVICE(dev);
+    sysbus_mmio_map(busdev, 0, 0x40013800);
+    sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(nvic, 71));
 
     /* Attach UART (uses USART registers) and USART controllers */
     for (i = 0; i < STM_NUM_USARTS; i++) {
-        usartdev = DEVICE(&(s->usart[i]));
-        qdev_prop_set_chr(usartdev, "chardev", i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL);
+        dev = DEVICE(&(s->usart[i]));
+        qdev_prop_set_chr(dev, "chardev",
+                          i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL);
         object_property_set_bool(OBJECT(&s->usart[i]), true, "realized", &err);
         if (err != NULL) {
             error_propagate(errp, err);
             return;
         }
-        usartbusdev = SYS_BUS_DEVICE(usartdev);
-        sysbus_mmio_map(usartbusdev, 0, usart_addr[i]);
-        sysbus_connect_irq(usartbusdev, 0,
-                           qdev_get_gpio_in(nvic, usart_irq[i]));
+        busdev = SYS_BUS_DEVICE(dev);
+        sysbus_mmio_map(busdev, 0, usart_addr[i]);
+        sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(nvic, usart_irq[i]));
     }
 
     /* Timer 2 to 5 */
     for (i = 0; i < STM_NUM_TIMERS; i++) {
-        timerdev = DEVICE(&(s->timer[i]));
-        qdev_prop_set_uint64(timerdev, "clock-frequency", 1000000000);
+        dev = DEVICE(&(s->timer[i]));
+        qdev_prop_set_uint64(dev, "clock-frequency", 1000000000);
         object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);
         if (err != NULL) {
             error_propagate(errp, err);
             return;
         }
-        timerbusdev = SYS_BUS_DEVICE(timerdev);
-        sysbus_mmio_map(timerbusdev, 0, timer_addr[i]);
-        sysbus_connect_irq(timerbusdev, 0,
-                           qdev_get_gpio_in(nvic, timer_irq[i]));
+        busdev = SYS_BUS_DEVICE(dev);
+        sysbus_mmio_map(busdev, 0, timer_addr[i]);
+        sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(nvic, timer_irq[i]));
     }
 }
 
Signature · 1 line
2.7.4
#2 lore raw

PATCH v6 2/8 STM32F2xx: Display PWM duty cycle from timer

In reply to Alistair Francis

If correctly configured allow the STM32F2xx timer to print out the PWM duty cycle information.

---
V3:
- Use OR instead of + for masking
- Improve clarity of print statement
V2:
- Fix up if statement braces
- Remove stm32f2xx_timer_set_alarm() call

 hw/timer/stm32f2xx_timer.c | 9 +++++++++
 1 file changed, 9 insertions(+)
hw/timer/stm32f2xx_timer.c +9 -0
index bf0fb28..8c4c1f9 100644
@@ -51,6 +51,15 @@ static void stm32f2xx_timer_interrupt(void *opaque)
         qemu_irq_pulse(s->irq);
         stm32f2xx_timer_set_alarm(s, s->hit_time);
     }
+
+    if (s->tim_ccmr1 & (TIM_CCMR1_OC2M2 | TIM_CCMR1_OC2M1) &&
+        !(s->tim_ccmr1 & TIM_CCMR1_OC2M0) &&
+        s->tim_ccmr1 & TIM_CCMR1_OC2PE &&
+        s->tim_ccer & TIM_CCER_CC2E) {
+        /* PWM 2 - Mode 1 */
+        DB_PRINT("PWM2 Duty Cycle: %d%%\n",
+                s->tim_ccr2 / (100 * (s->tim_psc + 1)));
+    }
 }
 
 static inline int64_t stm32f2xx_ns_to_ticks(STM32F2XXTimerState *s, int64_t t)
Signature · 1 line
2.7.4
#3 lore raw

PATCH v6 3/8 STM32F2xx: Add the ADC device

In reply to Alistair Francis

Add the STM32F2xx ADC device. This device randomly generates values on each read.

This also includes creating a hw/adc directory.

---
V4:
- Remove the rand() function
- Add VMState
- Small cleanups
V2:
- Address Peter C's comments
- Create a ADC folder and move the file in there
- Move some of the registers into arrays

 default-configs/arm-softmmu.mak |   1 +
 hw/Makefile.objs                |   1 +
 hw/adc/Makefile.objs            |   1 +
 hw/adc/stm32f2xx_adc.c          | 306 ++++++++++++++++++++++++++++++++++++++++
 include/hw/adc/stm32f2xx_adc.h  |  87 ++++++++++++
 5 files changed, 396 insertions(+)
 create mode 100644 hw/adc/Makefile.objs
 create mode 100644 hw/adc/stm32f2xx_adc.c
 create mode 100644 include/hw/adc/stm32f2xx_adc.h
default-configs/arm-softmmu.mak +1 -0
index 7a19863..5b1696d 100644
@@ -87,6 +87,7 @@ CONFIG_ZYNQ=y
 CONFIG_STM32F2XX_TIMER=y
 CONFIG_STM32F2XX_USART=y
 CONFIG_STM32F2XX_SYSCFG=y
+CONFIG_STM32F2XX_ADC=y
 CONFIG_STM32F205_SOC=y
 
 CONFIG_VERSATILE_PCI=y
hw/Makefile.objs +1 -0
index 4a07ed4..0ffd281 100644
@@ -1,5 +1,6 @@
 devices-dirs-$(call land, $(CONFIG_VIRTIO),$(call land,$(CONFIG_VIRTFS),$(CONFIG_PCI))) += 9pfs/
 devices-dirs-$(CONFIG_ACPI) += acpi/
+devices-dirs-$(CONFIG_SOFTMMU) += adc/
 devices-dirs-$(CONFIG_SOFTMMU) += audio/
 devices-dirs-$(CONFIG_SOFTMMU) += block/
 devices-dirs-$(CONFIG_SOFTMMU) += bt/
hw/adc/Makefile.objs new file +1 -0
new file mode 100644
index 0000000..3f6dfde
@@ -0,0 +1 @@
+obj-$(CONFIG_STM32F2XX_ADC) += stm32f2xx_adc.o
hw/adc/stm32f2xx_adc.c new file +306 -0

306 lines not on this page · raw message

include/hw/adc/stm32f2xx_adc.h new file +87 -0

87 lines not on this page · raw message

Signature · 1 line
2.7.4
#4 lore raw

PATCH v6 4/8 STM32F2xx: Add the SPI device

In reply to Alistair Francis

Add the STM32F2xx SPI device.

---
V4:
- Add VMState
- Small fixes
V2:
- Address Peter C's comments

 default-configs/arm-softmmu.mak |   1 +
 hw/ssi/Makefile.objs            |   1 +
 hw/ssi/stm32f2xx_spi.c          | 225 ++++++++++++++++++++++++++++++++++++++++
 include/hw/ssi/stm32f2xx_spi.h  |  72 +++++++++++++
 4 files changed, 299 insertions(+)
 create mode 100644 hw/ssi/stm32f2xx_spi.c
 create mode 100644 include/hw/ssi/stm32f2xx_spi.h
default-configs/arm-softmmu.mak +1 -0
index 5b1696d..e9e2de3 100644
@@ -88,6 +88,7 @@ CONFIG_STM32F2XX_TIMER=y
 CONFIG_STM32F2XX_USART=y
 CONFIG_STM32F2XX_SYSCFG=y
 CONFIG_STM32F2XX_ADC=y
+CONFIG_STM32F2XX_SPI=y
 CONFIG_STM32F205_SOC=y
 
 CONFIG_VERSATILE_PCI=y
hw/ssi/Makefile.objs +1 -0
index c79a8dc..487add2 100644
@@ -3,6 +3,7 @@ common-obj-$(CONFIG_SSI) += ssi.o
 common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
 common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
+common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
 
 obj-$(CONFIG_OMAP) += omap_spi.o
 obj-$(CONFIG_IMX) += imx_spi.o
hw/ssi/stm32f2xx_spi.c new file +225 -0

225 lines not on this page · raw message

include/hw/ssi/stm32f2xx_spi.h new file +72 -0

72 lines not on this page · raw message

Signature · 1 line
2.7.4
#5 lore raw

PATCH v6 5/8 irq: Add a new irq device that allows the ORing of lines

In reply to Alistair Francis

---
As the migration framework is not included in user mode this needs to be a new file.

V6:
- Make the OR IRQ device a TYPE_DEVICE
- Add vmstate

 hw/core/Makefile.objs |   1 +
 hw/core/irq.c         |   1 +
 hw/core/or-irq.c      | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/irq.h      |  15 ++++++++
 4 files changed, 119 insertions(+)
 create mode 100644 hw/core/or-irq.c
hw/core/Makefile.objs +1 -0
index cfd4840..b47241b 100644
@@ -16,4 +16,5 @@ common-obj-$(CONFIG_SOFTMMU) += null-machine.o
 common-obj-$(CONFIG_SOFTMMU) += loader.o
 common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
 common-obj-$(CONFIG_SOFTMMU) += register.o
+common-obj-$(CONFIG_SOFTMMU) += or-irq.o
 common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o
hw/core/irq.c +1 -0
index 49ff2e6..dc874cc 100644
@@ -24,6 +24,7 @@
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "hw/irq.h"
+#include "hw/sysbus.h"
 #include "qom/object.h"
 
 #define IRQ(obj) OBJECT_CHECK(struct IRQState, (obj), TYPE_IRQ)
hw/core/or-irq.c new file +102 -0

102 lines not on this page · raw message

include/hw/irq.h +15 -0
index 4c4c2ea..5e8a3b6 100644
@@ -4,8 +4,12 @@
 /* Generic IRQ/GPIO pin infrastructure.  */
 
 #define TYPE_IRQ "irq"
+#define TYPE_OR_IRQ "or-irq"
+
+#define MAX_OR_LINES      16
 
 typedef struct IRQState *qemu_irq;
+typedef struct OrIRQState qemu_or_irq;
 
 typedef void (*qemu_irq_handler)(void *opaque, int n, int level);
 
@@ -38,6 +42,17 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n);
  */
 qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n);
 
+/*
+ * qemu_allocate_or_irqs
+ * @in_irq: An input IRQ. It will be the result of the @out_irqs ORed together
+ * @n: The number of interrupt lines that should be ORed together
+ *
+ * returns: An array of interrupts that should be ORed together
+ *
+ * OR all of the interrupts returned in the array into a single @in_irq.
+ */
+qemu_irq *qemu_allocate_or_irqs(qemu_irq in_irq, int n);
+
 /* Extends an Array of IRQs. Old IRQs have their handlers and opaque data
  * preserved. New IRQs are assigned the argument handler and opaque data.
  */
Signature · 1 line
2.7.4
#6 lore raw

Re: [Qemu-devel] [PATCH v6 5/8] irq: Add a new irq device that allows the ORing of lines

Quoted 31 lines · Alistair Francis

---
As the migration framework is not included in user mode this needs to be a new file.

V6:
- Make the OR IRQ device a TYPE_DEVICE
- Add vmstate

 hw/core/Makefile.objs |   1 +
 hw/core/irq.c         |   1 +
 hw/core/or-irq.c      | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/irq.h      |  15 ++++++++
 4 files changed, 119 insertions(+)
 create mode 100644 hw/core/or-irq.c
hw/core/Makefile.objs +1 -0
index cfd4840..b47241b 100644
@@ -16,4 +16,5 @@ common-obj-$(CONFIG_SOFTMMU) += null-machine.o
 common-obj-$(CONFIG_SOFTMMU) += loader.o
 common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
 common-obj-$(CONFIG_SOFTMMU) += register.o
+common-obj-$(CONFIG_SOFTMMU) += or-irq.o
 common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o
hw/core/irq.c +0 -0
index 49ff2e6..dc874cc 100644

hw/core/irq.c line 30

Quoted 7 lines
hw/core/irq.c +1 -0
@@ -24,6 +24,7 @@
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "hw/irq.h"
+#include "hw/sysbus.h"
 #include "qom/object.h"
 
 #define IRQ(obj) OBJECT_CHECK(struct IRQState, (obj), TYPE_IRQ)

We don't change anything else in this file so I think this added include is leftover from development?

Quoted 32 lines
hw/core/or-irq.c new file +26 -0
new file mode 100644
index 0000000..2bd181b
@@ -0,0 +1,102 @@
+/*
+ * QEMU IRQ/GPIO common code.
+ *
+ * Copyright (c) 2016 Alistair Francis <[email protected]>.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/irq.h"

hw/core/or-irq.c line 36

Quoted 10 lines
hw/core/or-irq.c new file +10 -0
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define OR_IRQ(obj) OBJECT_CHECK(qemu_or_irq, (obj), TYPE_OR_IRQ)
+
+struct OrIRQState {
+    Object parent_obj;
+
+    qemu_irq in_irq;
+    qemu_irq *out_irqs;

Aren't these names backwards? An OR gate has multiple inputs and one output.

hw/core/or-irq.c line 37

Quoted 1 line
hw/core/or-irq.c new file +1 -0
+    int16_t levels[MAX_OR_LINES];

Why is this an int16_t array? I was expecting an array of bool (or whatever the equivalent is for vmstate), or alternatively a bitmap.h bitmap with one bit per input.

Quoted 9 lines
hw/core/or-irq.c new file +9 -0
+    int n;
+};
+
+static void or_irq_handler(void *opaque, int n, int level)
+{
+    qemu_or_irq *or_irq = OR_IRQ(opaque);
+    int or_level = 0;
+    int i;
+

hw/core/or-irq.c line 56

Quoted 10 lines
hw/core/or-irq.c new file +10 -0
+    or_irq->levels[n] = level;
+
+    for (i = 0; i < or_irq->n; i++) {
+        or_level |= or_irq->levels[i];
+    }
+
+    qemu_set_irq(or_irq->in_irq, or_level);
+}
+
+qemu_irq *qemu_allocate_or_irqs(qemu_irq in_irq, int n)

This API is awkward because it means that there's no way for the caller to arrange for the OR_IRQ object to be freed (for instance if you want to use it in a hotpluggable device), unless I'm missing something.

I was sort of expecting this to be just-another-device that you would wire up with the existing sysbus gpio APIs.

Quoted 21 lines
hw/core/or-irq.c new file +21 -0
+{
+    qemu_or_irq *or_irq;
+
+    assert(n < MAX_OR_LINES);
+
+    or_irq = OR_IRQ(object_new(TYPE_OR_IRQ));
+    object_initialize(or_irq, sizeof(qemu_or_irq),
+                      TYPE_OR_IRQ);
+
+    or_irq->out_irqs = qemu_allocate_irqs(or_irq_handler, or_irq, n);
+    or_irq->in_irq = in_irq;
+    or_irq->n = n;
+
+    return or_irq->out_irqs;
+}
+
+static const VMStateDescription vmstate_or_irq = {
+    .name = TYPE_OR_IRQ,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {

hw/core/or-irq.c line 87

Quoted 10 lines
hw/core/or-irq.c new file +10 -0
+        VMSTATE_INT16_ARRAY(levels, qemu_or_irq, MAX_OR_LINES),
+        VMSTATE_END_OF_LIST(),
+    }
+};
+
+static void or_irq_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->vmsd = &vmstate_or_irq;

I think this also needs a reset method that just zeroes the levels array.

Quoted 51 lines
hw/core/or-irq.c new file +15 -0
+}
+
+static const TypeInfo or_irq_type_info = {
+   .name = TYPE_OR_IRQ,
+   .parent = TYPE_DEVICE,
+   .instance_size = sizeof(qemu_or_irq),
+   .class_init = or_irq_class_init,
+};
+
+static void or_irq_register_types(void)
+{
+    type_register_static(&or_irq_type_info);
+}
+
+type_init(or_irq_register_types)
include/hw/irq.h +15 -1
index 4c4c2ea..5e8a3b6 100644
@@ -4,8 +4,12 @@
 /* Generic IRQ/GPIO pin infrastructure.  */
 
 #define TYPE_IRQ "irq"
+#define TYPE_OR_IRQ "or-irq"
+
+#define MAX_OR_LINES      16
 
 typedef struct IRQState *qemu_irq;
+typedef struct OrIRQState qemu_or_irq;
 
 typedef void (*qemu_irq_handler)(void *opaque, int n, int level);
 
@@ -38,6 +42,17 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n);
  */
 qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n);
 
+/*
+ * qemu_allocate_or_irqs
+ * @in_irq: An input IRQ. It will be the result of the @out_irqs ORed together
+ * @n: The number of interrupt lines that should be ORed together
+ *
+ * returns: An array of interrupts that should be ORed together
+ *
+ * OR all of the interrupts returned in the array into a single @in_irq.
+ */
+qemu_irq *qemu_allocate_or_irqs(qemu_irq in_irq, int n);
+
 /* Extends an Array of IRQs. Old IRQs have their handlers and opaque data
  * preserved. New IRQs are assigned the argument handler and opaque data.
  */
--
Quoted 2 lines

2.7.4

thanks
-- PMM

#7 lore raw

Re: [Qemu-devel] [PATCH v6 5/8] irq: Add a new irq device that allows the ORing of lines

Quoted 38 lines · Peter Maydell
Quoted 37 lines · Alistair Francis

---
As the migration framework is not included in user mode this needs to be a new file.

V6:
- Make the OR IRQ device a TYPE_DEVICE
- Add vmstate

 hw/core/Makefile.objs |   1 +
 hw/core/irq.c         |   1 +
 hw/core/or-irq.c      | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/irq.h      |  15 ++++++++
 4 files changed, 119 insertions(+)
 create mode 100644 hw/core/or-irq.c
hw/core/Makefile.objs +1 -0
index cfd4840..b47241b 100644
@@ -16,4 +16,5 @@ common-obj-$(CONFIG_SOFTMMU) += null-machine.o
 common-obj-$(CONFIG_SOFTMMU) += loader.o
 common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
 common-obj-$(CONFIG_SOFTMMU) += register.o
+common-obj-$(CONFIG_SOFTMMU) += or-irq.o
 common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o
hw/core/irq.c +1 -0
index 49ff2e6..dc874cc 100644
@@ -24,6 +24,7 @@
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "hw/irq.h"
+#include "hw/sysbus.h"
 #include "qom/object.h"
 
Quoted 4 lines

hw/core/irq.c line 30

Quoted 1 line
hw/core/irq.c +0 -0
 #define IRQ(obj) OBJECT_CHECK(struct IRQState, (obj), TYPE_IRQ)

We don't change anything else in this file so I think this added include is leftover from development?

Yep, it is. I have fixed this.

Quoted 38 lines
Quoted 38 lines
hw/core/or-irq.c new file +31 -0
new file mode 100644
index 0000000..2bd181b
@@ -0,0 +1,102 @@
+/*
+ * QEMU IRQ/GPIO common code.
+ *
+ * Copyright (c) 2016 Alistair Francis <[email protected]>.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/irq.h"
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define OR_IRQ(obj) OBJECT_CHECK(qemu_or_irq, (obj), TYPE_OR_IRQ)
+
Quoted 8 lines

hw/core/or-irq.c line 36

Quoted 5 lines
hw/core/or-irq.c new file +5 -0
+struct OrIRQState {
+    Object parent_obj;
+
+    qemu_irq in_irq;
+    qemu_irq *out_irqs;

Aren't these names backwards? An OR gate has multiple inputs and one output.

I think I was thinking of the direction from the devices. So the out_irqs are the lines that go out from the device and the in_irq goes into the next device (the GIC in this case).

Although that probably is somewhat confusing.

Quoted 6 lines

hw/core/or-irq.c line 37

Quoted 2 lines
hw/core/or-irq.c new file +1 -0
+    int16_t levels[MAX_OR_LINES];

Why is this an int16_t array? I was expecting an array of bool (or whatever the equivalent is for vmstate), or alternatively a bitmap.h bitmap with one bit per input.

It should be bools, I just couldn't find the VMstate macro for bools at the time.

I have fixed this.

Quoted 26 lines
Quoted 10 lines
hw/core/or-irq.c new file +9 -0
+    int n;
+};
+
+static void or_irq_handler(void *opaque, int n, int level)
+{
+    qemu_or_irq *or_irq = OR_IRQ(opaque);
+    int or_level = 0;
+    int i;
+

hw/core/or-irq.c line 56

Quoted 10 lines
hw/core/or-irq.c new file +10 -0
+    or_irq->levels[n] = level;
+
+    for (i = 0; i < or_irq->n; i++) {
+        or_level |= or_irq->levels[i];
+    }
+
+    qemu_set_irq(or_irq->in_irq, or_level);
+}
+
+qemu_irq *qemu_allocate_or_irqs(qemu_irq in_irq, int n)

This API is awkward because it means that there's no way for the caller to arrange for the OR_IRQ object to be freed (for instance if you want to use it in a hotpluggable device), unless I'm missing something.

Quoted 2 lines

I was sort of expecting this to be just-another-device that you would wire up with the existing sysbus gpio APIs.

Ok, I have fixed this up. It now follows the standard API.

Quoted 27 lines
Quoted 27 lines
hw/core/or-irq.c new file +26 -0
+{
+    qemu_or_irq *or_irq;
+
+    assert(n < MAX_OR_LINES);
+
+    or_irq = OR_IRQ(object_new(TYPE_OR_IRQ));
+    object_initialize(or_irq, sizeof(qemu_or_irq),
+                      TYPE_OR_IRQ);
+
+    or_irq->out_irqs = qemu_allocate_irqs(or_irq_handler, or_irq, n);
+    or_irq->in_irq = in_irq;
+    or_irq->n = n;
+
+    return or_irq->out_irqs;
+}
+
+static const VMStateDescription vmstate_or_irq = {
+    .name = TYPE_OR_IRQ,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_INT16_ARRAY(levels, qemu_or_irq, MAX_OR_LINES),
+        VMSTATE_END_OF_LIST(),
+    }
+};
+
Quoted 8 lines

hw/core/or-irq.c line 87

Quoted 5 lines
hw/core/or-irq.c new file +5 -0
+static void or_irq_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->vmsd = &vmstate_or_irq;

I think this also needs a reset method that just zeroes the levels array.

Fixed.

Thanks,

Alistair

Quoted 57 lines
Quoted 52 lines
hw/core/or-irq.c new file +15 -0
+}
+
+static const TypeInfo or_irq_type_info = {
+   .name = TYPE_OR_IRQ,
+   .parent = TYPE_DEVICE,
+   .instance_size = sizeof(qemu_or_irq),
+   .class_init = or_irq_class_init,
+};
+
+static void or_irq_register_types(void)
+{
+    type_register_static(&or_irq_type_info);
+}
+
+type_init(or_irq_register_types)
include/hw/irq.h +15 -1
index 4c4c2ea..5e8a3b6 100644
@@ -4,8 +4,12 @@
 /* Generic IRQ/GPIO pin infrastructure.  */
 
 #define TYPE_IRQ "irq"
+#define TYPE_OR_IRQ "or-irq"
+
+#define MAX_OR_LINES      16
 
 typedef struct IRQState *qemu_irq;
+typedef struct OrIRQState qemu_or_irq;
 
 typedef void (*qemu_irq_handler)(void *opaque, int n, int level);
 
@@ -38,6 +42,17 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n);
  */
 qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n);
 
+/*
+ * qemu_allocate_or_irqs
+ * @in_irq: An input IRQ. It will be the result of the @out_irqs ORed together
+ * @n: The number of interrupt lines that should be ORed together
+ *
+ * returns: An array of interrupts that should be ORed together
+ *
+ * OR all of the interrupts returned in the array into a single @in_irq.
+ */
+qemu_irq *qemu_allocate_or_irqs(qemu_irq in_irq, int n);
+
 /* Extends an Array of IRQs. Old IRQs have their handlers and opaque data
  * preserved. New IRQs are assigned the argument handler and opaque data.
  */
--
Quoted 2 lines

2.7.4

thanks
-- PMM

#8 lore raw

PATCH v6 8/8 MAINTAINERS: Add Alistair to the maintainers list

In reply to Alistair Francis

Add Alistair Francis as the maintainer for the Netduino 2 and SMM32F205 SoC.

---

 MAINTAINERS | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
MAINTAINERS +15 -0
index d1439a8..e55be55 100644
@@ -475,6 +475,21 @@ S: Maintained
 F: hw/arm/virt-acpi-build.c
 F: include/hw/arm/virt-acpi-build.h
 
+STM32F205
+M: Alistair Francis <[email protected]>
+S: Maintained
+F: hw/arm/stm32f205_soc.c
+F: hw/misc/stm32f2xx_syscfg.c
+F: hw/char/stm32f2xx_usart.c
+F: hw/timer/stm32f2xx_timer.c
+F: hw/adc/*
+F: hw/ssi/stm32f2xx_spi.c
+
+Netduino 2
+M: Alistair Francis <[email protected]>
+S: Maintained
+F: hw/arm/netduino2.c
+
 CRIS Machines
 -------------
 Axis Dev88
Signature · 1 line
2.7.4