All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board
@ 2015-07-16 21:21 Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 01/19] i.MX: Split UART emulator in a header file and a source file Jean-Christophe Dubois
                   ` (20 more replies)
  0 siblings, 21 replies; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 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 PDK evaluation board.

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

In the process the KZM platform was split into an i.MX31 SOC
and a plateform part.

Also, I2C devices was added to the i.MX31 SOC.

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

Jean-Christophe Dubois (19):
  i.MX: Split UART emulator in a header file and a source file
  i.MX: Move serial initialization to init/realize of DeviceClass.
  i.MX:Fix Coding style for UART emulator.
  i.MX: Split AVIC emulator in a header file and a source file
  i.MX: Fix Coding style for AVIC emulator.
  i.MX: Split CCM emulator in a header file and a source file
  i.MX: Fix Coding style for CCM emulator
  i.MX: Split EPIT emulator in a header file and a source file
  i.MX: Fix Coding style for EPIT emulator
  i.MX: Split GPT emulator in a header file and a source file
  i.MX: Fix Coding style for GPT emulator
  i.MX: Add SOC support for i.MX31
  i.MX: KZM now uses the standalone i.MX31 SOC support
  i.MX: Add I2C controller emulator
  i.MX: Add FEC Ethernet Emulator
  i.MX: Add SOC support for i.MX25
  i.MX: Add the i.MX25 PDK plateform
  i.MX: Add qtest support for I2C device emulator.
  i.MX: Adding i2C devices to i.MX31 SOC

 default-configs/arm-softmmu.mak |   6 +
 hw/arm/Makefile.objs            |   4 +-
 hw/arm/fsl-imx25.c              | 260 +++++++++++++++
 hw/arm/fsl-imx31.c              | 233 +++++++++++++
 hw/arm/imx25_pdk.c              | 162 +++++++++
 hw/arm/kzm.c                    | 205 ++++++------
 hw/char/imx_serial.c            | 180 ++--------
 hw/i2c/Makefile.objs            |   1 +
 hw/i2c/imx_i2c.c                | 339 +++++++++++++++++++
 hw/intc/imx_avic.c              |  56 +---
 hw/misc/imx_ccm.c               |  81 +----
 hw/net/Makefile.objs            |   1 +
 hw/net/imx_fec.c                | 709 ++++++++++++++++++++++++++++++++++++++++
 hw/timer/imx_epit.c             |  75 +----
 hw/timer/imx_gpt.c              |  96 +-----
 include/hw/arm/fsl-imx25.h      | 234 +++++++++++++
 include/hw/arm/fsl-imx31.h      | 110 +++++++
 include/hw/arm/imx.h            |  34 --
 include/hw/char/imx_serial.h    | 102 ++++++
 include/hw/i2c/imx_i2c.h        |  85 +++++
 include/hw/intc/imx_avic.h      |  55 ++++
 include/hw/misc/imx_ccm.h       |  91 ++++++
 include/hw/net/imx_fec.h        | 113 +++++++
 include/hw/timer/imx_epit.h     |  79 +++++
 include/hw/timer/imx_gpt.h      | 107 ++++++
 tests/Makefile                  |   3 +
 tests/ds1338-test.c             |  75 +++++
 tests/libqos/i2c-imx.c          | 209 ++++++++++++
 tests/libqos/i2c.h              |   3 +
 29 files changed, 3151 insertions(+), 557 deletions(-)
 create mode 100644 hw/arm/fsl-imx25.c
 create mode 100644 hw/arm/fsl-imx31.c
 create mode 100644 hw/arm/imx25_pdk.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
 create mode 100644 include/hw/arm/fsl-imx31.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] 32+ messages in thread

* [Qemu-devel] [PATCH v13 01/19] i.MX: Split UART emulator in a header file and a source file
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 02/19] i.MX: Move serial initialization to init/realize of DeviceClass Jean-Christophe Dubois
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
    
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
  
Changes since v8:
    * no change
  
Changes since v9:  
    * Small style rework
  
Changes since v10:
    * no change 
  
Changes since v11:
    * no change

Changes since v12:
    * no change

 hw/char/imx_serial.c         |  82 +---------------------------------
 include/hw/char/imx_serial.h | 102 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 104 insertions(+), 80 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..1dcb325 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,8 +18,7 @@
  *     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"
@@ -43,35 +43,6 @@ do { printf("imx_serial: " fmt , ##args); } while (0)
 #  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",
     .version_id = 1,
@@ -91,55 +62,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;
diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h
new file mode 100644
index 0000000..6cd75c0
--- /dev/null
+++ b/include/hw/char/imx_serial.h
@@ -0,0 +1,102 @@
+/*
+ * 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;
+
+#endif
-- 
2.1.4

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

* [Qemu-devel] [PATCH v13 02/19] i.MX: Move serial initialization to init/realize of DeviceClass.
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 01/19] i.MX: Split UART emulator in a header file and a source file Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 03/19] i.MX:Fix Coding style for UART emulator Jean-Christophe Dubois
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

Move constructor to DeviceClass methods
 * imx_serial_init
 * imx_serial_realize

imx32_serial_properties is renamed to imx_serial_properties.

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

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:
    * not present on v7

Changes since v8:
    * Remove Qdev construction helper

Changes since v9: 
    * Qdev construction helper is reintegrated and moved to a header file
      as an inline function.

Changes since v10:
    * Qdev construction helper is put back in the main file.
    * Qdev construction helper is reworked
    * We don't use qemu_char_get_next_serial() anymore but the chardev
      property instead.
    * Fix code to work with an unitialized (null) chardev property

Changes since v11:
    * remove fix to work with an unitialized (null) chardev property
    * restore Qdev construction helper to initial state.

Changes since v12:
    * move some coding style fixes to patch 03

 hw/char/imx_serial.c | 35 +++++++++++++++++++----------------
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index 1dcb325..f0ed255 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -306,16 +306,10 @@ static const struct MemoryRegionOps imx_serial_ops = {
     .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);
-
     if (s->chr) {
         qemu_chr_add_handlers(s->chr, imx_can_receive, imx_receive,
                               imx_event, s);
@@ -323,8 +317,17 @@ static int imx_serial_init(SysBusDevice *dev)
         DPRINTF("No char dev for uart at 0x%lx\n",
                 (unsigned long)s->iomem.ram_addr);
     }
+}
+
+static void imx_serial_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    IMXSerialState *s = IMX_SERIAL(obj);
 
-    return 0;
+    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)
@@ -361,7 +364,7 @@ void imx_serial_create(int uart, const hwaddr addr, qemu_irq irq)
 }
 
 
-static Property imx32_serial_properties[] = {
+static Property imx_serial_properties[] = {
     DEFINE_PROP_CHR("chardev", IMXSerialState, chr),
     DEFINE_PROP_END_OF_LIST(),
 };
@@ -369,21 +372,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;
 }
 
 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)
-- 
2.1.4

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

* [Qemu-devel] [PATCH v13 03/19] i.MX:Fix Coding style for UART emulator.
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 01/19] i.MX: Split UART emulator in a header file and a source file Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 02/19] i.MX: Move serial initialization to init/realize of DeviceClass Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 04/19] i.MX: Split AVIC emulator in a header file and a source file Jean-Christophe Dubois
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

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

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:
    * not preset on v7

Changes since v8: 
    * Fix coding style

Changes since v9:
    * no change

Changes since v10:
    * no change

Changes since v11:
    * no change

Changes since v12:
    * Some more coding style fixes from patch 02

 hw/char/imx_serial.c | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index f0ed255..f9da59f 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -26,7 +26,7 @@
 //#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,13 +38,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
 
 static const VMStateDescription vmstate_imx_serial = {
-    .name = "imx-serial",
+    .name = TYPE_IMX_SERIAL,
     .version_id = 1,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
@@ -164,13 +164,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;
@@ -220,25 +220,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;
@@ -266,7 +266,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);
     }
 }
 
-- 
2.1.4

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

* [Qemu-devel] [PATCH v13 04/19] i.MX: Split AVIC emulator in a header file and a source file
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (2 preceding siblings ...)
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 03/19] i.MX:Fix Coding style for UART emulator Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 05/19] i.MX: Fix Coding style for AVIC emulator Jean-Christophe Dubois
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

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

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
    
Changes since v8:
    * no changes
    
Changes since v9:
    * Small style rework.
    
Changes since v10:
    * no change

Changes since v11:
    * no change

Changes since v12:
    * no change

 hw/arm/kzm.c               |  3 ++-
 hw/intc/imx_avic.c         | 40 +++------------------------------
 include/hw/intc/imx_avic.h | 55 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 60 insertions(+), 38 deletions(-)
 create mode 100644 include/hw/intc/imx_avic.h

diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
index 5be0369..c906da7 100644
--- a/hw/arm/kzm.c
+++ b/hw/arm/kzm.c
@@ -22,6 +22,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/boards.h"
 #include "hw/char/serial.h"
+#include "hw/intc/imx_avic.h"
 #include "hw/arm/imx.h"
 
     /* Memory map for Kzm Emulation Baseboard:
@@ -106,7 +107,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);
diff --git a/hw/intc/imx_avic.c b/hw/intc/imx_avic.c
index e48f66c..c5eecb5 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,9 +15,7 @@
  * 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 */
@@ -40,39 +39,6 @@ do { printf("imx_avic: " fmt , ##args); } while (0)
 #  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",
     .version_id = 1,
@@ -370,7 +336,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..1b80769
--- /dev/null
+++ b/include/hw/intc/imx_avic.h
@@ -0,0 +1,55 @@
+/*
+ * 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 IMXAVICState{
+    /*< 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] 32+ messages in thread

* [Qemu-devel] [PATCH v13 05/19] i.MX: Fix Coding style for AVIC emulator.
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (3 preceding siblings ...)
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 04/19] i.MX: Split AVIC emulator in a header file and a source file Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 06/19] i.MX: Split CCM emulator in a header file and a source file Jean-Christophe Dubois
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

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

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:
    * not present on v7
    
Changes since v8: 
    * improve log
    * Do style cleaning
    
Changes since v9:
    * Change patch title.
    
Changes since v10:
    * no change.

Changes since v11:
    * no change.

Changes since v12:
    * no change.

 hw/intc/imx_avic.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/hw/intc/imx_avic.c b/hw/intc/imx_avic.c
index c5eecb5..96c376b 100644
--- a/hw/intc/imx_avic.c
+++ b/hw/intc/imx_avic.c
@@ -22,7 +22,7 @@
 
 #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
@@ -34,13 +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
 
 static const VMStateDescription vmstate_imx_avic = {
-    .name = "imx-avic",
+    .name = TYPE_IMX_AVIC,
     .version_id = 1,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
@@ -54,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;
@@ -215,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;
     }
 }
@@ -227,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 */
@@ -307,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);
 }
-- 
2.1.4

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

* [Qemu-devel] [PATCH v13 06/19] i.MX: Split CCM emulator in a header file and a source file
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (4 preceding siblings ...)
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 05/19] i.MX: Fix Coding style for AVIC emulator Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 07/19] i.MX: Fix Coding style for CCM emulator Jean-Christophe Dubois
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

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

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
    
Changes since v8:
    * no change
    
Changes since v9:
    * change kzm to avoid run time error on CCM creation.

Changes since v10:
    * no change

Changes since v11:
    * no change

Changes since v12:
    * no change

 hw/arm/kzm.c              |  2 +-
 hw/misc/imx_ccm.c         | 70 ++----------------------------------
 include/hw/arm/imx.h      | 12 ++-----
 include/hw/misc/imx_ccm.h | 91 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 97 insertions(+), 78 deletions(-)
 create mode 100644 include/hw/misc/imx_ccm.h

diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
index c906da7..d7af230 100644
--- a/hw/arm/kzm.c
+++ b/hw/arm/kzm.c
@@ -115,7 +115,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/hw/misc/imx_ccm.c b/hw/misc/imx_ccm.c
index 0920288..2e9bd9c 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,10 +11,7 @@
  * 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 */
@@ -29,30 +27,6 @@ do { printf("imx_ccm: " fmt , ##args); } while (0)
 
 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",
     .version_id = 1,
@@ -72,44 +46,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 +222,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/arm/imx.h b/include/hw/arm/imx.h
index ea9e093..b188560 100644
--- a/include/hw/arm/imx.h
+++ b/include/hw/arm/imx.h
@@ -11,17 +11,9 @@
 #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;
+#include "hw/misc/imx_ccm.h"
 
-uint32_t imx_clock_frequency(DeviceState *s, IMXClk clock);
+void imx_serial_create(int uart, const hwaddr addr, qemu_irq irq);
 
 void imx_timerp_create(const hwaddr addr,
                       qemu_irq irq,
diff --git a/include/hw/misc/imx_ccm.h b/include/hw/misc/imx_ccm.h
new file mode 100644
index 0000000..0f2e469
--- /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 IMXCCMState {
+    /* <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] 32+ messages in thread

* [Qemu-devel] [PATCH v13 07/19] i.MX: Fix Coding style for CCM emulator
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (5 preceding siblings ...)
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 06/19] i.MX: Split CCM emulator in a header file and a source file Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 08/19] i.MX: Split EPIT emulator in a header file and a source file Jean-Christophe Dubois
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

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

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:
    * not present on v7

Changes since v8:
    * Improve logs

Changes since v9:
    * Change patch title.

Changes since v10:
    * no change.

Changes since v11: 
    * no change.

Changes since v12:  
    * no change.

 hw/misc/imx_ccm.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/hw/misc/imx_ccm.c b/hw/misc/imx_ccm.c
index 2e9bd9c..2e19dbb 100644
--- a/hw/misc/imx_ccm.c
+++ b/hw/misc/imx_ccm.c
@@ -16,11 +16,10 @@
 #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
@@ -28,7 +27,7 @@ do { printf("imx_ccm: " fmt , ##args); } while (0)
 static int imx_ccm_post_load(void *opaque, int version_id);
 
 static const VMStateDescription vmstate_imx_ccm = {
-    .name = "imx-ccm",
+    .name = TYPE_IMX_CCM,
     .version_id = 1,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
@@ -110,7 +109,7 @@ static void update_clocks(IMXCCMState *s)
     s->hsp_clk_freq = s->mcu_clk_freq / (1 + EXTRACT(s->pdr0, HSP));
     s->ipg_clk_freq = s->hsp_clk_freq / (1 + EXTRACT(s->pdr0, IPG));
 
-    DPRINTF("Clocks: mcu %uMHz, HSP %uMHz, IPG %uHz\n",
+    DPRINTF("%s: mcu %uMHz, HSP %uMHz, IPG %uHz\n", __func__,
             s->mcu_clk_freq / 1000000,
             s->hsp_clk_freq / 1000000,
             s->ipg_clk_freq);
@@ -136,7 +135,7 @@ static uint64_t imx_ccm_read(void *opaque, hwaddr offset,
 {
     IMXCCMState *s = (IMXCCMState *)opaque;
 
-    DPRINTF("read(offset=%x)", offset >> 2);
+    DPRINTF("%s(offset=%x)", __func__, offset >> 2);
     switch (offset >> 2) {
     case 0: /* CCMR */
         DPRINTF(" ccmr = 0x%x\n", s->ccmr);
@@ -177,7 +176,7 @@ static void imx_ccm_write(void *opaque, hwaddr offset,
 {
     IMXCCMState *s = (IMXCCMState *)opaque;
 
-    DPRINTF("write(offset=%x, value = %x)\n",
+    DPRINTF("%s(offset=%x, value = %x)\n", __func__,
             offset >> 2, (unsigned int)value);
     switch (offset >> 2) {
     case 0:
-- 
2.1.4

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

* [Qemu-devel] [PATCH v13 08/19] i.MX: Split EPIT emulator in a header file and a source file
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (6 preceding siblings ...)
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 07/19] i.MX: Fix Coding style for CCM emulator Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 09/19] i.MX: Fix Coding style for EPIT emulator Jean-Christophe Dubois
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

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

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

Changes since: v8:
    * no change
    
Changes since v9:
    * no change

Changes since v10:
    * Coding style changes.

Changes since v11:
    * no change

Changes since v12:
    * no change

 hw/timer/imx_epit.c         | 52 ++---------------------------
 include/hw/timer/imx_epit.h | 79 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+), 49 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..f1f82e9 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -5,23 +5,18 @@
  * 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 +56,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 +67,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
  */
diff --git a/include/hw/timer/imx_epit.h b/include/hw/timer/imx_epit.h
new file mode 100644
index 0000000..c5328ae
--- /dev/null
+++ b/include/hw/timer/imx_epit.h
@@ -0,0 +1,79 @@
+/*
+ * 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 IMXEPITState{
+    /*< 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;
+
+#endif /* IMX_EPIT_H */
-- 
2.1.4

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

* [Qemu-devel] [PATCH v13 09/19] i.MX: Fix Coding style for EPIT emulator
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (7 preceding siblings ...)
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 08/19] i.MX: Split EPIT emulator in a header file and a source file Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 10/19] i.MX: Split GPT emulator in a header file and a source file Jean-Christophe Dubois
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

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

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:
    * not present on v7

Changes since v8: 
    * Fix coding style

Changes since v9:
    * no change

Changes since v10:
    * no change.

Changes since v11:
    * no change.

Changes since v12: 
    * no change.

 hw/timer/imx_epit.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index f1f82e9..10c5d2b 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -128,9 +128,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)
@@ -298,13 +298,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[]) {
-- 
2.1.4

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

* [Qemu-devel] [PATCH v13 10/19] i.MX: Split GPT emulator in a header file and a source file
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (8 preceding siblings ...)
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 09/19] i.MX: Fix Coding style for EPIT emulator Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 11/19] i.MX: Fix Coding style for GPT emulator Jean-Christophe Dubois
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

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

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

Changes since v8:
    * no change

Changes since v9:
    * no change
    
Changes since v10:
    * Fix coding style.

Changes since v11:
    * no change

Changes since v12:
    * no change

 hw/timer/imx_gpt.c         |  79 ++-------------------------------
 include/hw/timer/imx_gpt.h | 107 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 110 insertions(+), 76 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..f61d4e5 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -5,23 +5,18 @@
  * 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,74 +69,6 @@ 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",
     .version_id = 3,
diff --git a/include/hw/timer/imx_gpt.h b/include/hw/timer/imx_gpt.h
new file mode 100644
index 0000000..3f02d3b
--- /dev/null
+++ b/include/hw/timer/imx_gpt.h
@@ -0,0 +1,107 @@
+/*
+ * 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 IMXGPTState{
+    /*< 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;
+
+#endif /* IMX_GPT_H */
-- 
2.1.4

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

* [Qemu-devel] [PATCH v13 11/19] i.MX: Fix Coding style for GPT emulator
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (9 preceding siblings ...)
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 10/19] i.MX: Split GPT emulator in a header file and a source file Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 12/19] i.MX: Add SOC support for i.MX31 Jean-Christophe Dubois
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

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

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:
    * not present on v7

Changes since v8:
    * Fix coding style
    
Changes since v9:
    * no change

Changes since v10:
    * no change.

Changes since v11:
    * no change.

Changes since v12:
    * no change.

 hw/timer/imx_gpt.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index f61d4e5..01f802e 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -70,7 +70,7 @@ static char const *imx_gpt_reg_name(uint32_t reg)
 #endif
 
 static const VMStateDescription vmstate_imx_timer_gpt = {
-    .name = "imx.gpt",
+    .name = TYPE_IMX_GPT,
     .version_id = 3,
     .minimum_version_id = 3,
     .fields = (VMStateField[]) {
@@ -107,7 +107,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);
@@ -134,7 +134,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;
-- 
2.1.4

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

* [Qemu-devel] [PATCH v13 12/19] i.MX: Add SOC support for i.MX31
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (10 preceding siblings ...)
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 11/19] i.MX: Fix Coding style for GPT emulator Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 13/19] i.MX: KZM now uses the standalone i.MX31 SOC support Jean-Christophe Dubois
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

For now we support the following devices:
  * CPU: ARM1136
  * Interrupt Controller: AVIC
  * CCM
  * UART x 2
  * EPIT x 2
  * GPT

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

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:
    * not present on v7

Changes since v8:
    * use defines instead of hardcoded values for IRQ and ADDR
    * Add i.MX31 SOC support

Changes since v9:
    * no change.

Changes since v10:
    * added description of supported devices
    * rework of UART init to use chardev property
    * use memory_region_allocate_system_memory()
    * Fix coding style.

Changes since v11:
    * no change.

Changes since v12:
    * no change.

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

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 74f1db3..3f86e7e 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -98,6 +98,8 @@ CONFIG_ALLWINNER_A10_PIT=y
 CONFIG_ALLWINNER_A10_PIC=y
 CONFIG_ALLWINNER_A10=y
 
+CONFIG_FSL_IMX31=y
+
 CONFIG_XIO3130=y
 CONFIG_IOH3420=y
 CONFIG_I82801B11=y
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index cf346c1..f35f731 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_IMX31) += fsl-imx31.o
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
new file mode 100644
index 0000000..8d349c9
--- /dev/null
+++ b/hw/arm/fsl-imx31.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2013 Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * i.MX31 SOC emulation.
+ *
+ * Based on hw/arm/fsl-imx31.c
+ *
+ *  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-imx31.h"
+#include "sysemu/sysemu.h"
+#include "exec/address-spaces.h"
+#include "hw/boards.h"
+#include "sysemu/char.h"
+
+static void fsl_imx31_init(Object *obj)
+{
+    FslIMX31State *s = FSL_IMX31(obj);
+    int i;
+
+    object_initialize(&s->cpu, sizeof(s->cpu), "arm1136-" 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_IMX31_NUM_UARTS; i++) {
+        object_initialize(&s->uart[i], sizeof(s->uart[i]), TYPE_IMX_SERIAL);
+        qdev_set_parent_bus(DEVICE(&s->uart[i]), sysbus_get_default());
+    }
+
+    object_initialize(&s->gpt, sizeof(s->gpt), TYPE_IMX_GPT);
+    qdev_set_parent_bus(DEVICE(&s->gpt), sysbus_get_default());
+
+    for (i = 0; i < FSL_IMX31_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());
+    }
+}
+
+static void fsl_imx31_realize(DeviceState *dev, Error **errp)
+{
+    FslIMX31State *s = FSL_IMX31(dev);
+    uint16_t i;
+    Error *err = NULL;
+
+    object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    object_property_set_bool(OBJECT(&s->avic), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->avic), 0, FSL_IMX31_AVIC_ADDR);
+    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));
+
+    object_property_set_bool(OBJECT(&s->ccm), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX31_CCM_ADDR);
+
+    /* Initialize all UARTS */
+    for (i = 0; i < FSL_IMX31_NUM_UARTS; i++) {
+        static const struct {
+            hwaddr addr;
+            unsigned int irq;
+        } serial_table[FSL_IMX31_NUM_UARTS] = {
+            { FSL_IMX31_UART1_ADDR, FSL_IMX31_UART1_IRQ },
+            { FSL_IMX31_UART2_ADDR, FSL_IMX31_UART2_IRQ },
+        };
+
+        if (i < MAX_SERIAL_PORTS) {
+            CharDriverState *chr;
+
+            chr = serial_hds[i];
+
+            if (!chr) {
+                char label[20];
+                snprintf(label, sizeof(label), "imx31.uart%d", i);
+                chr = qemu_chr_new(label, "null", NULL);
+            }
+
+            qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr);
+        }
+
+        object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", &err);
+        if (err) {
+            error_propagate(errp, err);
+            return;
+        }
+
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr);
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
+                           qdev_get_gpio_in(DEVICE(&s->avic),
+                                            serial_table[i].irq));
+    }
+
+    s->gpt.ccm = DEVICE(&s->ccm);
+
+    object_property_set_bool(OBJECT(&s->gpt), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt), 0, FSL_IMX31_GPT_ADDR);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt), 0,
+                       qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX31_GPT_IRQ));
+
+    /* Initialize all EPIT timers */
+    for (i = 0; i < FSL_IMX31_NUM_EPITS; i++) {
+        static const struct {
+            hwaddr addr;
+            unsigned int irq;
+        } epit_table[FSL_IMX31_NUM_EPITS] = {
+            { FSL_IMX31_EPIT1_ADDR, FSL_IMX31_EPIT1_IRQ },
+            { FSL_IMX31_EPIT2_ADDR, FSL_IMX31_EPIT2_IRQ },
+        };
+
+        s->epit[i].ccm = DEVICE(&s->ccm);
+
+        object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err);
+        if (err) {
+            error_propagate(errp, err);
+            return;
+        }
+
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0, epit_table[i].addr);
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
+                           qdev_get_gpio_in(DEVICE(&s->avic),
+                                            epit_table[i].irq));
+    }
+
+    /* On a real system, the first 16k is a `secure boot rom' */
+    memory_region_init_rom_device(&s->secure_rom, NULL, NULL, NULL,
+                                  "imx31.secure_rom",
+                                  FSL_IMX31_SECURE_ROM_SIZE, &err);
+    memory_region_add_subregion(get_system_memory(), FSL_IMX31_SECURE_ROM_ADDR,
+                                &s->secure_rom);
+
+    /* There is also a 16k ROM */
+    memory_region_init_rom_device(&s->rom, NULL, NULL, NULL, "imx31.rom",
+                                  FSL_IMX31_ROM_SIZE, &err);
+    memory_region_add_subregion(get_system_memory(), FSL_IMX31_ROM_ADDR,
+                                &s->rom);
+
+    /* initialize internal RAM (16 KB) */
+    memory_region_allocate_system_memory(&s->iram, NULL, "imx31.iram",
+                                         FSL_IMX31_IRAM_SIZE);
+    memory_region_add_subregion(get_system_memory(), FSL_IMX31_IRAM_ADDR,
+                                &s->iram);
+
+    /* internal RAM (16 KB) is aliased over 256 MB - 16 KB */
+    memory_region_init_alias(&s->iram_alias, NULL, "imx31.iram_alias",
+                             &s->iram, 0, FSL_IMX31_IRAM_ALIAS_SIZE);
+    memory_region_add_subregion(get_system_memory(), FSL_IMX31_IRAM_ALIAS_ADDR,
+                                &s->iram_alias);
+}
+
+static void fsl_imx31_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = fsl_imx31_realize;
+}
+
+static const TypeInfo fsl_imx31_type_info = {
+    .name = TYPE_FSL_IMX31,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(FslIMX31State),
+    .instance_init = fsl_imx31_init,
+    .class_init = fsl_imx31_class_init,
+};
+
+static void fsl_imx31_register_types(void)
+{
+    type_register_static(&fsl_imx31_type_info);
+}
+
+type_init(fsl_imx31_register_types)
diff --git a/include/hw/arm/fsl-imx31.h b/include/hw/arm/fsl-imx31.h
new file mode 100644
index 0000000..d8a7e86
--- /dev/null
+++ b/include/hw/arm/fsl-imx31.h
@@ -0,0 +1,98 @@
+/*
+ * Freescale i.MX31 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_IMX31_H
+#define FSL_IMX31_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 "exec/memory.h"
+
+#define TYPE_FSL_IMX31 "fsl,imx31"
+#define FSL_IMX31(obj) OBJECT_CHECK(FslIMX31State, (obj), TYPE_FSL_IMX31)
+
+#define FSL_IMX31_NUM_UARTS 2
+#define FSL_IMX31_NUM_EPITS 2
+
+typedef struct FslIMX31State{
+    /*< private >*/
+    DeviceState parent_obj;
+
+    /*< public >*/
+    ARMCPU         cpu;
+    IMXAVICState   avic;
+    IMXCCMState    ccm;
+    IMXSerialState uart[FSL_IMX31_NUM_UARTS];
+    IMXGPTState    gpt;
+    IMXEPITState   epit[FSL_IMX31_NUM_EPITS];
+    MemoryRegion   secure_rom;
+    MemoryRegion   rom;
+    MemoryRegion   iram;
+    MemoryRegion   iram_alias;
+} FslIMX31State;
+
+#define FSL_IMX31_SECURE_ROM_ADDR	0x00000000
+#define FSL_IMX31_SECURE_ROM_SIZE	0x4000
+#define FSL_IMX31_ROM_ADDR		0x00404000
+#define FSL_IMX31_ROM_SIZE		0x4000
+#define FSL_IMX31_IRAM_ALIAS_ADDR	0x10000000
+#define FSL_IMX31_IRAM_ALIAS_SIZE	0xFFC0000
+#define FSL_IMX31_IRAM_ADDR		0x1FFFC000
+#define FSL_IMX31_IRAM_SIZE		0x4000
+#define FSL_IMX31_UART1_ADDR		0x43F90000
+#define FSL_IMX31_UART1_SIZE		0x4000
+#define FSL_IMX31_UART2_ADDR		0x43F94000
+#define FSL_IMX31_UART2_SIZE		0x4000
+#define FSL_IMX31_CCM_ADDR		0x53F80000
+#define FSL_IMX31_CCM_SIZE		0x4000
+#define FSL_IMX31_GPT_ADDR		0x53F90000
+#define FSL_IMX31_GPT_SIZE		0x4000
+#define FSL_IMX31_EPIT1_ADDR		0x53F94000
+#define FSL_IMX31_EPIT1_SIZE		0x4000
+#define FSL_IMX31_EPIT2_ADDR		0x53F98000
+#define FSL_IMX31_EPIT2_SIZE		0x4000
+#define FSL_IMX31_AVIC_ADDR		0x68000000
+#define FSL_IMX31_AVIC_SIZE		0x100
+#define FSL_IMX31_SDRAM0_ADDR		0x80000000
+#define FSL_IMX31_SDRAM0_SIZE		0x10000000
+#define FSL_IMX31_SDRAM1_ADDR		0x90000000
+#define FSL_IMX31_SDRAM1_SIZE		0x10000000
+#define FSL_IMX31_FLASH0_ADDR		0xA0000000
+#define FSL_IMX31_FLASH0_SIZE		0x8000000
+#define FSL_IMX31_FLASH1_ADDR		0xA8000000
+#define FSL_IMX31_FLASH1_SIZE		0x8000000
+#define FSL_IMX31_CS2_ADDR		0xB0000000
+#define FSL_IMX31_CS2_SIZE		0x2000000
+#define FSL_IMX31_CS3_ADDR		0xB2000000
+#define FSL_IMX31_CS3_SIZE		0x2000000
+#define FSL_IMX31_CS4_ADDR		0xB4000000
+#define FSL_IMX31_CS4_SIZE		0x2000000
+#define FSL_IMX31_CS5_ADDR		0xB6000000
+#define FSL_IMX31_CS5_SIZE		0x2000000
+#define FSL_IMX31_NAND_ADDR		0xB8000000
+#define FSL_IMX31_NAND_SIZE		0x1000
+
+#define FSL_IMX31_EPIT2_IRQ		27
+#define FSL_IMX31_EPIT1_IRQ		28
+#define FSL_IMX31_GPT_IRQ		29
+#define FSL_IMX31_UART2_IRQ		32
+#define FSL_IMX31_UART1_IRQ		45
+
+#endif /* FSL_IMX31_H */
-- 
2.1.4

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

