qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v8 00/11] i.MX: Add i.MX25 support through the 3DS evaluation board.
@ 2015-06-29 20:11 Jean-Christophe Dubois
  2015-06-29 20:11 ` [Qemu-devel] [PATCH v8 01/11] i.MX: Split the i.MX serial driver into a header file and a source file Jean-Christophe Dubois
                   ` (10 more replies)
  0 siblings, 11 replies; 17+ messages in thread
From: Jean-Christophe Dubois @ 2015-06-29 20:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

This series of patches add the support for the i.MX25 processor through the
Freescale 3DS evaluation board.

For now a limited set of devices are supported.
    * GPT timers (from i.MX31)
    * EPIT timers (from i.MX31)
    * Serial ports (from i.MX31)
    * Ethernet FEC port
    * I2C controller

This was tested by:
    * booting a minimal linux system on the i.MX25_3DS platform
    * booting the Xvisor hypervisor on the i.MX25_3DS platform
    * booting a minimal linux system on the KZM platform

Jean-Christophe Dubois (11):
  i.MX: Split the i.MX serial driver into a haeder file and a source
    file
  i.MX: Split the i.MX emulator into a header file and a source file
  i.MX: Split the i.MX CCM emulator into a header file and a source
    file.
  i.MX: Split the i.MX EPIT emulator into a header file and a source
    file.
  i.MX: Split the i.MX GPT emulator into a header file and a source
    file.
  kzm: Use modified i.MX emulators.
  i.MX: Add FEC Ethernet Emulator
  i.MX: Add I2C controller emulator
  i.MX25: Add the i.MX25 SOC support
  i.MX25: Add support for the i.MX25 PDK 3DS evaluation board
  i.MX: Add qtest support for I2C device emulator.

 default-configs/arm-softmmu.mak |   4 +
 hw/arm/Makefile.objs            |   1 +
 hw/arm/fsl-imx25.c              | 304 +++++++++++++++++
 hw/arm/imx25_3ds.c              | 217 ++++++++++++
 hw/arm/kzm.c                    |  86 ++---
 hw/char/imx_serial.c            | 176 +++-------
 hw/i2c/Makefile.objs            |   1 +
 hw/i2c/imx_i2c.c                | 339 +++++++++++++++++++
 hw/intc/imx_avic.c              |  56 +--
 hw/misc/imx_ccm.c               |  75 +---
 hw/net/Makefile.objs            |   1 +
 hw/net/imx_fec.c                | 733 ++++++++++++++++++++++++++++++++++++++++
 hw/timer/imx_epit.c             |  65 +---
 hw/timer/imx_gpt.c              |  86 +----
 include/hw/arm/fsl-imx25.h      |  52 +++
 include/hw/arm/imx.h            |  34 --
 include/hw/char/imx_serial.h    | 104 ++++++
 include/hw/i2c/imx_i2c.h        |  85 +++++
 include/hw/intc/imx_avic.h      |  56 +++
 include/hw/misc/imx_ccm.h       |  91 +++++
 include/hw/net/imx_fec.h        | 115 +++++++
 include/hw/timer/imx_epit.h     |  83 +++++
 include/hw/timer/imx_gpt.h      | 111 ++++++
 tests/Makefile                  |   3 +
 tests/ds1338-test.c             |  75 ++++
 tests/libqos/i2c-imx.c          | 209 ++++++++++++
 tests/libqos/i2c.h              |   3 +
 27 files changed, 2707 insertions(+), 458 deletions(-)
 create mode 100644 hw/arm/fsl-imx25.c
 create mode 100644 hw/arm/imx25_3ds.c
 create mode 100644 hw/i2c/imx_i2c.c
 create mode 100644 hw/net/imx_fec.c
 create mode 100644 include/hw/arm/fsl-imx25.h
 delete mode 100644 include/hw/arm/imx.h
 create mode 100644 include/hw/char/imx_serial.h
 create mode 100644 include/hw/i2c/imx_i2c.h
 create mode 100644 include/hw/intc/imx_avic.h
 create mode 100644 include/hw/misc/imx_ccm.h
 create mode 100644 include/hw/net/imx_fec.h
 create mode 100644 include/hw/timer/imx_epit.h
 create mode 100644 include/hw/timer/imx_gpt.h
 create mode 100644 tests/ds1338-test.c
 create mode 100644 tests/libqos/i2c-imx.c

-- 
2.1.4

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

* [Qemu-devel] [PATCH v8 01/11] i.MX: Split the i.MX serial driver into a header file and a source file
  2015-06-29 20:11 [Qemu-devel] [PATCH v8 00/11] i.MX: Add i.MX25 support through the 3DS evaluation board Jean-Christophe Dubois
@ 2015-06-29 20:11 ` Jean-Christophe Dubois
  2015-06-30  7:04   ` Peter Crosthwaite
  2015-06-29 20:11 ` [Qemu-devel] [PATCH v8 02/11] i.MX: Split the i.MX AVIC emulator " Jean-Christophe Dubois
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 17+ messages in thread
From: Jean-Christophe Dubois @ 2015-06-29 20:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

Also adding a "realise" callback.

This is to prepare to accomodate the SOC requirements.

Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
---

Changes since v1:
    * not present on v1

Changes since v2:
    * not present on v2

Changes since v3:
    * not present on v3

Changes since v4:
    * not present on v4

Changes since v5:
    * not present on v5

Changes since v6:
    * not present on v6

Changes since v7:
    * Splited the i.MX serial emulator into a header file and a source file

 hw/char/imx_serial.c         | 176 +++++++++++--------------------------------
 include/hw/char/imx_serial.h | 104 +++++++++++++++++++++++++
 2 files changed, 149 insertions(+), 131 deletions(-)
 create mode 100644 include/hw/char/imx_serial.h

diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index f3fbc77..8c2d071 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -4,6 +4,7 @@
  * Copyright (c) 2008 OKL
  * Originally Written by Hans Jiang
  * Copyright (c) 2011 NICTA Pty Ltd.
+ * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
@@ -17,16 +18,14 @@
  *     is a real serial device.
  */
 
-#include "hw/hw.h"
-#include "hw/sysbus.h"
+#include "hw/char/imx_serial.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/char.h"
-#include "hw/arm/imx.h"
 
 //#define DEBUG_SERIAL 1
 #ifdef DEBUG_SERIAL
 #define DPRINTF(fmt, args...) \
-do { printf("imx_serial: " fmt , ##args); } while (0)
+do { printf("%s: " fmt , TYPE_IMX_SERIAL, ##args); } while (0)
 #else
 #define DPRINTF(fmt, args...) do {} while (0)
 #endif
@@ -38,42 +37,13 @@ do { printf("imx_serial: " fmt , ##args); } while (0)
 //#define DEBUG_IMPLEMENTATION 1
 #ifdef DEBUG_IMPLEMENTATION
 #  define IPRINTF(fmt, args...) \
-    do  { fprintf(stderr, "imx_serial: " fmt, ##args); } while (0)
+    do  { fprintf(stderr, "%s: " fmt, TYPE_IMX_SERIAL, ##args); } while (0)
 #else
 #  define IPRINTF(fmt, args...) do {} while (0)
 #endif
 
-#define TYPE_IMX_SERIAL "imx-serial"
-#define IMX_SERIAL(obj) OBJECT_CHECK(IMXSerialState, (obj), TYPE_IMX_SERIAL)
-
-typedef struct IMXSerialState {
-    SysBusDevice parent_obj;
-
-    MemoryRegion iomem;
-    int32_t readbuff;
-
-    uint32_t usr1;
-    uint32_t usr2;
-    uint32_t ucr1;
-    uint32_t ucr2;
-    uint32_t uts1;
-
-    /*
-     * The registers below are implemented just so that the
-     * guest OS sees what it has written
-     */
-    uint32_t onems;
-    uint32_t ufcr;
-    uint32_t ubmr;
-    uint32_t ubrc;
-    uint32_t ucr3;
-
-    qemu_irq irq;
-    CharDriverState *chr;
-} IMXSerialState;
-
 static const VMStateDescription vmstate_imx_serial = {
-    .name = "imx-serial",
+    .name = TYPE_IMX_SERIAL,
     .version_id = 1,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
@@ -91,55 +61,6 @@ static const VMStateDescription vmstate_imx_serial = {
     },
 };
 
-
-#define URXD_CHARRDY    (1<<15)   /* character read is valid */
-#define URXD_ERR        (1<<14)   /* Character has error */
-#define URXD_BRK        (1<<11)   /* Break received */
-
-#define USR1_PARTYER    (1<<15)   /* Parity Error */
-#define USR1_RTSS       (1<<14)   /* RTS pin status */
-#define USR1_TRDY       (1<<13)   /* Tx ready */
-#define USR1_RTSD       (1<<12)   /* RTS delta: pin changed state */
-#define USR1_ESCF       (1<<11)   /* Escape sequence interrupt */
-#define USR1_FRAMERR    (1<<10)   /* Framing error  */
-#define USR1_RRDY       (1<<9)    /* receiver ready */
-#define USR1_AGTIM      (1<<8)    /* Aging timer interrupt */
-#define USR1_DTRD       (1<<7)    /* DTR changed */
-#define USR1_RXDS       (1<<6)    /* Receiver is idle */
-#define USR1_AIRINT     (1<<5)    /* Aysnch IR interrupt */
-#define USR1_AWAKE      (1<<4)    /* Falling edge detected on RXd pin */
-
-#define USR2_ADET       (1<<15)   /* Autobaud complete */
-#define USR2_TXFE       (1<<14)   /* Transmit FIFO empty */
-#define USR2_DTRF       (1<<13)   /* DTR/DSR transition */
-#define USR2_IDLE       (1<<12)   /* UART has been idle for too long */
-#define USR2_ACST       (1<<11)   /* Autobaud counter stopped */
-#define USR2_RIDELT     (1<<10)   /* Ring Indicator delta */
-#define USR2_RIIN       (1<<9)    /* Ring Indicator Input */
-#define USR2_IRINT      (1<<8)    /* Serial Infrared Interrupt */
-#define USR2_WAKE       (1<<7)    /* Start bit detected */
-#define USR2_DCDDELT    (1<<6)    /* Data Carrier Detect delta */
-#define USR2_DCDIN      (1<<5)    /* Data Carrier Detect Input */
-#define USR2_RTSF       (1<<4)    /* RTS transition */
-#define USR2_TXDC       (1<<3)    /* Transmission complete */
-#define USR2_BRCD       (1<<2)    /* Break condition detected */
-#define USR2_ORE        (1<<1)    /* Overrun error */
-#define USR2_RDR        (1<<0)    /* Receive data ready */
-
-#define UCR1_TRDYEN     (1<<13)   /* Tx Ready Interrupt Enable */
-#define UCR1_RRDYEN     (1<<9)    /* Rx Ready Interrupt Enable */
-#define UCR1_TXMPTYEN   (1<<6)    /* Tx Empty Interrupt Enable */
-#define UCR1_UARTEN     (1<<0)    /* UART Enable */
-
-#define UCR2_TXEN       (1<<2)    /* Transmitter enable */
-#define UCR2_RXEN       (1<<1)    /* Receiver enable */
-#define UCR2_SRST       (1<<0)    /* Reset complete */
-
-#define UTS1_TXEMPTY    (1<<6)
-#define UTS1_RXEMPTY    (1<<5)
-#define UTS1_TXFULL     (1<<4)
-#define UTS1_RXFULL     (1<<3)
-
 static void imx_update(IMXSerialState *s)
 {
     uint32_t flags;
@@ -242,13 +163,13 @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset,
         return 0x0; /* TODO */
 
     default:
-        IPRINTF("imx_serial_read: bad offset: 0x%x\n", (int)offset);
+        IPRINTF("%s: bad offset: 0x%x\n", __func__, (int)offset);
         return 0;
     }
 }
 
 static void imx_serial_write(void *opaque, hwaddr offset,
-                      uint64_t value, unsigned size)
+                             uint64_t value, unsigned size)
 {
     IMXSerialState *s = (IMXSerialState *)opaque;
     unsigned char ch;
@@ -298,25 +219,25 @@ static void imx_serial_write(void *opaque, hwaddr offset,
 
     case 0x25: /* USR1 */
         value &= USR1_AWAKE | USR1_AIRINT | USR1_DTRD | USR1_AGTIM |
-            USR1_FRAMERR | USR1_ESCF | USR1_RTSD | USR1_PARTYER;
+                 USR1_FRAMERR | USR1_ESCF | USR1_RTSD | USR1_PARTYER;
         s->usr1 &= ~value;
         break;
 
     case 0x26: /* USR2 */
-       /*
-        * Writing 1 to some bits clears them; all other
-        * values are ignored
-        */
+        /*
+         * Writing 1 to some bits clears them; all other
+         * values are ignored
+         */
         value &= USR2_ADET | USR2_DTRF | USR2_IDLE | USR2_ACST |
-            USR2_RIDELT | USR2_IRINT | USR2_WAKE |
-            USR2_DCDDELT | USR2_RTSF | USR2_BRCD | USR2_ORE;
+                 USR2_RIDELT | USR2_IRINT | USR2_WAKE |
+                 USR2_DCDDELT | USR2_RTSF | USR2_BRCD | USR2_ORE;
         s->usr2 &= ~value;
         break;
 
-        /*
-         * Linux expects to see what it writes to these registers
-         * We don't currently alter the baud rate
-         */
+    /*
+     * Linux expects to see what it writes to these registers
+     * We don't currently alter the baud rate
+     */
     case 0x29: /* UBIR */
         s->ubrc = value & 0xffff;
         break;
@@ -344,7 +265,7 @@ static void imx_serial_write(void *opaque, hwaddr offset,
         break;
 
     default:
-        IPRINTF("imx_serial_write: Bad offset 0x%x\n", (int)offset);
+        IPRINTF("%s: Bad offset 0x%x\n", __func__, (int)offset);
     }
 }
 
@@ -377,22 +298,18 @@ static void imx_event(void *opaque, int event)
     }
 }
 
-
 static const struct MemoryRegionOps imx_serial_ops = {
     .read = imx_serial_read,
     .write = imx_serial_write,
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static int imx_serial_init(SysBusDevice *dev)
+static void imx_serial_realize(DeviceState *dev, Error **errp)
 {
     IMXSerialState *s = IMX_SERIAL(dev);
 
-
-    memory_region_init_io(&s->iomem, OBJECT(s), &imx_serial_ops, s,
-                          "imx-serial", 0x1000);
-    sysbus_init_mmio(dev, &s->iomem);
-    sysbus_init_irq(dev, &s->irq);
+    /* FIXME use a qdev chardev prop instead of qemu_char_get_next_serial() */
+    s->chr = qemu_char_get_next_serial();
 
     if (s->chr) {
         qemu_chr_add_handlers(s->chr, imx_can_receive, imx_receive,
@@ -401,45 +318,42 @@ static int imx_serial_init(SysBusDevice *dev)
         DPRINTF("No char dev for uart at 0x%lx\n",
                 (unsigned long)s->iomem.ram_addr);
     }
+}
 
-    return 0;
+static void imx_serial_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    IMXSerialState *s = IMX_SERIAL(obj);
+
+    memory_region_init_io(&s->iomem, obj, &imx_serial_ops, s,
+                          TYPE_IMX_SERIAL, 0x1000);
+    sysbus_init_mmio(sbd, &s->iomem);
+    sysbus_init_irq(sbd, &s->irq);
 }
 
 void imx_serial_create(int uart, const hwaddr addr, qemu_irq irq)
 {
     DeviceState *dev;
     SysBusDevice *bus;
-    CharDriverState *chr;
-    const char chr_name[] = "serial";
-    char label[ARRAY_SIZE(chr_name) + 1];
-
-    dev = qdev_create(NULL, TYPE_IMX_SERIAL);
 
     if (uart >= MAX_SERIAL_PORTS) {
         hw_error("Cannot assign uart %d: QEMU supports only %d ports\n",
                  uart, MAX_SERIAL_PORTS);
     }
-    chr = serial_hds[uart];
-    if (!chr) {
-        snprintf(label, ARRAY_SIZE(label), "%s%d", chr_name, uart);
-        chr = qemu_chr_new(label, "null", NULL);
-        if (!(chr)) {
-            hw_error("Can't assign serial port to imx-uart%d.\n", uart);
-        }
-    }
 
-    qdev_prop_set_chr(dev, "chardev", chr);
+    dev = qdev_create(NULL, TYPE_IMX_SERIAL);
+
     bus = SYS_BUS_DEVICE(dev);
     qdev_init_nofail(dev);
+
     if (addr != (hwaddr)-1) {
         sysbus_mmio_map(bus, 0, addr);
     }
-    sysbus_connect_irq(bus, 0, irq);
 
+    sysbus_connect_irq(bus, 0, irq);
 }
 
-
-static Property imx32_serial_properties[] = {
+static Property imx_serial_properties[] = {
     DEFINE_PROP_CHR("chardev", IMXSerialState, chr),
     DEFINE_PROP_END_OF_LIST(),
 };
@@ -447,21 +361,21 @@ static Property imx32_serial_properties[] = {
 static void imx_serial_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    k->init = imx_serial_init;
+    dc->realize = imx_serial_realize;
     dc->vmsd = &vmstate_imx_serial;
     dc->reset = imx_serial_reset_at_boot;
-    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
     dc->desc = "i.MX series UART";
-    dc->props = imx32_serial_properties;
+    dc->props = imx_serial_properties;
+    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
 }
 
 static const TypeInfo imx_serial_info = {
-    .name = TYPE_IMX_SERIAL,
-    .parent = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(IMXSerialState),
-    .class_init = imx_serial_class_init,
+    .name           = TYPE_IMX_SERIAL,
+    .parent         = TYPE_SYS_BUS_DEVICE,
+    .instance_size  = sizeof(IMXSerialState),
+    .instance_init  = imx_serial_init,
+    .class_init     = imx_serial_class_init,
 };
 
 static void imx_serial_register_types(void)
diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h
new file mode 100644
index 0000000..dba0cbb
--- /dev/null
+++ b/include/hw/char/imx_serial.h
@@ -0,0 +1,104 @@
+/*
+ * Device model for i.MX UART
+ *
+ * Copyright (c) 2008 OKL
+ * Originally Written by Hans Jiang
+ * Copyright (c) 2011 NICTA Pty Ltd.
+ * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef IMX_SERIAL_H
+#define IMX_SERIAL_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_IMX_SERIAL "imx.serial"
+#define IMX_SERIAL(obj) OBJECT_CHECK(IMXSerialState, (obj), TYPE_IMX_SERIAL)
+
+#define URXD_CHARRDY    (1<<15)   /* character read is valid */
+#define URXD_ERR        (1<<14)   /* Character has error */
+#define URXD_BRK        (1<<11)   /* Break received */
+
+#define USR1_PARTYER    (1<<15)   /* Parity Error */
+#define USR1_RTSS       (1<<14)   /* RTS pin status */
+#define USR1_TRDY       (1<<13)   /* Tx ready */
+#define USR1_RTSD       (1<<12)   /* RTS delta: pin changed state */
+#define USR1_ESCF       (1<<11)   /* Escape sequence interrupt */
+#define USR1_FRAMERR    (1<<10)   /* Framing error  */
+#define USR1_RRDY       (1<<9)    /* receiver ready */
+#define USR1_AGTIM      (1<<8)    /* Aging timer interrupt */
+#define USR1_DTRD       (1<<7)    /* DTR changed */
+#define USR1_RXDS       (1<<6)    /* Receiver is idle */
+#define USR1_AIRINT     (1<<5)    /* Aysnch IR interrupt */
+#define USR1_AWAKE      (1<<4)    /* Falling edge detected on RXd pin */
+
+#define USR2_ADET       (1<<15)   /* Autobaud complete */
+#define USR2_TXFE       (1<<14)   /* Transmit FIFO empty */
+#define USR2_DTRF       (1<<13)   /* DTR/DSR transition */
+#define USR2_IDLE       (1<<12)   /* UART has been idle for too long */
+#define USR2_ACST       (1<<11)   /* Autobaud counter stopped */
+#define USR2_RIDELT     (1<<10)   /* Ring Indicator delta */
+#define USR2_RIIN       (1<<9)    /* Ring Indicator Input */
+#define USR2_IRINT      (1<<8)    /* Serial Infrared Interrupt */
+#define USR2_WAKE       (1<<7)    /* Start bit detected */
+#define USR2_DCDDELT    (1<<6)    /* Data Carrier Detect delta */
+#define USR2_DCDIN      (1<<5)    /* Data Carrier Detect Input */
+#define USR2_RTSF       (1<<4)    /* RTS transition */
+#define USR2_TXDC       (1<<3)    /* Transmission complete */
+#define USR2_BRCD       (1<<2)    /* Break condition detected */
+#define USR2_ORE        (1<<1)    /* Overrun error */
+#define USR2_RDR        (1<<0)    /* Receive data ready */
+
+#define UCR1_TRDYEN     (1<<13)   /* Tx Ready Interrupt Enable */
+#define UCR1_RRDYEN     (1<<9)    /* Rx Ready Interrupt Enable */
+#define UCR1_TXMPTYEN   (1<<6)    /* Tx Empty Interrupt Enable */
+#define UCR1_UARTEN     (1<<0)    /* UART Enable */
+
+#define UCR2_TXEN       (1<<2)    /* Transmitter enable */
+#define UCR2_RXEN       (1<<1)    /* Receiver enable */
+#define UCR2_SRST       (1<<0)    /* Reset complete */
+
+#define UTS1_TXEMPTY    (1<<6)
+#define UTS1_RXEMPTY    (1<<5)
+#define UTS1_TXFULL     (1<<4)
+#define UTS1_RXFULL     (1<<3)
+
+typedef struct IMXSerialState {
+    /* Private */
+    SysBusDevice parent_obj;
+
+    /* Public */
+    MemoryRegion iomem;
+    int32_t readbuff;
+
+    uint32_t usr1;
+    uint32_t usr2;
+    uint32_t ucr1;
+    uint32_t ucr2;
+    uint32_t uts1;
+
+    /*
+     * The registers below are implemented just so that the
+     * guest OS sees what it has written
+     */
+    uint32_t onems;
+    uint32_t ufcr;
+    uint32_t ubmr;
+    uint32_t ubrc;
+    uint32_t ucr3;
+
+    qemu_irq irq;
+    CharDriverState *chr;
+} IMXSerialState;
+
+void imx_serial_create(int uart, const hwaddr addr, qemu_irq irq);
+
+#endif
-- 
2.1.4

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

* [Qemu-devel] [PATCH v8 02/11] i.MX: Split the i.MX AVIC emulator into a header file and a source file
  2015-06-29 20:11 [Qemu-devel] [PATCH v8 00/11] i.MX: Add i.MX25 support through the 3DS evaluation board Jean-Christophe Dubois
  2015-06-29 20:11 ` [Qemu-devel] [PATCH v8 01/11] i.MX: Split the i.MX serial driver into a header file and a source file Jean-Christophe Dubois
