All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v6 0/8]  Update the Netduino 2 Machine
@ 2016-08-03  3:10 Alistair Francis
  2016-08-03  3:10 ` [Qemu-devel] [PATCH v6 1/8] STM32F205: Remove the individual device variables Alistair Francis
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Alistair Francis @ 2016-08-03  3:10 UTC (permalink / raw)
  To: qemu-devel, peter.maydell; +Cc: alistair23, konstanty

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

-- 
2.7.4

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

* [Qemu-devel] [PATCH v6 1/8] STM32F205: Remove the individual device variables
  2016-08-03  3:10 [Qemu-devel] [PATCH v6 0/8] Update the Netduino 2 Machine Alistair Francis
@ 2016-08-03  3:10 ` Alistair Francis
  2016-08-03  3:10 ` [Qemu-devel] [PATCH v6 2/8] STM32F2xx: Display PWM duty cycle from timer Alistair Francis
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Alistair Francis @ 2016-08-03  3:10 UTC (permalink / raw)
  To: qemu-devel, peter.maydell; +Cc: alistair23, konstanty

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

Signed-off-by: Alistair Francis <alistair@alistair23.me>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---

 hw/arm/stm32f205_soc.c | 35 +++++++++++++++++------------------
 1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
index de26b8c..5b6fa3b 100644
--- a/hw/arm/stm32f205_soc.c
+++ b/hw/arm/stm32f205_soc.c
@@ -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]));
     }
 }
 
-- 
2.7.4

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

* [Qemu-devel] [PATCH v6 2/8] STM32F2xx: Display PWM duty cycle from timer
  2016-08-03  3:10 [Qemu-devel] [PATCH v6 0/8] Update the Netduino 2 Machine Alistair Francis
  2016-08-03  3:10 ` [Qemu-devel] [PATCH v6 1/8] STM32F205: Remove the individual device variables Alistair Francis
@ 2016-08-03  3:10 ` Alistair Francis
  2016-08-03  3:10 ` [Qemu-devel] [PATCH v6 3/8] STM32F2xx: Add the ADC device Alistair Francis
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Alistair Francis @ 2016-08-03  3:10 UTC (permalink / raw)
  To: qemu-devel, peter.maydell; +Cc: alistair23, konstanty

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

Signed-off-by: Alistair Francis <alistair@alistair23.me>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
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(+)

diff --git a/hw/timer/stm32f2xx_timer.c b/hw/timer/stm32f2xx_timer.c
index bf0fb28..8c4c1f9 100644
--- a/hw/timer/stm32f2xx_timer.c
+++ b/hw/timer/stm32f2xx_timer.c
@@ -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)
-- 
2.7.4

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

* [Qemu-devel] [PATCH v6 3/8] STM32F2xx: Add the ADC device
  2016-08-03  3:10 [Qemu-devel] [PATCH v6 0/8] Update the Netduino 2 Machine Alistair Francis
  2016-08-03  3:10 ` [Qemu-devel] [PATCH v6 1/8] STM32F205: Remove the individual device variables Alistair Francis
  2016-08-03  3:10 ` [Qemu-devel] [PATCH v6 2/8] STM32F2xx: Display PWM duty cycle from timer Alistair Francis
@ 2016-08-03  3:10 ` Alistair Francis
  2016-08-03  3:10 ` [Qemu-devel] [PATCH v6 4/8] STM32F2xx: Add the SPI device Alistair Francis
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Alistair Francis @ 2016-08-03  3:10 UTC (permalink / raw)
  To: qemu-devel, peter.maydell; +Cc: alistair23, konstanty

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

This also includes creating a hw/adc directory.