* [Qemu-devel] [PATCH v13 13/19] i.MX: KZM now uses the standalone i.MX31 SOC support
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (11 preceding siblings ...)
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 12/19] i.MX: Add SOC support for i.MX31 Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-08-07 13:45   ` Peter Maydell
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 14/19] i.MX: Add I2C controller emulator Jean-Christophe Dubois
                   ` (7 subsequent siblings)
  20 siblings, 1 reply; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

Tested by booting a minimal Linux system on the emulated platform

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

Changes since v8:
    * update KZM to user i.MX31 SOC
    * rework SDRAM memory initialisation

Changes since v9:
    * remove all Qdev construction helper fucntions.

Changes since v10:
    * use memory_region_allocate_system_memory()
    * rework of memory initialization loop.
    * remove all Qdev construction helper in device files.

Changes since v10:
    * no change.

Changes since v11:
    * no change.

Changes since v12:
    * no change.

 hw/arm/Makefile.objs |   4 +-
 hw/arm/kzm.c         | 206 +++++++++++++++++++++++++--------------------------
 hw/char/imx_serial.c |  35 ---------
 hw/timer/imx_epit.c  |  11 ---
 hw/timer/imx_gpt.c   |  11 ---
 include/hw/arm/imx.h |  26 -------
 6 files changed, 105 insertions(+), 188 deletions(-)
 delete mode 100644 include/hw/arm/imx.h

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index f35f731..2fbe344 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -1,6 +1,6 @@
 obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
 obj-$(CONFIG_DIGIC) += digic_boards.o
-obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
+obj-y += integratorcp.o mainstone.o musicpal.o nseries.o
 obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
 obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
 obj-$(CONFIG_ACPI) += virt-acpi-build.o
@@ -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_IMX31) += fsl-imx31.o
+obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
index d7af230..51f6194 100644
--- a/hw/arm/kzm.c
+++ b/hw/arm/kzm.c
@@ -13,131 +13,131 @@
  * i.MX31 SoC
  */
 
-#include "hw/sysbus.h"
+#include "hw/arm/fsl-imx31.h"
+#include "hw/boards.h"
+#include "qemu/error-report.h"
 #include "exec/address-spaces.h"
-#include "hw/hw.h"
-#include "hw/arm/arm.h"
-#include "hw/devices.h"
 #include "net/net.h"
-#include "sysemu/sysemu.h"
-#include "hw/boards.h"
+#include "hw/devices.h"
 #include "hw/char/serial.h"
-#include "hw/intc/imx_avic.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
-     */
-
-#define KZM_RAMADDRESS (0x80000000)
-#define KZM_FPGA       (0xb4001040)
+#include "sysemu/qtest.h"
+
+/* Memory map for Kzm Emulation Baseboard:
+ * 0x00000000-0x7fffffff See i.MX31 SOC for support
+ * 0x80000000-0x8fffffff RAM                  EMULATED
+ * 0x90000000-0x9fffffff RAM                  EMULATED
+ * 0xa0000000-0xafffffff 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
+ */
+
+typedef struct IMX31Kzm {
+    FslIMX31State soc;
+    MemoryRegion ram[2];
+    MemoryRegion ram_alias;
+} IMX31Kzm;
+
+#define KZM_RAM_ADDR		(FSL_IMX31_SDRAM0_ADDR)
+#define KZM_FPGA_ADDR		(FSL_IMX31_CS4_ADDR + 0x1040)
+#define KZM_LAN9118_ADDR	(FSL_IMX31_CS5_ADDR)
 
 static struct arm_boot_info kzm_binfo = {
-    .loader_start = KZM_RAMADDRESS,
+    .loader_start = KZM_RAM_ADDR,
     .board_id = 1722,
 };
 
 static void kzm_init(MachineState *machine)
 {
-    ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
-    const char *kernel_filename = machine->kernel_filename;
-    const char *kernel_cmdline = machine->kernel_cmdline;
-    const char *initrd_filename = machine->initrd_filename;
-    ARMCPU *cpu;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
-    MemoryRegion *sram = g_new(MemoryRegion, 1);
-    MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
-    DeviceState *dev;
-    DeviceState *ccm;
-
-    if (!cpu_model) {
-        cpu_model = "arm1136";
-    }
-
-    cpu = cpu_arm_init(cpu_model);
-    if (!cpu) {
-        fprintf(stderr, "Unable to find CPU definition\n");
+    IMX31Kzm *s = g_new0(IMX31Kzm, 1);
+    Error *err = NULL;
+    unsigned int ram_size;
+    unsigned int i;
+
+    object_initialize(&s->soc, sizeof(s->soc), TYPE_FSL_IMX31);
+    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);
     }
 
-    /* On a real system, the first 16k is a `secure boot rom' */
-
-    memory_region_allocate_system_memory(ram, NULL, "kzm.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, KZM_RAMADDRESS, ram);
-
-    memory_region_init_alias(ram_alias, NULL, "ram.alias", ram, 0, ram_size);
-    memory_region_add_subregion(address_space_mem, 0x88000000, ram_alias);
-
-    memory_region_init_ram(sram, NULL, "kzm.sram", 0x4000, &error_abort);
-    memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
-
-    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);
-
-    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(TYPE_IMX_CCM, 0x53f80000, NULL);
+    /* Check the amount of memory is compatible with the SOC */
+    if (machine->ram_size > (FSL_IMX31_SDRAM0_SIZE + FSL_IMX31_SDRAM1_SIZE)) {
+        error_report("WARNING: RAM size " RAM_ADDR_FMT " above max supported, "
+                     "reduced to %x", machine->ram_size,
+                     FSL_IMX31_SDRAM0_SIZE + FSL_IMX31_SDRAM1_SIZE);
+        machine->ram_size = FSL_IMX31_SDRAM0_SIZE + FSL_IMX31_SDRAM1_SIZE;
+    }
 
-    imx_timerp_create(0x53f94000, qdev_get_gpio_in(dev, 28), ccm);
-    imx_timerp_create(0x53f98000, qdev_get_gpio_in(dev, 27), ccm);
-    imx_timerg_create(0x53f90000, qdev_get_gpio_in(dev, 29), ccm);
+    /* initialize our memory */
+    for (i=0, ram_size = machine->ram_size; (i<2) && ram_size; i++) {
+        unsigned int size;
+        char ram_name[20];
+        static const struct {
+            hwaddr addr;
+            unsigned int size;
+        } ram[2] = {
+            { FSL_IMX31_SDRAM0_ADDR, FSL_IMX31_SDRAM0_SIZE },
+            { FSL_IMX31_SDRAM1_ADDR, FSL_IMX31_SDRAM1_SIZE },
+        };
+
+	if (ram_size > ram[i].size) {
+            size = ram[i].size;
+	} else {
+            size = ram_size;
+	}
+
+        sprintf(ram_name, "kzm.ram%d", i);
+
+        ram_size -= size;
+
+        memory_region_allocate_system_memory(&s->ram[i], NULL, ram_name, size);
+        memory_region_add_subregion(get_system_memory(), ram[i].addr,
+                                    &s->ram[i]);
+        if (size < ram[i].size) {
+            memory_region_init_alias(&s->ram_alias, NULL, "ram.alias",
+                                     &s->ram[i], 0, ram[i].size - size);
+            memory_region_add_subregion(get_system_memory(),
+                                        ram[i].addr + size, &s->ram_alias);
+        }
+    }
 
     if (nd_table[0].used) {
-        lan9118_init(&nd_table[0], 0xb6000000, qdev_get_gpio_in(dev, 52));
+        lan9118_init(&nd_table[0], KZM_LAN9118_ADDR,
+                     qdev_get_gpio_in(DEVICE(&s->soc.avic), 52));
     }
 
     if (serial_hds[2]) { /* touchscreen */
-        serial_mm_init(address_space_mem, KZM_FPGA+0x10, 0,
-                       qdev_get_gpio_in(dev, 52),
-                       14745600, serial_hds[2],
-                       DEVICE_NATIVE_ENDIAN);
+        serial_mm_init(get_system_memory(), KZM_FPGA_ADDR+0x10, 0,
+                       qdev_get_gpio_in(DEVICE(&s->soc.avic), 52),
+                       14745600, serial_hds[2], DEVICE_NATIVE_ENDIAN);
     }
 
-    kzm_binfo.ram_size = ram_size;
-    kzm_binfo.kernel_filename = kernel_filename;
-    kzm_binfo.kernel_cmdline = kernel_cmdline;
-    kzm_binfo.initrd_filename = initrd_filename;
+    kzm_binfo.ram_size = machine->ram_size;
+    kzm_binfo.kernel_filename = machine->kernel_filename;
+    kzm_binfo.kernel_cmdline = machine->kernel_cmdline;
+    kzm_binfo.initrd_filename = machine->initrd_filename;
     kzm_binfo.nb_cpus = 1;