@ 2015-06-29 20:11 ` Jean-Christophe Dubois
  2015-06-30  7:05   ` Peter Crosthwaite
  2015-06-29 20:11 ` [Qemu-devel] [PATCH v8 03/11] i.MX: Split the i.MX CCM " Jean-Christophe Dubois
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 17+ messages in thread
From: Jean-Christophe Dubois @ 2015-06-29 20:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

This is to prepare to accomodate the SOC requirements.

Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
---

Changes since v1:
    * not present on v1

Changes since v2:
    * not present on v2

Changes since v3:
    * not present on v3

Changes since v4:
    * not present on v4

Changes since v5:
    * not present on v5

Changes since v6:
    * not present on v6

Changes since v7:
    * Splited the i.MX AVIC emulator into a header file and a source file

 hw/intc/imx_avic.c         | 56 +++++++++-------------------------------------
 include/hw/intc/imx_avic.h | 56 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+), 46 deletions(-)
 create mode 100644 include/hw/intc/imx_avic.h

diff --git a/hw/intc/imx_avic.c b/hw/intc/imx_avic.c
index e48f66c..96c376b 100644
--- a/hw/intc/imx_avic.c
+++ b/hw/intc/imx_avic.c
@@ -7,6 +7,7 @@
  * Copyright (c) 2008 OKL
  * Copyright (c) 2011 NICTA Pty Ltd
  * Originally written by Hans Jiang
+ * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
  *
  * This code is licensed under the GPL version 2 or later.  See
  * the COPYING file in the top-level directory.
@@ -14,16 +15,14 @@
  * TODO: implement vectors.
  */
 
-#include "hw/hw.h"
-#include "hw/sysbus.h"
-#include "qemu/host-utils.h"
+#include "hw/intc/imx_avic.h"
 
 #define DEBUG_INT 1
 #undef DEBUG_INT /* comment out for debugging */
 
 #ifdef DEBUG_INT
 #define DPRINTF(fmt, args...) \
-do { printf("imx_avic: " fmt , ##args); } while (0)
+do { printf("%s: " fmt , TYPE_IMX_AVIC, ##args); } while (0)
 #else
 #define DPRINTF(fmt, args...) do {} while (0)
 #endif
@@ -35,46 +34,13 @@ do { printf("imx_avic: " fmt , ##args); } while (0)
 #define DEBUG_IMPLEMENTATION 1
 #if DEBUG_IMPLEMENTATION
 #  define IPRINTF(fmt, args...) \
-    do  { fprintf(stderr, "imx_avic: " fmt, ##args); } while (0)
+    do  { fprintf(stderr, "%s: " fmt, TYPE_IMX_AVIC, ##args); } while (0)
 #else
 #  define IPRINTF(fmt, args...) do {} while (0)
 #endif
 
-#define IMX_AVIC_NUM_IRQS 64
-
-/* Interrupt Control Bits */
-#define ABFLAG (1<<25)
-#define ABFEN (1<<24)
-#define NIDIS (1<<22) /* Normal Interrupt disable */
-#define FIDIS (1<<21) /* Fast interrupt disable */
-#define NIAD  (1<<20) /* Normal Interrupt Arbiter Rise ARM level */
-#define FIAD  (1<<19) /* Fast Interrupt Arbiter Rise ARM level */
-#define NM    (1<<18) /* Normal interrupt mode */
-
-
-#define PRIO_PER_WORD (sizeof(uint32_t) * 8 / 4)
-#define PRIO_WORDS (IMX_AVIC_NUM_IRQS/PRIO_PER_WORD)
-
-#define TYPE_IMX_AVIC "imx_avic"
-#define IMX_AVIC(obj) \
-    OBJECT_CHECK(IMXAVICState, (obj), TYPE_IMX_AVIC)
-
-typedef struct IMXAVICState {
-    SysBusDevice parent_obj;
-
-    MemoryRegion iomem;
-    uint64_t pending;
-    uint64_t enabled;
-    uint64_t is_fiq;
-    uint32_t intcntl;
-    uint32_t intmask;
-    qemu_irq irq;
-    qemu_irq fiq;
-    uint32_t prio[PRIO_WORDS]; /* Priorities are 4-bits each */
-} IMXAVICState;
-
 static const VMStateDescription vmstate_imx_avic = {
-    .name = "imx-avic",
+    .name = TYPE_IMX_AVIC,
     .version_id = 1,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
@@ -88,8 +54,6 @@ static const VMStateDescription vmstate_imx_avic = {
     },
 };
 
-
-
 static inline int imx_avic_prio(IMXAVICState *s, int irq)
 {
     uint32_t word = irq / PRIO_PER_WORD;
@@ -249,7 +213,7 @@ static uint64_t imx_avic_read(void *opaque,
         return 0x4;
 
     default:
-        IPRINTF("imx_avic_read: Bad offset 0x%x\n", (int)offset);
+        IPRINTF("%s: Bad offset 0x%x\n", __func__, (int)offset);
         return 0;
     }
 }
@@ -261,12 +225,12 @@ static void imx_avic_write(void *opaque, hwaddr offset,
 
     /* Vector Registers not yet supported */
     if (offset >= 0x100 && offset <= 0x2fc) {
-        IPRINTF("imx_avic_write to vector register %d ignored\n",
+        IPRINTF("%s to vector register %d ignored\n", __func__,
                 (unsigned int)((offset - 0x100) >> 2));
         return;
     }
 
-    DPRINTF("imx_avic_write(0x%x) = %x\n",
+    DPRINTF("%s(0x%x) = %x\n", __func__,
             (unsigned int)offset>>2, (unsigned int)val);
     switch (offset >> 2) {
     case 0: /* Interrupt Control Register, INTCNTL */
@@ -341,7 +305,7 @@ static void imx_avic_write(void *opaque, hwaddr offset,
         return;
 
     default:
-        IPRINTF("imx_avic_write: Bad offset %x\n", (int)offset);
+        IPRINTF("%s: Bad offset %x\n", __func__, (int)offset);
     }
     imx_avic_update(s);
 }
@@ -370,7 +334,7 @@ static int imx_avic_init(SysBusDevice *sbd)
     IMXAVICState *s = IMX_AVIC(dev);
 
     memory_region_init_io(&s->iomem, OBJECT(s), &imx_avic_ops, s,
-                          "imx_avic", 0x1000);
+                          TYPE_IMX_AVIC, 0x1000);
     sysbus_init_mmio(sbd, &s->iomem);
 
     qdev_init_gpio_in(dev, imx_avic_set_irq, IMX_AVIC_NUM_IRQS);
diff --git a/include/hw/intc/imx_avic.h b/include/hw/intc/imx_avic.h
new file mode 100644
index 0000000..1645ba6
--- /dev/null
+++ b/include/hw/intc/imx_avic.h
@@ -0,0 +1,56 @@
+/*
+ * i.MX31 Vectored Interrupt Controller
+ *
+ * Note this is NOT the PL192 provided by ARM, but
+ * a custom implementation by Freescale.
+ *
+ * Copyright (c) 2008 OKL
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally written by Hans Jiang
+ * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * TODO: implement vectors.
+ */
+#ifndef IMX_AVIC_H
+#define IMX_AVIC_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_IMX_AVIC "imx.avic"
+#define IMX_AVIC(obj) OBJECT_CHECK(IMXAVICState, (obj), TYPE_IMX_AVIC)
+
+#define IMX_AVIC_NUM_IRQS 64
+
+/* Interrupt Control Bits */
+#define ABFLAG (1<<25)
+#define ABFEN (1<<24)
+#define NIDIS (1<<22) /* Normal Interrupt disable */
+#define FIDIS (1<<21) /* Fast interrupt disable */
+#define NIAD  (1<<20) /* Normal Interrupt Arbiter Rise ARM level */
+#define FIAD  (1<<19) /* Fast Interrupt Arbiter Rise ARM level */
+#define NM    (1<<18) /* Normal interrupt mode */
+
+
+#define PRIO_PER_WORD (sizeof(uint32_t) * 8 / 4)
+#define PRIO_WORDS (IMX_AVIC_NUM_IRQS/PRIO_PER_WORD)
+
+typedef struct {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    MemoryRegion iomem;
+    uint64_t pending;
+    uint64_t enabled;
+    uint64_t is_fiq;
+    uint32_t intcntl;
+    uint32_t intmask;
+    qemu_irq irq;
+    qemu_irq fiq;
+    uint32_t prio[PRIO_WORDS]; /* Priorities are 4-bits each */
+} IMXAVICState;
+
+#endif // IMX_AVIC_H
-- 
2.1.4

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

* [Qemu-devel] [PATCH v8 03/11] i.MX: Split the i.MX CCM emulator into a header file and a source file.
  2015-06-29 20:11 [Qemu-devel] [PATCH v8 00/11] i.MX: Add i.MX25 support through the 3DS evaluation board Jean-Christophe Dubois
  2015-06-29 20:11 ` [Qemu-devel] [PATCH v8 01/11] i.MX: Split the i.MX serial driver into a header file and a source file Jean-Christophe Dubois
  2015-06-29 20:11 ` [Qemu-devel] [PATCH v8 02/11] i.MX: Split the i.MX AVIC emulator " Jean-Christophe Dubois
@ 2015-06-29 20:11 ` Jean-Christophe Dubois
  2015-06-29 20:11 ` [Qemu-devel] [PATCH v8 04/11] i.MX: Split the i.MX EPIT " Jean-Christophe Dubois
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Jean-Christophe Dubois @ 2015-06-29 20:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

This is to prepare to accomodate the SOC requirements.

Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
---

Changes since v1:
    * not present on v1

Changes since v2:
    * not present on v2

Changes since v3:
    * not present on v3

Changes since v4:
    * not present on v4

Changes since v5:
    * not present on v5

Changes since v6:
    * not present on v6

Changes since v7:
    * Splited the i.MX CCM emulator into a header file and a source file

 hw/misc/imx_ccm.c         | 75 +++-----------------------------------
 include/hw/misc/imx_ccm.h | 91 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+), 70 deletions(-)
 create mode 100644 include/hw/misc/imx_ccm.h

diff --git a/hw/misc/imx_ccm.c b/hw/misc/imx_ccm.c
index 0920288..c213282 100644
--- a/hw/misc/imx_ccm.c
+++ b/hw/misc/imx_ccm.c
@@ -2,6 +2,7 @@
  * IMX31 Clock Control Module
  *
  * Copyright (C) 2012 NICTA
+ * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
@@ -10,51 +11,23 @@
  * the CCM.
  */
 
-#include "hw/hw.h"
-#include "hw/sysbus.h"
-#include "sysemu/sysemu.h"
-#include "hw/arm/imx.h"
+#include "hw/misc/imx_ccm.h"
 
 #define CKIH_FREQ 26000000 /* 26MHz crystal input */
 #define CKIL_FREQ    32768 /* nominal 32khz clock */
 
-
 //#define DEBUG_CCM 1
 #ifdef DEBUG_CCM
 #define DPRINTF(fmt, args...) \
-do { printf("imx_ccm: " fmt , ##args); } while (0)
+do { printf("%s: " fmt , TYPE_IMX_CCM, ##args); } while (0)
 #else
 #define DPRINTF(fmt, args...) do {} while (0)
 #endif
 
 static int imx_ccm_post_load(void *opaque, int version_id);
 
-#define TYPE_IMX_CCM "imx_ccm"
-#define IMX_CCM(obj) OBJECT_CHECK(IMXCCMState, (obj), TYPE_IMX_CCM)
-
-typedef struct IMXCCMState {
-    SysBusDevice parent_obj;
-
-    MemoryRegion iomem;
-
-    uint32_t ccmr;
-    uint32_t pdr0;
-    uint32_t pdr1;
-    uint32_t mpctl;
-    uint32_t spctl;
-    uint32_t cgr[3];
-    uint32_t pmcr0;
-    uint32_t pmcr1;
-
-    /* Frequencies precalculated on register changes */
-    uint32_t pll_refclk_freq;
-    uint32_t mcu_clk_freq;
-    uint32_t hsp_clk_freq;
-    uint32_t ipg_clk_freq;
-} IMXCCMState;
-
 static const VMStateDescription vmstate_imx_ccm = {
-    .name = "imx-ccm",
+    .name = TYPE_IMX_CCM,
     .version_id = 1,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
@@ -72,44 +45,6 @@ static const VMStateDescription vmstate_imx_ccm = {
     .post_load = imx_ccm_post_load,
 };
 
-/* CCMR */
-#define CCMR_FPME (1<<0)
-#define CCMR_MPE  (1<<3)
-#define CCMR_MDS  (1<<7)
-#define CCMR_FPMF (1<<26)
-#define CCMR_PRCS (3<<1)
-
-/* PDR0 */
-#define PDR0_MCU_PODF_SHIFT (0)
-#define PDR0_MCU_PODF_MASK (0x7)
-#define PDR0_MAX_PODF_SHIFT (3)
-#define PDR0_MAX_PODF_MASK (0x7)
-#define PDR0_IPG_PODF_SHIFT (6)
-#define PDR0_IPG_PODF_MASK (0x3)
-#define PDR0_NFC_PODF_SHIFT (8)
-#define PDR0_NFC_PODF_MASK (0x7)
-#define PDR0_HSP_PODF_SHIFT (11)
-#define PDR0_HSP_PODF_MASK (0x7)
-#define PDR0_PER_PODF_SHIFT (16)
-#define PDR0_PER_PODF_MASK (0x1f)
-#define PDR0_CSI_PODF_SHIFT (23)
-#define PDR0_CSI_PODF_MASK (0x1ff)
-
-#define EXTRACT(value, name) (((value) >> PDR0_##name##_PODF_SHIFT) \
-                              & PDR0_##name##_PODF_MASK)
-#define INSERT(value, name) (((value) & PDR0_##name##_PODF_MASK) << \
-                             PDR0_##name##_PODF_SHIFT)
-/* PLL control registers */
-#define PD(v) (((v) >> 26) & 0xf)
-#define MFD(v) (((v) >> 16) & 0x3ff)
-#define MFI(v) (((v) >> 10) & 0xf);
-#define MFN(v) ((v) & 0x3ff)
-
-#define PLL_PD(x)               (((x) & 0xf) << 26)
-#define PLL_MFD(x)              (((x) & 0x3ff) << 16)
-#define PLL_MFI(x)              (((x) & 0xf) << 10)
-#define PLL_MFN(x)              (((x) & 0x3ff) << 0)
-
 uint32_t imx_clock_frequency(DeviceState *dev, IMXClk clock)
 {
     IMXCCMState *s = IMX_CCM(dev);
@@ -286,7 +221,7 @@ static int imx_ccm_init(SysBusDevice *dev)
     IMXCCMState *s = IMX_CCM(dev);
 
     memory_region_init_io(&s->iomem, OBJECT(dev), &imx_ccm_ops, s,
-                          "imx_ccm", 0x1000);
+                          TYPE_IMX_CCM, 0x1000);
     sysbus_init_mmio(dev, &s->iomem);
 
     return 0;
diff --git a/include/hw/misc/imx_ccm.h b/include/hw/misc/imx_ccm.h
new file mode 100644
index 0000000..7febafd
--- /dev/null
+++ b/include/hw/misc/imx_ccm.h
@@ -0,0 +1,91 @@
+/*
+ * IMX31 Clock Control Module
+ *
+ * Copyright (C) 2012 NICTA
+ * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef IMX_CCM_H
+#define IMX_CCM_H
+
+#include "hw/sysbus.h"
+
+/* CCMR */
+#define CCMR_FPME (1<<0)
+#define CCMR_MPE  (1<<3)
+#define CCMR_MDS  (1<<7)
+#define CCMR_FPMF (1<<26)
+#define CCMR_PRCS (3<<1)
+
+/* PDR0 */
+#define PDR0_MCU_PODF_SHIFT (0)
+#define PDR0_MCU_PODF_MASK (0x7)
+#define PDR0_MAX_PODF_SHIFT (3)
+#define PDR0_MAX_PODF_MASK (0x7)
+#define PDR0_IPG_PODF_SHIFT (6)
+#define PDR0_IPG_PODF_MASK (0x3)
+#define PDR0_NFC_PODF_SHIFT (8)
+#define PDR0_NFC_PODF_MASK (0x7)
+#define PDR0_HSP_PODF_SHIFT (11)
+#define PDR0_HSP_PODF_MASK (0x7)
+#define PDR0_PER_PODF_SHIFT (16)
+#define PDR0_PER_PODF_MASK (0x1f)
+#define PDR0_CSI_PODF_SHIFT (23)
+#define PDR0_CSI_PODF_MASK (0x1ff)
+
+#define EXTRACT(value, name) (((value) >> PDR0_##name##_PODF_SHIFT) \
+                              & PDR0_##name##_PODF_MASK)
+#define INSERT(value, name) (((value) & PDR0_##name##_PODF_MASK) << \
+                             PDR0_##name##_PODF_SHIFT)
+
+/* PLL control registers */
+#define PD(v) (((v) >> 26) & 0xf)
+#define MFD(v) (((v) >> 16) & 0x3ff)
+#define MFI(v) (((v) >> 10) & 0xf);
+#define MFN(v) ((v) & 0x3ff)
+
+#define PLL_PD(x)               (((x) & 0xf) << 26)
+#define PLL_MFD(x)              (((x) & 0x3ff) << 16)
+#define PLL_MFI(x)              (((x) & 0xf) << 10)
+#define PLL_MFN(x)              (((x) & 0x3ff) << 0)
+
+#define TYPE_IMX_CCM "imx.ccm"
+#define IMX_CCM(obj) OBJECT_CHECK(IMXCCMState, (obj), TYPE_IMX_CCM)
+
+typedef struct {
+    /* <private> */
+    SysBusDevice parent_obj;
+
+    /* <public> */
+    MemoryRegion iomem;
+
+    uint32_t ccmr;
+    uint32_t pdr0;
+    uint32_t pdr1;
+    uint32_t mpctl;
+    uint32_t spctl;
+    uint32_t cgr[3];
+    uint32_t pmcr0;
+    uint32_t pmcr1;
+
+    /* Frequencies precalculated on register changes */
+    uint32_t pll_refclk_freq;
+    uint32_t mcu_clk_freq;
+    uint32_t hsp_clk_freq;
+    uint32_t ipg_clk_freq;
+} IMXCCMState;
+
+typedef enum  {
+    NOCLK,
+    MCU,
+    HSP,
+    IPG,
+    CLK_32k
+} IMXClk;
+
+uint32_t imx_clock_frequency(DeviceState *s, IMXClk clock);
+
+#endif /* IMX_CCM_H */
-- 
2.1.4

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

* [Qemu-devel] [PATCH v8 04/11] i.MX: Split the i.MX EPIT emulator into a header file and a source file.
  2015-06-29 20:11 [Qemu-devel] [PATCH v8 00/11] i.MX: Add i.MX25 support through the 3DS evaluation board Jean-Christophe Dubois
                   ` (2 preceding siblings ...)
  2015-06-29 20:11 ` [Qemu-devel] [PATCH v8 03/11] i.MX: Split the i.MX CCM " Jean-Christophe Dubois
@ 2015-06-29 20:11 ` Jean-Christophe Dubois
  2015-06-30  7:12   ` Peter Crosthwaite
  2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 05/11] i.MX: Split the i.MX GPT " Jean-Christophe Dubois
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 17+ messages in thread
From: Jean-Christophe Dubois @ 2015-06-29 20:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

This is to prepare to accomodate the SOC requirements.

Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
---

Changes since v1:
    * not present on v1

Changes since v2:
    * not present on v2

Changes since v3:
    * not present on v3

Changes since v4:
    * not present on v4

Changes since v5:
    * not present on v5

Changes since v6:
    * not present on v6

Changes since v7:
    * Splited the i.MX EPIT emulator into a header file and a source file

 hw/timer/imx_epit.c         | 65 +++++------------------------------
 include/hw/timer/imx_epit.h | 83 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 92 insertions(+), 56 deletions(-)
 create mode 100644 include/hw/timer/imx_epit.h

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index ffefc22..39fc3f1 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -5,23 +5,17 @@
  * Copyright (c) 2011 NICTA Pty Ltd
  * Originally written by Hans Jiang
  * Updated by Peter Chubb
- * Updated by Jean-Christophe Dubois
+ * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
  *
  * This code is licensed under GPL version 2 or later.  See
  * the COPYING file in the top-level directory.
  *
  */
 
-#include "hw/hw.h"
-#include "qemu/bitops.h"
-#include "qemu/timer.h"
-#include "hw/ptimer.h"
-#include "hw/sysbus.h"
-#include "hw/arm/imx.h"
+#include "hw/timer/imx_epit.h"
+#include "hw/misc/imx_ccm.h"
 #include "qemu/main-loop.h"
 
-#define TYPE_IMX_EPIT "imx.epit"
-
 #define DEBUG_TIMER 0
 #if DEBUG_TIMER
 
@@ -61,30 +55,6 @@ static char const *imx_epit_reg_name(uint32_t reg)
 #  define IPRINTF(fmt, args...) do {} while (0)
 #endif
 
-#define IMX_EPIT(obj) \
-        OBJECT_CHECK(IMXEPITState, (obj), TYPE_IMX_EPIT)
-
-/*
- * EPIT: Enhanced periodic interrupt timer
- */
-
-#define CR_EN       (1 << 0)
-#define CR_ENMOD    (1 << 1)
-#define CR_OCIEN    (1 << 2)
-#define CR_RLD      (1 << 3)
-#define CR_PRESCALE_SHIFT (4)
-#define CR_PRESCALE_MASK  (0xfff)
-#define CR_SWR      (1 << 16)
-#define CR_IOVW     (1 << 17)
-#define CR_DBGEN    (1 << 18)
-#define CR_WAITEN   (1 << 19)
-#define CR_DOZEN    (1 << 20)
-#define CR_STOPEN   (1 << 21)
-#define CR_CLKSRC_SHIFT (24)
-#define CR_CLKSRC_MASK  (0x3 << CR_CLKSRC_SHIFT)
-
-#define EPIT_TIMER_MAX  0XFFFFFFFFUL
-
 /*
  * Exact clock frequencies vary from board to board.
  * These are typical.
@@ -96,23 +66,6 @@ static const IMXClk imx_epit_clocks[] =  {
     CLK_32k,  /* 11 ipg_clk_32k -- ~32kHz */
 };
 
-typedef struct {
-    SysBusDevice busdev;
-    ptimer_state *timer_reload;
-    ptimer_state *timer_cmp;
-    MemoryRegion iomem;
-    DeviceState *ccm;
-
-    uint32_t cr;
-    uint32_t sr;
-    uint32_t lr;
-    uint32_t cmp;
-    uint32_t cnt;
-
-    uint32_t freq;
-    qemu_irq irq;
-} IMXEPITState;
-
 /*
  * Update interrupt status
  */
@@ -174,9 +127,9 @@ static void imx_epit_reset(DeviceState *dev)
 
 static uint32_t imx_epit_update_count(IMXEPITState *s)
 {
-     s->cnt = ptimer_get_count(s->timer_reload);
+    s->cnt = ptimer_get_count(s->timer_reload);
 
-     return s->cnt;
+    return s->cnt;
 }
 
 static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
@@ -344,13 +297,13 @@ void imx_timerp_create(const hwaddr addr, qemu_irq irq, DeviceState *ccm)
 }
 
 static const MemoryRegionOps imx_epit_ops = {
-  .read = imx_epit_read,
-  .write = imx_epit_write,
-  .endianness = DEVICE_NATIVE_ENDIAN,
+    .read = imx_epit_read,
+    .write = imx_epit_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static const VMStateDescription vmstate_imx_timer_epit = {
-    .name = "imx.epit",
+    .name = TYPE_IMX_EPIT,
     .version_id = 2,
     .minimum_version_id = 2,
     .fields = (VMStateField[]) {
diff --git a/include/hw/timer/imx_epit.h b/include/hw/timer/imx_epit.h
new file mode 100644
index 0000000..dbc99ca
--- /dev/null
+++ b/include/hw/timer/imx_epit.h
@@ -0,0 +1,83 @@
+/*
+ * i.MX EPIT Timer
+ *
+ * Copyright (c) 2008 OK Labs
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally written by Hans Jiang
+ * Updated by Peter Chubb
+ * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * 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 IMX_EPIT_H
+#define IMX_EPIT_H
+
+#include "hw/sysbus.h"
+#include "hw/ptimer.h"
+
+/*
+ * EPIT: Enhanced periodic interrupt timer
+ */
+
+#define CR_EN       (1 << 0)
+#define CR_ENMOD    (1 << 1)
+#define CR_OCIEN    (1 << 2)
+#define CR_RLD      (1 << 3)
+#define CR_PRESCALE_SHIFT (4)
+#define CR_PRESCALE_MASK  (0xfff)
+#define CR_SWR      (1 << 16)
+#define CR_IOVW     (1 << 17)
+#define CR_DBGEN    (1 << 18)
+#define CR_WAITEN   (1 << 19)
+#define CR_DOZEN    (1 << 20)
+#define CR_STOPEN   (1 << 21)
+#define CR_CLKSRC_SHIFT (24)
+#define CR_CLKSRC_MASK  (0x3 << CR_CLKSRC_SHIFT)
+
+#define EPIT_TIMER_MAX  0XFFFFFFFFUL
+
+#define TYPE_IMX_EPIT "imx.epit"
+#define IMX_EPIT(obj) OBJECT_CHECK(IMXEPITState, (obj), TYPE_IMX_EPIT)
+
+typedef struct {
+    /* <private> */
+    SysBusDevice parent_obj;
+
+    /* <public> */
+    ptimer_state *timer_reload;
+    ptimer_state *timer_cmp;
+    MemoryRegion iomem;
+    DeviceState *ccm;
+
+    uint32_t cr;
+    uint32_t sr;
+    uint32_t lr;
+    uint32_t cmp;
+    uint32_t cnt;
+
+    uint32_t freq;
+    qemu_irq irq;
+} IMXEPITState;
+
+void imx_timerp_create(const hwaddr addr,
+                       qemu_irq irq,
+                       DeviceState *ccm);
+
+#endif /* IMX_EPIT_H */
-- 
2.1.4

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

* [Qemu-devel] [PATCH v8 05/11] i.MX: Split the i.MX GPT emulator into a header file and a source file.
  2015-06-29 20:11 [Qemu-devel] [PATCH v8 00/11] i.MX: Add i.MX25 support through the 3DS evaluation board Jean-Christophe Dubois
                   ` (3 preceding siblings ...)
  2015-06-29 20:11 ` [Qemu-devel] [PATCH v8 04/11] i.MX: Split the i.MX EPIT " Jean-Christophe Dubois
@ 2015-06-29 20:12 ` Jean-Christophe Dubois
  2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 06/11] kzm: Use modified i.MX emulators Jean-Christophe Dubois
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Jean-Christophe Dubois @ 2015-06-29 20:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

This is to prepare to accomodate the SOC requirements.

Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
---

Changes since v1:
    * not present on v1

Changes since v2:
    * not present on v2

Changes since v3:
    * not present on v3

Changes since v4:
    * not present on v4

Changes since v5:
    * not present on v5

Changes since v6:
    * not present on v6

Changes since v7:
    * Splited the i.MX GPT emulator into a header file and a source file

 hw/timer/imx_gpt.c         |  86 +++--------------------------------
 include/hw/timer/imx_gpt.h | 111 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 117 insertions(+), 80 deletions(-)
 create mode 100644 include/hw/timer/imx_gpt.h

diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index 3b31010..90682e0 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -5,23 +5,17 @@
  * Copyright (c) 2011 NICTA Pty Ltd
  * Originally written by Hans Jiang
  * Updated by Peter Chubb
- * Updated by Jean-Christophe Dubois
+ * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
  *
  * This code is licensed under GPL version 2 or later.  See
  * the COPYING file in the top-level directory.
  *
  */
 
-#include "hw/hw.h"
-#include "qemu/bitops.h"
-#include "qemu/timer.h"
-#include "hw/ptimer.h"
-#include "hw/sysbus.h"
-#include "hw/arm/imx.h"
+#include "hw/timer/imx_gpt.h"
+#include "hw/misc/imx_ccm.h"
 #include "qemu/main-loop.h"
 
-#define TYPE_IMX_GPT "imx.gpt"
-
 /*
  * Define to 1 for debug messages
  */
@@ -74,76 +68,8 @@ static char const *imx_gpt_reg_name(uint32_t reg)
 #  define IPRINTF(fmt, args...) do {} while (0)
 #endif
 