Signed-off-by: Alistair Francis <alistair@alistair23.me>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
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

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 7a19863..5b1696d 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -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
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 4a07ed4..0ffd281 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -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/
diff --git a/hw/adc/Makefile.objs b/hw/adc/Makefile.objs
new file mode 100644
index 0000000..3f6dfde
--- /dev/null
+++ b/hw/adc/Makefile.objs
@@ -0,0 +1 @@
+obj-$(CONFIG_STM32F2XX_ADC) += stm32f2xx_adc.o
diff --git a/hw/adc/stm32f2xx_adc.c b/hw/adc/stm32f2xx_adc.c
new file mode 100644
index 0000000..90fe9de
--- /dev/null
+++ b/hw/adc/stm32f2xx_adc.c
@@ -0,0 +1,306 @@
+/*
+ * STM32F2XX ADC
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ *
+ * 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 "hw/sysbus.h"
+#include "hw/hw.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "hw/adc/stm32f2xx_adc.h"
+
+#ifndef STM_ADC_ERR_DEBUG
+#define STM_ADC_ERR_DEBUG 0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+    if (STM_ADC_ERR_DEBUG >= lvl) { \
+        qemu_log("%s: " fmt, __func__, ## args); \
+    } \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void stm32f2xx_adc_reset(DeviceState *dev)
+{
+    STM32F2XXADCState *s = STM32F2XX_ADC(dev);
+
+    s->adc_sr = 0x00000000;
+    s->adc_cr1 = 0x00000000;
+    s->adc_cr2 = 0x00000000;
+    s->adc_smpr1 = 0x00000000;
+    s->adc_smpr2 = 0x00000000;
+    s->adc_jofr[0] = 0x00000000;
+    s->adc_jofr[1] = 0x00000000;
+    s->adc_jofr[2] = 0x00000000;
+    s->adc_jofr[3] = 0x00000000;
+    s->adc_htr = 0x00000FFF;
+    s->adc_ltr = 0x00000000;
+    s->adc_sqr1 = 0x00000000;
+    s->adc_sqr2 = 0x00000000;
+    s->adc_sqr3 = 0x00000000;
+    s->adc_jsqr = 0x00000000;
+    s->adc_jdr[0] = 0x00000000;
+    s->adc_jdr[1] = 0x00000000;
+    s->adc_jdr[2] = 0x00000000;
+    s->adc_jdr[3] = 0x00000000;
+    s->adc_dr = 0x00000000;
+}
+
+static uint32_t stm32f2xx_adc_generate_value(STM32F2XXADCState *s)
+{
+    /* Attempts to fake some ADC values */
+    s->adc_dr = s->adc_dr + 7;
+
+    switch ((s->adc_cr1 & ADC_CR1_RES) >> 24) {
+    case 0:
+        /* 12-bit */
+        s->adc_dr &= 0xFFF;
+        break;
+    case 1:
+        /* 10-bit */
+        s->adc_dr &= 0x3FF;
+        break;
+    case 2:
+        /* 8-bit */
+        s->adc_dr &= 0xFF;
+        break;
+    default:
+        /* 6-bit */
+        s->adc_dr &= 0x3F;
+    }
+
+    if (s->adc_cr2 & ADC_CR2_ALIGN) {
+        return (s->adc_dr << 1) & 0xFFF0;
+    } else {
+        return s->adc_dr;
+    }
+}
+
+static uint64_t stm32f2xx_adc_read(void *opaque, hwaddr addr,
+                                     unsigned int size)
+{
+    STM32F2XXADCState *s = opaque;
+
+    DB_PRINT("Address: 0x%" HWADDR_PRIx "\n", addr);
+
+    if (addr >= ADC_COMMON_ADDRESS) {
+        qemu_log_mask(LOG_UNIMP,
+                      "%s: ADC Common Register Unsupported\n", __func__);
+    }
+
+    switch (addr) {
+    case ADC_SR:
+        return s->adc_sr;
+    case ADC_CR1:
+        return s->adc_cr1;
+    case ADC_CR2:
+        return s->adc_cr2 & 0xFFFFFFF;
+    case ADC_SMPR1:
+        return s->adc_smpr1;
+    case ADC_SMPR2:
+        return s->adc_smpr2;
+    case ADC_JOFR1:
+    case ADC_JOFR2:
+    case ADC_JOFR3:
+    case ADC_JOFR4:
+        qemu_log_mask(LOG_UNIMP, "%s: " \
+                      "Injection ADC is not implemented, the registers are " \
+                      "included for compatibility\n", __func__);
+        return s->adc_jofr[(addr - ADC_JOFR1) / 4];
+    case ADC_HTR:
+        return s->adc_htr;
+    case ADC_LTR:
+        return s->adc_ltr;
+    case ADC_SQR1:
+        return s->adc_sqr1;
+    case ADC_SQR2:
+        return s->adc_sqr2;
+    case ADC_SQR3:
+        return s->adc_sqr3;
+    case ADC_JSQR:
+        qemu_log_mask(LOG_UNIMP, "%s: " \
+                      "Injection ADC is not implemented, the registers are " \
+                      "included for compatibility\n", __func__);
+        return s->adc_jsqr;
+    case ADC_JDR1:
+    case ADC_JDR2:
+    case ADC_JDR3:
+    case ADC_JDR4:
+        qemu_log_mask(LOG_UNIMP, "%s: " \
+                      "Injection ADC is not implemented, the registers are " \
+                      "included for compatibility\n", __func__);
+        return s->adc_jdr[(addr - ADC_JDR1) / 4] -
+               s->adc_jofr[(addr - ADC_JDR1) / 4];
+    case ADC_DR:
+        if ((s->adc_cr2 & ADC_CR2_ADON) && (s->adc_cr2 & ADC_CR2_SWSTART)) {
+            s->adc_cr2 ^= ADC_CR2_SWSTART;
+            return stm32f2xx_adc_generate_value(s);
+        } else {
+            return 0;
+        }
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr);
+    }
+
+    return 0;
+}
+
+static void stm32f2xx_adc_write(void *opaque, hwaddr addr,
+                       uint64_t val64, unsigned int size)
+{
+    STM32F2XXADCState *s = opaque;
+    uint32_t value = (uint32_t) val64;
+
+    DB_PRINT("Address: 0x%" HWADDR_PRIx ", Value: 0x%x\n",
+             addr, value);
+
+    if (addr >= 0x100) {
+        qemu_log_mask(LOG_UNIMP,
+                      "%s: ADC Common Register Unsupported\n", __func__);
+    }
+
+    switch (addr) {
+    case ADC_SR:
+        s->adc_sr &= (value & 0x3F);
+        break;
+    case ADC_CR1:
+        s->adc_cr1 = value;
+        break;
+    case ADC_CR2:
+        s->adc_cr2 = value;
+        break;
+    case ADC_SMPR1:
+        s->adc_smpr1 = value;
+        break;
+    case ADC_SMPR2:
+        s->adc_smpr2 = value;
+        break;
+    case ADC_JOFR1:
+    case ADC_JOFR2:
+    case ADC_JOFR3:
+    case ADC_JOFR4:
+        s->adc_jofr[(addr - ADC_JOFR1) / 4] = (value & 0xFFF);
+        qemu_log_mask(LOG_UNIMP, "%s: " \
+                      "Injection ADC is not implemented, the registers are " \
+                      "included for compatibility\n", __func__);
+        break;
+    case ADC_HTR:
+        s->adc_htr = value;
+        break;
+    case ADC_LTR:
+        s->adc_ltr = value;
+        break;
+    case ADC_SQR1:
+        s->adc_sqr1 = value;
+        break;
+    case ADC_SQR2:
+        s->adc_sqr2 = value;
+        break;
+    case ADC_SQR3:
+        s->adc_sqr3 = value;
+        break;
+    case ADC_JSQR:
+        s->adc_jsqr = value;
+        qemu_log_mask(LOG_UNIMP, "%s: " \
+                      "Injection ADC is not implemented, the registers are " \
+                      "included for compatibility\n", __func__);
+        break;
+    case ADC_JDR1:
+    case ADC_JDR2:
+    case ADC_JDR3:
+    case ADC_JDR4:
+        s->adc_jdr[(addr - ADC_JDR1) / 4] = value;
+        qemu_log_mask(LOG_UNIMP, "%s: " \
+                      "Injection ADC is not implemented, the registers are " \
+                      "included for compatibility\n", __func__);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr);
+    }
+}
+
+static const MemoryRegionOps stm32f2xx_adc_ops = {
+    .read = stm32f2xx_adc_read,
+    .write = stm32f2xx_adc_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const VMStateDescription vmstate_stm32f2xx_adc = {
+    .name = TYPE_STM32F2XX_ADC,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(adc_sr, STM32F2XXADCState),
+        VMSTATE_UINT32(adc_cr1, STM32F2XXADCState),
+        VMSTATE_UINT32(adc_cr2, STM32F2XXADCState),
+        VMSTATE_UINT32(adc_smpr1, STM32F2XXADCState),
+        VMSTATE_UINT32(adc_smpr2, STM32F2XXADCState),
+        VMSTATE_UINT32_ARRAY(adc_jofr, STM32F2XXADCState, 4),
+        VMSTATE_UINT32(adc_htr, STM32F2XXADCState),
+        VMSTATE_UINT32(adc_ltr, STM32F2XXADCState),
+        VMSTATE_UINT32(adc_sqr1, STM32F2XXADCState),
+        VMSTATE_UINT32(adc_sqr2, STM32F2XXADCState),
+        VMSTATE_UINT32(adc_sqr3, STM32F2XXADCState),
+        VMSTATE_UINT32(adc_jsqr, STM32F2XXADCState),
+        VMSTATE_UINT32_ARRAY(adc_jdr, STM32F2XXADCState, 4),
+        VMSTATE_UINT32(adc_dr, STM32F2XXADCState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void stm32f2xx_adc_init(Object *obj)
+{
+    STM32F2XXADCState *s = STM32F2XX_ADC(obj);
+
+    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+
+    memory_region_init_io(&s->mmio, obj, &stm32f2xx_adc_ops, s,
+                          TYPE_STM32F2XX_ADC, 0xFF);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+}
+
+static void stm32f2xx_adc_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->reset = stm32f2xx_adc_reset;
+    dc->vmsd = &vmstate_stm32f2xx_adc;
+}
+
+static const TypeInfo stm32f2xx_adc_info = {
+    .name          = TYPE_STM32F2XX_ADC,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(STM32F2XXADCState),
+    .instance_init = stm32f2xx_adc_init,
+    .class_init    = stm32f2xx_adc_class_init,
+};
+
+static void stm32f2xx_adc_register_types(void)
+{
+    type_register_static(&stm32f2xx_adc_info);
+}
+
+type_init(stm32f2xx_adc_register_types)
diff --git a/include/hw/adc/stm32f2xx_adc.h b/include/hw/adc/stm32f2xx_adc.h
new file mode 100644
index 0000000..a72f734
--- /dev/null
+++ b/include/hw/adc/stm32f2xx_adc.h
@@ -0,0 +1,87 @@
+/*
+ * STM32F2XX ADC
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ *
+ * 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.
+ */
+
+#ifndef HW_STM32F2XX_ADC_H
+#define HW_STM32F2XX_ADC_H
+
+#define ADC_SR    0x00
+#define ADC_CR1   0x04
+#define ADC_CR2   0x08
+#define ADC_SMPR1 0x0C
+#define ADC_SMPR2 0x10
+#define ADC_JOFR1 0x14
+#define ADC_JOFR2 0x18
+#define ADC_JOFR3 0x1C
+#define ADC_JOFR4 0x20
+#define ADC_HTR   0x24
+#define ADC_LTR   0x28
+#define ADC_SQR1  0x2C
+#define ADC_SQR2  0x30
+#define ADC_SQR3  0x34
+#define ADC_JSQR  0x38
+#define ADC_JDR1  0x3C
+#define ADC_JDR2  0x40
+#define ADC_JDR3  0x44
+#define ADC_JDR4  0x48
+#define ADC_DR    0x4C
+
+#define ADC_CR2_ADON    0x01
+#define ADC_CR2_CONT    0x02
+#define ADC_CR2_ALIGN   0x800
+#define ADC_CR2_SWSTART 0x40000000
+
+#define ADC_CR1_RES 0x3000000
+
+#define ADC_COMMON_ADDRESS 0x100
+
+#define TYPE_STM32F2XX_ADC "stm32f2xx-adc"
+#define STM32F2XX_ADC(obj) \
+    OBJECT_CHECK(STM32F2XXADCState, (obj), TYPE_STM32F2XX_ADC)
+
+typedef struct {
+    /* <private> */
+    SysBusDevice parent_obj;
+
+    /* <public> */
+    MemoryRegion mmio;
+
+    uint32_t adc_sr;
+    uint32_t adc_cr1;
+    uint32_t adc_cr2;
+    uint32_t adc_smpr1;
+    uint32_t adc_smpr2;
+    uint32_t adc_jofr[4];
+    uint32_t adc_htr;
+    uint32_t adc_ltr;
+    uint32_t adc_sqr1;
+    uint32_t adc_sqr2;
+    uint32_t adc_sqr3;
+    uint32_t adc_jsqr;
+    uint32_t adc_jdr[4];
+    uint32_t adc_dr;
+
+    qemu_irq irq;
+} STM32F2XXADCState;
+
+#endif /* HW_STM32F2XX_ADC_H */
-- 
2.7.4

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

* [Qemu-devel] [PATCH v6 4/8] STM32F2xx: Add the SPI device
  2016-08-03  3:10 [Qemu-devel] [PATCH v6 0/8] Update the Netduino 2 Machine Alistair Francis
                   ` (2 preceding siblings ...)
  2016-08-03  3:10 ` [Qemu-devel] [PATCH v6 3/8] STM32F2xx: Add the ADC device Alistair Francis
@ 2016-08-03  3:10 ` Alistair Francis
  2016-08-03  3:10 ` [Qemu-devel] [PATCH v6 5/8] irq: Add a new irq device that allows the ORing of lines Alistair Francis
  2016-08-03  3:11 ` [Qemu-devel] [PATCH v6 8/8] MAINTAINERS: Add Alistair to the maintainers list Alistair Francis
  5 siblings, 0 replies; 9+ messages in thread
From: Alistair Francis @ 2016-08-03  3:10 UTC (permalink / raw)
  To: qemu-devel, peter.maydell; +Cc: alistair23, konstanty

Add the STM32F2xx SPI device.

Signed-off-by: Alistair Francis <alistair@alistair23.me>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
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

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 5b1696d..e9e2de3 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -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
diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
index c79a8dc..487add2 100644
--- a/hw/ssi/Makefile.objs
+++ b/hw/ssi/Makefile.objs
@@ -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
diff --git a/hw/ssi/stm32f2xx_spi.c b/hw/ssi/stm32f2xx_spi.c
new file mode 100644
index 0000000..26a1b4d
--- /dev/null
+++ b/hw/ssi/stm32f2xx_spi.c
@@ -0,0 +1,225 @@
+/*
+ * STM32F405 SPI
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ *
+ * 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 "qapi/error.h"
+#include "qemu/log.h"
+#include "hw/ssi/stm32f2xx_spi.h"
+
+#ifndef STM_SPI_ERR_DEBUG
+#define STM_SPI_ERR_DEBUG 0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+    if (STM_SPI_ERR_DEBUG >= lvl) { \
+        qemu_log("%s: " fmt, __func__, ## args); \
+    } \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void stm32f2xx_spi_reset(DeviceState *dev)
+{
+    STM32F2XXSPIState *s = STM32F2XX_SPI(dev);
+
+    s->spi_cr1 = 0x00000000;
+    s->spi_cr2 = 0x00000000;
+    s->spi_sr = 0x0000000A;
+    s->spi_dr = 0x0000000C;
+    s->spi_crcpr = 0x00000007;
+    s->spi_rxcrcr = 0x00000000;
+    s->spi_txcrcr = 0x00000000;
+    s->spi_i2scfgr = 0x00000000;
+    s->spi_i2spr = 0x00000002;
+}
+
+static void stm32f2xx_spi_transfer(STM32F2XXSPIState *s)
+{
+    DB_PRINT("Data to send: 0x%x\n", s->spi_dr);
+
+    s->spi_dr = ssi_transfer(s->ssi, s->spi_dr);
+    s->spi_sr |= STM_SPI_SR_RXNE;
+
+    DB_PRINT("Data received: 0x%x\n", s->spi_dr);
+}
+
+static uint64_t stm32f2xx_spi_read(void *opaque, hwaddr addr,
+                                     unsigned int size)
+{
+    STM32F2XXSPIState *s = opaque;
+
+    DB_PRINT("Address: 0x%" HWADDR_PRIx "\n", addr);
+
+    switch (addr) {
+    case STM_SPI_CR1:
+        return s->spi_cr1;
+    case STM_SPI_CR2:
+        qemu_log_mask(LOG_UNIMP, "%s: Interrupts and DMA are not implemented\n",
+                      __func__);
+        return s->spi_cr2;
+    case STM_SPI_SR:
+        return s->spi_sr;
+    case STM_SPI_DR:
+        stm32f2xx_spi_transfer(s);
+        s->spi_sr &= ~STM_SPI_SR_RXNE;
+        return s->spi_dr;
+    case STM_SPI_CRCPR:
+        qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented, the registers " \
+                      "are included for compatibility\n", __func__);
+        return s->spi_crcpr;
+    case STM_SPI_RXCRCR:
+        qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented, the registers " \
+                      "are included for compatibility\n", __func__);
+        return s->spi_rxcrcr;
+    case STM_SPI_TXCRCR:
+        qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented, the registers " \
+                      "are included for compatibility\n", __func__);
+        return s->spi_txcrcr;
+    case STM_SPI_I2SCFGR:
+        qemu_log_mask(LOG_UNIMP, "%s: I2S is not implemented, the registers " \
+                      "are included for compatibility\n", __func__);
+        return s->spi_i2scfgr;
+    case STM_SPI_I2SPR:
+        qemu_log_mask(LOG_UNIMP, "%s: I2S is not implemented, the registers " \
+                      "are included for compatibility\n", __func__);
+        return s->spi_i2spr;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
+                      __func__, addr);
+    }
+
+    return 0;
+}
+
+static void stm32f2xx_spi_write(void *opaque, hwaddr addr,
+                                uint64_t val64, unsigned int size)
+{
+    STM32F2XXSPIState *s = opaque;
+    uint32_t value = val64;
+
+    DB_PRINT("Address: 0x%" HWADDR_PRIx ", Value: 0x%x\n", addr, value);
+
+    switch (addr) {
+    case STM_SPI_CR1:
+        s->spi_cr1 = value;
+        return;
+    case STM_SPI_CR2:
+        qemu_log_mask(LOG_UNIMP, "%s: " \
+                      "Interrupts and DMA are not implemented\n", __func__);
+        s->spi_cr2 = value;
+        return;
+    case STM_SPI_SR:
+        /* Read only register, except for clearing the CRCERR bit, which
+         * is not supported
+         */
+        return;
+    case STM_SPI_DR:
+        s->spi_dr = value;
+        stm32f2xx_spi_transfer(s);
+        return;
+    case STM_SPI_CRCPR:
+        qemu_log_mask(LOG_UNIMP, "%s: CRC is not implemented\n", __func__);
+        return;
+    case STM_SPI_RXCRCR:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Read only register: " \
+                      "0x%" HWADDR_PRIx "\n", __func__, addr);
+        return;
+    case STM_SPI_TXCRCR:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Read only register: " \
+                      "0x%" HWADDR_PRIx "\n", __func__, addr);
+        return;
+    case STM_SPI_I2SCFGR:
+        qemu_log_mask(LOG_UNIMP, "%s: " \
+                      "I2S is not implemented\n", __func__);
+        return;
+    case STM_SPI_I2SPR:
+        qemu_log_mask(LOG_UNIMP, "%s: " \
+                      "I2S is not implemented\n", __func__);
+        return;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr);
+    }
+}
+
+static const MemoryRegionOps stm32f2xx_spi_ops = {
+    .read = stm32f2xx_spi_read,
+    .write = stm32f2xx_spi_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const VMStateDescription vmstate_stm32f2xx_spi = {
+    .name = TYPE_STM32F2XX_SPI,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(spi_cr1, STM32F2XXSPIState),
+        VMSTATE_UINT32(spi_cr2, STM32F2XXSPIState),
+        VMSTATE_UINT32(spi_sr, STM32F2XXSPIState),
+        VMSTATE_UINT32(spi_dr, STM32F2XXSPIState),
+        VMSTATE_UINT32(spi_crcpr, STM32F2XXSPIState),
+        VMSTATE_UINT32(spi_rxcrcr, STM32F2XXSPIState),
+        VMSTATE_UINT32(spi_txcrcr, STM32F2XXSPIState),
+        VMSTATE_UINT32(spi_i2scfgr, STM32F2XXSPIState),
+        VMSTATE_UINT32(spi_i2spr, STM32F2XXSPIState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void stm32f2xx_spi_init(Object *obj)
+{
+    STM32F2XXSPIState *s = STM32F2XX_SPI(obj);
+    DeviceState *dev = DEVICE(obj);
+
+    memory_region_init_io(&s->mmio, obj, &stm32f2xx_spi_ops, s,
+                          TYPE_STM32F2XX_SPI, 0x400);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+
+    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+
+    s->ssi = ssi_create_bus(dev, "ssi");
+}
+
+static void stm32f2xx_spi_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->reset = stm32f2xx_spi_reset;
+    dc->vmsd = &vmstate_stm32f2xx_spi;
+}
+
+static const TypeInfo stm32f2xx_spi_info = {
+    .name          = TYPE_STM32F2XX_SPI,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(STM32F2XXSPIState),
+    .instance_init = stm32f2xx_spi_init,
+    .class_init    = stm32f2xx_spi_class_init,
+};
+
+static void stm32f2xx_spi_register_types(void)
+{
+    type_register_static(&stm32f2xx_spi_info);
+}
+
+type_init(stm32f2xx_spi_register_types)
diff --git a/include/hw/ssi/stm32f2xx_spi.h b/include/hw/ssi/stm32f2xx_spi.h
new file mode 100644
index 0000000..1cd73e4
--- /dev/null
+++ b/include/hw/ssi/stm32f2xx_spi.h
@@ -0,0 +1,72 @@
+/*
+ * STM32F2XX SPI
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ *
+ * 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.
+ */
+
+#ifndef HW_STM32F2XX_SPI_H
+#define HW_STM32F2XX_SPI_H
+
+#include "hw/sysbus.h"
+#include "hw/hw.h"
+#include "hw/ssi/ssi.h"
+
+#define STM_SPI_CR1     0x00
+#define STM_SPI_CR2     0x04
+#define STM_SPI_SR      0x08
+#define STM_SPI_DR      0x0C
+#define STM_SPI_CRCPR   0x10
+#define STM_SPI_RXCRCR  0x14
+#define STM_SPI_TXCRCR  0x18
+#define STM_SPI_I2SCFGR 0x1C
+#define STM_SPI_I2SPR   0x20
+
+#define STM_SPI_CR1_SPE  (1 << 6)
+#define STM_SPI_CR1_MSTR (1 << 2)
+
+#define STM_SPI_SR_RXNE   1
+
+#define TYPE_STM32F2XX_SPI "stm32f2xx-spi"
+#define STM32F2XX_SPI(obj) \
+    OBJECT_CHECK(STM32F2XXSPIState, (obj), TYPE_STM32F2XX_SPI)
+
+typedef struct {
+    /* <private> */
+    SysBusDevice parent_obj;
+
+    /* <public> */
+    MemoryRegion mmio;
+
+    uint32_t spi_cr1;
+    uint32_t spi_cr2;
+    uint32_t spi_sr;
+    uint32_t spi_dr;
+    uint32_t spi_crcpr;
+    uint32_t spi_rxcrcr;
+    uint32_t spi_txcrcr;
+    uint32_t spi_i2scfgr;
+    uint32_t spi_i2spr;
+
+    qemu_irq irq;
+    SSIBus *ssi;
+} STM32F2XXSPIState;
+
+#endif /* HW_STM32F2XX_SPI_H */
-- 
2.7.4

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

* [Qemu-devel] [PATCH v6 5/8] irq: Add a new irq device that allows the ORing of lines
  2016-08-03  3:10 [Qemu-devel] [PATCH v6 0/8] Update the Netduino 2 Machine Alistair Francis
                   ` (3 preceding siblings ...)
  2016-08-03  3:10 ` [Qemu-devel] [PATCH v6 4/8] STM32F2xx: Add the SPI device Alistair Francis
@ 2016-08-03  3:10 ` Alistair Francis
  2016-08-09 16:42   ` Peter Maydell
  2016-08-03  3:11 ` [Qemu-devel] [PATCH v6 8/8] MAINTAINERS: Add Alistair to the maintainers list Alistair Francis
  5 siblings, 1 reply; 9+ messages in thread
From: Alistair Francis @ 2016-08-03  3:10 UTC (permalink / raw)
  To: qemu-devel, peter.maydell; +Cc: alistair23, konstanty

Signed-off-by: Alistair Francis <alistair@alistair23.me>
---
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

diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index cfd4840..b47241b 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -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
diff --git a/hw/core/irq.c b/hw/core/irq.c
index 49ff2e6..dc874cc 100644
--- a/hw/core/irq.c
+++ b/hw/core/irq.c
@@ -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)
diff --git a/hw/core/or-irq.c b/hw/core/or-irq.c
new file mode 100644
index 0000000..2bd181b
--- /dev/null
+++ b/hw/core/or-irq.c
@@ -0,0 +1,102 @@
+/*
+ * QEMU IRQ/GPIO common code.
+ *
+ * Copyright (c) 2016 Alistair Francis <alistair@alistair23.me>.
+ *
+ * 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)
+
+struct OrIRQState {
+    Object parent_obj;
+
+    qemu_irq in_irq;
+    qemu_irq *out_irqs;
+    int16_t levels[MAX_OR_LINES];
+    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;
+
+    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)
+{
+    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(),
+    }
+};
+
+static void or_irq_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->vmsd = &vmstate_or_irq;
+}
+
+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)
diff --git a/include/hw/irq.h b/include/hw/irq.h
index 4c4c2ea..5e8a3b6 100644
--- a/include/hw/irq.h
+++ b/include/hw/irq.h
@@ -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.
  */
-- 
2.7.4

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

* [Qemu-devel] [PATCH v6 8/8] MAINTAINERS: Add Alistair to the maintainers list
  2016-08-03  3:10 [Qemu-devel] [PATCH v6 0/8] Update the Netduino 2 Machine Alistair Francis
                   ` (4 preceding siblings ...)
  2016-08-03  3:10 ` [Qemu-devel] [PATCH v6 5/8] irq: Add a new irq device that allows the ORing of lines Alistair Francis
@ 2016-08-03  3:11 ` Alistair Francis
  5 siblings, 0 replies; 9+ messages in thread
From: Alistair Francis @ 2016-08-03  3:11 UTC (permalink / raw)
  To: qemu-devel, peter.maydell; +Cc: alistair23, konstanty

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

Signed-off-by: Alistair Francis <alistair@alistair23.me>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---

 MAINTAINERS | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index d1439a8..e55be55 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -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 <alistair@alistair23.me>
+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 <alistair@alistair23.me>
+S: Maintained
+F: hw/arm/netduino2.c
+
 CRIS Machines
 -------------
 Axis Dev88
-- 
2.7.4

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

* Re: [Qemu-devel] [PATCH v6 5/8] irq: Add a new irq device that allows the ORing of lines
  2016-08-03  3:10 ` [Qemu-devel] [PATCH v6 5/8] irq: Add a new irq device that allows the ORing of lines Alistair Francis
@ 2016-08-09 16:42   ` Peter Maydell
  2016-09-11  6:22     ` Alistair Francis
  0 siblings, 1 reply; 9+ messages in thread
From: Peter Maydell @ 2016-08-09 16:42 UTC (permalink / raw)
  To: Alistair Francis; +Cc: QEMU Developers, Konstanty Bialkowski

On 3 August 2016 at 04:10, Alistair Francis <alistair23@gmail.com> wrote:
> Signed-off-by: Alistair Francis <alistair@alistair23.me>
> ---
> 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
>
> diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
> index cfd4840..b47241b 100644
> --- a/hw/core/Makefile.objs
> +++ b/hw/core/Makefile.objs
> @@ -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
> diff --git a/hw/core/irq.c b/hw/core/irq.c
> index 49ff2e6..dc874cc 100644
> --- a/hw/core/irq.c
> +++ b/hw/core/irq.c
> @@ -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?

> diff --git a/hw/core/or-irq.c b/hw/core/or-irq.c
> new file mode 100644
> index 0000000..2bd181b
> --- /dev/null
> +++ b/hw/core/or-irq.c
> @@ -0,0 +1,102 @@
> +/*
> + * QEMU IRQ/GPIO common code.
> + *
> + * Copyright (c) 2016 Alistair Francis <alistair@alistair23.me>.
> + *
> + * 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)
> +
> +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.

> +    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.

> +    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;
> +
> +    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.

> +{
> +    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(),
> +    }
> +};
> +
> +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.

> +}
> +
> +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)
> diff --git a/include/hw/irq.h b/include/hw/irq.h
> index 4c4c2ea..5e8a3b6 100644
> --- a/include/hw/irq.h
> +++ b/include/hw/irq.h
> @@ -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.
>   */
> --
> 2.7.4
>

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v6 5/8] irq: Add a new irq device that allows the ORing of lines
  2016-08-09 16:42   ` Peter Maydell
@ 2016-09-11  6:22     ` Alistair Francis
  0 siblings, 0 replies; 9+ messages in thread