-    arm_load_kernel(cpu, &kzm_binfo);
+
+    if (!qtest_enabled()) {
+        arm_load_kernel(&s->soc.cpu, &kzm_binfo);
+    }
 }
 
 static QEMUMachine kzm_machine = {
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index f9da59f..bc4141b 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -21,7 +21,6 @@
 #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
@@ -330,40 +329,6 @@ static void imx_serial_init(Object *obj)
     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);
-    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);
-
-}
-
-
 static Property imx_serial_properties[] = {
     DEFINE_PROP_CHR("chardev", IMXSerialState, chr),
     DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 10c5d2b..9649851 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -12,7 +12,6 @@
  *
  */
 
-#include "hw/arm/imx.h"
 #include "hw/timer/imx_epit.h"
 #include "hw/misc/imx_ccm.h"
 #include "qemu/main-loop.h"
@@ -287,16 +286,6 @@ static void imx_epit_cmp(void *opaque)
     imx_epit_update_int(s);
 }
 
-void imx_timerp_create(const hwaddr addr, qemu_irq irq, DeviceState *ccm)
-{
-    IMXEPITState *pp;
-    DeviceState *dev;
-
-    dev = sysbus_create_simple(TYPE_IMX_EPIT, addr, irq);
-    pp = IMX_EPIT(dev);
-    pp->ccm = ccm;
-}
-
 static const MemoryRegionOps imx_epit_ops = {
     .read = imx_epit_read,
     .write = imx_epit_write,
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index 01f802e..4bac67d 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -12,7 +12,6 @@
  *
  */
 
-#include "hw/arm/imx.h"
 #include "hw/timer/imx_gpt.h"
 #include "hw/misc/imx_ccm.h"
 #include "qemu/main-loop.h"
@@ -449,16 +448,6 @@ static void imx_gpt_realize(DeviceState *dev, Error **errp)
     s->timer = ptimer_init(bh);
 }
 
-void imx_timerg_create(const hwaddr addr, qemu_irq irq, DeviceState *ccm)
-{
-    IMXGPTState *pp;
-    DeviceState *dev;
-
-    dev = sysbus_create_simple(TYPE_IMX_GPT, addr, irq);
-    pp = IMX_GPT(dev);
-    pp->ccm = ccm;
-}
-
 static void imx_gpt_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
diff --git a/include/hw/arm/imx.h b/include/hw/arm/imx.h
deleted file mode 100644
index b188560..0000000
--- a/include/hw/arm/imx.h
+++ /dev/null
@@ -1,26 +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
-
-#include "hw/misc/imx_ccm.h"
-
-void imx_serial_create(int uart, const hwaddr addr, qemu_irq irq);
-
-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] 32+ messages in thread

* [Qemu-devel] [PATCH v13 14/19] i.MX: Add I2C controller emulator
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (12 preceding siblings ...)
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 13/19] i.MX: KZM now uses the standalone i.MX31 SOC support Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 15/19] i.MX: Add FEC Ethernet Emulator Jean-Christophe Dubois
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 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

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

Changes since v8:
    * no change

Changes since v9:
    * no change

Changes since v10:
    * no change.

Changes since v11:
    * no change.

Changes since v12:
    * no change.

 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 3f86e7e..47390db 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -100,6 +100,8 @@ CONFIG_ALLWINNER_A10=y
 
 CONFIG_FSL_IMX31=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] 32+ messages in thread

* [Qemu-devel] [PATCH v13 15/19] i.MX: Add FEC Ethernet Emulator
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (13 preceding siblings ...)
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 14/19] i.MX: Add I2C controller emulator Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 16/19] i.MX: Add SOC support for i.MX25 Jean-Christophe Dubois
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 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

Changes since v7:
    * refactor to be used by SOC

Changes since v8:
    * no change

Changes since v9:
    * no change

Changes since v10:
    * no change

Changes since v11:
    * no change

Changes since v12:
    * no change

 default-configs/arm-softmmu.mak |   1 +
 hw/net/Makefile.objs            |   1 +
 hw/net/imx_fec.c                | 709 ++++++++++++++++++++++++++++++++++++++++
 include/hw/net/imx_fec.h        | 113 +++++++
 4 files changed, 824 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 47390db..5fa84c6 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..725f3fa