-#define IMX_GPT(obj) \
-        OBJECT_CHECK(IMXGPTState, (obj), TYPE_IMX_GPT)
-/*
- * GPT : General purpose timer
- *
- * This timer counts up continuously while it is enabled, resetting itself
- * to 0 when it reaches GPT_TIMER_MAX (in freerun mode) or when it
- * reaches the value of one of the ocrX (in periodic mode).
- */
-
-#define GPT_TIMER_MAX  0XFFFFFFFFUL
-
-/* Control register.  Not all of these bits have any effect (yet) */
-#define GPT_CR_EN     (1 << 0)  /* GPT Enable */
-#define GPT_CR_ENMOD  (1 << 1)  /* GPT Enable Mode */
-#define GPT_CR_DBGEN  (1 << 2)  /* GPT Debug mode enable */
-#define GPT_CR_WAITEN (1 << 3)  /* GPT Wait Mode Enable  */
-#define GPT_CR_DOZEN  (1 << 4)  /* GPT Doze mode enable */
-#define GPT_CR_STOPEN (1 << 5)  /* GPT Stop Mode Enable */
-#define GPT_CR_CLKSRC_SHIFT (6)
-#define GPT_CR_CLKSRC_MASK  (0x7)
-
-#define GPT_CR_FRR    (1 << 9)  /* Freerun or Restart */
-#define GPT_CR_SWR    (1 << 15) /* Software Reset */
-#define GPT_CR_IM1    (3 << 16) /* Input capture channel 1 mode (2 bits) */
-#define GPT_CR_IM2    (3 << 18) /* Input capture channel 2 mode (2 bits) */
-#define GPT_CR_OM1    (7 << 20) /* Output Compare Channel 1 Mode (3 bits) */
-#define GPT_CR_OM2    (7 << 23) /* Output Compare Channel 2 Mode (3 bits) */
-#define GPT_CR_OM3    (7 << 26) /* Output Compare Channel 3 Mode (3 bits) */
-#define GPT_CR_FO1    (1 << 29) /* Force Output Compare Channel 1 */
-#define GPT_CR_FO2    (1 << 30) /* Force Output Compare Channel 2 */
-#define GPT_CR_FO3    (1 << 31) /* Force Output Compare Channel 3 */
-
-#define GPT_SR_OF1  (1 << 0)
-#define GPT_SR_OF2  (1 << 1)
-#define GPT_SR_OF3  (1 << 2)
-#define GPT_SR_ROV  (1 << 5)
-
-#define GPT_IR_OF1IE  (1 << 0)
-#define GPT_IR_OF2IE  (1 << 1)
-#define GPT_IR_OF3IE  (1 << 2)
-#define GPT_IR_ROVIE  (1 << 5)
-
-typedef struct {
-    SysBusDevice busdev;
-    ptimer_state *timer;
-    MemoryRegion iomem;
-    DeviceState *ccm;
-
-    uint32_t cr;
-    uint32_t pr;
-    uint32_t sr;
-    uint32_t ir;
-    uint32_t ocr1;
-    uint32_t ocr2;
-    uint32_t ocr3;
-    uint32_t icr1;
-    uint32_t icr2;
-    uint32_t cnt;
-
-    uint32_t next_timeout;
-    uint32_t next_int;
-
-    uint32_t freq;
-
-    qemu_irq irq;
-} IMXGPTState;
-
 static const VMStateDescription vmstate_imx_timer_gpt = {
-    .name = "imx.gpt",
+    .name = TYPE_IMX_GPT,
     .version_id = 3,
     .minimum_version_id = 3,
     .fields = (VMStateField[]) {
@@ -180,7 +106,7 @@ static void imx_gpt_set_freq(IMXGPTState *s)
 {
     uint32_t clksrc = extract32(s->cr, GPT_CR_CLKSRC_SHIFT, 3);
     uint32_t freq = imx_clock_frequency(s->ccm, imx_gpt_clocks[clksrc])
-                                                / (1 + s->pr);
+                    / (1 + s->pr);
     s->freq = freq;
 
     DPRINTF("Setting clksrc %d to frequency %d\n", clksrc, freq);
@@ -207,7 +133,7 @@ static uint32_t imx_gpt_update_count(IMXGPTState *s)
 }
 
 static inline uint32_t imx_gpt_find_limit(uint32_t count, uint32_t reg,
-                                             uint32_t timeout)
+        uint32_t timeout)
 {
     if ((count < reg) && (timeout > reg)) {
         timeout = reg;
diff --git a/include/hw/timer/imx_gpt.h b/include/hw/timer/imx_gpt.h
new file mode 100644
index 0000000..8342c86
--- /dev/null
+++ b/include/hw/timer/imx_gpt.h
@@ -0,0 +1,111 @@
+/*
+ * i.MX GPT Timer
+ *
+ * Copyright (c) 2008 OK Labs
+ * Copyright (c) 2011 NICTA Pty Ltd
+ * Originally written by Hans Jiang
+ * Updated by Peter Chubb
+ * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * 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 IMX_GPT_H
+#define IMX_GPT_H
+
+#include "hw/sysbus.h"
+#include "hw/ptimer.h"
+
+/*
+ * GPT : General purpose timer
+ *
+ * This timer counts up continuously while it is enabled, resetting itself
+ * to 0 when it reaches GPT_TIMER_MAX (in freerun mode) or when it
+ * reaches the value of one of the ocrX (in periodic mode).
+ */
+
+#define GPT_TIMER_MAX  0XFFFFFFFFUL
+
+/* Control register.  Not all of these bits have any effect (yet) */
+#define GPT_CR_EN     (1 << 0)  /* GPT Enable */
+#define GPT_CR_ENMOD  (1 << 1)  /* GPT Enable Mode */
+#define GPT_CR_DBGEN  (1 << 2)  /* GPT Debug mode enable */
+#define GPT_CR_WAITEN (1 << 3)  /* GPT Wait Mode Enable  */
+#define GPT_CR_DOZEN  (1 << 4)  /* GPT Doze mode enable */
+#define GPT_CR_STOPEN (1 << 5)  /* GPT Stop Mode Enable */
+#define GPT_CR_CLKSRC_SHIFT (6)
+#define GPT_CR_CLKSRC_MASK  (0x7)
+
+#define GPT_CR_FRR    (1 << 9)  /* Freerun or Restart */
+#define GPT_CR_SWR    (1 << 15) /* Software Reset */
+#define GPT_CR_IM1    (3 << 16) /* Input capture channel 1 mode (2 bits) */
+#define GPT_CR_IM2    (3 << 18) /* Input capture channel 2 mode (2 bits) */
+#define GPT_CR_OM1    (7 << 20) /* Output Compare Channel 1 Mode (3 bits) */
+#define GPT_CR_OM2    (7 << 23) /* Output Compare Channel 2 Mode (3 bits) */
+#define GPT_CR_OM3    (7 << 26) /* Output Compare Channel 3 Mode (3 bits) */
+#define GPT_CR_FO1    (1 << 29) /* Force Output Compare Channel 1 */
+#define GPT_CR_FO2    (1 << 30) /* Force Output Compare Channel 2 */
+#define GPT_CR_FO3    (1 << 31) /* Force Output Compare Channel 3 */
+
+#define GPT_SR_OF1  (1 << 0)
+#define GPT_SR_OF2  (1 << 1)
+#define GPT_SR_OF3  (1 << 2)
+#define GPT_SR_ROV  (1 << 5)
+
+#define GPT_IR_OF1IE  (1 << 0)
+#define GPT_IR_OF2IE  (1 << 1)
+#define GPT_IR_OF3IE  (1 << 2)
+#define GPT_IR_ROVIE  (1 << 5)
+
+#define TYPE_IMX_GPT "imx.gpt"
+#define IMX_GPT(obj) OBJECT_CHECK(IMXGPTState, (obj), TYPE_IMX_GPT)
+
+typedef struct {
+    /* <private> */
+    SysBusDevice parent_obj;
+
+    /* <public> */
+    ptimer_state *timer;
+    MemoryRegion iomem;
+    DeviceState *ccm;
+
+    uint32_t cr;
+    uint32_t pr;
+    uint32_t sr;
+    uint32_t ir;
+    uint32_t ocr1;
+    uint32_t ocr2;
+    uint32_t ocr3;
+    uint32_t icr1;
+    uint32_t icr2;
+    uint32_t cnt;
+
+    uint32_t next_timeout;
+    uint32_t next_int;
+
+    uint32_t freq;
+
+    qemu_irq irq;
+} IMXGPTState;
+
+void imx_timerg_create(const hwaddr addr,
+                       qemu_irq irq,
+                       DeviceState *ccm);
+
+#endif /* IMX_GPT_H */
-- 
2.1.4

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

* [Qemu-devel] [PATCH v8 06/11] kzm: Use modified i.MX emulators.
  2015-06-29 20:11 [Qemu-devel] [PATCH v8 00/11] i.MX: Add i.MX25 support through the 3DS evaluation board Jean-Christophe Dubois
                   ` (4 preceding siblings ...)
  2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 05/11] i.MX: Split the i.MX GPT " Jean-Christophe Dubois
@ 2015-06-29 20:12 ` Jean-Christophe Dubois
  2015-06-30  7:12   ` Peter Crosthwaite
  2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 07/11] i.MX: Add FEC Ethernet Emulator Jean-Christophe Dubois
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 17+ messages in thread
From: Jean-Christophe Dubois @ 2015-06-29 20:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

Use modified AVIC, CCM, UART, GPT, EPIT emultors.

Tested by booting Linux one KZM emulator.

Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
---

Changes since v1:
    * not present on v1

Changes since v2:
    * not present on v2

Changes since v3:
    * not present on v3

Changes since v4:
    * not present on v4

Changes since v5:
    * not present on v5

Changes since v6:
    * not present on v6

Changes since v7:
    * update KZM target to use new emulators

 hw/arm/kzm.c         | 86 +++++++++++++++++++++++++++-------------------------
 include/hw/arm/imx.h | 34 ---------------------
 2 files changed, 45 insertions(+), 75 deletions(-)
 delete mode 100644 include/hw/arm/imx.h

diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
index 5be0369..485e745 100644
--- a/hw/arm/kzm.c
+++ b/hw/arm/kzm.c
@@ -22,45 +22,49 @@
 #include "sysemu/sysemu.h"
 #include "hw/boards.h"
 #include "hw/char/serial.h"
-#include "hw/arm/imx.h"
-
-    /* Memory map for Kzm Emulation Baseboard:
-     * 0x00000000-0x00003fff 16k secure ROM       IGNORED
-     * 0x00004000-0x00407fff Reserved             IGNORED
-     * 0x00404000-0x00407fff ROM                  IGNORED
-     * 0x00408000-0x0fffffff Reserved             IGNORED
-     * 0x10000000-0x1fffbfff RAM aliasing         IGNORED
-     * 0x1fffc000-0x1fffffff RAM                  EMULATED
-     * 0x20000000-0x2fffffff Reserved             IGNORED
-     * 0x30000000-0x7fffffff I.MX31 Internal Register Space
-     *   0x43f00000 IO_AREA0
-     *   0x43f90000 UART1                         EMULATED
-     *   0x43f94000 UART2                         EMULATED
-     *   0x68000000 AVIC                          EMULATED
-     *   0x53f80000 CCM                           EMULATED
-     *   0x53f94000 PIT 1                         EMULATED
-     *   0x53f98000 PIT 2                         EMULATED
-     *   0x53f90000 GPT                           EMULATED
-     * 0x80000000-0x87ffffff RAM                  EMULATED
-     * 0x88000000-0x8fffffff RAM Aliasing         EMULATED
-     * 0xa0000000-0xafffffff NAND Flash           IGNORED
-     * 0xb0000000-0xb3ffffff Unavailable          IGNORED
-     * 0xb4000000-0xb4000fff 8-bit free space     IGNORED
-     * 0xb4001000-0xb400100f Board control        IGNORED
-     *  0xb4001003           DIP switch
-     * 0xb4001010-0xb400101f 7-segment LED        IGNORED
-     * 0xb4001020-0xb400102f LED                  IGNORED
-     * 0xb4001030-0xb400103f LED                  IGNORED
-     * 0xb4001040-0xb400104f FPGA, UART           EMULATED
-     * 0xb4001050-0xb400105f FPGA, UART           EMULATED
-     * 0xb4001060-0xb40fffff FPGA                 IGNORED
-     * 0xb6000000-0xb61fffff LAN controller       EMULATED
-     * 0xb6200000-0xb62fffff FPGA NAND Controller IGNORED
-     * 0xb6300000-0xb7ffffff Free                 IGNORED
-     * 0xb8000000-0xb8004fff Memory control registers IGNORED
-     * 0xc0000000-0xc3ffffff PCMCIA/CF            IGNORED
-     * 0xc4000000-0xffffffff Reserved             IGNORED
-     */
+#include "hw/misc/imx_ccm.h"
+#include "hw/intc/imx_avic.h"
+#include "hw/timer/imx_epit.h"
+#include "hw/timer/imx_gpt.h"
+#include "hw/char/imx_serial.h"
+
+/* Memory map for Kzm Emulation Baseboard:
+ * 0x00000000-0x00003fff 16k secure ROM       IGNORED
+ * 0x00004000-0x00407fff Reserved             IGNORED
+ * 0x00404000-0x00407fff ROM                  IGNORED
+ * 0x00408000-0x0fffffff Reserved             IGNORED
+ * 0x10000000-0x1fffbfff RAM aliasing         IGNORED
+ * 0x1fffc000-0x1fffffff RAM                  EMULATED
+ * 0x20000000-0x2fffffff Reserved             IGNORED
+ * 0x30000000-0x7fffffff I.MX31 Internal Register Space
+ *   0x43f00000 IO_AREA0
+ *   0x43f90000 UART1                         EMULATED
+ *   0x43f94000 UART2                         EMULATED
+ *   0x68000000 AVIC                          EMULATED
+ *   0x53f80000 CCM                           EMULATED
+ *   0x53f94000 PIT 1                         EMULATED
+ *   0x53f98000 PIT 2                         EMULATED
+ *   0x53f90000 GPT                           EMULATED
+ * 0x80000000-0x87ffffff RAM                  EMULATED
+ * 0x88000000-0x8fffffff RAM Aliasing         EMULATED
+ * 0xa0000000-0xafffffff NAND Flash           IGNORED
+ * 0xb0000000-0xb3ffffff Unavailable          IGNORED
+ * 0xb4000000-0xb4000fff 8-bit free space     IGNORED
+ * 0xb4001000-0xb400100f Board control        IGNORED
+ *  0xb4001003           DIP switch
+ * 0xb4001010-0xb400101f 7-segment LED        IGNORED
+ * 0xb4001020-0xb400102f LED                  IGNORED
+ * 0xb4001030-0xb400103f LED                  IGNORED
+ * 0xb4001040-0xb400104f FPGA, UART           EMULATED
+ * 0xb4001050-0xb400105f FPGA, UART           EMULATED
+ * 0xb4001060-0xb40fffff FPGA                 IGNORED
+ * 0xb6000000-0xb61fffff LAN controller       EMULATED
+ * 0xb6200000-0xb62fffff FPGA NAND Controller IGNORED
+ * 0xb6300000-0xb7ffffff Free                 IGNORED
+ * 0xb8000000-0xb8004fff Memory control registers IGNORED
+ * 0xc0000000-0xc3ffffff PCMCIA/CF            IGNORED
+ * 0xc4000000-0xffffffff Reserved             IGNORED
+ */
 
 #define KZM_RAMADDRESS (0x80000000)
 #define KZM_FPGA       (0xb4001040)
@@ -106,7 +110,7 @@ static void kzm_init(MachineState *machine)
     memory_region_init_ram(sram, NULL, "kzm.sram", 0x4000, &error_abort);
     memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
 
-    dev = sysbus_create_varargs("imx_avic", 0x68000000,
+    dev = sysbus_create_varargs(TYPE_IMX_AVIC, 0x68000000,
                                 qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
                                 qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
                                 NULL);
@@ -114,7 +118,7 @@ static void kzm_init(MachineState *machine)
     imx_serial_create(0, 0x43f90000, qdev_get_gpio_in(dev, 45));
     imx_serial_create(1, 0x43f94000, qdev_get_gpio_in(dev, 32));
 
-    ccm = sysbus_create_simple("imx_ccm", 0x53f80000, NULL);
+    ccm = sysbus_create_simple(TYPE_IMX_CCM, 0x53f80000, NULL);
 
     imx_timerp_create(0x53f94000, qdev_get_gpio_in(dev, 28), ccm);
     imx_timerp_create(0x53f98000, qdev_get_gpio_in(dev, 27), ccm);
diff --git a/include/hw/arm/imx.h b/include/hw/arm/imx.h
deleted file mode 100644
index ea9e093..0000000
--- a/include/hw/arm/imx.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * i.MX31 emulation
- *
- * Copyright (C) 2012 Peter Chubb
- * NICTA
- *
- * This code is released under the GPL, version 2.0 or later
- * See the file `../COPYING' for details.
- */
-
-#ifndef IMX_H
-#define IMX_H
-
-void imx_serial_create(int uart, const hwaddr addr, qemu_irq irq);
-
-typedef enum  {
-    NOCLK,
-    MCU,
-    HSP,
-    IPG,
-    CLK_32k
-} IMXClk;
-
-uint32_t imx_clock_frequency(DeviceState *s, IMXClk clock);
-
-void imx_timerp_create(const hwaddr addr,
-                      qemu_irq irq,
-                      DeviceState *ccm);
-void imx_timerg_create(const hwaddr addr,
-                      qemu_irq irq,
-                      DeviceState *ccm);
-
-
-#endif /* IMX_H */
-- 
2.1.4

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

* [Qemu-devel] [PATCH v8 07/11] i.MX: Add FEC Ethernet Emulator
  2015-06-29 20:11 [Qemu-devel] [PATCH v8 00/11] i.MX: Add i.MX25 support through the 3DS evaluation board Jean-Christophe Dubois
                   ` (5 preceding siblings ...)
  2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 06/11] kzm: Use modified i.MX emulators Jean-Christophe Dubois
@ 2015-06-29 20:12 ` Jean-Christophe Dubois
  2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 08/11] i.MX: Add I2C controller emulator Jean-Christophe Dubois
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Jean-Christophe Dubois @ 2015-06-29 20:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

This is based on mcf_fec.c FEC implementation for Coldfire

  * A generic PHY was added (borrowwed from LAN9118)
  * The buffer management is also modified as buffers are
    slightly different between Coldfire and i.MX

Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
Reviewed-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---

Changes since v1:
    * none

Changes since v2:
    * use QOM cast
    * reworked debug printf
    * use CamelCase for state type
    * warn with qemu_log_mask(LOG_GUEST_ERROR) or qemu_log_mask(LOG_UNIMP)
    * move to dma_memory_read/write API
    * rework interrupt handling
    * use qemu_flush_queued_packets() in rx_enable()

Changes since v3:
    * use realise for device initialization
    * More QOM cast
    * reworked debug printf some more
    * standardise GPL header
    * use CamelCase for buffer descriptor type

Changes since v4:
    * none

Changes since v5:
    * replace hw_error() with qemu_log_mask(LOG_GUEST_ERROR, ...)
    * remove reformating of imx.h header file.
    * remove unnecessary spaces.

Changes since v6:
    * port to new memory API

Change since v7:
    * refactor emulator to be used by SOC

 default-configs/arm-softmmu.mak |   1 +
 hw/net/Makefile.objs            |   1 +
 hw/net/imx_fec.c                | 733 ++++++++++++++++++++++++++++++++++++++++
 include/hw/net/imx_fec.h        | 115 +++++++
 4 files changed, 850 insertions(+)
 create mode 100644 hw/net/imx_fec.c
 create mode 100644 include/hw/net/imx_fec.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 74f1db3..d21ff7b 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -28,6 +28,7 @@ CONFIG_SSI_M25P80=y
 CONFIG_LAN9118=y
 CONFIG_SMC91C111=y
 CONFIG_ALLWINNER_EMAC=y
+CONFIG_IMX_FEC=y
 CONFIG_DS1338=y
 CONFIG_PFLASH_CFI01=y
 CONFIG_PFLASH_CFI02=y
diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index 9880173..64d0449 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -19,6 +19,7 @@ common-obj-$(CONFIG_XGMAC) += xgmac.o
 common-obj-$(CONFIG_MIPSNET) += mipsnet.o
 common-obj-$(CONFIG_XILINX_AXI) += xilinx_axienet.o
 common-obj-$(CONFIG_ALLWINNER_EMAC) += allwinner_emac.o
+common-obj-$(CONFIG_IMX_FEC) += imx_fec.o
 
 common-obj-$(CONFIG_CADENCE) += cadence_gem.o
 common-obj-$(CONFIG_STELLARIS_ENET) += stellaris_enet.o
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
new file mode 100644
index 0000000..05e0f45
--- /dev/null
+++ b/hw/net/imx_fec.c
@@ -0,0 +1,733 @@
+/*
+ * i.MX Fast Ethernet Controller emulation.
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
+ *
+ * Based on Coldfire Fast Ethernet Controller emulation.
+ *
+ * Copyright (c) 2007 CodeSourcery.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw/net/imx_fec.h"
+#include "sysemu/dma.h"
+
+/* For crc32 */
+#include <zlib.h>
+
+#ifndef IMX_FEC_DEBUG
+#define IMX_FEC_DEBUG          0
+#endif
+
+#ifndef IMX_PHY_DEBUG
+#define IMX_PHY_DEBUG          0
+#endif
+
+#if IMX_FEC_DEBUG
+#define FEC_PRINTF(fmt, ...) \
+    do { fprintf(stderr, "%s[%s]: " fmt , TYPE_IMX_FEC, __func__, \
+                 ## __VA_ARGS__); \
+    } while (0)
+#else
+#define FEC_PRINTF(fmt, ...) do {} while (0)
+#endif
+
+#if IMX_PHY_DEBUG
+#define PHY_PRINTF(fmt, ...) \
+    do { fprintf(stderr, "%s.phy[%s]: " fmt , TYPE_IMX_FEC, __func__, \
+                 ## __VA_ARGS__); \
+    } while (0)
+#else
+#define PHY_PRINTF(fmt, ...) do {} while (0)
+#endif
+
+static const VMStateDescription vmstate_imx_fec = {
+    .name = TYPE_IMX_FEC,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(irq_state, IMXFECState),
+        VMSTATE_UINT32(eir, IMXFECState),
+        VMSTATE_UINT32(eimr, IMXFECState),
+        VMSTATE_UINT32(rx_enabled, IMXFECState),
+        VMSTATE_UINT32(rx_descriptor, IMXFECState),
+        VMSTATE_UINT32(tx_descriptor, IMXFECState),
+        VMSTATE_UINT32(ecr, IMXFECState),
+        VMSTATE_UINT32(mmfr, IMXFECState),
+        VMSTATE_UINT32(mscr, IMXFECState),
+        VMSTATE_UINT32(mibc, IMXFECState),
+        VMSTATE_UINT32(rcr, IMXFECState),
+        VMSTATE_UINT32(tcr, IMXFECState),
+        VMSTATE_UINT32(tfwr, IMXFECState),
+        VMSTATE_UINT32(frsr, IMXFECState),
+        VMSTATE_UINT32(erdsr, IMXFECState),
+        VMSTATE_UINT32(etdsr, IMXFECState),
+        VMSTATE_UINT32(emrbr, IMXFECState),
+        VMSTATE_UINT32(miigsk_cfgr, IMXFECState),
+        VMSTATE_UINT32(miigsk_enr, IMXFECState),
+
+        VMSTATE_UINT32(phy_status, IMXFECState),
+        VMSTATE_UINT32(phy_control, IMXFECState),
+        VMSTATE_UINT32(phy_advertise, IMXFECState),
+        VMSTATE_UINT32(phy_int, IMXFECState),
+        VMSTATE_UINT32(phy_int_mask, IMXFECState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+#define PHY_INT_ENERGYON            (1 << 7)
+#define PHY_INT_AUTONEG_COMPLETE    (1 << 6)
+#define PHY_INT_FAULT               (1 << 5)
+#define PHY_INT_DOWN                (1 << 4)
+#define PHY_INT_AUTONEG_LP          (1 << 3)
+#define PHY_INT_PARFAULT            (1 << 2)
+#define PHY_INT_AUTONEG_PAGE        (1 << 1)
+
+static void imx_fec_update(IMXFECState *s);
+
+/*
+ * The MII phy could raise a GPIO to the processor which in turn
+ * could be handled as an interrpt by the OS.
+ * For now we don't handle any GPIO/interrupt line, so the OS will
+ * have to poll for the PHY status.
+ */
+static void phy_update_irq(IMXFECState *s)
+{
+    imx_fec_update(s);
+}
+
+static void phy_update_link(IMXFECState *s)
+{
+    /* Autonegotiation status mirrors link status.  */
+    if (qemu_get_queue(s->nic)->link_down) {
+        PHY_PRINTF("link is down\n");
+        s->phy_status &= ~0x0024;
+        s->phy_int |= PHY_INT_DOWN;
+    } else {
+        PHY_PRINTF("link is up\n");
+        s->phy_status |= 0x0024;
+        s->phy_int |= PHY_INT_ENERGYON;
+        s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
+    }
+    phy_update_irq(s);
+}
+
+static void imx_fec_set_link(NetClientState *nc)
+{
+    phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
+}
+
+static void phy_reset(IMXFECState *s)
+{
+    s->phy_status = 0x7809;
+    s->phy_control = 0x3000;
+    s->phy_advertise = 0x01e1;
+    s->phy_int_mask = 0;
+    s->phy_int = 0;
+    phy_update_link(s);
+}
+
+static uint32_t do_phy_read(IMXFECState *s, int reg)
+{
+    uint32_t val;
+
+    if (reg > 31) {
+        /* we only advertise one phy */
+        return 0;
+    }
+
+    switch (reg) {
+    case 0:     /* Basic Control */
+        val = s->phy_control;
+        break;
+    case 1:     /* Basic Status */
+        val = s->phy_status;
+        break;
+    case 2:     /* ID1 */
+        val = 0x0007;
+        break;
+    case 3:     /* ID2 */
+        val = 0xc0d1;
+        break;
+    case 4:     /* Auto-neg advertisement */
+        val = s->phy_advertise;
+        break;
+    case 5:     /* Auto-neg Link Partner Ability */
+        val = 0x0f71;
+        break;
+    case 6:     /* Auto-neg Expansion */
+        val = 1;
+        break;
+    case 29:    /* Interrupt source.  */
+        val = s->phy_int;
+        s->phy_int = 0;
+        phy_update_irq(s);
+        break;
+    case 30:    /* Interrupt mask */
+        val = s->phy_int_mask;
+        break;
+    case 17:
+    case 18:
+    case 27:
+    case 31:
+        qemu_log_mask(LOG_UNIMP, "%s.phy[%s]: reg %d not implemented\n",
+                      TYPE_IMX_FEC, __func__, reg);
+        val = 0;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s[%s]: Bad address at offset %d\n",
+                      TYPE_IMX_FEC, __func__, reg);
+        val = 0;
+        break;
+    }
+
+    PHY_PRINTF("read 0x%04x @ %d\n", val, reg);
+
+    return val;
+}
+
+static void do_phy_write(IMXFECState *s, int reg, uint32_t val)
+{
+    PHY_PRINTF("write 0x%04x @ %d\n", val, reg);
+
+    if (reg > 31) {
+        /* we only advertise one phy */
+        return;
+    }
+
+    switch (reg) {
+    case 0:     /* Basic Control */
+        if (val & 0x8000) {
+            phy_reset(s);
+        } else {
+            s->phy_control = val & 0x7980;
+            /* Complete autonegotiation immediately.  */
+            if (val & 0x1000) {
+                s->phy_status |= 0x0020;
+            }
+        }
+        break;
+    case 4:     /* Auto-neg advertisement */
+        s->phy_advertise = (val & 0x2d7f) | 0x80;
+        break;
+    case 30:    /* Interrupt mask */
+        s->phy_int_mask = val & 0xff;
+        phy_update_irq(s);
+        break;
+    case 17:
+    case 18:
+    case 27:
+    case 31:
+        qemu_log_mask(LOG_UNIMP, "%s.phy[%s]: reg %d not implemented\n",
+                      TYPE_IMX_FEC, __func__, reg);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s.phy[%s]: Bad address at offset %d\n",
+                      TYPE_IMX_FEC, __func__, reg);
+        break;
+    }
+}
+
+static void imx_fec_read_bd(IMXFECBufDesc *bd, dma_addr_t addr)
+{
+    dma_memory_read(&address_space_memory, addr, bd, sizeof(*bd));
+}
+
+static void imx_fec_write_bd(IMXFECBufDesc *bd, dma_addr_t addr)
+{
+    dma_memory_write(&address_space_memory, addr, bd, sizeof(*bd));
+}
+
+static void imx_fec_update(IMXFECState *s)
+{
+    uint32_t active;
+    uint32_t changed;
+
+    active = s->eir & s->eimr;
+    changed = active ^ s->irq_state;
+    if (changed) {
+        qemu_set_irq(s->irq, active);
+    }
+    s->irq_state = active;
+}
+
+static void imx_fec_do_tx(IMXFECState *s)
+{
+    int frame_size = 0;
+    uint8_t frame[FEC_MAX_FRAME_SIZE];
+    uint8_t *ptr = frame;
+    uint32_t addr = s->tx_descriptor;
+
+    while (1) {
+        IMXFECBufDesc bd;
+        int len;
+
+        imx_fec_read_bd(&bd, addr);
+        FEC_PRINTF("tx_bd %x flags %04x len %d data %08x\n",
+                   addr, bd.flags, bd.length, bd.data);
+        if ((bd.flags & FEC_BD_R) == 0) {
+            /* Run out of descriptors to transmit.  */
+            break;
+        }
+        len = bd.length;
+        if (frame_size + len > FEC_MAX_FRAME_SIZE) {
+            len = FEC_MAX_FRAME_SIZE - frame_size;
+            s->eir |= FEC_INT_BABT;
+        }
+        dma_memory_read(&address_space_memory, bd.data, ptr, len);
+        ptr += len;
+        frame_size += len;
+        if (bd.flags & FEC_BD_L) {
+            /* Last buffer in frame.  */
+            qemu_send_packet(qemu_get_queue(s->nic), frame, len);
+            ptr = frame;
+            frame_size = 0;
+            s->eir |= FEC_INT_TXF;
+        }
+        s->eir |= FEC_INT_TXB;
+        bd.flags &= ~FEC_BD_R;
+        /* Write back the modified descriptor.  */
+        imx_fec_write_bd(&bd, addr);
+        /* Advance to the next descriptor.  */
+        if ((bd.flags & FEC_BD_W) != 0) {
+            addr = s->etdsr;
+        } else {
+            addr += 8;
+        }
+    }
+
+    s->tx_descriptor = addr;
+
+    imx_fec_update(s);
+}
+
+static void imx_fec_enable_rx(IMXFECState *s)
+{
+    IMXFECBufDesc bd;
+    uint32_t tmp;
+
+    imx_fec_read_bd(&bd, s->rx_descriptor);
+
+    tmp = ((bd.flags & FEC_BD_E) != 0);
+
+    if (!tmp) {
+        FEC_PRINTF("RX buffer full\n");
+    } else if (!s->rx_enabled) {
+        qemu_flush_queued_packets(qemu_get_queue(s->nic));
+    }
+
+    s->rx_enabled = tmp;
+}
+
+static void imx_fec_reset(DeviceState *d)
+{
+    IMXFECState *s = IMX_FEC(d);
+
+    /* Reset the FEC */
+    s->eir = 0;
+    s->eimr = 0;
+    s->rx_enabled = 0;
+    s->ecr = 0;
+    s->mscr = 0;
+    s->mibc = 0xc0000000;
+    s->rcr = 0x05ee0001;
+    s->tcr = 0;
+    s->tfwr = 0;
+    s->frsr = 0x500;
+    s->miigsk_cfgr = 0;
+    s->miigsk_enr = 0x6;
+
+    /* We also reset the PHY */
+    phy_reset(s);
+}
+
+static uint64_t imx_fec_read(void *opaque, hwaddr addr, unsigned size)
+{
+    IMXFECState *s = IMX_FEC(opaque);
+
+    FEC_PRINTF("reading from @ 0x%03x\n", (int)addr);
+
+    switch (addr & 0x3ff) {
+    case 0x004:
+        return s->eir;
+    case 0x008:
+        return s->eimr;
+    case 0x010:
+        return s->rx_enabled ? (1 << 24) : 0;   /* RDAR */
+    case 0x014:
+        return 0;   /* TDAR */
+    case 0x024:
+        return s->ecr;
+    case 0x040:
+        return s->mmfr;
+    case 0x044:
+        return s->mscr;
+    case 0x064:
+        return s->mibc; /* MIBC */
+    case 0x084:
+        return s->rcr;
+    case 0x0c4:
+        return s->tcr;
+    case 0x0e4:     /* PALR */
+        return (s->conf.macaddr.a[0] << 24)
+               | (s->conf.macaddr.a[1] << 16)
+               | (s->conf.macaddr.a[2] << 8)
+               | s->conf.macaddr.a[3];
+        break;
+    case 0x0e8:     /* PAUR */
+        return (s->conf.macaddr.a[4] << 24)
+               | (s->conf.macaddr.a[5] << 16)
+               | 0x8808;
+    case 0x0ec:
+        return 0x10000; /* OPD */
+    case 0x118:
+        return 0;
+    case 0x11c:
+        return 0;
+    case 0x120:
+        return 0;
+    case 0x124:
+        return 0;
+    case 0x144:
+        return s->tfwr;
+    case 0x14c:
+        return 0x600;
+    case 0x150:
+        return s->frsr;
+    case 0x180:
+        return s->erdsr;
+    case 0x184:
+        return s->etdsr;
+    case 0x188:
+        return s->emrbr;
+    case 0x300:
+        return s->miigsk_cfgr;
+    case 0x308:
+        return s->miigsk_enr;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s[%s]: Bad address at offset %d\n",
+                      TYPE_IMX_FEC, __func__, (int)addr);
+        return 0;
+    }
+}
+
+static void imx_fec_write(void *opaque, hwaddr addr,
+                          uint64_t value, unsigned size)
+{
+    IMXFECState *s = IMX_FEC(opaque);
+
+    FEC_PRINTF("writing 0x%08x @ 0x%03x\n", (int)value, (int)addr);
+
+    switch (addr & 0x3ff) {
+    case 0x004: /* EIR */
+        s->eir &= ~value;
+        break;
+    case 0x008: /* EIMR */
+        s->eimr = value;
+        break;
+    case 0x010: /* RDAR */
+        if ((s->ecr & FEC_EN) && !s->rx_enabled) {
+            imx_fec_enable_rx(s);
+        }
+        break;
+    case 0x014: /* TDAR */
+        if (s->ecr & FEC_EN) {
+            imx_fec_do_tx(s);
+        }
+        break;
+    case 0x024: /* ECR */
+        s->ecr = value;
+        if (value & FEC_RESET) {
+            imx_fec_reset(DEVICE(s));
+        }
+        if ((s->ecr & FEC_EN) == 0) {
+            s->rx_enabled = 0;
+        }
+        break;
+    case 0x040: /* MMFR */
+        /* store the value */
+        s->mmfr = value;
+        if (extract32(value, 28, 1)) {
+            do_phy_write(s, extract32(value, 18, 9), extract32(value, 0, 16));
+        } else {
+            s->mmfr = do_phy_read(s, extract32(value, 18, 9));
+        }
+        /* raise the interrupt as the PHY operation is done */
+        s->eir |= FEC_INT_MII;
+        break;
+    case 0x044: /* MSCR */
+        s->mscr = value & 0xfe;
+        break;
+    case 0x064: /* MIBC */
+        /* TODO: Implement MIB.  */
+        s->mibc = (value & 0x80000000) ? 0xc0000000 : 0;
+        break;
+    case 0x084: /* RCR */
+        s->rcr = value & 0x07ff003f;
+        /* TODO: Implement LOOP mode.  */
+        break;
+    case 0x0c4: /* TCR */
+        /* We transmit immediately, so raise GRA immediately.  */
+        s->tcr = value;
+        if (value & 1) {
+            s->eir |= FEC_INT_GRA;
+        }
+        break;
+    case 0x0e4: /* PALR */
+        s->conf.macaddr.a[0] = value >> 24;
+        s->conf.macaddr.a[1] = value >> 16;
+        s->conf.macaddr.a[2] = value >> 8;
+        s->conf.macaddr.a[3] = value;
+        break;
+    case 0x0e8: /* PAUR */
+        s->conf.macaddr.a[4] = value >> 24;
+        s->conf.macaddr.a[5] = value >> 16;
+        break;
+    case 0x0ec: /* OPDR */
+        break;
+    case 0x118: /* IAUR */
+    case 0x11c: /* IALR */
+    case 0x120: /* GAUR */
+    case 0x124: /* GALR */
+        /* TODO: implement MAC hash filtering.  */
+        break;
+    case 0x144: /* TFWR */
+        s->tfwr = value & 3;
+        break;
+    case 0x14c: /* FRBR */
+        /* FRBR writes ignored.  */
+        break;
+    case 0x150: /* FRSR */
+        s->frsr = (value & 0x3fc) | 0x400;
+        break;
+    case 0x180: /* ERDSR */
+        s->erdsr = value & ~3;
+        s->rx_descriptor = s->erdsr;
+        break;
+    case 0x184: /* ETDSR */
+        s->etdsr = value & ~3;
+        s->tx_descriptor = s->etdsr;
+        break;
+    case 0x188: /* EMRBR */
+        s->emrbr = value & 0x7f0;
+        break;
+    case 0x300: /* MIIGSK_CFGR */
+        s->miigsk_cfgr = value & 0x53;
+        break;
+    case 0x308: /* MIIGSK_ENR */
+        s->miigsk_enr = (value & 0x2) ? 0x6 : 0;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s[%s]: Bad address at offset %d\n",
+                      TYPE_IMX_FEC, __func__, (int)addr);
+        break;
+    }
+
+    imx_fec_update(s);
+}
+
+static int imx_fec_can_receive(NetClientState *nc)
+{
+    IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));
+
+    return s->rx_enabled;
+}
+
+static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
+                               size_t len)
+{
+    IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));
+    IMXFECBufDesc bd;
+    uint32_t flags = 0;
+    uint32_t addr;
+    uint32_t crc;
+    uint32_t buf_addr;
+    uint8_t *crc_ptr;
+    unsigned int buf_len;
+    size_t size = len;
+
+    FEC_PRINTF("len %d\n", (int)size);
+
+    if (!s->rx_enabled) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s[%s]: Unexpected packet\n",
+                      TYPE_IMX_FEC, __func__);
+        return 0;
+    }
+
+    /* 4 bytes for the CRC.  */
+    size += 4;
+    crc = cpu_to_be32(crc32(~0, buf, size));
+    crc_ptr = (uint8_t *) &crc;
+
+    /* Huge frames are truncted.  */
+    if (size > FEC_MAX_FRAME_SIZE) {
+        size = FEC_MAX_FRAME_SIZE;
+        flags |= FEC_BD_TR | FEC_BD_LG;
+    }
+
+    /* Frames larger than the user limit just set error flags.  */
+    if (size > (s->rcr >> 16)) {
+        flags |= FEC_BD_LG;
+    }
+
+    addr = s->rx_descriptor;
+    while (size > 0) {
+        imx_fec_read_bd(&bd, addr);
+        if ((bd.flags & FEC_BD_E) == 0) {
+            /* No descriptors available.  Bail out.  */
+            /*
+             * FIXME: This is wrong. We should probably either
+             * save the remainder for when more RX buffers are
+             * available, or flag an error.
+             */
+            qemu_log_mask(LOG_GUEST_ERROR, "%s[%s]: Lost end of frame\n",
+                          TYPE_IMX_FEC, __func__);
+            break;
+        }
+        buf_len = (size <= s->emrbr) ? size : s->emrbr;
+        bd.length = buf_len;
+        size -= buf_len;
+        FEC_PRINTF("rx_bd %x length %d\n", addr, bd.length);
+        /* The last 4 bytes are the CRC.  */
+        if (size < 4) {
+            buf_len += size - 4;
+        }
+        buf_addr = bd.data;
+        dma_memory_write(&address_space_memory, buf_addr, buf, buf_len);
+        buf += buf_len;
+        if (size < 4) {
+            dma_memory_write(&address_space_memory, buf_addr + buf_len,
+                             crc_ptr, 4 - size);
+            crc_ptr += 4 - size;
+        }
+        bd.flags &= ~FEC_BD_E;
+        if (size == 0) {
+            /* Last buffer in frame.  */
+            bd.flags |= flags | FEC_BD_L;
+            FEC_PRINTF("rx frame flags %04x\n", bd.flags);
+            s->eir |= FEC_INT_RXF;
+        } else {
+            s->eir |= FEC_INT_RXB;
+        }
+        imx_fec_write_bd(&bd, addr);
+        /* Advance to the next descriptor.  */
+        if ((bd.flags & FEC_BD_W) != 0) {
+            addr = s->erdsr;
+        } else {
+            addr += 8;
+        }
+    }
+    s->rx_descriptor = addr;
+    imx_fec_enable_rx(s);
+    imx_fec_update(s);
+    return len;
+}
+
+static const MemoryRegionOps imx_fec_ops = {
+    .read = imx_fec_read,
+    .write = imx_fec_write,
+    .valid.min_access_size = 4,
+    .valid.max_access_size = 4,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void imx_fec_cleanup(NetClientState *nc)
+{
+    IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));
+
+    s->nic = NULL;
+}
+
+static NetClientInfo net_imx_fec_info = {
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .size = sizeof(NICState),
+    .can_receive = imx_fec_can_receive,
+    .receive = imx_fec_receive,
+    .cleanup = imx_fec_cleanup,
+    .link_status_changed = imx_fec_set_link,
+};
+
+
+static void imx_fec_realize(DeviceState *dev, Error **errp)
+{
+    IMXFECState *s = IMX_FEC(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+    memory_region_init_io(&s->iomem, OBJECT(dev), &imx_fec_ops, s,
+                          TYPE_IMX_FEC, 0x400);
+    sysbus_init_mmio(sbd, &s->iomem);
+    sysbus_init_irq(sbd, &s->irq);
+    qemu_macaddr_default_if_unset(&s->conf.macaddr);
+
+    s->conf.peers.ncs[0] = nd_table[0].netdev;
+
+    s->nic = qemu_new_nic(&net_imx_fec_info, &s->conf,
+                          object_get_typename(OBJECT(dev)), DEVICE(dev)->id,
+                          s);
+    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
+}
+
+static Property imx_fec_properties[] = {
+    DEFINE_NIC_PROPERTIES(IMXFECState, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void imx_fec_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->vmsd = &vmstate_imx_fec;
+    dc->reset = imx_fec_reset;
+    dc->props = imx_fec_properties;
+    dc->realize = imx_fec_realize;
+}
+
+static const TypeInfo imx_fec_info = {
+    .name = TYPE_IMX_FEC,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(IMXFECState),
+    .class_init = imx_fec_class_init,
+};
+
+static void imx_fec_register_types(void)
+{
+    type_register_static(&imx_fec_info);
+}
+
+DeviceState *imx_fec_create(int nic, const hwaddr base, qemu_irq irq)
+{
+    NICInfo *nd;
+    DeviceState *dev;
+    SysBusDevice *sbd;
+
+    if (nic >= MAX_NICS) {
+        hw_error("Cannot assign nic %d: QEMU supports only %d ports\n",
+                 nic, MAX_NICS);
+    }
+
+    nd = &nd_table[nic];
+
+    qemu_check_nic_model(nd, TYPE_IMX_FEC);
+    dev = qdev_create(NULL, TYPE_IMX_FEC);
+    qdev_set_nic_properties(dev, nd);
+    qdev_init_nofail(dev);
+    sbd = SYS_BUS_DEVICE(dev);
+    sysbus_mmio_map(sbd, 0, base);
+    sysbus_connect_irq(sbd, 0, irq);
+
+    return dev;
+};
+
+type_init(imx_fec_register_types)
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
new file mode 100644
index 0000000..9d5a8d3
--- /dev/null
+++ b/include/hw/net/imx_fec.h
@@ -0,0 +1,115 @@
+/*
+ * i.MX Fast Ethernet Controller emulation.
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
+ *
+ * Based on Coldfire Fast Ethernet Controller emulation.
+ *
+ * Copyright (c) 2007 CodeSourcery.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef IMX_FEC_H
+#define IMX_FEC_H
+
+#define TYPE_IMX_FEC "imx.fec"
+#define IMX_FEC(obj) OBJECT_CHECK(IMXFECState, (obj), TYPE_IMX_FEC)
+
+#include "hw/sysbus.h"
+#include "net/net.h"
+
+#define FEC_MAX_FRAME_SIZE 2032
+
+#define FEC_INT_HB      (1 << 31)
+#define FEC_INT_BABR    (1 << 30)
+#define FEC_INT_BABT    (1 << 29)
+#define FEC_INT_GRA     (1 << 28)
+#define FEC_INT_TXF     (1 << 27)
+#define FEC_INT_TXB     (1 << 26)
+#define FEC_INT_RXF     (1 << 25)
+#define FEC_INT_RXB     (1 << 24)
+#define FEC_INT_MII     (1 << 23)
+#define FEC_INT_EBERR   (1 << 22)
+#define FEC_INT_LC      (1 << 21)
+#define FEC_INT_RL      (1 << 20)
+#define FEC_INT_UN      (1 << 19)
+
+#define FEC_EN      2
+#define FEC_RESET   1
+
+/* Buffer Descriptor.  */
+typedef struct {
+    uint16_t length;
+    uint16_t flags;
+    uint32_t data;
+} IMXFECBufDesc;
+
+#define FEC_BD_R    (1 << 15)
+#define FEC_BD_E    (1 << 15)
+#define FEC_BD_O1   (1 << 14)
+#define FEC_BD_W    (1 << 13)
+#define FEC_BD_O2   (1 << 12)
+#define FEC_BD_L    (1 << 11)
+#define FEC_BD_TC   (1 << 10)
+#define FEC_BD_ABC  (1 << 9)
+#define FEC_BD_M    (1 << 8)
+#define FEC_BD_BC   (1 << 7)
+#define FEC_BD_MC   (1 << 6)
+#define FEC_BD_LG   (1 << 5)
+#define FEC_BD_NO   (1 << 4)
+#define FEC_BD_CR   (1 << 2)
+#define FEC_BD_OV   (1 << 1)
+#define FEC_BD_TR   (1 << 0)
+
+typedef struct {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    NICState *nic;
+    NICConf conf;
+    qemu_irq irq;
+    MemoryRegion iomem;
+
+    uint32_t irq_state;
+    uint32_t eir;
+    uint32_t eimr;
+    uint32_t rx_enabled;
+    uint32_t rx_descriptor;
+    uint32_t tx_descriptor;
+    uint32_t ecr;
+    uint32_t mmfr;
+    uint32_t mscr;
+    uint32_t mibc;
+    uint32_t rcr;
+    uint32_t tcr;
+    uint32_t tfwr;
+    uint32_t frsr;
+    uint32_t erdsr;
+    uint32_t etdsr;
+    uint32_t emrbr;
+    uint32_t miigsk_cfgr;
+    uint32_t miigsk_enr;
+
+    uint32_t phy_status;
+    uint32_t phy_control;
+    uint32_t phy_advertise;
+    uint32_t phy_int;
+    uint32_t phy_int_mask;
+} IMXFECState;
+
+DeviceState *imx_fec_create(int nic, const hwaddr base, qemu_irq irq);
+
+#endif
-- 
2.1.4

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

* [Qemu-devel] [PATCH v8 08/11] i.MX: Add I2C controller emulator
  2015-06-29 20:11 [Qemu-devel] [PATCH v8 00/11] i.MX: Add i.MX25 support through the 3DS evaluation board Jean-Christophe Dubois
                   ` (6 preceding siblings ...)
  2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 07/11] i.MX: Add FEC Ethernet Emulator Jean-Christophe Dubois
@ 2015-06-29 20:12 ` Jean-Christophe Dubois
  2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 09/11] i.MX25: Add the i.MX25 SOC support Jean-Christophe Dubois
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Jean-Christophe Dubois @ 2015-06-29 20:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

The slave mode is not implemented.

Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
Reviewed-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---

Changes since v1:
    * none

Changes since v2:
    * use QOM cast
    * reworked debug printf
    * use CamelCase for state type
    * warn with qemu_log_mask(LOG_GUEST_ERROR) or qemu_log_mask(LOG_UNIMP)
    * move to dma_memory_read/write API
    * rework interrupt handling
    * use qemu_flush_queued_packets() in rx_enable()

Changes since v3:
    * use realise for device initialization
    * More QOM cast
    * reworked debug printf some more
    * standardise GPL header
    * use CamelCase for buffer descriptor type

Changes since v4:
    * none

Changes since v5:
    * replace hw_error() with qemu_log_mask(LOG_GUEST_ERROR, ...)
    * remove reformating of imx.h header file.
    * remove unnecessary spaces.

Changes since v6:
    * port to new memory API

Changes since v7:
    * refactor to be used by SOC

 default-configs/arm-softmmu.mak |   2 +
 hw/i2c/Makefile.objs            |   1 +
 hw/i2c/imx_i2c.c                | 339 ++++++++++++++++++++++++++++++++++++++++
 include/hw/i2c/imx_i2c.h        |  85 ++++++++++
 4 files changed, 427 insertions(+)
 create mode 100644 hw/i2c/imx_i2c.c
 create mode 100644 include/hw/i2c/imx_i2c.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index d21ff7b..c6f509d 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -99,6 +99,8 @@ CONFIG_ALLWINNER_A10_PIT=y
 CONFIG_ALLWINNER_A10_PIC=y
 CONFIG_ALLWINNER_A10=y
 
+CONFIG_IMX_I2C=y
+
 CONFIG_XIO3130=y
 CONFIG_IOH3420=y
 CONFIG_I82801B11=y
diff --git a/hw/i2c/Makefile.objs b/hw/i2c/Makefile.objs
index 0f13060..aeb8f38 100644
--- a/hw/i2c/Makefile.objs
+++ b/hw/i2c/Makefile.objs
@@ -4,4 +4,5 @@ common-obj-$(CONFIG_ACPI_X86) += smbus_ich9.o
 common-obj-$(CONFIG_APM) += pm_smbus.o
 common-obj-$(CONFIG_BITBANG_I2C) += bitbang_i2c.o
 common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o
+common-obj-$(CONFIG_IMX_I2C) += imx_i2c.o
 obj-$(CONFIG_OMAP) += omap_i2c.o
diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c
new file mode 100644
index 0000000..468712b
--- /dev/null
+++ b/hw/i2c/imx_i2c.c
@@ -0,0 +1,339 @@
+/*
+ *  i.MX I2C Bus Serial Interface Emulation
+ *
+ *  Copyright (C) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "hw/i2c/imx_i2c.h"
+#include "hw/i2c/i2c.h"
+
+#ifndef IMX_I2C_DEBUG
+#define IMX_I2C_DEBUG                 0
+#endif
+
+#if IMX_I2C_DEBUG
+#define DPRINT(fmt, args...)              \
+    do { fprintf(stderr, "%s: "fmt, __func__, ## args); } while (0)
+
+static const char *imx_i2c_get_regname(unsigned offset)
+{
+    switch (offset) {
+    case IADR_ADDR:
+        return "IADR";
+    case IFDR_ADDR:
+        return "IFDR";
+    case I2CR_ADDR:
+        return "I2CR";
+    case I2SR_ADDR:
+        return "I2SR";
+    case I2DR_ADDR:
+        return "I2DR";
+    default:
+        return "[?]";
+    }
+}
+#else
+#define DPRINT(fmt, args...)              do { } while (0)
+#endif
+
+static inline bool imx_i2c_is_enabled(IMXI2CState *s)
+{
+    return s->i2cr & I2CR_IEN;
+}
+
+static inline bool imx_i2c_interrupt_is_enabled(IMXI2CState *s)
+{
+    return s->i2cr & I2CR_IIEN;
+}
+
+static inline bool imx_i2c_is_master(IMXI2CState *s)
+{
+    return s->i2cr & I2CR_MSTA;
+}
+
+static inline bool imx_i2c_direction_is_tx(IMXI2CState *s)
+{
+    return s->i2cr & I2CR_MTX;
+}
+
+static void imx_i2c_reset(DeviceState *dev)
+{
+    IMXI2CState *s = IMX_I2C(dev);
+
+    if (s->address != ADDR_RESET) {
+        i2c_end_transfer(s->bus);
+    }
+
+    s->address    = ADDR_RESET;
+    s->iadr       = IADR_RESET;
+    s->ifdr       = IFDR_RESET;
+    s->i2cr       = I2CR_RESET;
+    s->i2sr       = I2SR_RESET;
+    s->i2dr_read  = I2DR_RESET;
+    s->i2dr_write = I2DR_RESET;
+}
+
+static inline void imx_i2c_raise_interrupt(IMXI2CState *s)
+{
+    /*
+     * raise an interrupt if the device is enabled and it is configured
+     * to generate some interrupts.
+     */
+    if (imx_i2c_is_enabled(s) && imx_i2c_interrupt_is_enabled(s)) {
+        s->i2sr |= I2SR_IIF;
+        qemu_irq_raise(s->irq);
+    }
+}
+
+static uint64_t imx_i2c_read(void *opaque, hwaddr offset,
+                             unsigned size)
+{
+    uint16_t value;
+    IMXI2CState *s = IMX_I2C(opaque);
+
+    switch (offset) {
+    case IADR_ADDR:
+        value = s->iadr;
+        break;
+    case IFDR_ADDR:
+        value = s->ifdr;
+        break;
+    case I2CR_ADDR:
+        value = s->i2cr;
+        break;
+    case I2SR_ADDR:
+        value = s->i2sr;
+        break;
+    case I2DR_ADDR:
+        value = s->i2dr_read;
+
+        if (imx_i2c_is_master(s)) { /* master mode */
+            int ret = 0xff;
+
+            if (s->address == ADDR_RESET) {
+                /* something is wrong as the address is not set */
+                qemu_log_mask(LOG_GUEST_ERROR, "%s[%s]: Trying to read "
+                              "without specifying the slave address\n",
+                              TYPE_IMX_I2C, __func__);
+            } else if (s->i2cr & I2CR_MTX) {
+                qemu_log_mask(LOG_GUEST_ERROR, "%s[%s]: Trying to read "
+                              "but MTX is set\n", TYPE_IMX_I2C, __func__);
+            } else {
+                /* get the next byte */
+                ret = i2c_recv(s->bus);
+
+                if (ret >= 0) {
+                    imx_i2c_raise_interrupt(s);
+                } else {
+                    qemu_log_mask(LOG_GUEST_ERROR, "%s[%s]: read failed "
+                                  "for device 0x%02x\n", TYPE_IMX_I2C,
+                                  __func__, s->address);
+                    ret = 0xff;
+                }
+            }
+
+            s->i2dr_read = ret;
+        } else {
+            qemu_log_mask(LOG_UNIMP, "%s[%s]: slave mode not implemented\n",
+                          TYPE_IMX_I2C, __func__);
+        }
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s[%s]: Bad address at offset %d\n",
+                      TYPE_IMX_I2C, __func__, s->address);
+        value = 0;
+        break;
+    }
+
+    DPRINT("read %s [0x%02x] -> 0x%02x\n", imx_i2c_get_regname(offset),
+           (unsigned int)offset, value);
+
+    return (uint64_t)value;
+}
+
+static void imx_i2c_write(void *opaque, hwaddr offset,
+                          uint64_t value, unsigned size)
+{
+    IMXI2CState *s = IMX_I2C(opaque);
+
+    DPRINT("write %s [0x%02x] <- 0x%02x\n", imx_i2c_get_regname(offset),
+           (unsigned int)offset, (int)value);
+
+    value &= 0xff;
+
+    switch (offset) {
+    case IADR_ADDR:
+        s->iadr = value & IADR_MASK;
+        /* i2c_set_slave_address(s->bus, (uint8_t)s->iadr); */
+        break;
+    case IFDR_ADDR:
+        s->ifdr = value & IFDR_MASK;
+        break;
+    case I2CR_ADDR:
+        if (imx_i2c_is_enabled(s) && ((value & I2CR_IEN) == 0)) {
+            /* This is a soft reset. IADR is preserved during soft resets */
+            uint16_t iadr = s->iadr;
+            imx_i2c_reset(DEVICE(s));
+            s->iadr = iadr;
+        } else { /* normal write */
+            s->i2cr = value & I2CR_MASK;
+
+            if (imx_i2c_is_master(s)) { /* master mode */
+                /* set the bus to busy */
+                s->i2sr |= I2SR_IBB;
+            } else { /* slave mode */
+                /* bus is not busy anymore */
+                s->i2sr &= ~I2SR_IBB;
+
+                /*
+                 * if we unset the master mode then it ends the ongoing
+                 * transfer if any
+                 */
+                if (s->address != ADDR_RESET) {
+                    i2c_end_transfer(s->bus);
+                    s->address = ADDR_RESET;
+                }
+            }
+
+            if (s->i2cr & I2CR_RSTA) { /* Restart */
+                /* if this is a restart then it ends the ongoing transfer */
+                if (s->address != ADDR_RESET) {
+                    i2c_end_transfer(s->bus);
+                    s->address = ADDR_RESET;
+                    s->i2cr &= ~I2CR_RSTA;
+                }
+            }
+        }
+        break;
+    case I2SR_ADDR:
+        /*
+         * if the user writes 0 to IIF then lower the interrupt and
+         * reset the bit
+         */
+        if ((s->i2sr & I2SR_IIF) && !(value & I2SR_IIF)) {
+            s->i2sr &= ~I2SR_IIF;
+            qemu_irq_lower(s->irq);
+        }
+
+        /*
+         * if the user writes 0 to IAL, reset the bit
+         */
+        if ((s->i2sr & I2SR_IAL) && !(value & I2SR_IAL)) {
+            s->i2sr &= ~I2SR_IAL;
+        }
+
+        break;
+    case I2DR_ADDR:
+        /* if the device is not enabled, nothing to do */
+        if (!imx_i2c_is_enabled(s)) {
+            break;
+        }
+
+        s->i2dr_write = value & I2DR_MASK;
+
+        if (imx_i2c_is_master(s)) { /* master mode */
+            /* If this is the first write cycle then it is the slave addr */
+            if (s->address == ADDR_RESET) {
+                if (i2c_start_transfer(s->bus, extract32(s->i2dr_write, 1, 7),
+                                       extract32(s->i2dr_write, 0, 1))) {
+                    /* if non zero is returned, the adress is not valid */
+                    s->i2sr |= I2SR_RXAK;
+                } else {
+                    s->address = s->i2dr_write;
+                    s->i2sr &= ~I2SR_RXAK;
+                    imx_i2c_raise_interrupt(s);
+                }
+            } else { /* This is a normal data write */
+                if (i2c_send(s->bus, s->i2dr_write)) {
+                    /* if the target return non zero then end the transfer */
+                    s->i2sr |= I2SR_RXAK;
+                    s->address = ADDR_RESET;
+                    i2c_end_transfer(s->bus);
+                } else {
+                    s->i2sr &= ~I2SR_RXAK;
+                    imx_i2c_raise_interrupt(s);
+                }
+            }
+        } else {
+            qemu_log_mask(LOG_UNIMP, "%s[%s]: slave mode not implemented\n",
+                          TYPE_IMX_I2C, __func__);
+        }
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s[%s]: Bad address at offset %d\n",
+                      TYPE_IMX_I2C, __func__, s->address);
+        break;
+    }
+}
+
+static const MemoryRegionOps imx_i2c_ops = {
+    .read = imx_i2c_read,
+    .write = imx_i2c_write,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 2,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const VMStateDescription imx_i2c_vmstate = {
+    .name = TYPE_IMX_I2C,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT16(address, IMXI2CState),
+        VMSTATE_UINT16(iadr, IMXI2CState),
+        VMSTATE_UINT16(ifdr, IMXI2CState),
+        VMSTATE_UINT16(i2cr, IMXI2CState),
+        VMSTATE_UINT16(i2sr, IMXI2CState),
+        VMSTATE_UINT16(i2dr_read, IMXI2CState),
+        VMSTATE_UINT16(i2dr_write, IMXI2CState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void imx_i2c_realize(DeviceState *dev, Error **errp)
+{
+    IMXI2CState *s = IMX_I2C(dev);
+
+    memory_region_init_io(&s->iomem, OBJECT(s), &imx_i2c_ops, s, TYPE_IMX_I2C,
+                          IMX_I2C_MEM_SIZE);
+    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
+    sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
+    s->bus = i2c_init_bus(DEVICE(dev), "i2c");
+}
+
+static void imx_i2c_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->vmsd = &imx_i2c_vmstate;
+    dc->reset = imx_i2c_reset;
+    dc->realize = imx_i2c_realize;
+}
+
+static const TypeInfo imx_i2c_type_info = {
+    .name = TYPE_IMX_I2C,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(IMXI2CState),
+    .class_init = imx_i2c_class_init,
+};
+
+static void imx_i2c_register_types(void)
+{
+    type_register_static(&imx_i2c_type_info);
+}
+
+type_init(imx_i2c_register_types)
diff --git a/include/hw/i2c/imx_i2c.h b/include/hw/i2c/imx_i2c.h
new file mode 100644
index 0000000..1c511ec
--- /dev/null
+++ b/include/hw/i2c/imx_i2c.h
@@ -0,0 +1,85 @@
+/*
+ *  i.MX I2C Bus Serial Interface registers definition
+ *
+ *  Copyright (C) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __IMX_I2C_H_
+#define __IMX_I2C_H_
+
+#include <hw/sysbus.h>
+
+#define TYPE_IMX_I2C "imx.i2c"
+#define IMX_I2C(obj) OBJECT_CHECK(IMXI2CState, (obj), TYPE_IMX_I2C)
+
+#define IMX_I2C_MEM_SIZE           0x14
+
+/* i.MX I2C memory map */
+#define IADR_ADDR                  0x00  /* address register */
+#define IFDR_ADDR                  0x04  /* frequency divider register */
+#define I2CR_ADDR                  0x08  /* control register */
+#define I2SR_ADDR                  0x0c  /* status register */
+#define I2DR_ADDR                  0x10  /* data register */
+
+#define IADR_MASK                  0xFE
+#define IADR_RESET                 0
+
+#define IFDR_MASK                  0x3F
+#define IFDR_RESET                 0
+
+#define I2CR_IEN                   (1 << 7)
+#define I2CR_IIEN                  (1 << 6)
+#define I2CR_MSTA                  (1 << 5)
+#define I2CR_MTX                   (1 << 4)
+#define I2CR_TXAK                  (1 << 3)
+#define I2CR_RSTA                  (1 << 2)
+#define I2CR_MASK                  0xFC
+#define I2CR_RESET                 0
+
+#define I2SR_ICF                   (1 << 7)
+#define I2SR_IAAF                  (1 << 6)
+#define I2SR_IBB                   (1 << 5)
+#define I2SR_IAL                   (1 << 4)
+#define I2SR_SRW                   (1 << 2)
+#define I2SR_IIF                   (1 << 1)
+#define I2SR_RXAK                  (1 << 0)
+#define I2SR_MASK                  0xE9
+#define I2SR_RESET                 0x81
+
+#define I2DR_MASK                  0xFF
+#define I2DR_RESET                 0
+
+#define ADDR_RESET                 0xFF00
+
+typedef struct IMXI2CState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion iomem;
+    I2CBus *bus;
+    qemu_irq irq;
+
+    uint16_t  address;
+
+    uint16_t iadr;
+    uint16_t ifdr;
+    uint16_t i2cr;
+    uint16_t i2sr;
+    uint16_t i2dr_read;
+    uint16_t i2dr_write;
+} IMXI2CState;
+
+#endif /* __IMX_I2C_H_ */
-- 
2.1.4

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

* [Qemu-devel] [PATCH v8 09/11] i.MX25: Add the i.MX25 SOC support
  2015-06-29 20:11 [Qemu-devel] [PATCH v8 00/11] i.MX: Add i.MX25 support through the 3DS evaluation board Jean-Christophe Dubois
                   ` (7 preceding siblings ...)
  2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 08/11] i.MX: Add I2C controller emulator Jean-Christophe Dubois
@ 2015-06-29 20:12 ` Jean-Christophe Dubois
  2015-06-30  7:29   ` Peter Crosthwaite
  2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 10/11] i.MX25: Add support for the i.MX25 PDK 3DS Jean-Christophe Dubois
  2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 11/11] i.MX: Add qtest support for I2C device emulator Jean-Christophe Dubois
  10 siblings, 1 reply; 17+ messages in thread
From: Jean-Christophe Dubois @ 2015-06-29 20:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

For now we do support the foolowing devices:
  * GPT timers (from i.MX31)
  * EPIT timers (from i.MX31)
  * CCM (from i.MX31)
  * AVIC (from i.MX31)
  * UART (from i.MX31)
  * Ethernet FEC port
  * I2C controller

Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
---

Changes since v1:
    * not present on v1

Changes since v2:
    * not present on v2

Changes since v3:
    * not present on v3

Changes since v4:
    * not present on v4

Changes since v5:
    * not present on v5

Changes since v6:
    * not present on v6

Changes since v7:
    * Added a SOC specific file for i.MX25

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs            |   1 +
 hw/arm/fsl-imx25.c              | 304 ++++++++++++++++++++++++++++++++++++++++
 include/hw/arm/fsl-imx25.h      |  52 +++++++
 4 files changed, 358 insertions(+)
 create mode 100644 hw/arm/fsl-imx25.c
 create mode 100644 include/hw/arm/fsl-imx25.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index c6f509d..057f39c 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -99,6 +99,7 @@ CONFIG_ALLWINNER_A10_PIT=y
 CONFIG_ALLWINNER_A10_PIC=y
 CONFIG_ALLWINNER_A10=y
 
+CONFIG_FSL_IMX25=y
 CONFIG_IMX_I2C=y
 
 CONFIG_XIO3130=y
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index cf346c1..b89c31d 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -13,3 +13,4 @@ obj-y += omap1.o omap2.o strongarm.o
 obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o
 obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
+obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
new file mode 100644
index 0000000..b2db548
--- /dev/null
+++ b/hw/arm/fsl-imx25.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2013 Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * i.MX25 SOC emulation.
+ *
+ * Based on hw/arm/xlnx-zynqmp.c
+ *
+ * Copyright (C) 2015 Xilinx Inc
+ * Written by Peter Crosthwaite <peter.crosthwaite@xilinx.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw/arm/fsl-imx25.h"
+#include "sysemu/sysemu.h"
+
+/* Memory map for 3D-Stack Emulation Baseboard:
+ * 0x00000000-0x00003fff 16k ROM              IGNORED
+ * 0x00004000-0x00403fff Reserved             IGNORED
+ * 0x00404000-0x00408fff 20k ROM              IGNORED
+ * 0x00409000-0x0fffffff Reserved             IGNORED
+ * 0x10000000-0x1fffffff Reserved             IGNORED
+ * 0x20000000-0x2fffffff Reserved             IGNORED
+ * 0x30000000-0x3fffffff Reserved             IGNORED
+ * 0x40000000-0x43efffff Reserved             IGNORED
+ * 0x43f00000-0x6fffffff I.MX25 Internal Register Space
+ *   0x43f00000 IO_AREA0
+ *   0x43f80000 I2C0                          EMULATED
+ *   0x43f84000 I2C2                          EMULATED
+ *   0x43f98000 I2C1                          EMULATED
+ *   0x43f90000 UART1                         EMULATED
+ *   0x43f94000 UART2                         EMULATED
+ *   0x43fb0000 UART4                         IGNORED
+ *   0x43fb4000 UART5                         IGNORED
+ *   0x5000c000 UART3                         EMULATED
+ *   0x50038000 FEC                           EMULATED
+ *   0x53f80000 CCM                           EMULATED
+ *   0x53f84000 GPT 4                         EMULATED
+ *   0x53f88000 GPT 3                         EMULATED
+ *   0x53f8c000 GPT 2                         EMULATED
+ *   0x53f90000 GPT 1                         EMULATED
+ *   0x53f94000 PIT 1                         EMULATED
+ *   0x53f98000 PIT 2                         EMULATED
+ *   0x53f9c000 GPIO-4                        EMULATED
+ *   0x53fa4000 GPIO-3                        EMULATED
+ *   0x53fcc000 GPIO-1                        EMULATED
+ *   0x53fd0000 GPIO-2                        EMULATED
+ *   0x68000000 ASIC                          EMULATED
+ * 0x78000000-0x7801ffff SRAM                 EMULATED
+ * 0x78020000-0x7fffffff SRAM Aliasing        EMULATED
+ * 0x80000000-0x87ffffff RAM + Alias          EMULATED
+ * 0x90000000-0x9fffffff RAM + Alias          EMULATED
+ * 0xa0000000-0xa7ffffff Flash                IGNORED
+ * 0xa8000000-0xafffffff Flash                IGNORED
+ * 0xb0000000-0xb1ffffff SRAM                 IGNORED
+ * 0xb2000000-0xb3ffffff SRAM                 IGNORED
+ * 0xb4000000-0xb5ffffff CS4                  IGNORED
+ * 0xb6000000-0xb8000fff Reserved             IGNORED
+ * 0xb8001000-0xb8001fff SDRAM CTRL reg       IGNORED
+ * 0xb8002000-0xb8002fff WEIM CTRL reg        IGNORED
+ * 0xb8003000-0xb8003fff M3IF CTRL reg        IGNORED
+ * 0xb8004000-0xb8004fff EMI CTRL reg         IGNORED
+ * 0xb8005000-0xbaffffff Reserved             IGNORED
+ * 0xbb000000-0xbb000fff NAND flash area buf  IGNORED
+ * 0xbb001000-0xbb0011ff NAND flash reserved  IGNORED
+ * 0xbb001200-0xbb001dff Reserved             IGNORED
+ * 0xbb001e00-0xbb001fff NAN flash CTRL reg   IGNORED
+ * 0xbb012000-0xbfffffff Reserved             IGNORED
+ * 0xc0000000-0xffffffff Reserved             IGNORED
+ */
+
+static void fsl_imx25_init(Object *obj)
+{
+    FslImx25State *s = FSL_IMX25(obj);
+    int i;
+
+    object_initialize(&s->cpu, sizeof(s->cpu), "arm926-" TYPE_ARM_CPU);
+
+    object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
+    qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());
+
+    object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX_CCM);
+    qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
+
+    for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
+        if (i >= MAX_SERIAL_PORTS) {
+            break;
+        }
+        object_initialize(&s->uart[i], sizeof(s->uart[i]), TYPE_IMX_SERIAL);
+        qdev_set_parent_bus(DEVICE(&s->uart[i]), sysbus_get_default());
+    }
+
+    for (i = 0; i < FSL_IMX25_NUM_GPTS; i++) {
+        object_initialize(&s->gpt[i], sizeof(s->gpt[i]), TYPE_IMX_GPT);
+        qdev_set_parent_bus(DEVICE(&s->gpt[i]), sysbus_get_default());
+    }
+
+    for (i = 0; i < FSL_IMX25_NUM_EPITS; i++) {
+        object_initialize(&s->epit[i], sizeof(s->epit[i]), TYPE_IMX_EPIT);
+        qdev_set_parent_bus(DEVICE(&s->epit[i]), sysbus_get_default());
+    }
+
+    object_initialize(&s->fec, sizeof(s->fec), TYPE_IMX_FEC);
+    qdev_set_parent_bus(DEVICE(&s->fec), sysbus_get_default());
+
+    for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) {
+        object_initialize(&s->i2c[i], sizeof(s->i2c[i]), TYPE_IMX_I2C);
+        qdev_set_parent_bus(DEVICE(&s->i2c[i]), sysbus_get_default());
+    }
+}
+
+static void fsl_imx25_realize(DeviceState *dev, Error **errp)
+{
+    FslImx25State *s = FSL_IMX25(dev);
+    //MemoryRegion *system_memory = get_system_memory();
+    uint8_t i;
+    Error *err = NULL;
+
+    /* Initialize the CPU */
+    object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
+    if (err) {
+        error_propagate((errp), (err));
+        return;
+    }
+
+    /* Initialize the PIC */
+    object_property_set_bool(OBJECT(&s->avic), true, "realized", &err);
+    if (err) {
+        error_propagate((errp), (err));
+        return;
+    }
+    /* Connect the PIC interrupt to the CPU */
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->avic), 0, 0x68000000);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 0,
+                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 1,
+                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));
+
+    /* Initialize the CCM */
+    object_property_set_bool(OBJECT(&s->ccm), true, "realized", &err);
+    if (err) {
+        error_propagate((errp), (err));
+        return;
+    }
+    /* Map CCM memory */
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, 0x53f80000);
+
+    /* Initialize all UARTS */
+    for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
+        static const struct {
+            hwaddr addr;
+            unsigned int irq;
+        } serial_table[FSL_IMX25_NUM_UARTS] = {
+            { 0x43f90000, 45 },
+            { 0x43f94000, 32 },
+            { 0x5000c000, 18 },
+            { 0x50008000, 5  },
+            { 0x5002c000, 40 }
+        };
+
+        /* Bail out if we exeeded Qemu UART count */
+        if (i >= MAX_SERIAL_PORTS) {
+            break;
+        }
+        /* Initialize the UART */
+        object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", &err);
+        if (err) {
+            error_propagate((errp), (err));
+            return;
+        }
+        /* Map UART memory */
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr);
+        /* Connet UART IRQ to PIC */
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
+                           qdev_get_gpio_in(DEVICE(&s->avic),
+                                            serial_table[i].irq));
+    }
+
+    /* Initialize all GPT timers */
+    for (i = 0; i < FSL_IMX25_NUM_GPTS; i++) {
+        static const struct {
+            hwaddr addr;
+            unsigned int irq;
+        } gpt_table[FSL_IMX25_NUM_GPTS] = {
+            { 0x53f84000, 1 },
+            { 0x53f88000, 29 },
+            { 0x53f8c000, 53 },
+            { 0x53f90000, 54 }
+        };
+
+        s->gpt[i].ccm = DEVICE(&s->ccm);
+
+        /* Initialize the GPT */
+        object_property_set_bool(OBJECT(&s->gpt[i]), true, "realized", &err);
+        if (err) {
+            error_propagate((errp), (err));
+            return;
+        }
+        /* Map GPT memory */
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, gpt_table[i].addr);
+        /* Connet GPT IRQ to PIC */
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
+                           qdev_get_gpio_in(DEVICE(&s->avic),
+                                            gpt_table[i].irq));
+    }
+
+    /* Initialize all EPIT timers */
+    for (i = 0; i < FSL_IMX25_NUM_EPITS; i++) {
+        static const struct {
+            hwaddr addr;
+            unsigned int irq;
+        } epit_table[FSL_IMX25_NUM_EPITS] = {
+            { 0x53f94000, 28 },
+            { 0x53f98000, 27 }
+        };
+
+        s->epit[i].ccm = DEVICE(&s->ccm);
+
+        /* Initialize the EPIT */
+        object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err);
+        if (err) {
+            error_propagate((errp), (err));
+            return;
+        }
+        /* Map EPIT memory */
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0, epit_table[i].addr);
+        /* Connet EPIT IRQ to PIC */
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
+                           qdev_get_gpio_in(DEVICE(&s->avic),
+                                            epit_table[i].irq));
+    }
+
+    /* Initialize the FEC */
+    qdev_set_nic_properties(DEVICE(&s->fec), &nd_table[0]);
+    object_property_set_bool(OBJECT(&s->fec), true, "realized", &err);
+    if (err) {
+        error_propagate((errp), (err));
+        return;
+    }
+    /* Map FEC memory */
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->fec), 0, 0x50038000);
+    /* Connet FEC IRQ to PIC */
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->fec), 0,
+                       qdev_get_gpio_in(DEVICE(&s->avic), 57));
+
+
+    /* Initialize all I2C */
+    for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) {
+        static const struct {
+            hwaddr addr;
+            unsigned int irq;
+        } i2c_table[FSL_IMX25_NUM_I2CS] = {
+            { 0x43f80000, 3  },
+            { 0x43f98000, 4  },
+            { 0x43f84000, 10 }
+        };
+
+        /* Initialize the I2C */
+        object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized", &err);
+        if (err) {
+            error_propagate((errp), (err));
+            return;
+        }
+        /* Map I2C memory */
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr);
+        /* Connet I2C IRQ to PIC */
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
+                           qdev_get_gpio_in(DEVICE(&s->avic),
+                                            i2c_table[i].irq));
+    }
+}
+
+static void fsl_imx25_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = fsl_imx25_realize;
+}
+
+static const TypeInfo fsl_imx25_type_info = {
+    .name = TYPE_FSL_IMX25,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(FslImx25State),
+    .instance_init = fsl_imx25_init,
+    .class_init = fsl_imx25_class_init,
+};
+
+static void fsl_imx25_register_types(void)
+{
+    type_register_static(&fsl_imx25_type_info);
+}
+
+type_init(fsl_imx25_register_types)
diff --git a/include/hw/arm/fsl-imx25.h b/include/hw/arm/fsl-imx25.h
new file mode 100644
index 0000000..43d89a1
--- /dev/null
+++ b/include/hw/arm/fsl-imx25.h
@@ -0,0 +1,52 @@
+/*
+ * Freescale i.MX25 SoC emulation
+ *
+ * Copyright (C) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef FSL_IMX25_H
+#define FSL_IMX25_H
+
+#include "hw/arm/arm.h"
+#include "hw/intc/imx_avic.h"
+#include "hw/misc/imx_ccm.h"
+#include "hw/char/imx_serial.h"
+#include "hw/timer/imx_gpt.h"
+#include "hw/timer/imx_epit.h"
+#include "hw/net/imx_fec.h"
+#include "hw/i2c/imx_i2c.h"
+
+#define TYPE_FSL_IMX25 "fsl,imx25"
+#define FSL_IMX25(obj) OBJECT_CHECK(FslImx25State, (obj), TYPE_FSL_IMX25)
+
+#define FSL_IMX25_NUM_UARTS 5
+#define FSL_IMX25_NUM_GPTS 4
+#define FSL_IMX25_NUM_EPITS 2
+#define FSL_IMX25_NUM_I2CS 3
+
+typedef struct {
+    /*< private >*/
+    DeviceState parent_obj;
+
+    /*< public >*/
+    ARMCPU         cpu;
+    IMXAVICState   avic;
+    IMXCCMState    ccm;
+    IMXSerialState uart[FSL_IMX25_NUM_UARTS];
+    IMXGPTState    gpt[FSL_IMX25_NUM_GPTS];
+    IMXEPITState   epit[FSL_IMX25_NUM_EPITS];
+    IMXFECState    fec;
+    IMXI2CState    i2c[FSL_IMX25_NUM_I2CS];
+} FslImx25State;
+
+#endif // FSL_IMX25_H
-- 
2.1.4

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

* [Qemu-devel] [PATCH v8 10/11] i.MX25: Add support for the i.MX25 PDK 3DS
  2015-06-29 20:11 [Qemu-devel] [PATCH v8 00/11] i.MX: Add i.MX25 support through the 3DS evaluation board Jean-Christophe Dubois
                   ` (8 preceding siblings ...)
  2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 09/11] i.MX25: Add the i.MX25 SOC support Jean-Christophe Dubois