From: Alistair Francis @ 2016-09-11  6:22 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Konstanty Bialkowski

On Tue, Aug 9, 2016 at 9:42 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 3 August 2016 at 04:10, Alistair Francis <alistair23@gmail.com> wrote:
>> Signed-off-by: Alistair Francis <alistair@alistair23.me>
>> ---
>> 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
>>
>> diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
>> index cfd4840..b47241b 100644
>> --- a/hw/core/Makefile.objs
>> +++ b/hw/core/Makefile.objs
>> @@ -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
>> diff --git a/hw/core/irq.c b/hw/core/irq.c
>> index 49ff2e6..dc874cc 100644
>> --- a/hw/core/irq.c
>> +++ b/hw/core/irq.c
>> @@ -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?

Yep, it is. I have fixed this.

>
>> diff --git a/hw/core/or-irq.c b/hw/core/or-irq.c
>> new file mode 100644
>> index 0000000..2bd181b
>> --- /dev/null
>> +++ b/hw/core/or-irq.c
>> @@ -0,0 +1,102 @@
>> +/*
>> + * QEMU IRQ/GPIO common code.
>> + *
>> + * Copyright (c) 2016 Alistair Francis <alistair@alistair23.me>.
>> + *
>> + * 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)
>> +
>> +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.

>
>> +    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.

>
>> +    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;
>> +
>> +    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.

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

>
>> +{
>> +    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(),
>> +    }
>> +};
>> +
>> +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

>
>> +}
>> +
>> +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)
>> diff --git a/include/hw/irq.h b/include/hw/irq.h
>> index 4c4c2ea..5e8a3b6 100644
>> --- a/include/hw/irq.h
>> +++ b/include/hw/irq.h
>> @@ -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.
>>   */
>> --
>> 2.7.4
>>
>
> thanks
> -- PMM

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

end of thread, other threads:[~2016-09-11  6:23 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-03  3:10 [Qemu-devel] [PATCH v6 0/8] Update the Netduino 2 Machine Alistair Francis
2016-08-03  3:10 ` [Qemu-devel] [PATCH v6 1/8] STM32F205: Remove the individual device variables Alistair Francis
2016-08-03  3:10 ` [Qemu-devel] [PATCH v6 2/8] STM32F2xx: Display PWM duty cycle from timer Alistair Francis
2016-08-03  3:10 ` [Qemu-devel] [PATCH v6 3/8] STM32F2xx: Add the ADC device Alistair Francis
2016-08-03  3:10 ` [Qemu-devel] [PATCH v6 4/8] STM32F2xx: Add the SPI device Alistair Francis
2016-08-03  3:10 ` [Qemu-devel] [PATCH v6 5/8] irq: Add a new irq device that allows the ORing of lines Alistair Francis
2016-08-09 16:42   ` Peter Maydell
2016-09-11  6:22     ` Alistair Francis
2016-08-03  3:11 ` [Qemu-devel] [PATCH v6 8/8] MAINTAINERS: Add Alistair to the maintainers list Alistair Francis

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.