--- /dev/null
+++ b/hw/net/imx_fec.c
@@ -0,0 +1,709 @@
+/*
+ * 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);
+}
+
+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..cbf8650
--- /dev/null
+++ b/include/hw/net/imx_fec.h
@@ -0,0 +1,113 @@
+/*
+ * 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 IMXFECState {
+    /*< 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;
+
+#endif
-- 
2.1.4

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

* [Qemu-devel] [PATCH v13 16/19] i.MX: Add SOC support for i.MX25
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (14 preceding siblings ...)
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 15/19] i.MX: Add FEC Ethernet Emulator Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-08-07 13:50   ` Peter Maydell
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 17/19] i.MX: Add the i.MX25 PDK plateform Jean-Christophe Dubois
                   ` (4 subsequent siblings)
  20 siblings, 1 reply; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

    For now we support the following devices:
      * CPU: ARM926
      * Interrupt Controller: AVIC
      * CCM
      * UART x 5
      * EPIT x 2
      * GPT x 4
      * FEC
      * I2C x 3

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

Changes since v8:
    * use defines instead of hardcoded values for IRQ and ADDR
    * reworked the memory allocation for SOC memory

Changes since v9:
    * no change

Changes since v10:
    * added deescription of supported devices
    * rework of UART init to use chardev property
    * use memory_region_allocate_system_memory()
    * Fix coding style.

Changes since v11:
    * no change

Changes since v12:
    * no change

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs            |   1 +
 hw/arm/fsl-imx25.c              | 260 ++++++++++++++++++++++++++++++++++++++++
 include/hw/arm/fsl-imx25.h      | 234 ++++++++++++++++++++++++++++++++++++
 4 files changed, 496 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 5fa84c6..bf7572b 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -100,6 +100,7 @@ CONFIG_ALLWINNER_A10_PIC=y
 CONFIG_ALLWINNER_A10=y
 
 CONFIG_FSL_IMX31=y
+CONFIG_FSL_IMX25=y
 
 CONFIG_IMX_I2C=y
 
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 2fbe344..b83aaca 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -13,4 +13,5 @@ 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_IMX31) += fsl-imx31.o kzm.o
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
new file mode 100644
index 0000000..df440e9
--- /dev/null
+++ b/hw/arm/fsl-imx25.c
@@ -0,0 +1,260 @@
+/*
+ * 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"
+#include "exec/address-spaces.h"
+#include "hw/boards.h"
+#include "sysemu/char.h"
+
+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++) {
+        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);
+    uint8_t i;
+    Error *err = NULL;
+
+    object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
+    if (err) {
+        error_propagate((errp), (err));
+        return;
+    }
+
+    object_property_set_bool(OBJECT(&s->avic), true, "realized", &err);
+    if (err) {
+        error_propagate((errp), (err));
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->avic), 0, FSL_IMX25_AVIC_ADDR);
+    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));
+
+    object_property_set_bool(OBJECT(&s->ccm), true, "realized", &err);
+    if (err) {
+        error_propagate((errp), (err));
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX25_CCM_ADDR);
+
+    /* 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] = {
+            { FSL_IMX25_UART1_ADDR, FSL_IMX25_UART1_IRQ },
+            { FSL_IMX25_UART2_ADDR, FSL_IMX25_UART2_IRQ },
+            { FSL_IMX25_UART3_ADDR, FSL_IMX25_UART3_IRQ },
+            { FSL_IMX25_UART4_ADDR, FSL_IMX25_UART4_IRQ },
+            { FSL_IMX25_UART5_ADDR, FSL_IMX25_UART5_IRQ }
+        };
+
+        if (i < MAX_SERIAL_PORTS) {
+            CharDriverState *chr;
+
+            chr = serial_hds[i];
+
+            if (!chr) {
+                char label[20];
+                snprintf(label, sizeof(label), "imx31.uart%d", i);
+                chr = qemu_chr_new(label, "null", NULL);
+            }
+
+            qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr);
+        }
+
+        object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", &err);
+        if (err) {
+            error_propagate((errp), (err));
+            return;
+        }
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr);
+        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] = {
+            { FSL_IMX25_GPT1_ADDR, FSL_IMX25_GPT1_IRQ },
+            { FSL_IMX25_GPT2_ADDR, FSL_IMX25_GPT2_IRQ },
+            { FSL_IMX25_GPT3_ADDR, FSL_IMX25_GPT3_IRQ },
+            { FSL_IMX25_GPT4_ADDR, FSL_IMX25_GPT4_IRQ }
+        };
+
+        s->gpt[i].ccm = DEVICE(&s->ccm);
+
+        object_property_set_bool(OBJECT(&s->gpt[i]), true, "realized", &err);
+        if (err) {
+            error_propagate((errp), (err));
+            return;
+        }
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, gpt_table[i].addr);
+        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] = {
+            { FSL_IMX25_EPIT1_ADDR, FSL_IMX25_EPIT1_IRQ },
+            { FSL_IMX25_EPIT2_ADDR, FSL_IMX25_EPIT2_IRQ }
+        };
+
+        s->epit[i].ccm = DEVICE(&s->ccm);
+
+        object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err);
+        if (err) {
+            error_propagate((errp), (err));
+            return;
+        }
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0, epit_table[i].addr);
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
+                           qdev_get_gpio_in(DEVICE(&s->avic),
+                                            epit_table[i].irq));
+    }
+
+    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;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->fec), 0, FSL_IMX25_FEC_ADDR);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->fec), 0,
+                       qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX25_FEC_IRQ));
+
+
+    /* 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] = {
+            { FSL_IMX25_I2C1_ADDR, FSL_IMX25_I2C1_IRQ },
+            { FSL_IMX25_I2C2_ADDR, FSL_IMX25_I2C2_IRQ },
+            { FSL_IMX25_I2C3_ADDR, FSL_IMX25_I2C3_IRQ }
+        };
+
+        object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized", &err);
+        if (err) {
+            error_propagate((errp), (err));
+            return;
+        }
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr);
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
+                           qdev_get_gpio_in(DEVICE(&s->avic),
+                                            i2c_table[i].irq));
+    }
+
+    /* initialize 2 x 16 KB ROM */
+    memory_region_init_rom_device(&s->rom[0], NULL, NULL, NULL,
+                                  "imx25.rom0", FSL_IMX25_ROM0_SIZE, &err);
+    memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM0_ADDR,
+                                &s->rom[0]);
+    memory_region_init_rom_device(&s->rom[1], NULL, NULL, NULL,
+                                  "imx25.rom1", FSL_IMX25_ROM1_SIZE, &err);
+    memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM1_ADDR,
+                                &s->rom[1]);
+
+    /* initialize internal RAM (128 KB) */
+    memory_region_allocate_system_memory(&s->iram, NULL, "imx25.iram",
+                                        FSL_IMX25_IRAM_SIZE);
+    memory_region_add_subregion(get_system_memory(), FSL_IMX25_IRAM_ADDR,
+                                &s->iram);
+
+    /* internal RAM (16 KB) is aliased over 128 MB - 128 KB */
+    memory_region_init_alias(&s->iram_alias, NULL, "imx25.iram_alias",
+                             &s->iram, 0, FSL_IMX25_IRAM_ALIAS_SIZE);
+    memory_region_add_subregion(get_system_memory(), FSL_IMX25_IRAM_ALIAS_ADDR,
+                                &s->iram_alias);
+}
+
+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..3cda09c
--- /dev/null
+++ b/include/hw/arm/fsl-imx25.h
@@ -0,0 +1,234 @@
+/*
+ * 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"
+#include "exec/memory.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 FslIMX25State{
+    /*< 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];
+    MemoryRegion   rom[2];
+    MemoryRegion   iram;
+    MemoryRegion   iram_alias;
+} FslIMX25State;
+
+/**
+ * i.MX25 memory map
+ ****************************************************************
+ * 0x0000_0000 0x0000_3FFF 16 Kbytes	ROM (36 Kbytes)
+ * 0x0000_4000 0x0040_3FFF 4 Mbytes	Reserved
+ * 0x0040_4000 0x0040_8FFF 20 Kbytes	ROM (36 Kbytes)
+ * 0x0040_9000 0x0FFF_FFFF 252 Mbytes (minus 36 Kbytes) Reserved
+ * 0x1000_0000 0x1FFF_FFFF 256 Mbytes	Reserved
+ * 0x2000_0000 0x2FFF_FFFF 256 Mbytes	Reserved
+ * 0x3000_0000 0x3FFF_FFFF 256 Mbytes	Reserved
+ * 0x4000_0000 0x43EF_FFFF 63 Mbytes	Reserved
+ * 0x43F0_0000 0x43F0_3FFF 16 Kbytes	AIPS A control registers
+ * 0x43F0_4000 0x43F0_7FFF 16 Kbytes	ARM926 platform MAX
+ * 0x43F0_8000 0x43F0_BFFF 16 Kbytes	ARM926 platform CLKCTL
+ * 0x43F0_C000 0x43F0_FFFF 16 Kbytes	ARM926 platform ETB registers
+ * 0x43F1_0000 0x43F1_3FFF 16 Kbytes	ARM926 platform ETB memory
+ * 0x43F1_4000 0x43F1_7FFF 16 Kbytes	ARM926 platform AAPE registers
+ * 0x43F1_8000 0x43F7_FFFF 416 Kbytes	Reserved
+ * 0x43F8_0000 0x43F8_3FFF 16 Kbytes	I2C-1
+ * 0x43F8_4000 0x43F8_7FFF 16 Kbytes	I2C-3
+ * 0x43F8_8000 0x43F8_BFFF 16 Kbytes	CAN-1
+ * 0x43F8_C000 0x43F8_FFFF 16 Kbytes	CAN-2
+ * 0x43F9_0000 0x43F9_3FFF 16 Kbytes	UART-1
+ * 0x43F9_4000 0x43F9_7FFF 16 Kbytes	UART-2
+ * 0x43F9_8000 0x43F9_BFFF 16 Kbytes	I2C-2
+ * 0x43F9_C000 0x43F9_FFFF 16 Kbytes	1-Wire
+ * 0x43FA_0000 0x43FA_3FFF 16 Kbytes	ATA (CPU side)
+ * 0x43FA_4000 0x43FA_7FFF 16 Kbytes	CSPI-1
+ * 0x43FA_8000 0x43FA_BFFF 16 Kbytes	KPP
+ * 0x43FA_C000 0x43FA_FFFF 16 Kbytes	IOMUXC
+ * 0x43FB_0000 0x43FB_3FFF 16 Kbytes	AUDMUX
+ * 0x43FB_4000 0x43FB_7FFF 16 Kbytes	Reserved
+ * 0x43FB_8000 0x43FB_BFFF 16 Kbytes	ECT (IP BUS A)
+ * 0x43FB_C000 0x43FB_FFFF 16 Kbytes	ECT (IP BUS B)
+ * 0x43FC_0000 0x43FF_FFFF 256 Kbytes	Reserved AIPS A off-platform slots
+ * 0x4400_0000 0x4FFF_FFFF 192 Mbytes	Reserved
+ * 0x5000_0000 0x5000_3FFF 16 Kbytes	SPBA base address
+ * 0x5000_4000 0x5000_7FFF 16 Kbytes	CSPI-3
+ * 0x5000_8000 0x5000_BFFF 16 Kbytes	UART-4
+ * 0x5000_C000 0x5000_FFFF 16 Kbytes	UART-3
+ * 0x5001_0000 0x5001_3FFF 16 Kbytes	CSPI-2
+ * 0x5001_4000 0x5001_7FFF 16 Kbytes	SSI-2
+ * 0x5001_C000 0x5001_FFFF 16 Kbytes	Reserved
+ * 0x5002_0000 0x5002_3FFF 16 Kbytes	ATA
+ * 0x5002_4000 0x5002_7FFF 16 Kbytes	SIM-1
+ * 0x5002_8000 0x5002_BFFF 16 Kbytes	SIM-2
+ * 0x5002_C000 0x5002_FFFF 16 Kbytes	UART-5
+ * 0x5003_0000 0x5003_3FFF 16 Kbytes	TSC
+ * 0x5003_4000 0x5003_7FFF 16 Kbytes	SSI-1
+ * 0x5003_8000 0x5003_BFFF 16 Kbytes	FEC
+ * 0x5003_C000 0x5003_FFFF 16 Kbytes	SPBA registers
+ * 0x5004_0000 0x51FF_FFFF 32 Mbytes (minus 256 Kbytes)
+ * 0x5200_0000 0x53EF_FFFF 31 Mbytes	Reserved
+ * 0x53F0_0000 0x53F0_3FFF 16 Kbytes	AIPS B control registers
+ * 0x53F0_4000 0x53F7_FFFF 496 Kbytes	Reserved
+ * 0x53F8_0000 0x53F8_3FFF 16 Kbytes	CCM
+ * 0x53F8_4000 0x53F8_7FFF 16 Kbytes	GPT-4
+ * 0x53F8_8000 0x53F8_BFFF 16 Kbytes	GPT-3
+ * 0x53F8_C000 0x53F8_FFFF 16 Kbytes	GPT-2
+ * 0x53F9_0000 0x53F9_3FFF 16 Kbytes	GPT-1
+ * 0x53F9_4000 0x53F9_7FFF 16 Kbytes	EPIT-1
+ * 0x53F9_8000 0x53F9_BFFF 16 Kbytes	EPIT-2
+ * 0x53F9_C000 0x53F9_FFFF 16 Kbytes	GPIO-4
+ * 0x53FA_0000 0x53FA_3FFF 16 Kbytes	PWM-2
+ * 0x53FA_4000 0x53FA_7FFF 16 Kbytes	GPIO-3
+ * 0x53FA_8000 0x53FA_BFFF 16 Kbytes	PWM-3
+ * 0x53FA_C000 0x53FA_FFFF 16 Kbytes	SCC
+ * 0x53FB_0000 0x53FB_3FFF 16 Kbytes	RNGB
+ * 0x53FB_4000 0x53FB_7FFF 16 Kbytes	eSDHC-1
+ * 0x53FB_8000 0x53FB_BFFF 16 Kbytes	eSDHC-2
+ * 0x53FB_C000 0x53FB_FFFF 16 Kbytes	LCDC
+ * 0x53FC_0000 0x53FC_3FFF 16 Kbytes	SLCDC
+ * 0x53FC_4000 0x53FC_7FFF 16 Kbytes	Reserved
+ * 0x53FC_8000 0x53FC_BFFF 16 Kbytes	PWM-4
+ * 0x53FC_C000 0x53FC_FFFF 16 Kbytes	GPIO-1
+ * 0x53FD_0000 0x53FD_3FFF 16 Kbytes	GPIO-2
+ * 0x53FD_4000 0x53FD_7FFF 16 Kbytes	SDMA
+ * 0x53FD_8000 0x53FD_BFFF 16 Kbytes	Reserved
+ * 0x53FD_C000 0x53FD_FFFF 16 Kbytes	WDOG
+ * 0x53FE_0000 0x53FE_3FFF 16 Kbytes	PWM-1
+ * 0x53FE_4000 0x53FE_7FFF 16 Kbytes	Reserved
+ * 0x53FE_8000 0x53FE_BFFF 16 Kbytes	Reserved
+ * 0x53FE_C000 0x53FE_FFFF 16 Kbytes	RTICv3
+ * 0x53FF_0000 0x53FF_3FFF 16 Kbytes	IIM
+ * 0x53FF_4000 0x53FF_7FFF 16 Kbytes	USB
+ * 0x53FF_8000 0x53FF_BFFF 16 Kbytes	CSI
+ * 0x53FF_C000 0x53FF_FFFF 16 Kbytes	DryIce
+ * 0x5400_0000 0x5FFF_FFFF 192 Mbytes	Reserved (aliased AIPS B slots)
+ * 0x6000_0000 0x67FF_FFFF 128 Mbytes	ARM926 platform ROMPATCH
+ * 0x6800_0000 0x6FFF_FFFF 128 Mbytes	ARM926 platform ASIC
+ * 0x7000_0000 0x77FF_FFFF 128 Mbytes	Reserved
+ * 0x7800_0000 0x7801_FFFF 128 Kbytes	RAM
+ * 0x7802_0000 0x7FFF_FFFF 128 Mbytes (minus 128 Kbytes)
+ * 0x8000_0000 0x8FFF_FFFF 256 Mbytes	SDRAM bank 0
+ * 0x9000_0000 0x9FFF_FFFF 256 Mbytes	SDRAM bank 1
+ * 0xA000_0000 0xA7FF_FFFF 128 Mbytes	WEIM CS0 (flash 128) 1
+ * 0xA800_0000 0xAFFF_FFFF 128 Mbytes	WEIM CS1 (flash 64) 1
+ * 0xB000_0000 0xB1FF_FFFF 32 Mbytes	WEIM CS2 (SRAM)
+ * 0xB200_0000 0xB3FF_FFFF 32 Mbytes	WEIM CS3 (SRAM)
+ * 0xB400_0000 0xB5FF_FFFF 32 Mbytes	WEIM CS4
+ * 0xB600_0000 0xB7FF_FFFF 32 Mbytes	Reserved
+ * 0xB800_0000 0xB800_0FFF 4 Kbytes	Reserved
+ * 0xB800_1000 0xB800_1FFF 4 Kbytes	SDRAM control registers
+ * 0xB800_2000 0xB800_2FFF 4 Kbytes	WEIM control registers
+ * 0xB800_3000 0xB800_3FFF 4 Kbytes	M3IF control registers
+ * 0xB800_4000 0xB800_4FFF 4 Kbytes	EMI control registers
+ * 0xB800_5000 0xBAFF_FFFF 32 Mbytes (minus 20 Kbytes)
+ * 0xBB00_0000 0xBB00_0FFF 4 Kbytes	NAND flash main area buffer
+ * 0xBB00_1000 0xBB00_11FF 512 B	NAND flash spare area buffer
+ * 0xBB00_1200 0xBB00_1DFF 3 Kbytes	Reserved
+ * 0xBB00_1E00 0xBB00_1FFF 512 B	NAND flash control regisers
+ * 0xBB01_2000 0xBFFF_FFFF 96 Mbytes (minus 8 Kbytes) Reserved
+ * 0xC000_0000 0xFFFF_FFFF 1024 Mbytes	Reserved
+ */
+
+#define FSL_IMX25_ROM0_ADDR	0x00000000
+#define FSL_IMX25_ROM0_SIZE	0x4000
+#define FSL_IMX25_ROM1_ADDR	0x00404000
+#define FSL_IMX25_ROM1_SIZE	0x4000
+#define FSL_IMX25_I2C1_ADDR	0x43F80000
+#define FSL_IMX25_I2C1_SIZE	0x4000
+#define FSL_IMX25_I2C3_ADDR	0x43F84000
+#define FSL_IMX25_I2C3_SIZE	0x4000
+#define FSL_IMX25_UART1_ADDR	0x43F90000
+#define FSL_IMX25_UART1_SIZE	0x4000
+#define FSL_IMX25_UART2_ADDR	0x43F94000
+#define FSL_IMX25_UART2_SIZE	0x4000
+#define FSL_IMX25_I2C2_ADDR	0x43F98000
+#define FSL_IMX25_I2C2_SIZE	0x4000
+#define FSL_IMX25_UART4_ADDR	0x50008000
+#define FSL_IMX25_UART4_SIZE	0x4000
+#define FSL_IMX25_UART3_ADDR	0x5000C000
+#define FSL_IMX25_UART3_SIZE	0x4000
+#define FSL_IMX25_UART5_ADDR	0x5002C000
+#define FSL_IMX25_UART5_SIZE	0x4000
+#define FSL_IMX25_FEC_ADDR	0x50038000
+#define FSL_IMX25_FEC_SIZE	0x4000
+#define FSL_IMX25_CCM_ADDR	0x53F80000
+#define FSL_IMX25_CCM_SIZE	0x4000
+#define FSL_IMX25_GPT4_ADDR	0x53F84000
+#define FSL_IMX25_GPT4_SIZE	0x4000
+#define FSL_IMX25_GPT3_ADDR	0x53F88000
+#define FSL_IMX25_GPT3_SIZE	0x4000
+#define FSL_IMX25_GPT2_ADDR	0x53F8C000
+#define FSL_IMX25_GPT2_SIZE	0x4000
+#define FSL_IMX25_GPT1_ADDR	0x53F90000
+#define FSL_IMX25_GPT1_SIZE	0x4000
+#define FSL_IMX25_EPIT1_ADDR	0x53F94000
+#define FSL_IMX25_EPIT1_SIZE	0x4000
+#define FSL_IMX25_EPIT2_ADDR	0x53F98000
+#define FSL_IMX25_EPIT2_SIZE	0x4000
+#define FSL_IMX25_AVIC_ADDR	0x68000000
+#define FSL_IMX25_AVIC_SIZE	0x4000
+#define FSL_IMX25_IRAM_ADDR	0x78000000
+#define FSL_IMX25_IRAM_SIZE	0x20000
+#define FSL_IMX25_IRAM_ALIAS_ADDR	0x78020000
+#define FSL_IMX25_IRAM_ALIAS_SIZE	0x7FE0000
+#define FSL_IMX25_SDRAM0_ADDR	0x80000000
+#define FSL_IMX25_SDRAM0_SIZE	0x10000000
+#define FSL_IMX25_SDRAM1_ADDR	0x90000000
+#define FSL_IMX25_SDRAM1_SIZE	0x10000000
+
+#define FSL_IMX25_UART1_IRQ	45
+#define FSL_IMX25_UART2_IRQ	32
+#define FSL_IMX25_UART3_IRQ	18
+#define FSL_IMX25_UART4_IRQ	5
+#define FSL_IMX25_UART5_IRQ	40
+#define FSL_IMX25_GPT1_IRQ	54
+#define FSL_IMX25_GPT2_IRQ	53
+#define FSL_IMX25_GPT3_IRQ	29
+#define FSL_IMX25_GPT4_IRQ	1
+#define FSL_IMX25_EPIT1_IRQ	28
+#define FSL_IMX25_EPIT2_IRQ	27
+#define FSL_IMX25_FEC_IRQ	57
+#define FSL_IMX25_I2C1_IRQ	3
+#define FSL_IMX25_I2C2_IRQ	4
+#define FSL_IMX25_I2C3_IRQ	10
+
+#endif /* FSL_IMX25_H */
-- 
2.1.4

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