@ 2015-06-29 20:12 ` Jean-Christophe Dubois
  2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 11/11] i.MX: Add qtest support for I2C device emulator Jean-Christophe Dubois
  10 siblings, 0 replies; 17+ messages in thread
From: Jean-Christophe Dubois @ 2015-06-29 20:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

This just adds the required memory arround the i.MX25 SOC.

Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
---

Changes since v1:
    * Added a ds1338 I2C device for qtest purpose.

Changes since v2:
    * none
 
Changes since v3:
    * Rework GPL header          
    * use I2C constructor helper.

Changes since v4:
    * use sysbus_create_simple() instead of I2C constructor helper

Changes since v5:
    * Add ds1338 only for qtest mode.
    * small comment fixes.

Changes since v6:
    * Allow for more than 4 serial if suppoted by Qemu.

Changes since v7:
    * Move the SOC part into its own file.

 hw/arm/Makefile.objs |   2 +-
 hw/arm/imx25_3ds.c   | 217 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 218 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/imx25_3ds.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index b89c31d..c03228d 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -13,4 +13,4 @@ obj-y += omap1.o omap2.o strongarm.o
 obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o
 obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
-obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o
+obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_3ds.o
diff --git a/hw/arm/imx25_3ds.c b/hw/arm/imx25_3ds.c
new file mode 100644
index 0000000..ce97946
--- /dev/null
+++ b/hw/arm/imx25_3ds.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2013 Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * 3Dstack Board System emulation.
+ *
+ * Based on hw/arm/kzm.c
+ *
+ * Copyright (c) 2008 OKL and 2011 NICTA
+ * Written by Hans at OK-Labs
+ * Updated by Peter Chubb.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw/arm/fsl-imx25.h"
+#include "hw/boards.h"
+#include "qemu/error-report.h"
+#include "exec/address-spaces.h"
+#include "sysemu/qtest.h"
+#include "hw/i2c/i2c.h"
+
+/* Memory map for 3D-Stack Emulation Baseboard:
+ * 0x00000000-0x00003fff 16k ROM              IGNORED
+ * 0x00004000-0x00403fff Reserved             IGNORED
+ * 0x00404000-0x00408fff 20k ROM              IGNORED
+ * 0x00409000-0x0fffffff Reserved             IGNORED
+ * 0x10000000-0x1fffffff Reserved             IGNORED
+ * 0x20000000-0x2fffffff Reserved             IGNORED
+ * 0x30000000-0x3fffffff Reserved             IGNORED
+ * 0x40000000-0x43efffff Reserved             IGNORED
+ * 0x43f00000-0x6fffffff I.MX25 Internal Register Space
+ *   0x43f00000 IO_AREA0
+ *   0x43f80000 I2C0                          EMULATED
+ *   0x43f84000 I2C2                          EMULATED
+ *   0x43f98000 I2C1                          EMULATED
+ *   0x43f90000 UART1                         EMULATED
+ *   0x43f94000 UART2                         EMULATED
+ *   0x43fb0000 UART4                         IGNORED
+ *   0x43fb4000 UART5                         IGNORED
+ *   0x5000c000 UART3                         EMULATED
+ *   0x50038000 FEC                           EMULATED
+ *   0x53f80000 CCM                           EMULATED
+ *   0x53f84000 GPT 4                         EMULATED
+ *   0x53f88000 GPT 3                         EMULATED
+ *   0x53f8c000 GPT 2                         EMULATED
+ *   0x53f90000 GPT 1                         EMULATED
+ *   0x53f94000 PIT 1                         EMULATED
+ *   0x53f98000 PIT 2                         EMULATED
+ *   0x53f9c000 GPIO-4                        EMULATED
+ *   0x53fa4000 GPIO-3                        EMULATED
+ *   0x53fcc000 GPIO-1                        EMULATED
+ *   0x53fd0000 GPIO-2                        EMULATED
+ *   0x68000000 ASIC                          EMULATED
+ * 0x78000000-0x7801ffff SRAM                 EMULATED
+ * 0x78020000-0x7fffffff SRAM Aliasing        EMULATED
+ * 0x80000000-0x87ffffff RAM + Alias          EMULATED
+ * 0x90000000-0x9fffffff RAM + Alias          EMULATED
+ * 0xa0000000-0xa7ffffff Flash                IGNORED
+ * 0xa8000000-0xafffffff Flash                IGNORED
+ * 0xb0000000-0xb1ffffff SRAM                 IGNORED
+ * 0xb2000000-0xb3ffffff SRAM                 IGNORED
+ * 0xb4000000-0xb5ffffff CS4                  IGNORED
+ * 0xb6000000-0xb8000fff Reserved             IGNORED
+ * 0xb8001000-0xb8001fff SDRAM CTRL reg       IGNORED
+ * 0xb8002000-0xb8002fff WEIM CTRL reg        IGNORED
+ * 0xb8003000-0xb8003fff M3IF CTRL reg        IGNORED
+ * 0xb8004000-0xb8004fff EMI CTRL reg         IGNORED
+ * 0xb8005000-0xbaffffff Reserved             IGNORED
+ * 0xbb000000-0xbb000fff NAND flash area buf  IGNORED
+ * 0xbb001000-0xbb0011ff NAND flash reserved  IGNORED
+ * 0xbb001200-0xbb001dff Reserved             IGNORED
+ * 0xbb001e00-0xbb001fff NAN flash CTRL reg   IGNORED
+ * 0xbb012000-0xbfffffff Reserved             IGNORED
+ * 0xc0000000-0xffffffff Reserved             IGNORED
+ */
+
+typedef struct imx25_3ds {
+    FslImx25State soc;
+    MemoryRegion ram[2];
+    MemoryRegion ram_alias;
+    MemoryRegion sram;
+    MemoryRegion sram_alias;
+} imx25_3ds;
+
+#define IMX25_SRAM_ADDRESS  (0x78000000)
+#define IMX25_SRAMSIZE      (128*1024)
+#define IMX25_CS_SRAMSIZE   (128*1024*1024)
+#define IMX25_3DS_ADDRESS   (0x80000000)
+#define IMX25_CS_RAMSIZE    (256*1024*1024)
+
+static struct arm_boot_info imx25_3ds_binfo;
+
+static void imx25_3ds_init(MachineState *machine)
+{
+    imx25_3ds *s = g_new0(imx25_3ds, 1);
+    Error *err = NULL;
+    int i;
+
+    object_initialize(&s->soc, sizeof(s->soc), TYPE_FSL_IMX25);
+    object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
+                              &error_abort);
+
+    object_property_set_bool(OBJECT(&s->soc), true, "realized", &err);
+    if (err != NULL) {
+        error_report("%s", error_get_pretty(err));
+        exit(1);
+    }
+
+    /* We need to initialize our memory */
+
+    if (machine->ram_size > (2 * IMX25_CS_RAMSIZE)) {
+	error_report("WARNING: RAM size " RAM_ADDR_FMT " above max supported, "
+                     "reduced to %x", machine->ram_size,
+                     2 * IMX25_CS_RAMSIZE);
+	machine->ram_size = 2 * IMX25_CS_RAMSIZE;
+    }
+
+    /* create our main memory */
+    for (i = 0; i <= (machine->ram_size / IMX25_CS_RAMSIZE); i++) {
+        ram_addr_t blk_size = machine->ram_size - (IMX25_CS_RAMSIZE * i);
+        char ram_name[20];
+
+        if (blk_size > IMX25_CS_RAMSIZE) {
+            blk_size = IMX25_CS_RAMSIZE;
+        }
+
+        if (blk_size == 0) {
+            break;
+        }
+
+        sprintf(ram_name, "imx25.ram%d", i);
+
+        memory_region_init_ram(&s->ram[i], NULL, ram_name, blk_size, &error_abort);
+        vmstate_register_ram_global(&s->ram[i]);
+        memory_region_add_subregion(get_system_memory(), IMX25_3DS_ADDRESS
+                                    + (IMX25_CS_RAMSIZE * i), &s->ram[i]);
+
+        /* Add ram alias */
+        if (blk_size < IMX25_CS_RAMSIZE) {
+            char alias_name[20];
+
+            sprintf(alias_name, "ram.alias%d", i);
+
+            memory_region_init_alias(&s->ram_alias, NULL, alias_name,
+                                     &s->ram[i], 0,
+                                     IMX25_CS_RAMSIZE - blk_size);
+            memory_region_add_subregion(get_system_memory(), IMX25_3DS_ADDRESS
+                                        + (IMX25_CS_RAMSIZE * i) + blk_size,
+                                        &s->ram_alias);
+            break;
+        }
+    }
+
+    /* create the sram area */
+    memory_region_init_ram(&s->sram, NULL, "imx25.sram", IMX25_SRAMSIZE,
+                           &error_abort);
+    vmstate_register_ram_global(&s->sram);
+    memory_region_add_subregion(get_system_memory(), IMX25_SRAM_ADDRESS,
+                                &s->sram);
+
+    /* add sram alias */
+    memory_region_init_alias(&s->sram_alias, NULL, "sram.alias", &s->sram, 0,
+                             IMX25_CS_SRAMSIZE - IMX25_SRAMSIZE);
+    memory_region_add_subregion(get_system_memory(),
+                                IMX25_SRAM_ADDRESS + IMX25_SRAMSIZE,
+                                &s->sram_alias);
+
+    imx25_3ds_binfo.ram_size = machine->ram_size;
+    imx25_3ds_binfo.kernel_filename = machine->kernel_filename;
+    imx25_3ds_binfo.kernel_cmdline = machine->kernel_cmdline;
+    imx25_3ds_binfo.initrd_filename = machine->initrd_filename;
+    imx25_3ds_binfo.loader_start = IMX25_3DS_ADDRESS;
+    imx25_3ds_binfo.board_id = 1771,
+    imx25_3ds_binfo.nb_cpus = 1;
+
+    /*
+     * We test explicitly for qtest here as it is not done (yet?) in
+     * arm_load_kernel(). Without this the "make check" command would
+     * fail.
+     */
+    if (!qtest_enabled()) {
+        arm_load_kernel(&s->soc.cpu, &imx25_3ds_binfo);
+    } else {
+        /*
+         * This I2C device doesn't exist on the real board.
+         * We add it here (only on qtest usage) to be able to do a bit
+         * of simple qtest. See "make check" for details.
+         */
+        i2c_create_slave((I2CBus *)qdev_get_child_bus(DEVICE(&s->soc.i2c[0]),
+                                                      "i2c"),
+                         "ds1338", 0x68);
+    }
+}
+
+static QEMUMachine imx25_3ds_machine = {
+    .name = "imx25_3ds",
+    .desc = "ARM i.MX25 PDK board (ARM926)",
+    .init = imx25_3ds_init,
+};
+
+static void imx25_3ds_machine_init(void)
+{
+    qemu_register_machine(&imx25_3ds_machine);
+}
+
+machine_init(imx25_3ds_machine_init)
-- 
2.1.4

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

* [Qemu-devel] [PATCH v8 11/11] i.MX: Add qtest support for I2C device emulator.
  2015-06-29 20:11 [Qemu-devel] [PATCH v8 00/11] i.MX: Add i.MX25 support through the 3DS evaluation board Jean-Christophe Dubois
                   ` (9 preceding siblings ...)
  2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 10/11] i.MX25: Add support for the i.MX25 PDK 3DS Jean-Christophe Dubois
