* [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board
@ 2015-07-10 23:31 Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 01/19] i.MX: Split UART emulator in a header file and a source file Jean-Christophe Dubois
` (18 more replies)
0 siblings, 19 replies; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 01/19] i.MX: Split UART emulator in a header file and a source file
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 02/19] i.MX: Move serial initialization to init/realize of DeviceClass Jean-Christophe Dubois
` (17 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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
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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 02/19] i.MX: Move serial initialization to init/realize of DeviceClass.
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 01/19] i.MX: Split UART emulator in a header file and a source file Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-07-15 7:38 ` Peter Crosthwaite
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 03/19] i.MX:Fix Coding style for UART emulator Jean-Christophe Dubois
` (16 subsequent siblings)
18 siblings, 1 reply; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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>
---
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.
hw/char/imx_serial.c | 39 +++++++++++++++++++++------------------
1 file changed, 21 insertions(+), 18 deletions(-)
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index 1dcb325..180bc45 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -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[]) {
@@ -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);
}
+}
- return 0;
+static void imx_serial_init(Object *obj)
+{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+ IMXSerialState *s = IMX_SERIAL(obj);
+
+ memory_region_init_io(&s->iomem, obj, &imx_serial_ops, s,
+ TYPE_IMX_SERIAL, 0x1000);
+ sysbus_init_mmio(sbd, &s->iomem);
+ sysbus_init_irq(sbd, &s->irq);
}
void imx_serial_create(int uart, const hwaddr addr, qemu_irq irq)
@@ -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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 03/19] i.MX:Fix Coding style for UART emulator.
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 01/19] i.MX: Split UART emulator in a header file and a source file Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 02/19] i.MX: Move serial initialization to init/realize of DeviceClass Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-07-15 7:43 ` Peter Crosthwaite
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 04/19] i.MX: Split AVIC emulator in a header file and a source file Jean-Christophe Dubois
` (15 subsequent siblings)
18 siblings, 1 reply; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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 preset on v7
Changes since v8:
* Fix coding style
Changes since v9:
* no change
Changes since v10:
* no change
Changes since v11:
* no change
hw/char/imx_serial.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index 180bc45..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
@@ -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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 04/19] i.MX: Split AVIC emulator in a header file and a source file
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
` (2 preceding siblings ...)
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 03/19] i.MX:Fix Coding style for UART emulator Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 05/19] i.MX: Fix Coding style for AVIC emulator Jean-Christophe Dubois
` (14 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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
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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 05/19] i.MX: Fix Coding style for AVIC emulator.
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
` (3 preceding siblings ...)
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 04/19] i.MX: Split AVIC emulator in a header file and a source file Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-07-15 7:44 ` Peter Crosthwaite
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 06/19] i.MX: Split CCM emulator in a header file and a source file Jean-Christophe Dubois
` (13 subsequent siblings)
18 siblings, 1 reply; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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:
* improve log
* Do style cleaning
Changes since v9:
* Change patch title.
Changes since v10:
* no change.
Changes since v11:
* 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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 06/19] i.MX: Split CCM emulator in a header file and a source file
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
` (4 preceding siblings ...)
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 05/19] i.MX: Fix Coding style for AVIC emulator Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 07/19] i.MX: Fix Coding style for CCM emulator Jean-Christophe Dubois
` (12 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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
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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 07/19] i.MX: Fix Coding style for CCM emulator
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
` (5 preceding siblings ...)
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 06/19] i.MX: Split CCM emulator in a header file and a source file Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-07-15 7:48 ` Peter Crosthwaite
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 08/19] i.MX: Split EPIT emulator in a header file and a source file Jean-Christophe Dubois
` (11 subsequent siblings)
18 siblings, 1 reply; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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:
* Improve logs
Changes since v9:
* Change patch title.
Changes since v10:
* no change.
Changes since v11:
* 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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 08/19] i.MX: Split EPIT emulator in a header file and a source file
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
` (6 preceding siblings ...)
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 07/19] i.MX: Fix Coding style for CCM emulator Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 09/19] i.MX: Fix Coding style for EPIT emulator Jean-Christophe Dubois
` (10 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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
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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 09/19] i.MX: Fix Coding style for EPIT emulator
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
` (7 preceding siblings ...)
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 08/19] i.MX: Split EPIT emulator in a header file and a source file Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-07-15 7:51 ` Peter Crosthwaite
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 10/19] i.MX: Split GPT emulator in a header file and a source file Jean-Christophe Dubois
` (9 subsequent siblings)
18 siblings, 1 reply; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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:
* Fix coding style
Changes since v9:
* no change
Changes since v10:
* no change.
Changes since v11:
* 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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 10/19] i.MX: Split GPT emulator in a header file and a source file
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
` (8 preceding siblings ...)
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 09/19] i.MX: Fix Coding style for EPIT emulator Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 11/19] i.MX: Fix Coding style for GPT emulator Jean-Christophe Dubois
` (8 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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
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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 11/19] i.MX: Fix Coding style for GPT emulator
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
` (9 preceding siblings ...)
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 10/19] i.MX: Split GPT emulator in a header file and a source file Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-07-15 7:53 ` Peter Crosthwaite
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 12/19] i.MX: Add SOC support for i.MX31 Jean-Christophe Dubois
` (7 subsequent siblings)
18 siblings, 1 reply; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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:
* Fix coding style
Changes since v9:
* no change
Changes since v10:
* no change.
Changes since v11:
* 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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 12/19] i.MX: Add SOC support for i.MX31
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
` (10 preceding siblings ...)
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 11/19] i.MX: Fix Coding style for GPT emulator Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 13/19] i.MX: KZM now uses the standalone i.MX31 SOC support Jean-Christophe Dubois
` (6 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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.
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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 13/19] i.MX: KZM now uses the standalone i.MX31 SOC support
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
` (11 preceding siblings ...)
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 12/19] i.MX: Add SOC support for i.MX31 Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 14/19] i.MX: Add I2C controller emulator Jean-Christophe Dubois
` (5 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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.
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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 14/19] i.MX: Add I2C controller emulator
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
` (12 preceding siblings ...)
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 13/19] i.MX: KZM now uses the standalone i.MX31 SOC support Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 15/19] i.MX: Add FEC Ethernet Emulator Jean-Christophe Dubois
` (4 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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.
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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 15/19] i.MX: Add FEC Ethernet Emulator
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
` (13 preceding siblings ...)
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 14/19] i.MX: Add I2C controller emulator Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 16/19] i.MX: Add SOC support for i.MX25 Jean-Christophe Dubois
` (3 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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
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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 16/19] i.MX: Add SOC support for i.MX25
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
` (14 preceding siblings ...)
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 15/19] i.MX: Add FEC Ethernet Emulator Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 17/19] i.MX: Add the i.MX25 PDK plateform Jean-Christophe Dubois
` (2 subsequent siblings)
18 siblings, 0 replies; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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
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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 17/19] i.MX: Add the i.MX25 PDK plateform
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
` (15 preceding siblings ...)
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 16/19] i.MX: Add SOC support for i.MX25 Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-08-07 13:55 ` Peter Maydell
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 18/19] i.MX: Add qtest support for I2C device emulator Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 19/19] i.MX: Adding i2C devices to i.MX31 SOC Jean-Christophe Dubois
18 siblings, 1 reply; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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
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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 18/19] i.MX: Add qtest support for I2C device emulator.
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
` (16 preceding siblings ...)
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 17/19] i.MX: Add the i.MX25 PDK plateform Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 19/19] i.MX: Adding i2C devices to i.MX31 SOC Jean-Christophe Dubois
18 siblings, 0 replies; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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
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] 27+ messages in thread
* [Qemu-devel] [PATCH v12 19/19] i.MX: Adding i2C devices to i.MX31 SOC
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
` (17 preceding siblings ...)
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 18/19] i.MX: Add qtest support for I2C device emulator Jean-Christophe Dubois
@ 2015-07-10 23:31 ` Jean-Christophe Dubois
18 siblings, 0 replies; 27+ messages in thread
From: Jean-Christophe Dubois @ 2015-07-10 23:31 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.
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] 27+ messages in thread
* Re: [Qemu-devel] [PATCH v12 02/19] i.MX: Move serial initialization to init/realize of DeviceClass.
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 02/19] i.MX: Move serial initialization to init/realize of DeviceClass Jean-Christophe Dubois
@ 2015-07-15 7:38 ` Peter Crosthwaite
0 siblings, 0 replies; 27+ messages in thread
From: Peter Crosthwaite @ 2015-07-15 7:38 UTC (permalink / raw)
To: Jean-Christophe Dubois; +Cc: qemu-devel@nongnu.org Developers
On Fri, Jul 10, 2015 at 4:31 PM, Jean-Christophe Dubois
<jcd@tribudubois.net> wrote:
> 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>
> ---
>
> 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.
>
> hw/char/imx_serial.c | 39 +++++++++++++++++++++------------------
> 1 file changed, 21 insertions(+), 18 deletions(-)
>
> diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
> index 1dcb325..180bc45 100644
> --- a/hw/char/imx_serial.c
> +++ b/hw/char/imx_serial.c
> @@ -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)
This hunk.
> #else
> # define IPRINTF(fmt, args...) do {} while (0)
> #endif
>
> static const VMStateDescription vmstate_imx_serial = {
> - .name = "imx-serial",
> + .name = TYPE_IMX_SERIAL,
and this go to patch 3.
Otherwise,
Reviewed-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Regards,
Peter
> .version_id = 1,
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> @@ -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);
> }
> +}
>
> - return 0;
> +static void imx_serial_init(Object *obj)
> +{
> + SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
> + IMXSerialState *s = IMX_SERIAL(obj);
> +
> + memory_region_init_io(&s->iomem, obj, &imx_serial_ops, s,
> + TYPE_IMX_SERIAL, 0x1000);
> + sysbus_init_mmio(sbd, &s->iomem);
> + sysbus_init_irq(sbd, &s->irq);
> }
>
> void imx_serial_create(int uart, const hwaddr addr, qemu_irq irq)
> @@ -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 [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH v12 03/19] i.MX:Fix Coding style for UART emulator.
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 03/19] i.MX:Fix Coding style for UART emulator Jean-Christophe Dubois
@ 2015-07-15 7:43 ` Peter Crosthwaite
0 siblings, 0 replies; 27+ messages in thread
From: Peter Crosthwaite @ 2015-07-15 7:43 UTC (permalink / raw)
To: Jean-Christophe Dubois; +Cc: qemu-devel@nongnu.org Developers
On Fri, Jul 10, 2015 at 4:31 PM, Jean-Christophe Dubois
<jcd@tribudubois.net> wrote:
> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
Reviewed-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
One minor optional nit below.
> ---
>
> 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
>
> hw/char/imx_serial.c | 30 +++++++++++++++---------------
> 1 file changed, 15 insertions(+), 15 deletions(-)
>
> diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
> index 180bc45..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
> @@ -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
> + */
This change is correct, in that comment goes with the case so needs a
de-indent for current position ...
> case 0x29: /* UBIR */
... but re-locating the comment here will be more consistent with
surrounding code and is a more adopted style.
Regards,
Peter
> 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 [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH v12 05/19] i.MX: Fix Coding style for AVIC emulator.
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 05/19] i.MX: Fix Coding style for AVIC emulator Jean-Christophe Dubois
@ 2015-07-15 7:44 ` Peter Crosthwaite
0 siblings, 0 replies; 27+ messages in thread
From: Peter Crosthwaite @ 2015-07-15 7:44 UTC (permalink / raw)
To: Jean-Christophe Dubois; +Cc: qemu-devel@nongnu.org Developers
On Fri, Jul 10, 2015 at 4:31 PM, Jean-Christophe Dubois
<jcd@tribudubois.net> wrote:
> 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.
>
> 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 [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH v12 07/19] i.MX: Fix Coding style for CCM emulator
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 07/19] i.MX: Fix Coding style for CCM emulator Jean-Christophe Dubois
@ 2015-07-15 7:48 ` Peter Crosthwaite
0 siblings, 0 replies; 27+ messages in thread
From: Peter Crosthwaite @ 2015-07-15 7:48 UTC (permalink / raw)
To: Jean-Christophe Dubois; +Cc: qemu-devel@nongnu.org Developers
On Fri, Jul 10, 2015 at 4:31 PM, Jean-Christophe Dubois
<jcd@tribudubois.net> wrote:
> 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.
>
> 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 [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH v12 09/19] i.MX: Fix Coding style for EPIT emulator
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 09/19] i.MX: Fix Coding style for EPIT emulator Jean-Christophe Dubois
@ 2015-07-15 7:51 ` Peter Crosthwaite
0 siblings, 0 replies; 27+ messages in thread
From: Peter Crosthwaite @ 2015-07-15 7:51 UTC (permalink / raw)
To: Jean-Christophe Dubois; +Cc: qemu-devel@nongnu.org Developers
On Fri, Jul 10, 2015 at 4:31 PM, Jean-Christophe Dubois
<jcd@tribudubois.net> wrote:
> 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.
>
> 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 [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH v12 11/19] i.MX: Fix Coding style for GPT emulator
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 11/19] i.MX: Fix Coding style for GPT emulator Jean-Christophe Dubois
@ 2015-07-15 7:53 ` Peter Crosthwaite
0 siblings, 0 replies; 27+ messages in thread
From: Peter Crosthwaite @ 2015-07-15 7:53 UTC (permalink / raw)
To: Jean-Christophe Dubois; +Cc: qemu-devel@nongnu.org Developers
On Fri, Jul 10, 2015 at 4:31 PM, Jean-Christophe Dubois
<jcd@tribudubois.net> wrote:
> 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.
>
> 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 [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [PATCH v12 17/19] i.MX: Add the i.MX25 PDK plateform
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 17/19] i.MX: Add the i.MX25 PDK plateform Jean-Christophe Dubois
@ 2015-08-07 13:55 ` Peter Maydell
0 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2015-08-07 13:55 UTC (permalink / raw)
To: Jean-Christophe Dubois; +Cc: QEMU Developers
On 11 July 2015 at 00:31, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
> Tested by booting a minimal Linux system on the emulated platform
> Tested by booting the Xvisor hyprvisor on the emulated platform
Typo in subject: "platform".
This commit message could probably use a little elaboration.
What is a PDK board?
> + /* 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);
This has the same 'calls this function twice' issues as the other patch.
> + 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);
> + }
This is kind of ugly. It's a shame you can't add an I2C device
via -device...
thanks
-- PMM
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2015-08-07 13:56 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-10 23:31 [Qemu-devel] [PATCH v12 00/19] i.MX: Add i.MX25 support through the PDK evaluation board Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 01/19] i.MX: Split UART emulator in a header file and a source file Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 02/19] i.MX: Move serial initialization to init/realize of DeviceClass Jean-Christophe Dubois
2015-07-15 7:38 ` Peter Crosthwaite
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 03/19] i.MX:Fix Coding style for UART emulator Jean-Christophe Dubois
2015-07-15 7:43 ` Peter Crosthwaite
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 04/19] i.MX: Split AVIC emulator in a header file and a source file Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 05/19] i.MX: Fix Coding style for AVIC emulator Jean-Christophe Dubois
2015-07-15 7:44 ` Peter Crosthwaite
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 06/19] i.MX: Split CCM emulator in a header file and a source file Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 07/19] i.MX: Fix Coding style for CCM emulator Jean-Christophe Dubois
2015-07-15 7:48 ` Peter Crosthwaite
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 08/19] i.MX: Split EPIT emulator in a header file and a source file Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 09/19] i.MX: Fix Coding style for EPIT emulator Jean-Christophe Dubois
2015-07-15 7:51 ` Peter Crosthwaite
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 10/19] i.MX: Split GPT emulator in a header file and a source file Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 11/19] i.MX: Fix Coding style for GPT emulator Jean-Christophe Dubois
2015-07-15 7:53 ` Peter Crosthwaite
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 12/19] i.MX: Add SOC support for i.MX31 Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 13/19] i.MX: KZM now uses the standalone i.MX31 SOC support Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 14/19] i.MX: Add I2C controller emulator Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 15/19] i.MX: Add FEC Ethernet Emulator Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 16/19] i.MX: Add SOC support for i.MX25 Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 17/19] i.MX: Add the i.MX25 PDK plateform Jean-Christophe Dubois
2015-08-07 13:55 ` Peter Maydell
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 18/19] i.MX: Add qtest support for I2C device emulator Jean-Christophe Dubois
2015-07-10 23:31 ` [Qemu-devel] [PATCH v12 19/19] i.MX: Adding i2C devices to i.MX31 SOC 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.