* [Qemu-devel] [PATCH v13 17/19] i.MX: Add the i.MX25 PDK plateform
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (15 preceding siblings ...)
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 16/19] i.MX: Add SOC support for i.MX25 Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 18/19] i.MX: Add qtest support for I2C device emulator Jean-Christophe Dubois
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

Tested by booting a minimal Linux system on the emulated platform
Tested by booting the Xvisor hyprvisor on the emulated platform

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.

Changes since v8:
    * rework SDRAM memory initialisation

Changes since v9: 
    * no change

Changes since v10:
    * rename board from 3DS to PDK
    * use memory_region_allocate_system_memory()
    * rework of memory initialization loop.

Changes since v11:
    * no change

Changes since v12:
    * no change

 hw/arm/Makefile.objs |   2 +-
 hw/arm/imx25_pdk.c   | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 163 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/imx25_pdk.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index b83aaca..2195b60 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -13,5 +13,5 @@ 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_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c
new file mode 100644
index 0000000..c07349f
--- /dev/null
+++ b/hw/arm/imx25_pdk.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2013 Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * PDK 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 PDK Emulation Baseboard:
+ * 0x00000000-0x7fffffff See i.MX25 SOC fr support
+ * 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 IMX25Pdk {
+    FslIMX25State soc;
+    MemoryRegion ram[2];
+    MemoryRegion ram_alias;
+} IMX25Pdk;
+
+#define IMX25_PDK_ADDRESS   (FSL_IMX25_SDRAM0_ADDR)
+
+static struct arm_boot_info imx25_pdk_binfo;
+
+static void imx25_pdk_init(MachineState *machine)
+{
+    IMX25Pdk *s = g_new0(IMX25Pdk, 1);
+    Error *err = NULL;
+    unsigned int ram_size;
+    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 > (FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE)) {
+	error_report("WARNING: RAM size " RAM_ADDR_FMT " above max supported, "
+                     "reduced to %x", machine->ram_size,
+                     FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE);
+	machine->ram_size = FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE;
+    }
+
+    /* initialize our memory */
+    for (i=0, ram_size = machine->ram_size; (i<2) && ram_size; i++) {
+        unsigned int size;
+        char ram_name[20];
+        static const struct {
+            hwaddr addr;
+            unsigned int size;
+        } ram[2] = {
+            { FSL_IMX25_SDRAM0_ADDR, FSL_IMX25_SDRAM0_SIZE },
+            { FSL_IMX25_SDRAM1_ADDR, FSL_IMX25_SDRAM1_SIZE },
+        };
+
+        if (ram_size > ram[i].size) {
+            size = ram[i].size;
+        } else {
+            size = ram_size;
+        }
+
+        sprintf(ram_name, "imx25.ram%d", i);
+
+        ram_size -= size;
+
+        memory_region_allocate_system_memory(&s->ram[i], NULL, ram_name, size);
+        memory_region_add_subregion(get_system_memory(), ram[i].addr,
+                                    &s->ram[i]);
+        if (size < ram[i].size) {
+            memory_region_init_alias(&s->ram_alias, NULL, "ram.alias",
+                                     &s->ram[i], 0, ram[i].size - size);
+            memory_region_add_subregion(get_system_memory(),
+                                        ram[i].addr + size, &s->ram_alias);
+        }
+    }
+
+    imx25_pdk_binfo.ram_size = machine->ram_size;
+    imx25_pdk_binfo.kernel_filename = machine->kernel_filename;
+    imx25_pdk_binfo.kernel_cmdline = machine->kernel_cmdline;
+    imx25_pdk_binfo.initrd_filename = machine->initrd_filename;
+    imx25_pdk_binfo.loader_start = IMX25_PDK_ADDRESS;
+    imx25_pdk_binfo.board_id = 1771,
+    imx25_pdk_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_pdk_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_pdk_machine = {
+    .name = "imx25_pdk",
+    .desc = "ARM i.MX25 PDK board (ARM926)",
+    .init = imx25_pdk_init,
+};
+
+static void imx25_pdk_machine_init(void)
+{
+    qemu_register_machine(&imx25_pdk_machine);
+}
+
+machine_init(imx25_pdk_machine_init)
-- 
2.1.4

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

* [Qemu-devel] [PATCH v13 18/19] i.MX: Add qtest support for I2C device emulator.
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (16 preceding siblings ...)
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 17/19] i.MX: Add the i.MX25 PDK plateform Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-08-07 13:05   ` Peter Maydell
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 19/19] i.MX: Adding i2C devices to i.MX31 SOC Jean-Christophe Dubois
                   ` (2 subsequent siblings)
  20 siblings, 1 reply; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 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 3DS PDK 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.

Changes since v8:
    * no change

Changes since v9:
    * no change

Changes since v10:
    * no change

Changes since v11:
    * no change

Changes since v12:
    * no change

 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] 32+ messages in thread

* [Qemu-devel] [PATCH v13 19/19] i.MX: Adding i2C devices to i.MX31 SOC
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (17 preceding siblings ...)
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 18/19] i.MX: Add qtest support for I2C device emulator Jean-Christophe Dubois
@ 2015-07-16 21:21 ` Jean-Christophe Dubois
  2015-08-07 14:02   ` Peter Maydell
  2015-07-30 21:36 ` [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe DUBOIS
  2015-08-07 14:13 ` Peter Maydell
  20 siblings, 1 reply; 32+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-16 21:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jean-Christophe Dubois

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:
    * not present on v7

Changes since v8:
    * not present on v8

Changes since v9:
    * Added 3 I2C devices to i.MX31 SOC

Changes since v10:
    * no change.

Changes since v11:      
    * no change.

Changes since v12:      
    * no change.

 hw/arm/fsl-imx31.c         | 30 ++++++++++++++++++++++++++++++
 include/hw/arm/fsl-imx31.h | 12 ++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
index 8d349c9..fb46577 100644
--- a/hw/arm/fsl-imx31.c
+++ b/hw/arm/fsl-imx31.c
@@ -50,6 +50,11 @@ static void fsl_imx31_init(Object *obj)
         object_initialize(&s->epit[i], sizeof(s->epit[i]), TYPE_IMX_EPIT);
         qdev_set_parent_bus(DEVICE(&s->epit[i]), sysbus_get_default());
     }
+
+    for (i = 0; i < FSL_IMX31_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_imx31_realize(DeviceState *dev, Error **errp)
@@ -154,6 +159,31 @@ static void fsl_imx31_realize(DeviceState *dev, Error **errp)
                                             epit_table[i].irq));
     }
 