@ 2015-06-29 20:12 ` Jean-Christophe Dubois
  10 siblings, 0 replies; 17+ messages in thread
From: Jean-Christophe Dubois @ 2015-06-29 20:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

This is using a ds1338 RTC chip on the I2C bus. This RTC chip is
not present on the real board.

Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
---


Changes since v1:
    * not present on v1

Changes since v2:
    * use a common header file for I2C regs definition

Changes since v3:
    * rework GPL headers.

Changes since v4:
    * none

Changes since v5:
    * none

Changes since v6:
    * none

Changes since v7:
    * adapt to new i.MX I2C header file.

 tests/Makefile         |   3 +
 tests/ds1338-test.c    |  75 ++++++++++++++++++
 tests/libqos/i2c-imx.c | 209 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/libqos/i2c.h     |   3 +
 4 files changed, 290 insertions(+)
 create mode 100644 tests/ds1338-test.c
 create mode 100644 tests/libqos/i2c-imx.c

diff --git a/tests/Makefile b/tests/Makefile
index c5e4744..93890a8 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -193,6 +193,7 @@ check-qtest-sparc64-y = tests/endianness-test$(EXESUF)
 gcov-files-sparc-y += hw/timer/m48t59.c
 gcov-files-sparc64-y += hw/timer/m48t59.c
 check-qtest-arm-y = tests/tmp105-test$(EXESUF)
+check-qtest-arm-y = tests/ds1338-test$(EXESUF)
 gcov-files-arm-y += hw/misc/tmp105.c
 check-qtest-arm-y += tests/virtio-blk-test$(EXESUF)
 gcov-files-arm-y += arm-softmmu/hw/block/virtio-blk.c
@@ -342,6 +343,7 @@ libqos-pc-obj-y = $(libqos-obj-y) tests/libqos/pci-pc.o
 libqos-pc-obj-y += tests/libqos/malloc-pc.o tests/libqos/libqos-pc.o
 libqos-pc-obj-y += tests/libqos/ahci.o
 libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o
+libqos-imx-obj-y = $(libqos-obj-y) tests/libqos/i2c-imx.o
 libqos-usb-obj-y = $(libqos-pc-obj-y) tests/libqos/usb.o
 libqos-virtio-obj-y = $(libqos-pc-obj-y) tests/libqos/virtio.o tests/libqos/virtio-pci.o tests/libqos/virtio-mmio.o tests/libqos/malloc-generic.o
 
@@ -356,6 +358,7 @@ tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o
 tests/boot-order-test$(EXESUF): tests/boot-order-test.o $(libqos-obj-y)
 tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o $(libqos-obj-y)
 tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
+tests/ds1338-test$(EXESUF): tests/ds1338-test.o $(libqos-imx-obj-y)
 tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
 tests/q35-test$(EXESUF): tests/q35-test.o $(libqos-pc-obj-y)
 tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
diff --git a/tests/ds1338-test.c b/tests/ds1338-test.c
new file mode 100644
index 0000000..fbc989b
--- /dev/null
+++ b/tests/ds1338-test.c
@@ -0,0 +1,75 @@
+/*
+ * QTest testcase for the DS1338 RTC
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "libqtest.h"
+#include "libqos/i2c.h"
+
+#include <glib.h>
+
+#define IMX25_I2C_0_BASE 0x43F80000
+
+#define DS1338_ADDR 0x68
+
+static I2CAdapter *i2c;
+static uint8_t addr;
+
+#define bcd2bin(x)        (((x) & 0x0f) + ((x) >> 4) * 10)
+
+static void send_and_receive(void)
+{
+    uint8_t cmd[1];
+    uint8_t resp[7];
+    time_t now = time(NULL);
+    struct tm *tm_ptr = gmtime(&now);
+
+    /* reset the index in the RTC memory */
+    cmd[0] = 0;
+    i2c_send(i2c, addr, cmd, 1);
+
+    /* retrieve the date */
+    i2c_recv(i2c, addr, resp, 7);
+
+    /* check retreived time againt local time */
+    g_assert_cmpuint(bcd2bin(resp[4]), == , tm_ptr->tm_mday);
+    g_assert_cmpuint(bcd2bin(resp[5]), == , 1 + tm_ptr->tm_mon);
+    g_assert_cmpuint(2000 + bcd2bin(resp[6]), == , 1900 + tm_ptr->tm_year);
+}
+
+int main(int argc, char **argv)
+{
+    QTestState *s = NULL;
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+
+    s = qtest_start("-display none -machine imx25_3ds");
+    i2c = imx_i2c_create(IMX25_I2C_0_BASE);
+    addr = DS1338_ADDR;
+
+    qtest_add_func("/ds1338/tx-rx", send_and_receive);
+
+    ret = g_test_run();
+
+    if (s) {
+        qtest_quit(s);
+    }
+    g_free(i2c);
+
+    return ret;
+}
diff --git a/tests/libqos/i2c-imx.c b/tests/libqos/i2c-imx.c
new file mode 100644
index 0000000..b5cef66
--- /dev/null
+++ b/tests/libqos/i2c-imx.c
@@ -0,0 +1,209 @@
+/*
+ * QTest i.MX I2C driver
+ *
+ * Copyright (c) 2013 Jean-Christophe Dubois
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "libqos/i2c.h"
+
+#include <glib.h>
+#include <string.h>
+
+#include "qemu/osdep.h"
+#include "libqtest.h"
+
+#include "hw/i2c/imx_i2c.h"
+
+enum IMXI2CDirection {
+    IMX_I2C_READ,
+    IMX_I2C_WRITE,
+};
+
+typedef struct IMXI2C {
+    I2CAdapter parent;
+
+    uint64_t addr;
+} IMXI2C;
+
+
+static void imx_i2c_set_slave_addr(IMXI2C *s, uint8_t addr,
+                                   enum IMXI2CDirection direction)
+{
+    writeb(s->addr + I2DR_ADDR, (addr << 1) |
+           (direction == IMX_I2C_READ ? 1 : 0));
+}
+
+static void imx_i2c_send(I2CAdapter *i2c, uint8_t addr,
+                         const uint8_t *buf, uint16_t len)
+{
+    IMXI2C *s = (IMXI2C *)i2c;
+    uint8_t data;
+    uint8_t status;
+    uint16_t size = 0;
+
+    if (!len) {
+        return;
+    }
+
+    /* set the bus for write */
+    data = I2CR_IEN |
+           I2CR_IIEN |
+           I2CR_MSTA |
+           I2CR_MTX |
+           I2CR_TXAK;
+
+    writeb(s->addr + I2CR_ADDR, data);
+    status = readb(s->addr + I2SR_ADDR);
+    g_assert((status & I2SR_IBB) != 0);
+
+    /* set the slave address */
+    imx_i2c_set_slave_addr(s, addr, IMX_I2C_WRITE);
+    status = readb(s->addr + I2SR_ADDR);
+    g_assert((status & I2SR_IIF) != 0);
+    g_assert((status & I2SR_RXAK) == 0);
+
+    /* ack the interrupt */
+    writeb(s->addr + I2SR_ADDR, 0);
+    status = readb(s->addr + I2SR_ADDR);
+    g_assert((status & I2SR_IIF) == 0);
+
+    while (size < len) {
+        /* check we are still busy */
+        status = readb(s->addr + I2SR_ADDR);
+        g_assert((status & I2SR_IBB) != 0);
+
+        /* write the data */
+        writeb(s->addr + I2DR_ADDR, buf[size]);
+        status = readb(s->addr + I2SR_ADDR);
+        g_assert((status & I2SR_IIF) != 0);
+        g_assert((status & I2SR_RXAK) == 0);
+
+        /* ack the interrupt */
+        writeb(s->addr + I2SR_ADDR, 0);
+        status = readb(s->addr + I2SR_ADDR);
+        g_assert((status & I2SR_IIF) == 0);
+
+        size++;
+    }
+
+    /* release the bus */
+    data &= ~(I2CR_MSTA | I2CR_MTX);
+    writeb(s->addr + I2CR_ADDR, data);
+    status = readb(s->addr + I2SR_ADDR);
+    g_assert((status & I2SR_IBB) == 0);
+}
+
+static void imx_i2c_recv(I2CAdapter *i2c, uint8_t addr,
+                         uint8_t *buf, uint16_t len)
+{
+    IMXI2C *s = (IMXI2C *)i2c;
+    uint8_t data;
+    uint8_t status;
+    uint16_t size = 0;
+
+    if (!len) {
+        return;
+    }
+
+    /* set the bus for write */
+    data = I2CR_IEN |
+           I2CR_IIEN |
+           I2CR_MSTA |
+           I2CR_MTX |
+           I2CR_TXAK;
+
+    writeb(s->addr + I2CR_ADDR, data);
+    status = readb(s->addr + I2SR_ADDR);
+    g_assert((status & I2SR_IBB) != 0);
+
+    /* set the slave address */
+    imx_i2c_set_slave_addr(s, addr, IMX_I2C_READ);
+    status = readb(s->addr + I2SR_ADDR);
+    g_assert((status & I2SR_IIF) != 0);
+    g_assert((status & I2SR_RXAK) == 0);
+
+    /* ack the interrupt */
+    writeb(s->addr + I2SR_ADDR, 0);
+    status = readb(s->addr + I2SR_ADDR);
+    g_assert((status & I2SR_IIF) == 0);
+
+    /* set the bus for read */
+    data &= ~I2CR_MTX;
+    /* if only one byte don't ack */
+    if (len != 1) {
+        data &= ~I2CR_TXAK;
+    }
+    writeb(s->addr + I2CR_ADDR, data);
+    status = readb(s->addr + I2SR_ADDR);
+    g_assert((status & I2SR_IBB) != 0);
+
+    /* dummy read */
+    readb(s->addr + I2DR_ADDR);
+    status = readb(s->addr + I2SR_ADDR);
+    g_assert((status & I2SR_IIF) != 0);
+
+    /* ack the interrupt */
+    writeb(s->addr + I2SR_ADDR, 0);
+    status = readb(s->addr + I2SR_ADDR);
+    g_assert((status & I2SR_IIF) == 0);
+
+    while (size < len) {
+        /* check we are still busy */
+        status = readb(s->addr + I2SR_ADDR);
+        g_assert((status & I2SR_IBB) != 0);
+
+        if (size == (len - 1)) {
+            /* stop the read transaction */
+            data &= ~(I2CR_MSTA | I2CR_MTX);
+        } else {
+            /* ack the data read */
+            data |= I2CR_TXAK;
+        }
+        writeb(s->addr + I2CR_ADDR, data);
+
+        /* read the data */
+        buf[size] = readb(s->addr + I2DR_ADDR);
+
+        if (size != (len - 1)) {
+            status = readb(s->addr + I2SR_ADDR);
+            g_assert((status & I2SR_IIF) != 0);
+
+            /* ack the interrupt */
+            writeb(s->addr + I2SR_ADDR, 0);
+        }
+
+        status = readb(s->addr + I2SR_ADDR);
+        g_assert((status & I2SR_IIF) == 0);
+
+        size++;
+    }
+
+    status = readb(s->addr + I2SR_ADDR);
+    g_assert((status & I2SR_IBB) == 0);
+}
+
+I2CAdapter *imx_i2c_create(uint64_t addr)
+{
+    IMXI2C *s = g_malloc0(sizeof(*s));
+    I2CAdapter *i2c = (I2CAdapter *)s;
+
+    s->addr = addr;
+
+    i2c->send = imx_i2c_send;
+    i2c->recv = imx_i2c_recv;
+
+    return i2c;
+}
diff --git a/tests/libqos/i2c.h b/tests/libqos/i2c.h
index 1ce9af4..c21f1dc 100644
--- a/tests/libqos/i2c.h
+++ b/tests/libqos/i2c.h
@@ -27,4 +27,7 @@ void i2c_recv(I2CAdapter *i2c, uint8_t addr,
 /* libi2c-omap.c */
 I2CAdapter *omap_i2c_create(uint64_t addr);
 
+/* libi2c-imx.c */
+I2CAdapter *imx_i2c_create(uint64_t addr);
+
 #endif
-- 
2.1.4

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

* Re: [Qemu-devel] [PATCH v8 01/11] i.MX: Split the i.MX serial driver into a header file and a source file
  2015-06-29 20:11 ` [Qemu-devel] [PATCH v8 01/11] i.MX: Split the i.MX serial driver into a header file and a source file Jean-Christophe Dubois
@ 2015-06-30  7:04   ` Peter Crosthwaite
  0 siblings, 0 replies; 17+ messages in thread
From: Peter Crosthwaite @ 2015-06-30  7:04 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: qemu-devel@nongnu.org Developers

On Mon, Jun 29, 2015 at 1:11 PM, Jean-Christophe Dubois
<jcd@tribudubois.net> wrote:
> Also adding a "realise" callback.
>
> This is to prepare to accomodate the SOC requirements.
>

You have also done a significant code style sweep. I would suggest
doing a git add -p and split this into 3 patches:

1: Style cleanups
2: Header movement
3: realize

The hunks look pretty self contained so it should be churn free.
Perhaps do the style cleanup last so there are no "you missed a bit"
for style issues in header-movement/realize changes.

Regards,
Peter

> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
> ---
>
> Changes since v1:
>     * not present on v1
>
> Changes since v2:
>     * not present on v2
>
> Changes since v3:
>     * not present on v3
>
> Changes since v4:
>     * not present on v4
>
> Changes since v5:
>     * not present on v5
>
> Changes since v6:
>     * not present on v6
>
> Changes since v7:
>     * Splited the i.MX serial emulator into a header file and a source file
>
>  hw/char/imx_serial.c         | 176 +++++++++++--------------------------------
>  include/hw/char/imx_serial.h | 104 +++++++++++++++++++++++++
>  2 files changed, 149 insertions(+), 131 deletions(-)
>  create mode 100644 include/hw/char/imx_serial.h
>
> diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
> index f3fbc77..8c2d071 100644
> --- a/hw/char/imx_serial.c
> +++ b/hw/char/imx_serial.c
> @@ -4,6 +4,7 @@
>   * Copyright (c) 2008 OKL
>   * Originally Written by Hans Jiang
>   * Copyright (c) 2011 NICTA Pty Ltd.
> + * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
>   *
>   * This work is licensed under the terms of the GNU GPL, version 2 or later.
>   * See the COPYING file in the top-level directory.
> @@ -17,16 +18,14 @@
>   *     is a real serial device.
>   */
>
> -#include "hw/hw.h"
> -#include "hw/sysbus.h"
> +#include "hw/char/imx_serial.h"
>  #include "sysemu/sysemu.h"
>  #include "sysemu/char.h"
> -#include "hw/arm/imx.h"
>
>  //#define DEBUG_SERIAL 1
>  #ifdef DEBUG_SERIAL
>  #define DPRINTF(fmt, args...) \
> -do { printf("imx_serial: " fmt , ##args); } while (0)
> +do { printf("%s: " fmt , TYPE_IMX_SERIAL, ##args); } while (0)
>  #else
>  #define DPRINTF(fmt, args...) do {} while (0)
>  #endif
> @@ -38,42 +37,13 @@ do { printf("imx_serial: " fmt , ##args); } while (0)
>  //#define DEBUG_IMPLEMENTATION 1
>  #ifdef DEBUG_IMPLEMENTATION
>  #  define IPRINTF(fmt, args...) \
> -    do  { fprintf(stderr, "imx_serial: " fmt, ##args); } while (0)
> +    do  { fprintf(stderr, "%s: " fmt, TYPE_IMX_SERIAL, ##args); } while (0)
>  #else
>  #  define IPRINTF(fmt, args...) do {} while (0)
>  #endif
>
> -#define TYPE_IMX_SERIAL "imx-serial"
> -#define IMX_SERIAL(obj) OBJECT_CHECK(IMXSerialState, (obj), TYPE_IMX_SERIAL)
> -
> -typedef struct IMXSerialState {
> -    SysBusDevice parent_obj;
> -
> -    MemoryRegion iomem;
> -    int32_t readbuff;
> -
> -    uint32_t usr1;
> -    uint32_t usr2;
> -    uint32_t ucr1;
> -    uint32_t ucr2;
> -    uint32_t uts1;
> -
> -    /*
> -     * The registers below are implemented just so that the
> -     * guest OS sees what it has written
> -     */
> -    uint32_t onems;
> -    uint32_t ufcr;
> -    uint32_t ubmr;
> -    uint32_t ubrc;
> -    uint32_t ucr3;
> -
> -    qemu_irq irq;
> -    CharDriverState *chr;
> -} IMXSerialState;
> -
>  static const VMStateDescription vmstate_imx_serial = {
> -    .name = "imx-serial",
> +    .name = TYPE_IMX_SERIAL,
>      .version_id = 1,
>      .minimum_version_id = 1,
>      .fields = (VMStateField[]) {
> @@ -91,55 +61,6 @@ static const VMStateDescription vmstate_imx_serial = {
>      },
>  };
>
> -
> -#define URXD_CHARRDY    (1<<15)   /* character read is valid */
> -#define URXD_ERR        (1<<14)   /* Character has error */
> -#define URXD_BRK        (1<<11)   /* Break received */
> -
> -#define USR1_PARTYER    (1<<15)   /* Parity Error */
> -#define USR1_RTSS       (1<<14)   /* RTS pin status */
> -#define USR1_TRDY       (1<<13)   /* Tx ready */
> -#define USR1_RTSD       (1<<12)   /* RTS delta: pin changed state */
> -#define USR1_ESCF       (1<<11)   /* Escape sequence interrupt */
> -#define USR1_FRAMERR    (1<<10)   /* Framing error  */
> -#define USR1_RRDY       (1<<9)    /* receiver ready */
> -#define USR1_AGTIM      (1<<8)    /* Aging timer interrupt */
> -#define USR1_DTRD       (1<<7)    /* DTR changed */
> -#define USR1_RXDS       (1<<6)    /* Receiver is idle */
> -#define USR1_AIRINT     (1<<5)    /* Aysnch IR interrupt */
> -#define USR1_AWAKE      (1<<4)    /* Falling edge detected on RXd pin */
> -
> -#define USR2_ADET       (1<<15)   /* Autobaud complete */
> -#define USR2_TXFE       (1<<14)   /* Transmit FIFO empty */
> -#define USR2_DTRF       (1<<13)   /* DTR/DSR transition */
> -#define USR2_IDLE       (1<<12)   /* UART has been idle for too long */
> -#define USR2_ACST       (1<<11)   /* Autobaud counter stopped */
> -#define USR2_RIDELT     (1<<10)   /* Ring Indicator delta */
> -#define USR2_RIIN       (1<<9)    /* Ring Indicator Input */
> -#define USR2_IRINT      (1<<8)    /* Serial Infrared Interrupt */
> -#define USR2_WAKE       (1<<7)    /* Start bit detected */
> -#define USR2_DCDDELT    (1<<6)    /* Data Carrier Detect delta */
> -#define USR2_DCDIN      (1<<5)    /* Data Carrier Detect Input */
> -#define USR2_RTSF       (1<<4)    /* RTS transition */
> -#define USR2_TXDC       (1<<3)    /* Transmission complete */
> -#define USR2_BRCD       (1<<2)    /* Break condition detected */
> -#define USR2_ORE        (1<<1)    /* Overrun error */
> -#define USR2_RDR        (1<<0)    /* Receive data ready */
> -
> -#define UCR1_TRDYEN     (1<<13)   /* Tx Ready Interrupt Enable */
> -#define UCR1_RRDYEN     (1<<9)    /* Rx Ready Interrupt Enable */
> -#define UCR1_TXMPTYEN   (1<<6)    /* Tx Empty Interrupt Enable */
> -#define UCR1_UARTEN     (1<<0)    /* UART Enable */
> -
> -#define UCR2_TXEN       (1<<2)    /* Transmitter enable */
> -#define UCR2_RXEN       (1<<1)    /* Receiver enable */
> -#define UCR2_SRST       (1<<0)    /* Reset complete */
> -
> -#define UTS1_TXEMPTY    (1<<6)
> -#define UTS1_RXEMPTY    (1<<5)
> -#define UTS1_TXFULL     (1<<4)
> -#define UTS1_RXFULL     (1<<3)
> -
>  static void imx_update(IMXSerialState *s)
>  {
>      uint32_t flags;
> @@ -242,13 +163,13 @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset,
>          return 0x0; /* TODO */
>
>      default:
> -        IPRINTF("imx_serial_read: bad offset: 0x%x\n", (int)offset);
> +        IPRINTF("%s: bad offset: 0x%x\n", __func__, (int)offset);
>          return 0;
>      }
>  }
>
>  static void imx_serial_write(void *opaque, hwaddr offset,
> -                      uint64_t value, unsigned size)
> +                             uint64_t value, unsigned size)
>  {
>      IMXSerialState *s = (IMXSerialState *)opaque;
>      unsigned char ch;
> @@ -298,25 +219,25 @@ static void imx_serial_write(void *opaque, hwaddr offset,
>
>      case 0x25: /* USR1 */
>          value &= USR1_AWAKE | USR1_AIRINT | USR1_DTRD | USR1_AGTIM |
> -            USR1_FRAMERR | USR1_ESCF | USR1_RTSD | USR1_PARTYER;
> +                 USR1_FRAMERR | USR1_ESCF | USR1_RTSD | USR1_PARTYER;
>          s->usr1 &= ~value;
>          break;
>
>      case 0x26: /* USR2 */
> -       /*
> -        * Writing 1 to some bits clears them; all other
> -        * values are ignored
> -        */
> +        /*
> +         * Writing 1 to some bits clears them; all other
> +         * values are ignored
> +         */
>          value &= USR2_ADET | USR2_DTRF | USR2_IDLE | USR2_ACST |
> -            USR2_RIDELT | USR2_IRINT | USR2_WAKE |
> -            USR2_DCDDELT | USR2_RTSF | USR2_BRCD | USR2_ORE;
> +                 USR2_RIDELT | USR2_IRINT | USR2_WAKE |
> +                 USR2_DCDDELT | USR2_RTSF | USR2_BRCD | USR2_ORE;
>          s->usr2 &= ~value;
>          break;
>
> -        /*
> -         * Linux expects to see what it writes to these registers
> -         * We don't currently alter the baud rate
> -         */
> +    /*
> +     * Linux expects to see what it writes to these registers
> +     * We don't currently alter the baud rate
> +     */
>      case 0x29: /* UBIR */
>          s->ubrc = value & 0xffff;
>          break;
> @@ -344,7 +265,7 @@ static void imx_serial_write(void *opaque, hwaddr offset,
>          break;
>
>      default:
> -        IPRINTF("imx_serial_write: Bad offset 0x%x\n", (int)offset);
> +        IPRINTF("%s: Bad offset 0x%x\n", __func__, (int)offset);
>      }
>  }
>
> @@ -377,22 +298,18 @@ static void imx_event(void *opaque, int event)
>      }
>  }
>
> -
>  static const struct MemoryRegionOps imx_serial_ops = {
>      .read = imx_serial_read,
>      .write = imx_serial_write,
>      .endianness = DEVICE_NATIVE_ENDIAN,
>  };
>
> -static int imx_serial_init(SysBusDevice *dev)
> +static void imx_serial_realize(DeviceState *dev, Error **errp)
>  {
>      IMXSerialState *s = IMX_SERIAL(dev);
>
> -
> -    memory_region_init_io(&s->iomem, OBJECT(s), &imx_serial_ops, s,
> -                          "imx-serial", 0x1000);
> -    sysbus_init_mmio(dev, &s->iomem);
> -    sysbus_init_irq(dev, &s->irq);
> +    /* FIXME use a qdev chardev prop instead of qemu_char_get_next_serial() */
> +    s->chr = qemu_char_get_next_serial();
>
>      if (s->chr) {
>          qemu_chr_add_handlers(s->chr, imx_can_receive, imx_receive,
> @@ -401,45 +318,42 @@ static int imx_serial_init(SysBusDevice *dev)
>          DPRINTF("No char dev for uart at 0x%lx\n",
>                  (unsigned long)s->iomem.ram_addr);
>      }
> +}
>
> -    return 0;
> +static void imx_serial_init(Object *obj)
> +{
> +    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
> +    IMXSerialState *s = IMX_SERIAL(obj);
> +
> +    memory_region_init_io(&s->iomem, obj, &imx_serial_ops, s,
> +                          TYPE_IMX_SERIAL, 0x1000);
> +    sysbus_init_mmio(sbd, &s->iomem);
> +    sysbus_init_irq(sbd, &s->irq);
>  }
>
>  void imx_serial_create(int uart, const hwaddr addr, qemu_irq irq)
>  {
>      DeviceState *dev;
>      SysBusDevice *bus;
> -    CharDriverState *chr;
> -    const char chr_name[] = "serial";
> -    char label[ARRAY_SIZE(chr_name) + 1];
> -
> -    dev = qdev_create(NULL, TYPE_IMX_SERIAL);
>
>      if (uart >= MAX_SERIAL_PORTS) {
>          hw_error("Cannot assign uart %d: QEMU supports only %d ports\n",
>                   uart, MAX_SERIAL_PORTS);
>      }
> -    chr = serial_hds[uart];
> -    if (!chr) {
> -        snprintf(label, ARRAY_SIZE(label), "%s%d", chr_name, uart);
> -        chr = qemu_chr_new(label, "null", NULL);
> -        if (!(chr)) {
> -            hw_error("Can't assign serial port to imx-uart%d.\n", uart);
> -        }
> -    }
>
> -    qdev_prop_set_chr(dev, "chardev", chr);
> +    dev = qdev_create(NULL, TYPE_IMX_SERIAL);
> +
>      bus = SYS_BUS_DEVICE(dev);
>      qdev_init_nofail(dev);
> +
>      if (addr != (hwaddr)-1) {
>          sysbus_mmio_map(bus, 0, addr);
>      }
> -    sysbus_connect_irq(bus, 0, irq);
>
> +    sysbus_connect_irq(bus, 0, irq);
>  }
>
> -
> -static Property imx32_serial_properties[] = {
> +static Property imx_serial_properties[] = {
>      DEFINE_PROP_CHR("chardev", IMXSerialState, chr),
>      DEFINE_PROP_END_OF_LIST(),
>  };
> @@ -447,21 +361,21 @@ static Property imx32_serial_properties[] = {
>  static void imx_serial_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> -    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
>
> -    k->init = imx_serial_init;
> +    dc->realize = imx_serial_realize;
>      dc->vmsd = &vmstate_imx_serial;
>      dc->reset = imx_serial_reset_at_boot;
> -    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
>      dc->desc = "i.MX series UART";
> -    dc->props = imx32_serial_properties;
> +    dc->props = imx_serial_properties;
> +    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
>  }
>
>  static const TypeInfo imx_serial_info = {
> -    .name = TYPE_IMX_SERIAL,
> -    .parent = TYPE_SYS_BUS_DEVICE,
> -    .instance_size = sizeof(IMXSerialState),
> -    .class_init = imx_serial_class_init,
> +    .name           = TYPE_IMX_SERIAL,
> +    .parent         = TYPE_SYS_BUS_DEVICE,
> +    .instance_size  = sizeof(IMXSerialState),
> +    .instance_init  = imx_serial_init,
> +    .class_init     = imx_serial_class_init,
>  };
>
>  static void imx_serial_register_types(void)
> diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h
> new file mode 100644
> index 0000000..dba0cbb
> --- /dev/null
> +++ b/include/hw/char/imx_serial.h
> @@ -0,0 +1,104 @@
> +/*
> + * Device model for i.MX UART
> + *
> + * Copyright (c) 2008 OKL
> + * Originally Written by Hans Jiang
> + * Copyright (c) 2011 NICTA Pty Ltd.
> + * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef IMX_SERIAL_H
> +#define IMX_SERIAL_H
> +
> +#include "hw/sysbus.h"
> +
> +#define TYPE_IMX_SERIAL "imx.serial"
> +#define IMX_SERIAL(obj) OBJECT_CHECK(IMXSerialState, (obj), TYPE_IMX_SERIAL)
> +
> +#define URXD_CHARRDY    (1<<15)   /* character read is valid */
> +#define URXD_ERR        (1<<14)   /* Character has error */
> +#define URXD_BRK        (1<<11)   /* Break received */
> +
> +#define USR1_PARTYER    (1<<15)   /* Parity Error */
> +#define USR1_RTSS       (1<<14)   /* RTS pin status */
> +#define USR1_TRDY       (1<<13)   /* Tx ready */
> +#define USR1_RTSD       (1<<12)   /* RTS delta: pin changed state */
> +#define USR1_ESCF       (1<<11)   /* Escape sequence interrupt */
> +#define USR1_FRAMERR    (1<<10)   /* Framing error  */
> +#define USR1_RRDY       (1<<9)    /* receiver ready */
> +#define USR1_AGTIM      (1<<8)    /* Aging timer interrupt */
> +#define USR1_DTRD       (1<<7)    /* DTR changed */
> +#define USR1_RXDS       (1<<6)    /* Receiver is idle */
> +#define USR1_AIRINT     (1<<5)    /* Aysnch IR interrupt */
> +#define USR1_AWAKE      (1<<4)    /* Falling edge detected on RXd pin */
> +
> +#define USR2_ADET       (1<<15)   /* Autobaud complete */
> +#define USR2_TXFE       (1<<14)   /* Transmit FIFO empty */
> +#define USR2_DTRF       (1<<13)   /* DTR/DSR transition */
> +#define USR2_IDLE       (1<<12)   /* UART has been idle for too long */
> +#define USR2_ACST       (1<<11)   /* Autobaud counter stopped */
> +#define USR2_RIDELT     (1<<10)   /* Ring Indicator delta */
> +#define USR2_RIIN       (1<<9)    /* Ring Indicator Input */
> +#define USR2_IRINT      (1<<8)    /* Serial Infrared Interrupt */
> +#define USR2_WAKE       (1<<7)    /* Start bit detected */
> +#define USR2_DCDDELT    (1<<6)    /* Data Carrier Detect delta */
> +#define USR2_DCDIN      (1<<5)    /* Data Carrier Detect Input */
> +#define USR2_RTSF       (1<<4)    /* RTS transition */
> +#define USR2_TXDC       (1<<3)    /* Transmission complete */
> +#define USR2_BRCD       (1<<2)    /* Break condition detected */
> +#define USR2_ORE        (1<<1)    /* Overrun error */
> +#define USR2_RDR        (1<<0)    /* Receive data ready */
> +
> +#define UCR1_TRDYEN     (1<<13)   /* Tx Ready Interrupt Enable */
> +#define UCR1_RRDYEN     (1<<9)    /* Rx Ready Interrupt Enable */
> +#define UCR1_TXMPTYEN   (1<<6)    /* Tx Empty Interrupt Enable */
> +#define UCR1_UARTEN     (1<<0)    /* UART Enable */
> +
> +#define UCR2_TXEN       (1<<2)    /* Transmitter enable */
> +#define UCR2_RXEN       (1<<1)    /* Receiver enable */
> +#define UCR2_SRST       (1<<0)    /* Reset complete */
> +
> +#define UTS1_TXEMPTY    (1<<6)
> +#define UTS1_RXEMPTY    (1<<5)
> +#define UTS1_TXFULL     (1<<4)
> +#define UTS1_RXFULL     (1<<3)
> +
> +typedef struct IMXSerialState {
> +    /* Private */
> +    SysBusDevice parent_obj;
> +
> +    /* Public */
> +    MemoryRegion iomem;
> +    int32_t readbuff;
> +
> +    uint32_t usr1;
> +    uint32_t usr2;
> +    uint32_t ucr1;
> +    uint32_t ucr2;
> +    uint32_t uts1;
> +
> +    /*
> +     * The registers below are implemented just so that the
> +     * guest OS sees what it has written
> +     */
> +    uint32_t onems;
> +    uint32_t ufcr;
> +    uint32_t ubmr;
> +    uint32_t ubrc;
> +    uint32_t ucr3;
> +
> +    qemu_irq irq;
> +    CharDriverState *chr;
> +} IMXSerialState;
> +
> +void imx_serial_create(int uart, const hwaddr addr, qemu_irq irq);
> +
> +#endif
> --
> 2.1.4
>
>

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

* Re: [Qemu-devel] [PATCH v8 02/11] i.MX: Split the i.MX AVIC emulator into a header file and a source file
  2015-06-29 20:11 ` [Qemu-devel] [PATCH v8 02/11] i.MX: Split the i.MX AVIC emulator " Jean-Christophe Dubois