+    /* Initialize all I2C */
+    for (i = 0; i < FSL_IMX31_NUM_I2CS; i++) {
+        static const struct {
+            hwaddr addr;
+            unsigned int irq;
+        } i2c_table[FSL_IMX31_NUM_I2CS] = {
+            { FSL_IMX31_I2C1_ADDR, FSL_IMX31_I2C1_IRQ  },
+            { FSL_IMX31_I2C2_ADDR, FSL_IMX31_I2C2_IRQ  },
+            { FSL_IMX31_I2C3_ADDR, FSL_IMX31_I2C3_IRQ }
+        };
+
+        /* 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));
+    }
+
     /* On a real system, the first 16k is a `secure boot rom' */
     memory_region_init_rom_device(&s->secure_rom, NULL, NULL, NULL,
                                   "imx31.secure_rom",
diff --git a/include/hw/arm/fsl-imx31.h b/include/hw/arm/fsl-imx31.h
index d8a7e86..32744a1 100644
--- a/include/hw/arm/fsl-imx31.h
+++ b/include/hw/arm/fsl-imx31.h
@@ -23,6 +23,7 @@
 #include "hw/char/imx_serial.h"
 #include "hw/timer/imx_gpt.h"
 #include "hw/timer/imx_epit.h"
+#include "hw/i2c/imx_i2c.h"
 #include "exec/memory.h"
 
 #define TYPE_FSL_IMX31 "fsl,imx31"
@@ -30,6 +31,7 @@
 
 #define FSL_IMX31_NUM_UARTS 2
 #define FSL_IMX31_NUM_EPITS 2
+#define FSL_IMX31_NUM_I2CS 3
 
 typedef struct FslIMX31State{
     /*< private >*/
@@ -42,6 +44,7 @@ typedef struct FslIMX31State{
     IMXSerialState uart[FSL_IMX31_NUM_UARTS];
     IMXGPTState    gpt;
     IMXEPITState   epit[FSL_IMX31_NUM_EPITS];
+    IMXI2CState    i2c[FSL_IMX31_NUM_I2CS];
     MemoryRegion   secure_rom;
     MemoryRegion   rom;
     MemoryRegion   iram;
@@ -56,10 +59,16 @@ typedef struct FslIMX31State{
 #define FSL_IMX31_IRAM_ALIAS_SIZE	0xFFC0000
 #define FSL_IMX31_IRAM_ADDR		0x1FFFC000
 #define FSL_IMX31_IRAM_SIZE		0x4000
+#define FSL_IMX31_I2C1_ADDR		0x43F80000
+#define FSL_IMX31_I2C1_SIZE		0x4000
+#define FSL_IMX31_I2C3_ADDR		0x43F84000
+#define FSL_IMX31_I2C3_SIZE		0x4000
 #define FSL_IMX31_UART1_ADDR		0x43F90000
 #define FSL_IMX31_UART1_SIZE		0x4000
 #define FSL_IMX31_UART2_ADDR		0x43F94000
 #define FSL_IMX31_UART2_SIZE		0x4000
+#define FSL_IMX31_I2C2_ADDR		0x43F98000
+#define FSL_IMX31_I2C2_SIZE		0x4000
 #define FSL_IMX31_CCM_ADDR		0x53F80000
 #define FSL_IMX31_CCM_SIZE		0x4000
 #define FSL_IMX31_GPT_ADDR		0x53F90000
@@ -94,5 +103,8 @@ typedef struct FslIMX31State{
 #define FSL_IMX31_GPT_IRQ		29
 #define FSL_IMX31_UART2_IRQ		32
 #define FSL_IMX31_UART1_IRQ		45
+#define FSL_IMX31_I2C1_IRQ		10
+#define FSL_IMX31_I2C2_IRQ		4
+#define FSL_IMX31_I2C3_IRQ		3
 
 #endif /* FSL_IMX31_H */
-- 
2.1.4

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

* Re: [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (18 preceding siblings ...)
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 19/19] i.MX: Adding i2C devices to i.MX31 SOC Jean-Christophe Dubois
@ 2015-07-30 21:36 ` Jean-Christophe DUBOIS
  2015-07-30 22:32   ` Peter Maydell
  2015-08-07 14:13 ` Peter Maydell
  20 siblings, 1 reply; 32+ messages in thread
From: Jean-Christophe DUBOIS @ 2015-07-30 21:36 UTC (permalink / raw)
  To: qemu-devel

Hi,

Is there any more work needed on this series?

Regards

JC

Le 16/07/2015 23:21, Jean-Christophe Dubois a écrit :
> This series of patches add the support for the i.MX25 processor through the
> Freescale PDK evaluation board.
>
> For now a limited set of devices is supported.
>      * GPT timers (from i.MX31)
>      * EPIT timers (from i.MX31)
>      * Serial ports (from i.MX31)
>      * Ethernet FEC port
>      * I2C controller
>
> In the process the KZM platform was split into an i.MX31 SOC
> and a plateform part.
>
> Also, I2C devices was added to the i.MX31 SOC.
>
> This was tested by:
>      * booting a minimal linux system on the i.MX25 PDK platform
>      * booting the Xvisor hypervisor on the i.MX25 PDK platform
>      * booting a minimal linux system on the KZM platform
>
> Jean-Christophe Dubois (19):
>    i.MX: Split UART emulator in a header file and a source file
>    i.MX: Move serial initialization to init/realize of DeviceClass.
>    i.MX:Fix Coding style for UART emulator.
>    i.MX: Split AVIC emulator in a header file and a source file
>    i.MX: Fix Coding style for AVIC emulator.
>    i.MX: Split CCM emulator in a header file and a source file
>    i.MX: Fix Coding style for CCM emulator
>    i.MX: Split EPIT emulator in a header file and a source file
>    i.MX: Fix Coding style for EPIT emulator
>    i.MX: Split GPT emulator in a header file and a source file
>    i.MX: Fix Coding style for GPT emulator
>    i.MX: Add SOC support for i.MX31
>    i.MX: KZM now uses the standalone i.MX31 SOC support
>    i.MX: Add I2C controller emulator
>    i.MX: Add FEC Ethernet Emulator
>    i.MX: Add SOC support for i.MX25
>    i.MX: Add the i.MX25 PDK plateform
>    i.MX: Add qtest support for I2C device emulator.
>    i.MX: Adding i2C devices to i.MX31 SOC
>
>   default-configs/arm-softmmu.mak |   6 +
>   hw/arm/Makefile.objs            |   4 +-
>   hw/arm/fsl-imx25.c              | 260 +++++++++++++++
>   hw/arm/fsl-imx31.c              | 233 +++++++++++++
>   hw/arm/imx25_pdk.c              | 162 +++++++++
>   hw/arm/kzm.c                    | 205 ++++++------
>   hw/char/imx_serial.c            | 180 ++--------
>   hw/i2c/Makefile.objs            |   1 +
>   hw/i2c/imx_i2c.c                | 339 +++++++++++++++++++
>   hw/intc/imx_avic.c              |  56 +---
>   hw/misc/imx_ccm.c               |  81 +----
>   hw/net/Makefile.objs            |   1 +
>   hw/net/imx_fec.c                | 709 ++++++++++++++++++++++++++++++++++++++++
>   hw/timer/imx_epit.c             |  75 +----
>   hw/timer/imx_gpt.c              |  96 +-----
>   include/hw/arm/fsl-imx25.h      | 234 +++++++++++++
>   include/hw/arm/fsl-imx31.h      | 110 +++++++
>   include/hw/arm/imx.h            |  34 --
>   include/hw/char/imx_serial.h    | 102 ++++++
>   include/hw/i2c/imx_i2c.h        |  85 +++++
>   include/hw/intc/imx_avic.h      |  55 ++++
>   include/hw/misc/imx_ccm.h       |  91 ++++++
>   include/hw/net/imx_fec.h        | 113 +++++++
>   include/hw/timer/imx_epit.h     |  79 +++++
>   include/hw/timer/imx_gpt.h      | 107 ++++++
>   tests/Makefile                  |   3 +
>   tests/ds1338-test.c             |  75 +++++
>   tests/libqos/i2c-imx.c          | 209 ++++++++++++
>   tests/libqos/i2c.h              |   3 +
>   29 files changed, 3151 insertions(+), 557 deletions(-)
>   create mode 100644 hw/arm/fsl-imx25.c
>   create mode 100644 hw/arm/fsl-imx31.c
>   create mode 100644 hw/arm/imx25_pdk.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
>   create mode 100644 include/hw/arm/fsl-imx31.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
>

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

* Re: [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board
  2015-07-30 21:36 ` [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe DUBOIS
@ 2015-07-30 22:32   ` Peter Maydell
  0 siblings, 0 replies; 32+ messages in thread
From: Peter Maydell @ 2015-07-30 22:32 UTC (permalink / raw)
  To: Jean-Christophe DUBOIS; +Cc: Peter Crosthwaite, QEMU Developers

On 30 July 2015 at 22:36, Jean-Christophe DUBOIS <jcd@tribudubois.net> wrote:
> Is there any more work needed on this series?

I was expecting Peter C to review this, but he might be busy just
now, and I see he already reviewed most of the patches in the
set anyway. It's on my todo list; I'll try to get to it tomorrow
or early next week. We have a little time yet until 2.4 releases
and we can put things in master for 2.5 anyway...

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v13 18/19] i.MX: Add qtest support for I2C device emulator.
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 18/19] i.MX: Add qtest support for I2C device emulator Jean-Christophe Dubois
@ 2015-08-07 13:05   ` Peter Maydell
  2015-08-10 16:19     ` Jean-Christophe DUBOIS
  0 siblings, 1 reply; 32+ messages in thread
From: Peter Maydell @ 2015-08-07 13:05 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: QEMU Developers

On 16 July 2015 at 22:21, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
> This is using a ds1338 RTC chip on the I2C bus. This RTC chip is
> not present on the real 3DS PDK board.
>
> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>

'make check' doesn't pass with this patch, because it tries to start
an "imx25_3ds" machine, which doesn't exist.

> +#define bcd2bin(x)        (((x) & 0x0f) + ((x) >> 4) * 10)

Why not just make this an inline function?

> +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 */

"retrieved"

-- PMM

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

* Re: [Qemu-devel] [PATCH v13 13/19] i.MX: KZM now uses the standalone i.MX31 SOC support
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 13/19] i.MX: KZM now uses the standalone i.MX31 SOC support Jean-Christophe Dubois
@ 2015-08-07 13:45   ` Peter Maydell
  2015-08-10 16:15     ` Jean-Christophe DUBOIS
  0 siblings, 1 reply; 32+ messages in thread
From: Peter Maydell @ 2015-08-07 13:45 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: QEMU Developers

On 16 July 2015 at 22:21, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
> Tested by booting a minimal Linux system on the emulated platform
>
> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
> ---

This said:

> -     * 0x80000000-0x87ffffff RAM                  EMULATED
> -     * 0x88000000-0x8fffffff RAM Aliasing         EMULATED

but your patch changes it:

> + * 0x00000000-0x7fffffff See i.MX31 SOC for support
> + * 0x80000000-0x8fffffff RAM                  EMULATED
> + * 0x90000000-0x9fffffff RAM                  EMULATED

> +    /* initialize our memory */
> +    for (i=0, ram_size = machine->ram_size; (i<2) && ram_size; i++) {
> +        unsigned int size;
> +        char ram_name[20];
> +        static const struct {
> +            hwaddr addr;
> +            unsigned int size;
> +        } ram[2] = {
> +            { FSL_IMX31_SDRAM0_ADDR, FSL_IMX31_SDRAM0_SIZE },
> +            { FSL_IMX31_SDRAM1_ADDR, FSL_IMX31_SDRAM1_SIZE },
> +        };
> +
> +       if (ram_size > ram[i].size) {
> +            size = ram[i].size;
> +       } else {
> +            size = ram_size;
> +       }
> +
> +        sprintf(ram_name, "kzm.ram%d", i);
> +
> +        ram_size -= size;
> +
> +        memory_region_allocate_system_memory(&s->ram[i], NULL, ram_name, size);

memory_region_allocate_system_memory() needs to be called once and
only once by a board init. You're going to end up calling it twice here.

> +        memory_region_add_subregion(get_system_memory(), ram[i].addr,
> +                                    &s->ram[i]);
> +        if (size < ram[i].size) {
> +            memory_region_init_alias(&s->ram_alias, NULL, "ram.alias",
> +                                     &s->ram[i], 0, ram[i].size - size);
> +            memory_region_add_subregion(get_system_memory(),
> +                                        ram[i].addr + size, &s->ram_alias);
> +        }
> +    }

What is this code trying to do with that alias? It looks very odd.
(Are we trying to model under-decoded address bits?)

My instinct is to say that rather than modelling two separate lumps
of RAM we should just have one region -- they're contiguous, after
all.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v13 16/19] i.MX: Add SOC support for i.MX25
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 16/19] i.MX: Add SOC support for i.MX25 Jean-Christophe Dubois
@ 2015-08-07 13:50   ` Peter Maydell
  0 siblings, 0 replies; 32+ messages in thread
From: Peter Maydell @ 2015-08-07 13:50 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: QEMU Developers, Peter Crosthwaite

On 16 July 2015 at 22:21, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
>     For now we support the following devices:
>       * CPU: ARM926
>       * Interrupt Controller: AVIC
>       * CCM
>       * UART x 5
>       * EPIT x 2
>       * GPT x 4
>       * FEC
>       * I2C x 3
>
> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>

> +static void fsl_imx25_realize(DeviceState *dev, Error **errp)
> +{
> +    FslIMX25State *s = FSL_IMX25(dev);
> +    uint8_t i;
> +    Error *err = NULL;
> +
> +    object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
> +    if (err) {
> +        error_propagate((errp), (err));

What's with the extra brackets?

> +        return;
> +    }
> +
> +    object_property_set_bool(OBJECT(&s->avic), true, "realized", &err);
> +    if (err) {
> +        error_propagate((errp), (err));
> +        return;
> +    }
> +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->avic), 0, FSL_IMX25_AVIC_ADDR);

Having SoC realize functions map devices into the system address
space doesn't really seem right to me, but are we already doing this
elsewhere?

> +    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));
> +
> +    object_property_set_bool(OBJECT(&s->ccm), true, "realized", &err);
> +    if (err) {
> +        error_propagate((errp), (err));
> +        return;
> +    }
> +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX25_CCM_ADDR);
> +
> +    /* Initialize all UARTS */

"UARTs"

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v13 19/19] i.MX: Adding i2C devices to i.MX31 SOC
  2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 19/19] i.MX: Adding i2C devices to i.MX31 SOC Jean-Christophe Dubois
@ 2015-08-07 14:02   ` Peter Maydell
  0 siblings, 0 replies; 32+ messages in thread
From: Peter Maydell @ 2015-08-07 14:02 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: QEMU Developers

On 16 July 2015 at 22:21, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>

The usual commit message verb form is "Add foo", not "Adding foo".
Empty commit message bodies are also generally worth avoiding.

> @@ -154,6 +159,31 @@ static void fsl_imx31_realize(DeviceState *dev, Error **errp)
>                                              epit_table[i].irq));
>      }
>
> +    /* Initialize all I2C */
> +    for (i = 0; i < FSL_IMX31_NUM_I2CS; i++) {
> +        static const struct {
> +            hwaddr addr;
> +            unsigned int irq;
> +        } i2c_table[FSL_IMX31_NUM_I2CS] = {
> +            { FSL_IMX31_I2C1_ADDR, FSL_IMX31_I2C1_IRQ  },
> +            { FSL_IMX31_I2C2_ADDR, FSL_IMX31_I2C2_IRQ  },
> +            { FSL_IMX31_I2C3_ADDR, FSL_IMX31_I2C3_IRQ }

Inconsistent spacing.

> +        };
> +
> +        /* Initialize the I2C */
> +        object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized", &err);
> +        if (err) {
> +            error_propagate((errp), (err));

Unnecessary brackets.

> +            return;
> +        }
> +        /* Map I2C memory */
> +        sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr);
> +        /* Connet I2C IRQ to PIC */

"Connect".

> +        sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
> +                           qdev_get_gpio_in(DEVICE(&s->avic),
> +                                            i2c_table[i].irq));
> +    }

Looks OK otherwise, though I haven't checked against hw specs
and don't have any test images for this SoC.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board
  2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
                   ` (19 preceding siblings ...)
  2015-07-30 21:36 ` [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe DUBOIS
@ 2015-08-07 14:13 ` Peter Maydell
  2015-08-10 16:20   ` Jean-Christophe DUBOIS
  20 siblings, 1 reply; 32+ messages in thread
From: Peter Maydell @ 2015-08-07 14:13 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: QEMU Developers

On 16 July 2015 at 22:21, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
> This series of patches add the support for the i.MX25 processor through the
> Freescale PDK evaluation board.
>
> For now a limited set of devices is supported.
>     * GPT timers (from i.MX31)
>     * EPIT timers (from i.MX31)
>     * Serial ports (from i.MX31)
>     * Ethernet FEC port
>     * I2C controller
>
> In the process the KZM platform was split into an i.MX31 SOC
> and a plateform part.
>
> Also, I2C devices was added to the i.MX31 SOC.
>
> This was tested by:
>     * booting a minimal linux system on the i.MX25 PDK platform
>     * booting the Xvisor hypervisor on the i.MX25 PDK platform
>     * booting a minimal linux system on the KZM platform
>
> Jean-Christophe Dubois (19):
>   i.MX: Split UART emulator in a header file and a source file
>   i.MX: Move serial initialization to init/realize of DeviceClass.
>   i.MX:Fix Coding style for UART emulator.
>   i.MX: Split AVIC emulator in a header file and a source file
>   i.MX: Fix Coding style for AVIC emulator.
>   i.MX: Split CCM emulator in a header file and a source file
>   i.MX: Fix Coding style for CCM emulator
>   i.MX: Split EPIT emulator in a header file and a source file
>   i.MX: Fix Coding style for EPIT emulator
>   i.MX: Split GPT emulator in a header file and a source file
>   i.MX: Fix Coding style for GPT emulator

I have some review comments on the later patches, but I've taken
this first set of code cleanup patches into my target-arm-post-2.4
tree, which should reduce the size of your patchset and make it a bit
easier to deal with.

(https://git.linaro.org/people/peter.maydell/qemu-arm.git target-arm-post-2.4
 -- caution, branch rebases. Will go into master once it reopens
post-release.)

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v13 13/19] i.MX: KZM now uses the standalone i.MX31 SOC support
  2015-08-07 13:45   ` Peter Maydell
@ 2015-08-10 16:15     ` Jean-Christophe DUBOIS
  2015-08-10 16:23       ` Peter Maydell
  0 siblings, 1 reply; 32+ messages in thread
From: Jean-Christophe DUBOIS @ 2015-08-10 16:15 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

[-- Attachment #1: Type: text/plain, Size: 3921 bytes --]

Le 07/08/2015 15:45, Peter Maydell a écrit :
> On 16 July 2015 at 22:21, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
>> Tested by booting a minimal Linux system on the emulated platform
>>
>> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
>> ---
> This said:
>
>> -     * 0x80000000-0x87ffffff RAM                  EMULATED
>> -     * 0x88000000-0x8fffffff RAM Aliasing         EMULATED
> but your patch changes it:
>
>> + * 0x00000000-0x7fffffff See i.MX31 SOC for support
>> + * 0x80000000-0x8fffffff RAM                  EMULATED
>> + * 0x90000000-0x9fffffff RAM                  EMULATED
The i.MX31 has 2 SDRAM controllers:

  *

    0x80000000-0x8fffffff:First SDRAM controller. There is memory aliasing if we have less than 256 MB of memory in this slot.

  *

    0x90000000-0x9fffffff:Second SDRAM controller. There is memory aliasing if we have less than 256 MB of memory in this slot.

>> +    /* initialize our memory */
>> +    for (i=0, ram_size = machine->ram_size; (i<2) && ram_size; i++) {
>> +        unsigned int size;
>> +        char ram_name[20];
>> +        static const struct {
>> +            hwaddr addr;
>> +            unsigned int size;
>> +        } ram[2] = {
>> +            { FSL_IMX31_SDRAM0_ADDR, FSL_IMX31_SDRAM0_SIZE },
>> +            { FSL_IMX31_SDRAM1_ADDR, FSL_IMX31_SDRAM1_SIZE },
>> +        };
>> +
>> +       if (ram_size > ram[i].size) {
>> +            size = ram[i].size;
>> +       } else {
>> +            size = ram_size;
>> +       }
>> +
>> +        sprintf(ram_name, "kzm.ram%d", i);
>> +
>> +        ram_size -= size;
>> +
>> +        memory_region_allocate_system_memory(&s->ram[i], NULL, ram_name, size);
> memory_region_allocate_system_memory() needs to be called once and
> only once by a board init. You're going to end up calling it twice here.

Actually, I may be calling it up 3 time because there is also an 
internal (16KB) memory range that is allocated during the SOC init 
(fsl-imx31.c file).

Now as my memory (the 3 memory banks) is  (partially) discontiguous how 
am I suppose to init all of it in one call?

And if memory_region_allocate_system_memory() should really be called 
only once, why is it not enforced in this function? After all, 
memory_region_allocate_system_memory() only calls 
memory_region_init_ram() and vmstate_register_ram_global() in one step ...

>
>> +        memory_region_add_subregion(get_system_memory(), ram[i].addr,
>> +                                    &s->ram[i]);
>> +        if (size < ram[i].size) {
>> +            memory_region_init_alias(&s->ram_alias, NULL, "ram.alias",
>> +                                     &s->ram[i], 0, ram[i].size - size);
>> +            memory_region_add_subregion(get_system_memory(),
>> +                                        ram[i].addr + size, &s->ram_alias);
>> +        }
>> +    }
> What is this code trying to do with that alias? It looks very odd.
> (Are we trying to model under-decoded address bits?)
Yes in case the RAM size does not take all of the SDRAM controller 
window size (this is more or less what was done in the previous kzm code 
but for only one SDRAM controller).

Actually I am trying to allow a KZM board with a memory that can vary 
from 0MB to 512MB (instead of 0MB to 256 MB as before). This might be 
more than what the real board allow (I am not sure) but why not if the 
user needs more memory?
>
> My instinct is to say that rather than modelling two separate lumps
> of RAM we should just have one region -- they're contiguous, after
> all.
If the requested RAM is smaller than the SDRAM controller window, the 
function is only called once. It is called twice here if the requested 
RAM exceed the SDRAM first controller window.

And I still have this 16 KB internal memory to allocate/initialize.

>
> thanks
> -- PMM
>


[-- Attachment #2: Type: text/html, Size: 5810 bytes --]

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

* Re: [Qemu-devel] [PATCH v13 18/19] i.MX: Add qtest support for I2C device emulator.
  2015-08-07 13:05   ` Peter Maydell
@ 2015-08-10 16:19     ` Jean-Christophe DUBOIS
  0 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe DUBOIS @ 2015-08-10 16:19 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

Le 07/08/2015 15:05, Peter Maydell a écrit :
> On 16 July 2015 at 22:21, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
>> This is using a ds1338 RTC chip on the I2C bus. This RTC chip is
>> not present on the real 3DS PDK board.
>>
>> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
> 'make check' doesn't pass with this patch, because it tries to start
> an "imx25_3ds" machine, which doesn't exist.

Thanks, I will fix it.
>
>> +#define bcd2bin(x)        (((x) & 0x0f) + ((x) >> 4) * 10)
> Why not just make this an inline function?
>
>> +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 */
> "retrieved"
>
> -- PMM
>

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

* Re: [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board
  2015-08-07 14:13 ` Peter Maydell
@ 2015-08-10 16:20   ` Jean-Christophe DUBOIS
  0 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe DUBOIS @ 2015-08-10 16:20 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

Le 07/08/2015 16:13, Peter Maydell a écrit :
> On 16 July 2015 at 22:21, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
>> This series of patches add the support for the i.MX25 processor through the
>> Freescale PDK evaluation board.
>>
>> For now a limited set of devices is supported.
>>      * GPT timers (from i.MX31)
>>      * EPIT timers (from i.MX31)
>>      * Serial ports (from i.MX31)
>>      * Ethernet FEC port
>>      * I2C controller
>>
>> In the process the KZM platform was split into an i.MX31 SOC
>> and a plateform part.
>>
>> Also, I2C devices was added to the i.MX31 SOC.
>>
>> This was tested by:
>>      * booting a minimal linux system on the i.MX25 PDK platform
>>      * booting the Xvisor hypervisor on the i.MX25 PDK platform
>>      * booting a minimal linux system on the KZM platform
>>
>> Jean-Christophe Dubois (19):
>>    i.MX: Split UART emulator in a header file and a source file
>>    i.MX: Move serial initialization to init/realize of DeviceClass.
>>    i.MX:Fix Coding style for UART emulator.
>>    i.MX: Split AVIC emulator in a header file and a source file
>>    i.MX: Fix Coding style for AVIC emulator.
>>    i.MX: Split CCM emulator in a header file and a source file
>>    i.MX: Fix Coding style for CCM emulator
>>    i.MX: Split EPIT emulator in a header file and a source file
>>    i.MX: Fix Coding style for EPIT emulator
>>    i.MX: Split GPT emulator in a header file and a source file
>>    i.MX: Fix Coding style for GPT emulator
> I have some review comments on the later patches, but I've taken
> this first set of code cleanup patches into my target-arm-post-2.4
> tree, which should reduce the size of your patchset and make it a bit
> easier to deal with.
>
> (https://git.linaro.org/people/peter.maydell/qemu-arm.git target-arm-post-2.4
>   -- caution, branch rebases. Will go into master once it reopens
> post-release.)

Ok, I will submit my next patches based on your target-arm-post-2.4 branch.
>
> thanks
> -- PMM
>

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

* Re: [Qemu-devel] [PATCH v13 13/19] i.MX: KZM now uses the standalone i.MX31 SOC support
  2015-08-10 16:15     ` Jean-Christophe DUBOIS
@ 2015-08-10 16:23       ` Peter Maydell
  2015-08-10 17:01         ` Jean-Christophe DUBOIS
  0 siblings, 1 reply; 32+ messages in thread
From: Peter Maydell @ 2015-08-10 16:23 UTC (permalink / raw)
  To: Jean-Christophe DUBOIS; +Cc: Paolo Bonzini, QEMU Developers

On 10 August 2015 at 17:15, Jean-Christophe DUBOIS <jcd@tribudubois.net> wrote:
> Le 07/08/2015 15:45, Peter Maydell a écrit :
>
> On 16 July 2015 at 22:21, Jean-Christophe Dubois <jcd@tribudubois.net>
> wrote:

>
> memory_region_allocate_system_memory() needs to be called once and
> only once by a board init. You're going to end up calling it twice here.
>
>
> Actually, I may be calling it up 3 time because there is also an internal
> (16KB) memory range that is allocated during the SOC init (fsl-imx31.c
> file).

Small blocks of stuff like 16KB are not the "main lump of RAM", so
should not be initialized with memory_region_allocate_system_memory().
Use memory_region_init_ram() followed by vmstate_register_ram_global()
for that sort of small RAM region.

> Now as my memory (the 3 memory banks) is  (partially) discontiguous how am I
> suppose to init all of it in one call?

Your main RAM will be all contiguous, the only reason it would be
discontiguous is if you were trying to model 128MB + 128MB,
which you can't specify anyway with a single 'this much memory' ram_size
argument.

> And if memory_region_allocate_system_memory() should really be called only
> once, why is it not enforced in this function? After all,
> memory_region_allocate_system_memory() only calls memory_region_init_ram()
> and vmstate_register_ram_global() in one step ...

It does a lot more complicated things than that, potentially.
I agree that it ought to assert the once-and-only-once property;
in fact I suggested on IRC last week that that would be a good
plan, since it's an easy mistake to make.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v13 13/19] i.MX: KZM now uses the standalone i.MX31 SOC support
  2015-08-10 16:23       ` Peter Maydell
@ 2015-08-10 17:01         ` Jean-Christophe DUBOIS
  0 siblings, 0 replies; 32+ messages in thread
From: Jean-Christophe DUBOIS @ 2015-08-10 17:01 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Paolo Bonzini, QEMU Developers

[-- Attachment #1: Type: text/plain, Size: 2159 bytes --]

Le 10/08/2015 18:23, Peter Maydell a écrit :
> On 10 August 2015 at 17:15, Jean-Christophe DUBOIS <jcd@tribudubois.net> wrote:
>> Le 07/08/2015 15:45, Peter Maydell a écrit :
>>
>> On 16 July 2015 at 22:21, Jean-Christophe Dubois <jcd@tribudubois.net>
>> wrote:
>> memory_region_allocate_system_memory() needs to be called once and
>> only once by a board init. You're going to end up calling it twice here.
>>
>>
>> Actually, I may be calling it up 3 time because there is also an internal
>> (16KB) memory range that is allocated during the SOC init (fsl-imx31.c
>> file).
> Small blocks of stuff like 16KB are not the "main lump of RAM", so
> should not be initialized with memory_region_allocate_system_memory().
> Use memory_region_init_ram() followed by vmstate_register_ram_global()
> for that sort of small RAM region.

OK, I'll do it but it seems to me that in our case 
memory_region_allocate_system_memory() basically do:

  * memory_region_init_ram()
  * vmstate_register_ram_global()

>
>> Now as my memory (the 3 memory banks) is  (partially) discontiguous how am I
>> suppose to init all of it in one call?
> Your main RAM will be all contiguous, the only reason it would be
> discontiguous is if you were trying to model 128MB + 128MB,
> which you can't specify anyway with a single 'this much memory' ram_size
> argument.

Yes, It will make things a little more complex for the alias memory (if 
any).
I'll work something up.

>
>> And if memory_region_allocate_system_memory() should really be called only
>> once, why is it not enforced in this function? After all,
>> memory_region_allocate_system_memory() only calls memory_region_init_ram()
>> and vmstate_register_ram_global() in one step ...
> It does a lot more complicated things than that, potentially.

For NUMA platforms, it seems. But in our simple case it seems that it 
doesn't do a lot more. But OK, I'll change things.

> I agree that it ought to assert the once-and-only-once property;
> in fact I suggested on IRC last week that that would be a good
> plan, since it's an easy mistake to make.
>
> thanks
> -- PMM
>


[-- Attachment #2: Type: text/html, Size: 3694 bytes --]

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

end of thread, other threads:[~2015-08-10 17:01 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-16 21:21 [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 01/19] i.MX: Split UART emulator in a header file and a source file Jean-Christophe Dubois
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 02/19] i.MX: Move serial initialization to init/realize of DeviceClass Jean-Christophe Dubois
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 03/19] i.MX:Fix Coding style for UART emulator Jean-Christophe Dubois
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 04/19] i.MX: Split AVIC emulator in a header file and a source file Jean-Christophe Dubois
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 05/19] i.MX: Fix Coding style for AVIC emulator Jean-Christophe Dubois
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 06/19] i.MX: Split CCM emulator in a header file and a source file Jean-Christophe Dubois
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 07/19] i.MX: Fix Coding style for CCM emulator Jean-Christophe Dubois
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 08/19] i.MX: Split EPIT emulator in a header file and a source file Jean-Christophe Dubois
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 09/19] i.MX: Fix Coding style for EPIT emulator Jean-Christophe Dubois
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 10/19] i.MX: Split GPT emulator in a header file and a source file Jean-Christophe Dubois
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 11/19] i.MX: Fix Coding style for GPT emulator Jean-Christophe Dubois
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 12/19] i.MX: Add SOC support for i.MX31 Jean-Christophe Dubois
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 13/19] i.MX: KZM now uses the standalone i.MX31 SOC support Jean-Christophe Dubois
2015-08-07 13:45   ` Peter Maydell
2015-08-10 16:15     ` Jean-Christophe DUBOIS
2015-08-10 16:23       ` Peter Maydell
2015-08-10 17:01         ` Jean-Christophe DUBOIS
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 14/19] i.MX: Add I2C controller emulator Jean-Christophe Dubois
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 15/19] i.MX: Add FEC Ethernet Emulator Jean-Christophe Dubois
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 16/19] i.MX: Add SOC support for i.MX25 Jean-Christophe Dubois
2015-08-07 13:50   ` Peter Maydell
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 17/19] i.MX: Add the i.MX25 PDK plateform Jean-Christophe Dubois
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 18/19] i.MX: Add qtest support for I2C device emulator Jean-Christophe Dubois
2015-08-07 13:05   ` Peter Maydell
2015-08-10 16:19     ` Jean-Christophe DUBOIS
2015-07-16 21:21 ` [Qemu-devel] [PATCH v13 19/19] i.MX: Adding i2C devices to i.MX31 SOC Jean-Christophe Dubois
2015-08-07 14:02   ` Peter Maydell
2015-07-30 21:36 ` [Qemu-devel] [PATCH v13 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe DUBOIS
2015-07-30 22:32   ` Peter Maydell
2015-08-07 14:13 ` Peter Maydell
2015-08-10 16:20   ` Jean-Christophe DUBOIS

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