@ 2015-06-30  7:05   ` Peter Crosthwaite
  0 siblings, 0 replies; 17+ messages in thread
From: Peter Crosthwaite @ 2015-06-30  7:05 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: qemu-devel@nongnu.org Developers

On Mon, Jun 29, 2015 at 1:11 PM, Jean-Christophe Dubois
<jcd@tribudubois.net> wrote:
> This is to prepare to accomodate the SOC requirements.
>

Same but only 2, one for style, one for headering.

Regards,
Peter

> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
> ---
>
> Changes since v1:
>     * not present on v1
>
> Changes since v2:
>     * not present on v2
>
> Changes since v3:
>     * not present on v3
>
> Changes since v4:
>     * not present on v4
>
> Changes since v5:
>     * not present on v5
>
> Changes since v6:
>     * not present on v6
>
> Changes since v7:
>     * Splited the i.MX AVIC emulator into a header file and a source file
>
>  hw/intc/imx_avic.c         | 56 +++++++++-------------------------------------
>  include/hw/intc/imx_avic.h | 56 ++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 66 insertions(+), 46 deletions(-)
>  create mode 100644 include/hw/intc/imx_avic.h
>
> diff --git a/hw/intc/imx_avic.c b/hw/intc/imx_avic.c
> index e48f66c..96c376b 100644
> --- a/hw/intc/imx_avic.c
> +++ b/hw/intc/imx_avic.c
> @@ -7,6 +7,7 @@
>   * Copyright (c) 2008 OKL
>   * Copyright (c) 2011 NICTA Pty Ltd
>   * Originally written by Hans Jiang
> + * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
>   *
>   * This code is licensed under the GPL version 2 or later.  See
>   * the COPYING file in the top-level directory.
> @@ -14,16 +15,14 @@
>   * TODO: implement vectors.
>   */
>
> -#include "hw/hw.h"
> -#include "hw/sysbus.h"
> -#include "qemu/host-utils.h"
> +#include "hw/intc/imx_avic.h"
>
>  #define DEBUG_INT 1
>  #undef DEBUG_INT /* comment out for debugging */
>
>  #ifdef DEBUG_INT
>  #define DPRINTF(fmt, args...) \
> -do { printf("imx_avic: " fmt , ##args); } while (0)
> +do { printf("%s: " fmt , TYPE_IMX_AVIC, ##args); } while (0)
>  #else
>  #define DPRINTF(fmt, args...) do {} while (0)
>  #endif
> @@ -35,46 +34,13 @@ do { printf("imx_avic: " fmt , ##args); } while (0)
>  #define DEBUG_IMPLEMENTATION 1
>  #if DEBUG_IMPLEMENTATION
>  #  define IPRINTF(fmt, args...) \
> -    do  { fprintf(stderr, "imx_avic: " fmt, ##args); } while (0)
> +    do  { fprintf(stderr, "%s: " fmt, TYPE_IMX_AVIC, ##args); } while (0)
>  #else
>  #  define IPRINTF(fmt, args...) do {} while (0)
>  #endif
>
> -#define IMX_AVIC_NUM_IRQS 64
> -
> -/* Interrupt Control Bits */
> -#define ABFLAG (1<<25)
> -#define ABFEN (1<<24)
> -#define NIDIS (1<<22) /* Normal Interrupt disable */
> -#define FIDIS (1<<21) /* Fast interrupt disable */
> -#define NIAD  (1<<20) /* Normal Interrupt Arbiter Rise ARM level */
> -#define FIAD  (1<<19) /* Fast Interrupt Arbiter Rise ARM level */
> -#define NM    (1<<18) /* Normal interrupt mode */
> -
> -
> -#define PRIO_PER_WORD (sizeof(uint32_t) * 8 / 4)
> -#define PRIO_WORDS (IMX_AVIC_NUM_IRQS/PRIO_PER_WORD)
> -
> -#define TYPE_IMX_AVIC "imx_avic"
> -#define IMX_AVIC(obj) \
> -    OBJECT_CHECK(IMXAVICState, (obj), TYPE_IMX_AVIC)
> -
> -typedef struct IMXAVICState {
> -    SysBusDevice parent_obj;
> -
> -    MemoryRegion iomem;
> -    uint64_t pending;
> -    uint64_t enabled;
> -    uint64_t is_fiq;
> -    uint32_t intcntl;
> -    uint32_t intmask;
> -    qemu_irq irq;
> -    qemu_irq fiq;
> -    uint32_t prio[PRIO_WORDS]; /* Priorities are 4-bits each */
> -} IMXAVICState;
> -
>  static const VMStateDescription vmstate_imx_avic = {
> -    .name = "imx-avic",
> +    .name = TYPE_IMX_AVIC,
>      .version_id = 1,
>      .minimum_version_id = 1,
>      .fields = (VMStateField[]) {
> @@ -88,8 +54,6 @@ static const VMStateDescription vmstate_imx_avic = {
>      },
>  };
>
> -
> -
>  static inline int imx_avic_prio(IMXAVICState *s, int irq)
>  {
>      uint32_t word = irq / PRIO_PER_WORD;
> @@ -249,7 +213,7 @@ static uint64_t imx_avic_read(void *opaque,
>          return 0x4;
>
>      default:
> -        IPRINTF("imx_avic_read: Bad offset 0x%x\n", (int)offset);
> +        IPRINTF("%s: Bad offset 0x%x\n", __func__, (int)offset);
>          return 0;
>      }
>  }
> @@ -261,12 +225,12 @@ static void imx_avic_write(void *opaque, hwaddr offset,
>
>      /* Vector Registers not yet supported */
>      if (offset >= 0x100 && offset <= 0x2fc) {
> -        IPRINTF("imx_avic_write to vector register %d ignored\n",
> +        IPRINTF("%s to vector register %d ignored\n", __func__,
>                  (unsigned int)((offset - 0x100) >> 2));
>          return;
>      }
>
> -    DPRINTF("imx_avic_write(0x%x) = %x\n",
> +    DPRINTF("%s(0x%x) = %x\n", __func__,
>              (unsigned int)offset>>2, (unsigned int)val);
>      switch (offset >> 2) {
>      case 0: /* Interrupt Control Register, INTCNTL */
> @@ -341,7 +305,7 @@ static void imx_avic_write(void *opaque, hwaddr offset,
>          return;
>
>      default:
> -        IPRINTF("imx_avic_write: Bad offset %x\n", (int)offset);
> +        IPRINTF("%s: Bad offset %x\n", __func__, (int)offset);
>      }
>      imx_avic_update(s);
>  }
> @@ -370,7 +334,7 @@ static int imx_avic_init(SysBusDevice *sbd)
>      IMXAVICState *s = IMX_AVIC(dev);
>
>      memory_region_init_io(&s->iomem, OBJECT(s), &imx_avic_ops, s,
> -                          "imx_avic", 0x1000);
> +                          TYPE_IMX_AVIC, 0x1000);
>      sysbus_init_mmio(sbd, &s->iomem);
>
>      qdev_init_gpio_in(dev, imx_avic_set_irq, IMX_AVIC_NUM_IRQS);
> diff --git a/include/hw/intc/imx_avic.h b/include/hw/intc/imx_avic.h
> new file mode 100644
> index 0000000..1645ba6
> --- /dev/null
> +++ b/include/hw/intc/imx_avic.h
> @@ -0,0 +1,56 @@
> +/*
> + * i.MX31 Vectored Interrupt Controller
> + *
> + * Note this is NOT the PL192 provided by ARM, but
> + * a custom implementation by Freescale.
> + *
> + * Copyright (c) 2008 OKL
> + * Copyright (c) 2011 NICTA Pty Ltd
> + * Originally written by Hans Jiang
> + * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
> + *
> + * This code is licensed under the GPL version 2 or later.  See
> + * the COPYING file in the top-level directory.
> + *
> + * TODO: implement vectors.
> + */
> +#ifndef IMX_AVIC_H
> +#define IMX_AVIC_H
> +
> +#include "hw/sysbus.h"
> +
> +#define TYPE_IMX_AVIC "imx.avic"
> +#define IMX_AVIC(obj) OBJECT_CHECK(IMXAVICState, (obj), TYPE_IMX_AVIC)
> +
> +#define IMX_AVIC_NUM_IRQS 64
> +
> +/* Interrupt Control Bits */
> +#define ABFLAG (1<<25)
> +#define ABFEN (1<<24)
> +#define NIDIS (1<<22) /* Normal Interrupt disable */
> +#define FIDIS (1<<21) /* Fast interrupt disable */
> +#define NIAD  (1<<20) /* Normal Interrupt Arbiter Rise ARM level */
> +#define FIAD  (1<<19) /* Fast Interrupt Arbiter Rise ARM level */
> +#define NM    (1<<18) /* Normal interrupt mode */
> +
> +
> +#define PRIO_PER_WORD (sizeof(uint32_t) * 8 / 4)
> +#define PRIO_WORDS (IMX_AVIC_NUM_IRQS/PRIO_PER_WORD)
> +
> +typedef struct {
> +    /*< private >*/
> +    SysBusDevice parent_obj;
> +
> +    /*< public >*/
> +    MemoryRegion iomem;
> +    uint64_t pending;
> +    uint64_t enabled;
> +    uint64_t is_fiq;
> +    uint32_t intcntl;
> +    uint32_t intmask;
> +    qemu_irq irq;
> +    qemu_irq fiq;
> +    uint32_t prio[PRIO_WORDS]; /* Priorities are 4-bits each */
> +} IMXAVICState;
> +
> +#endif // IMX_AVIC_H
> --
> 2.1.4
>
>

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

* Re: [Qemu-devel] [PATCH v8 04/11] i.MX: Split the i.MX EPIT emulator into a header file and a source file.
  2015-06-29 20:11 ` [Qemu-devel] [PATCH v8 04/11] i.MX: Split the i.MX EPIT " Jean-Christophe Dubois
@ 2015-06-30  7:12   ` Peter Crosthwaite
  0 siblings, 0 replies; 17+ messages in thread
From: Peter Crosthwaite @ 2015-06-30  7:12 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: qemu-devel@nongnu.org Developers

On Mon, Jun 29, 2015 at 1:11 PM, Jean-Christophe Dubois
<jcd@tribudubois.net> wrote:
> This is to prepare to accomodate the SOC requirements.
>
> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
> ---
>
> Changes since v1:
>     * not present on v1
>
> Changes since v2:
>     * not present on v2
>
> Changes since v3:
>     * not present on v3
>
> Changes since v4:
>     * not present on v4
>
> Changes since v5:
>     * not present on v5
>
> Changes since v6:
>     * not present on v6
>
> Changes since v7:
>     * Splited the i.MX EPIT emulator into a header file and a source file
>
>  hw/timer/imx_epit.c         | 65 +++++------------------------------
>  include/hw/timer/imx_epit.h | 83 +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 92 insertions(+), 56 deletions(-)
>  create mode 100644 include/hw/timer/imx_epit.h
>
> diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
> index ffefc22..39fc3f1 100644
> --- a/hw/timer/imx_epit.c
> +++ b/hw/timer/imx_epit.c
> @@ -5,23 +5,17 @@
>   * Copyright (c) 2011 NICTA Pty Ltd
>   * Originally written by Hans Jiang
>   * Updated by Peter Chubb
> - * Updated by Jean-Christophe Dubois
> + * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
>   *
>   * This code is licensed under GPL version 2 or later.  See
>   * the COPYING file in the top-level directory.
>   *
>   */
>
> -#include "hw/hw.h"
> -#include "qemu/bitops.h"
> -#include "qemu/timer.h"
> -#include "hw/ptimer.h"
> -#include "hw/sysbus.h"
> -#include "hw/arm/imx.h"
> +#include "hw/timer/imx_epit.h"
> +#include "hw/misc/imx_ccm.h"
>  #include "qemu/main-loop.h"
>
> -#define TYPE_IMX_EPIT "imx.epit"
> -
>  #define DEBUG_TIMER 0
>  #if DEBUG_TIMER
>
> @@ -61,30 +55,6 @@ static char const *imx_epit_reg_name(uint32_t reg)
>  #  define IPRINTF(fmt, args...) do {} while (0)
>  #endif
>
> -#define IMX_EPIT(obj) \
> -        OBJECT_CHECK(IMXEPITState, (obj), TYPE_IMX_EPIT)
> -
> -/*
> - * EPIT: Enhanced periodic interrupt timer
> - */
> -
> -#define CR_EN       (1 << 0)
> -#define CR_ENMOD    (1 << 1)
> -#define CR_OCIEN    (1 << 2)
> -#define CR_RLD      (1 << 3)
> -#define CR_PRESCALE_SHIFT (4)
> -#define CR_PRESCALE_MASK  (0xfff)
> -#define CR_SWR      (1 << 16)
> -#define CR_IOVW     (1 << 17)
> -#define CR_DBGEN    (1 << 18)
> -#define CR_WAITEN   (1 << 19)
> -#define CR_DOZEN    (1 << 20)
> -#define CR_STOPEN   (1 << 21)
> -#define CR_CLKSRC_SHIFT (24)
> -#define CR_CLKSRC_MASK  (0x3 << CR_CLKSRC_SHIFT)
> -
> -#define EPIT_TIMER_MAX  0XFFFFFFFFUL
> -
>  /*
>   * Exact clock frequencies vary from board to board.
>   * These are typical.
> @@ -96,23 +66,6 @@ static const IMXClk imx_epit_clocks[] =  {
>      CLK_32k,  /* 11 ipg_clk_32k -- ~32kHz */
>  };
>
> -typedef struct {
> -    SysBusDevice busdev;
> -    ptimer_state *timer_reload;
> -    ptimer_state *timer_cmp;
> -    MemoryRegion iomem;
> -    DeviceState *ccm;
> -
> -    uint32_t cr;
> -    uint32_t sr;
> -    uint32_t lr;
> -    uint32_t cmp;
> -    uint32_t cnt;
> -
> -    uint32_t freq;
> -    qemu_irq irq;
> -} IMXEPITState;
> -
>  /*
>   * Update interrupt status
>   */
> @@ -174,9 +127,9 @@ static void imx_epit_reset(DeviceState *dev)
>
>  static uint32_t imx_epit_update_count(IMXEPITState *s)
>  {
> -     s->cnt = ptimer_get_count(s->timer_reload);
> +    s->cnt = ptimer_get_count(s->timer_reload);
>
> -     return s->cnt;
> +    return s->cnt;
>  }
>
>  static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
> @@ -344,13 +297,13 @@ void imx_timerp_create(const hwaddr addr, qemu_irq irq, DeviceState *ccm)
>  }
>
>  static const MemoryRegionOps imx_epit_ops = {
> -  .read = imx_epit_read,
> -  .write = imx_epit_write,
> -  .endianness = DEVICE_NATIVE_ENDIAN,
> +    .read = imx_epit_read,
> +    .write = imx_epit_write,
> +    .endianness = DEVICE_NATIVE_ENDIAN,
>  };
>
>  static const VMStateDescription vmstate_imx_timer_epit = {
> -    .name = "imx.epit",
> +    .name = TYPE_IMX_EPIT,
>      .version_id = 2,
>      .minimum_version_id = 2,
>      .fields = (VMStateField[]) {
> diff --git a/include/hw/timer/imx_epit.h b/include/hw/timer/imx_epit.h
> new file mode 100644
> index 0000000..dbc99ca
> --- /dev/null
> +++ b/include/hw/timer/imx_epit.h
> @@ -0,0 +1,83 @@
> +/*
> + * i.MX EPIT Timer
> + *
> + * Copyright (c) 2008 OK Labs
> + * Copyright (c) 2011 NICTA Pty Ltd
> + * Originally written by Hans Jiang
> + * Updated by Peter Chubb
> + * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
> + *
> + * 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 IMX_EPIT_H
> +#define IMX_EPIT_H
> +
> +#include "hw/sysbus.h"
> +#include "hw/ptimer.h"
> +
> +/*
> + * EPIT: Enhanced periodic interrupt timer
> + */
> +
> +#define CR_EN       (1 << 0)
> +#define CR_ENMOD    (1 << 1)
> +#define CR_OCIEN    (1 << 2)
> +#define CR_RLD      (1 << 3)
> +#define CR_PRESCALE_SHIFT (4)
> +#define CR_PRESCALE_MASK  (0xfff)
> +#define CR_SWR      (1 << 16)
> +#define CR_IOVW     (1 << 17)
> +#define CR_DBGEN    (1 << 18)
> +#define CR_WAITEN   (1 << 19)
> +#define CR_DOZEN    (1 << 20)
> +#define CR_STOPEN   (1 << 21)
> +#define CR_CLKSRC_SHIFT (24)
> +#define CR_CLKSRC_MASK  (0x3 << CR_CLKSRC_SHIFT)
> +
> +#define EPIT_TIMER_MAX  0XFFFFFFFFUL
> +
> +#define TYPE_IMX_EPIT "imx.epit"
> +#define IMX_EPIT(obj) OBJECT_CHECK(IMXEPITState, (obj), TYPE_IMX_EPIT)
> +
> +typedef struct {
> +    /* <private> */
> +    SysBusDevice parent_obj;
> +
> +    /* <public> */
> +    ptimer_state *timer_reload;
> +    ptimer_state *timer_cmp;
> +    MemoryRegion iomem;
> +    DeviceState *ccm;
> +
> +    uint32_t cr;
> +    uint32_t sr;
> +    uint32_t lr;
> +    uint32_t cmp;
> +    uint32_t cnt;
> +
> +    uint32_t freq;
> +    qemu_irq irq;
> +} IMXEPITState;
> +
> +void imx_timerp_create(const hwaddr addr,
> +                       qemu_irq irq,
> +                       DeviceState *ccm);
> +

Qdev construction helpers are depracated in favor of just inlining the
qdev_creation process in the machine model. Since this is pre-existing
though, I would just leave it in imx.h.

Regards,
Peter

> +#endif /* IMX_EPIT_H */
> --
> 2.1.4
>
>

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

* Re: [Qemu-devel] [PATCH v8 06/11] kzm: Use modified i.MX emulators.
  2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 06/11] kzm: Use modified i.MX emulators Jean-Christophe Dubois
@ 2015-06-30  7:12   ` Peter Crosthwaite
  0 siblings, 0 replies; 17+ messages in thread
From: Peter Crosthwaite @ 2015-06-30  7:12 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: qemu-devel@nongnu.org Developers

On Mon, Jun 29, 2015 at 1:12 PM, Jean-Christophe Dubois
<jcd@tribudubois.net> wrote:
> Use modified AVIC, CCM, UART, GPT, EPIT emultors.
>

"emulators"

> Tested by booting Linux one KZM emulator.
>

"on"?

> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
> ---
>
> Changes since v1:
>     * not present on v1
>
> Changes since v2:
>     * not present on v2
>
> Changes since v3:
>     * not present on v3
>
> Changes since v4:
>     * not present on v4
>
> Changes since v5:
>     * not present on v5
>
> Changes since v6:
>     * not present on v6
>
> Changes since v7:
>     * update KZM target to use new emulators
>
>  hw/arm/kzm.c         | 86 +++++++++++++++++++++++++++-------------------------
>  include/hw/arm/imx.h | 34 ---------------------
>  2 files changed, 45 insertions(+), 75 deletions(-)
>  delete mode 100644 include/hw/arm/imx.h
>
> diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
> index 5be0369..485e745 100644
> --- a/hw/arm/kzm.c
> +++ b/hw/arm/kzm.c
> @@ -22,45 +22,49 @@
>  #include "sysemu/sysemu.h"
>  #include "hw/boards.h"
>  #include "hw/char/serial.h"
> -#include "hw/arm/imx.h"
> -
> -    /* Memory map for Kzm Emulation Baseboard:
> -     * 0x00000000-0x00003fff 16k secure ROM       IGNORED
> -     * 0x00004000-0x00407fff Reserved             IGNORED
> -     * 0x00404000-0x00407fff ROM                  IGNORED
> -     * 0x00408000-0x0fffffff Reserved             IGNORED
> -     * 0x10000000-0x1fffbfff RAM aliasing         IGNORED
> -     * 0x1fffc000-0x1fffffff RAM                  EMULATED
> -     * 0x20000000-0x2fffffff Reserved             IGNORED
> -     * 0x30000000-0x7fffffff I.MX31 Internal Register Space
> -     *   0x43f00000 IO_AREA0
> -     *   0x43f90000 UART1                         EMULATED
> -     *   0x43f94000 UART2                         EMULATED
> -     *   0x68000000 AVIC                          EMULATED
> -     *   0x53f80000 CCM                           EMULATED
> -     *   0x53f94000 PIT 1                         EMULATED
> -     *   0x53f98000 PIT 2                         EMULATED
> -     *   0x53f90000 GPT                           EMULATED
> -     * 0x80000000-0x87ffffff RAM                  EMULATED
> -     * 0x88000000-0x8fffffff RAM Aliasing         EMULATED
> -     * 0xa0000000-0xafffffff NAND Flash           IGNORED
> -     * 0xb0000000-0xb3ffffff Unavailable          IGNORED
> -     * 0xb4000000-0xb4000fff 8-bit free space     IGNORED
> -     * 0xb4001000-0xb400100f Board control        IGNORED
> -     *  0xb4001003           DIP switch
> -     * 0xb4001010-0xb400101f 7-segment LED        IGNORED
> -     * 0xb4001020-0xb400102f LED                  IGNORED
> -     * 0xb4001030-0xb400103f LED                  IGNORED
> -     * 0xb4001040-0xb400104f FPGA, UART           EMULATED
> -     * 0xb4001050-0xb400105f FPGA, UART           EMULATED
> -     * 0xb4001060-0xb40fffff FPGA                 IGNORED
> -     * 0xb6000000-0xb61fffff LAN controller       EMULATED
> -     * 0xb6200000-0xb62fffff FPGA NAND Controller IGNORED
> -     * 0xb6300000-0xb7ffffff Free                 IGNORED
> -     * 0xb8000000-0xb8004fff Memory control registers IGNORED
> -     * 0xc0000000-0xc3ffffff PCMCIA/CF            IGNORED
> -     * 0xc4000000-0xffffffff Reserved             IGNORED
> -     */
> +#include "hw/misc/imx_ccm.h"
> +#include "hw/intc/imx_avic.h"
> +#include "hw/timer/imx_epit.h"
> +#include "hw/timer/imx_gpt.h"
> +#include "hw/char/imx_serial.h"
> +
> +/* Memory map for Kzm Emulation Baseboard:
> + * 0x00000000-0x00003fff 16k secure ROM       IGNORED
> + * 0x00004000-0x00407fff Reserved             IGNORED
> + * 0x00404000-0x00407fff ROM                  IGNORED
> + * 0x00408000-0x0fffffff Reserved             IGNORED
> + * 0x10000000-0x1fffbfff RAM aliasing         IGNORED
> + * 0x1fffc000-0x1fffffff RAM                  EMULATED
> + * 0x20000000-0x2fffffff Reserved             IGNORED
> + * 0x30000000-0x7fffffff I.MX31 Internal Register Space
> + *   0x43f00000 IO_AREA0
> + *   0x43f90000 UART1                         EMULATED
> + *   0x43f94000 UART2                         EMULATED
> + *   0x68000000 AVIC                          EMULATED
> + *   0x53f80000 CCM                           EMULATED
> + *   0x53f94000 PIT 1                         EMULATED
> + *   0x53f98000 PIT 2                         EMULATED
> + *   0x53f90000 GPT                           EMULATED
> + * 0x80000000-0x87ffffff RAM                  EMULATED
> + * 0x88000000-0x8fffffff RAM Aliasing         EMULATED
> + * 0xa0000000-0xafffffff NAND Flash           IGNORED
> + * 0xb0000000-0xb3ffffff Unavailable          IGNORED
> + * 0xb4000000-0xb4000fff 8-bit free space     IGNORED
> + * 0xb4001000-0xb400100f Board control        IGNORED
> + *  0xb4001003           DIP switch
> + * 0xb4001010-0xb400101f 7-segment LED        IGNORED
> + * 0xb4001020-0xb400102f LED                  IGNORED
> + * 0xb4001030-0xb400103f LED                  IGNORED
> + * 0xb4001040-0xb400104f FPGA, UART           EMULATED
> + * 0xb4001050-0xb400105f FPGA, UART           EMULATED
> + * 0xb4001060-0xb40fffff FPGA                 IGNORED
> + * 0xb6000000-0xb61fffff LAN controller       EMULATED
> + * 0xb6200000-0xb62fffff FPGA NAND Controller IGNORED
> + * 0xb6300000-0xb7ffffff Free                 IGNORED
> + * 0xb8000000-0xb8004fff Memory control registers IGNORED
> + * 0xc0000000-0xc3ffffff PCMCIA/CF            IGNORED
> + * 0xc4000000-0xffffffff Reserved             IGNORED
> + */
>

Split off style sweep, although this one may be not worth it. Out of
scope style changes do reduce the utility of git-blame so unless they
are local to, or prepare for a functional change they are discouraged.

Regards,
Peter

>  #define KZM_RAMADDRESS (0x80000000)
>  #define KZM_FPGA       (0xb4001040)
> @@ -106,7 +110,7 @@ static void kzm_init(MachineState *machine)
>      memory_region_init_ram(sram, NULL, "kzm.sram", 0x4000, &error_abort);
>      memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
>
> -    dev = sysbus_create_varargs("imx_avic", 0x68000000,
> +    dev = sysbus_create_varargs(TYPE_IMX_AVIC, 0x68000000,
>                                  qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
>                                  qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
>                                  NULL);
> @@ -114,7 +118,7 @@ static void kzm_init(MachineState *machine)
>      imx_serial_create(0, 0x43f90000, qdev_get_gpio_in(dev, 45));
>      imx_serial_create(1, 0x43f94000, qdev_get_gpio_in(dev, 32));
>
> -    ccm = sysbus_create_simple("imx_ccm", 0x53f80000, NULL);
> +    ccm = sysbus_create_simple(TYPE_IMX_CCM, 0x53f80000, NULL);
>
>      imx_timerp_create(0x53f94000, qdev_get_gpio_in(dev, 28), ccm);
>      imx_timerp_create(0x53f98000, qdev_get_gpio_in(dev, 27), ccm);
> diff --git a/include/hw/arm/imx.h b/include/hw/arm/imx.h
> deleted file mode 100644
> index ea9e093..0000000
> --- a/include/hw/arm/imx.h
> +++ /dev/null
> @@ -1,34 +0,0 @@
> -/*
> - * i.MX31 emulation
> - *
> - * Copyright (C) 2012 Peter Chubb
> - * NICTA
> - *
> - * This code is released under the GPL, version 2.0 or later
> - * See the file `../COPYING' for details.
> - */
> -
> -#ifndef IMX_H
> -#define IMX_H
> -
> -void imx_serial_create(int uart, const hwaddr addr, qemu_irq irq);
> -
> -typedef enum  {
> -    NOCLK,
> -    MCU,
> -    HSP,
> -    IPG,
> -    CLK_32k
> -} IMXClk;
> -
> -uint32_t imx_clock_frequency(DeviceState *s, IMXClk clock);
> -
> -void imx_timerp_create(const hwaddr addr,
> -                      qemu_irq irq,
> -                      DeviceState *ccm);
> -void imx_timerg_create(const hwaddr addr,
> -                      qemu_irq irq,
> -                      DeviceState *ccm);
> -
> -
> -#endif /* IMX_H */
> --
> 2.1.4
>
>

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

* Re: [Qemu-devel] [PATCH v8 09/11] i.MX25: Add the i.MX25 SOC support
  2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 09/11] i.MX25: Add the i.MX25 SOC support Jean-Christophe Dubois
@ 2015-06-30  7:29   ` Peter Crosthwaite
  0 siblings, 0 replies; 17+ messages in thread
From: Peter Crosthwaite @ 2015-06-30  7:29 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: qemu-devel@nongnu.org Developers

On Mon, Jun 29, 2015 at 1:12 PM, Jean-Christophe Dubois
<jcd@tribudubois.net> wrote:
> For now we do support the foolowing devices:
>   * GPT timers (from i.MX31)
>   * EPIT timers (from i.MX31)
>   * CCM (from i.MX31)
>   * AVIC (from i.MX31)
>   * UART (from i.MX31)
>   * Ethernet FEC port
>   * I2C controller
>
> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
> ---
>
> Changes since v1:
>     * not present on v1
>
> Changes since v2:
>     * not present on v2
>
> Changes since v3:
>     * not present on v3
>
> Changes since v4:
>     * not present on v4
>
> Changes since v5:
>     * not present on v5
>
> Changes since v6:
>     * not present on v6
>
> Changes since v7:
>     * Added a SOC specific file for i.MX25
>
>  default-configs/arm-softmmu.mak |   1 +
>  hw/arm/Makefile.objs            |   1 +
>  hw/arm/fsl-imx25.c              | 304 ++++++++++++++++++++++++++++++++++++++++
>  include/hw/arm/fsl-imx25.h      |  52 +++++++
>  4 files changed, 358 insertions(+)
>  create mode 100644 hw/arm/fsl-imx25.c
>  create mode 100644 include/hw/arm/fsl-imx25.h
>
> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
> index c6f509d..057f39c 100644
> --- a/default-configs/arm-softmmu.mak
> +++ b/default-configs/arm-softmmu.mak
> @@ -99,6 +99,7 @@ CONFIG_ALLWINNER_A10_PIT=y
>  CONFIG_ALLWINNER_A10_PIC=y
>  CONFIG_ALLWINNER_A10=y
>
> +CONFIG_FSL_IMX25=y
>  CONFIG_IMX_I2C=y
>
>  CONFIG_XIO3130=y
> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
> index cf346c1..b89c31d 100644
> --- a/hw/arm/Makefile.objs
> +++ b/hw/arm/Makefile.objs
> @@ -13,3 +13,4 @@ obj-y += omap1.o omap2.o strongarm.o
>  obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o
>  obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
>  obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
> +obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o
> diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
> new file mode 100644
> index 0000000..b2db548
> --- /dev/null
> +++ b/hw/arm/fsl-imx25.c
> @@ -0,0 +1,304 @@
> +/*
> + * Copyright (c) 2013 Jean-Christophe Dubois <jcd@tribudubois.net>
> + *
> + * i.MX25 SOC emulation.
> + *
> + * Based on hw/arm/xlnx-zynqmp.c
> + *
> + * Copyright (C) 2015 Xilinx Inc
> + * Written by Peter Crosthwaite <peter.crosthwaite@xilinx.com>
> + *

You probably don't need this if you are just borrowing template.

> + *  This program is free software; you can redistribute it and/or modify it
> + *  under the terms of the GNU General Public License as published by the
> + *  Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful, but WITHOUT
> + *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
> + *  for more details.
> + *
> + *  You should have received a copy of the GNU General Public License along
> + *  with this program; if not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "hw/arm/fsl-imx25.h"
> +#include "sysemu/sysemu.h"
> +
> +/* Memory map for 3D-Stack Emulation Baseboard:
> + * 0x00000000-0x00003fff 16k ROM              IGNORED
> + * 0x00004000-0x00403fff Reserved             IGNORED
> + * 0x00404000-0x00408fff 20k ROM              IGNORED
> + * 0x00409000-0x0fffffff Reserved             IGNORED
> + * 0x10000000-0x1fffffff Reserved             IGNORED
> + * 0x20000000-0x2fffffff Reserved             IGNORED
> + * 0x30000000-0x3fffffff Reserved             IGNORED
> + * 0x40000000-0x43efffff Reserved             IGNORED
> + * 0x43f00000-0x6fffffff I.MX25 Internal Register Space
> + *   0x43f00000 IO_AREA0
> + *   0x43f80000 I2C0                          EMULATED
> + *   0x43f84000 I2C2                          EMULATED
> + *   0x43f98000 I2C1                          EMULATED
> + *   0x43f90000 UART1                         EMULATED
> + *   0x43f94000 UART2                         EMULATED
> + *   0x43fb0000 UART4                         IGNORED
> + *   0x43fb4000 UART5                         IGNORED
> + *   0x5000c000 UART3                         EMULATED
> + *   0x50038000 FEC                           EMULATED
> + *   0x53f80000 CCM                           EMULATED
> + *   0x53f84000 GPT 4                         EMULATED

So the ones thare are use by the code should just be #defines. This
eliminates repetition of the literal constants in the mmio mappings..

#define GPT_4_ADDR    0x53f83000 /* EMULATED */

For consistency I would just convert the whole table, even the ignored devs.

> + *   0x53f88000 GPT 3                         EMULATED
> + *   0x53f8c000 GPT 2                         EMULATED
> + *   0x53f90000 GPT 1                         EMULATED
> + *   0x53f94000 PIT 1                         EMULATED
> + *   0x53f98000 PIT 2                         EMULATED
> + *   0x53f9c000 GPIO-4                        EMULATED
> + *   0x53fa4000 GPIO-3                        EMULATED
> + *   0x53fcc000 GPIO-1                        EMULATED
> + *   0x53fd0000 GPIO-2                        EMULATED
> + *   0x68000000 ASIC                          EMULATED
> + * 0x78000000-0x7801ffff SRAM                 EMULATED
> + * 0x78020000-0x7fffffff SRAM Aliasing        EMULATED
> + * 0x80000000-0x87ffffff RAM + Alias          EMULATED
> + * 0x90000000-0x9fffffff RAM + Alias          EMULATED
> + * 0xa0000000-0xa7ffffff Flash                IGNORED
> + * 0xa8000000-0xafffffff Flash                IGNORED
> + * 0xb0000000-0xb1ffffff SRAM                 IGNORED
> + * 0xb2000000-0xb3ffffff SRAM                 IGNORED
> + * 0xb4000000-0xb5ffffff CS4                  IGNORED
> + * 0xb6000000-0xb8000fff Reserved             IGNORED
> + * 0xb8001000-0xb8001fff SDRAM CTRL reg       IGNORED
> + * 0xb8002000-0xb8002fff WEIM CTRL reg        IGNORED
> + * 0xb8003000-0xb8003fff M3IF CTRL reg        IGNORED
> + * 0xb8004000-0xb8004fff EMI CTRL reg         IGNORED
> + * 0xb8005000-0xbaffffff Reserved             IGNORED
> + * 0xbb000000-0xbb000fff NAND flash area buf  IGNORED
> + * 0xbb001000-0xbb0011ff NAND flash reserved  IGNORED
> + * 0xbb001200-0xbb001dff Reserved             IGNORED
> + * 0xbb001e00-0xbb001fff NAN flash CTRL reg   IGNORED
> + * 0xbb012000-0xbfffffff Reserved             IGNORED
> + * 0xc0000000-0xffffffff Reserved             IGNORED
> + */
> +
> +static void fsl_imx25_init(Object *obj)
> +{
> +    FslImx25State *s = FSL_IMX25(obj);
> +    int i;
> +
> +    object_initialize(&s->cpu, sizeof(s->cpu), "arm926-" TYPE_ARM_CPU);
> +
> +    object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
> +    qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());
> +
> +    object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX_CCM);
> +    qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
> +
> +    for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
> +        if (i >= MAX_SERIAL_PORTS) {
> +            break;
> +        }
> +        object_initialize(&s->uart[i], sizeof(s->uart[i]), TYPE_IMX_SERIAL);
> +        qdev_set_parent_bus(DEVICE(&s->uart[i]), sysbus_get_default());
> +    }
> +
> +    for (i = 0; i < FSL_IMX25_NUM_GPTS; i++) {
> +        object_initialize(&s->gpt[i], sizeof(s->gpt[i]), TYPE_IMX_GPT);
> +        qdev_set_parent_bus(DEVICE(&s->gpt[i]), sysbus_get_default());
> +    }
> +
> +    for (i = 0; i < FSL_IMX25_NUM_EPITS; i++) {
> +        object_initialize(&s->epit[i], sizeof(s->epit[i]), TYPE_IMX_EPIT);
> +        qdev_set_parent_bus(DEVICE(&s->epit[i]), sysbus_get_default());
> +    }
> +
> +    object_initialize(&s->fec, sizeof(s->fec), TYPE_IMX_FEC);
> +    qdev_set_parent_bus(DEVICE(&s->fec), sysbus_get_default());
> +
> +    for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) {
> +        object_initialize(&s->i2c[i], sizeof(s->i2c[i]), TYPE_IMX_I2C);
> +        qdev_set_parent_bus(DEVICE(&s->i2c[i]), sysbus_get_default());
> +    }
> +}
> +
> +static void fsl_imx25_realize(DeviceState *dev, Error **errp)
> +{
> +    FslImx25State *s = FSL_IMX25(dev);
> +    //MemoryRegion *system_memory = get_system_memory();

Remove commented code. (does checkpatch catch this due to CPP comment?)

> +    uint8_t i;
> +    Error *err = NULL;
> +
> +    /* Initialize the CPU */

Code is self documentating, you can drop these. I would drop most of
them except in cases where the code is irrugular, unusual or tricky in
some way.

> +    object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
> +    if (err) {
> +        error_propagate((errp), (err));
> +        return;
> +    }
> +
> +    /* Initialize the PIC */
> +    object_property_set_bool(OBJECT(&s->avic), true, "realized", &err);
> +    if (err) {
> +        error_propagate((errp), (err));
> +        return;
> +    }
> +    /* Connect the PIC interrupt to the CPU */

This comment ...

> +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->avic), 0, 0x68000000);

Should go here.

> +    sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 0,
> +                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
> +    sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 1,
> +                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));
> +
> +    /* Initialize the CCM */
> +    object_property_set_bool(OBJECT(&s->ccm), true, "realized", &err);
> +    if (err) {
> +        error_propagate((errp), (err));
> +        return;
> +    }
> +    /* Map CCM memory */
> +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, 0x53f80000);
> +

Constants can be replaced with the macro defs.

> +    /* Initialize all UARTS */
> +    for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
> +        static const struct {
> +            hwaddr addr;
> +            unsigned int irq;
> +        } serial_table[FSL_IMX25_NUM_UARTS] = {
> +            { 0x43f90000, 45 },
> +            { 0x43f94000, 32 },
> +            { 0x5000c000, 18 },
> +            { 0x50008000, 5  },
> +            { 0x5002c000, 40 }

And the same.

Alternatively, zynqmp defines these tables up top of the files as
static const. This is to avoid the need for a memory map comment. You
could do the same, pulling these tables up top to replace relevant
sections of the comment.

> +        };
> +
> +        /* Bail out if we exeeded Qemu UART count */

"exceeded" "QEMU"

Regards,
Peter

> +        if (i >= MAX_SERIAL_PORTS) {
> +            break;
> +        }

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

end of thread, other threads:[~2015-06-30  7:29 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-06-29 20:11 [Qemu-devel] [PATCH v8 00/11] i.MX: Add i.MX25 support through the 3DS evaluation board Jean-Christophe Dubois
2015-06-29 20:11 ` [Qemu-devel] [PATCH v8 01/11] i.MX: Split the i.MX serial driver into a header file and a source file Jean-Christophe Dubois
2015-06-30  7:04   ` Peter Crosthwaite
2015-06-29 20:11 ` [Qemu-devel] [PATCH v8 02/11] i.MX: Split the i.MX AVIC emulator " Jean-Christophe Dubois
2015-06-30  7:05   ` Peter Crosthwaite
2015-06-29 20:11 ` [Qemu-devel] [PATCH v8 03/11] i.MX: Split the i.MX CCM " Jean-Christophe Dubois
2015-06-29 20:11 ` [Qemu-devel] [PATCH v8 04/11] i.MX: Split the i.MX EPIT " Jean-Christophe Dubois
2015-06-30  7:12   ` Peter Crosthwaite
2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 05/11] i.MX: Split the i.MX GPT " Jean-Christophe Dubois
2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 06/11] kzm: Use modified i.MX emulators Jean-Christophe Dubois
2015-06-30  7:12   ` Peter Crosthwaite
2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 07/11] i.MX: Add FEC Ethernet Emulator Jean-Christophe Dubois
2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 08/11] i.MX: Add I2C controller emulator Jean-Christophe Dubois
2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 09/11] i.MX25: Add the i.MX25 SOC support Jean-Christophe Dubois
2015-06-30  7:29   ` Peter Crosthwaite
2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 10/11] i.MX25: Add support for the i.MX25 PDK 3DS Jean-Christophe Dubois
2015-06-29 20:12 ` [Qemu-devel] [PATCH v8 11/11] i.MX: Add qtest support for I2C device emulator Jean-Christophe Dubois

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).