qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Michel Pollet <buserror@gmail.com>
To: qemu-devel@nongnu.org
Cc: Michel Pollet <buserror@gmail.com>
Subject: [Qemu-devel] [PATCH 12/13] mxs/imx23: Main core instantiation and minor IO blocks
Date: Wed, 11 Dec 2013 13:56:31 +0000	[thread overview]
Message-ID: <1386770192-19585-13-git-send-email-buserror@gmail.com> (raw)
In-Reply-To: <1386770192-19585-1-git-send-email-buserror@gmail.com>

This adds support for creating an imx23 instance. This also contains
some of the more minor IO blocks, and a 'catchall' driver that helps
debugging access to undocumented IO registers.
Currently the instance can boot a linux kernel, but does not support
booting from the 'special' signed Freescale binary blobs.

Signed-off-by: Michel Pollet <buserror@gmail.com>
---
 hw/arm/Makefile.objs |   2 +-
 hw/arm/mxs.c         | 388 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 389 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/mxs.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index ea53988..45bbdb8 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -5,4 +5,4 @@ obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
 obj-y += omap1.o omap2.o strongarm.o
-obj-$(CONFIG_MXS) += imx23_digctl.o imx23_pinctrl.o
+obj-$(CONFIG_MXS) += imx23_digctl.o imx23_pinctrl.o mxs.o
diff --git a/hw/arm/mxs.c b/hw/arm/mxs.c
new file mode 100644
index 0000000..bee7880
--- /dev/null
+++ b/hw/arm/mxs.c
@@ -0,0 +1,388 @@
+/*
+ * mxs.c
+ *
+ * Copyright: Michel Pollet <buserror@gmail.com>
+ *
+ * QEMU Licence
+ */
+
+#include "hw/sysbus.h"
+#include "hw/arm/mxs.h"
+#include "hw/arm/arm.h"
+#include "target-arm/cpu.h"
+#include "hw/boards.h"
+
+#include "exec/address-spaces.h"
+
+#define D(w)
+//#define D(w) w
+/*
+ * 	0x00000000 - 0x00007fff	On Chip SRAM
+ * 			   - 0x5fffffff	External DRAM
+ * 	0x60000000 - 0x7fffffff	Default Slave
+ * 	0x80000000 - 0x800fffff	Peripheral Space (128KB)
+ * 		0x80000000 0x8000		APBH
+ * 		----------------------------
+ * 		0x80000000 0x2000		icol
+ * 		0x80004000 0x2000		DMA
+ * 		0x80008000 0x2000		ECC
+ * 		0x8000c000 0x2000		GPMI-NAND
+ * 		0x8000a000 0x2000		GPMI-NAND
+ * 		0x80010000 0x2000		SSP0
+ * 		0x80014000 0x2000		ETM
+ * 		0x80018000 0x2000		pinctrl
+ * 		0x8001c000 0x2000		digctl
+ * 		0x80020000 0x2000		EMI
+ * 		0x80024000 0x2000		DMA APBX
+ * 		0x80028000 0x2000		DCP
+ * 		0x8002a000 0x2000		PXP
+ * 		0x8002c000 0x2000		ocotp
+ * 		0x8002e000 0x2000		axi-ahb
+ * 		0x80030000 0x2000		lcdif
+ * 		0x80034000 0x2000		SSP1
+ * 		0x80038000 0x2000		TVEnc
+ *
+ * 		0x80040000 0x40000		APBX
+ * 		----------------------------
+ * 		0x80040000 0x2000		clkctrl
+ * 		0x80042000 0x2000		saif0
+ * 		0x80044000 0x2000		power
+ * 		0x80046000 0x2000		saif1
+ * 		0x80048000 0x2000		audio-out
+ * 		0x8004c000 0x2000		audio-in
+ * 		0x80050000 0x2000		LRADC
+ * 		0x80054000 0x2000		SPDIF
+ * 		0x80058000 0x2000		i2c
+ * 		0x8005c000 0x2000		RTC	fsl,imx23-rtc - fsl,stmp3xxx-rtc
+ * 		0x80064000 0x2000		PWM
+ * 		0x80068000 0x2000		Timrot
+ * 		0x8006c000 0x2000		UART0
+ * 		0x8006e000 0x2000		UART1
+ * 		0x80070000 0x2000		DUART PL011
+ * 		0x8007c000 0x2000		USB PHY
+ * 	0x80100000 - 0xc0000000	Default Slave
+ * 	0xc0000000 - 0xfffeffff	ROM Alias
+ * 	0xffff0000 - 0xffffffff  On Chip ROM
+ */
+
+enum {
+    HW_CLKCTRL_CPU = 2,
+    HW_CLKCTRL_HBUS = 3,
+    HW_CLKCTRL_XBUS = 4,
+    HW_CLKCTRL_XTAL = 0x5,
+    HW_CLKCTRL_PIX = 0x6,
+    HW_CLKCTRL_SSP = 0x7,
+    HW_CLKCTRL_GPMI = 0x8,
+    HW_CLKCTRL_SPDIF = 0x9,
+    HW_CLKCTRL_EMI = 0xa,
+    HW_CLKCTRL_SAIF = 0xc,
+    HW_CLKCTRL_TV = 0xd,
+    HW_CLKCTRL_ETM = 0xe,
+    HW_CLKCTRL_FRAC = 0xf,
+    HW_CLKCTRL_FRAC1 = 0x10,
+    HW_CLKCTRL_CLKSEQ = 0x11,
+    HW_CLKCTRL_RESET = 0x12,
+    HW_CLKCTRL_STATUS = 0x13,
+    HW_CLKCTRL_VERSION = 0x14,
+    HW_CLKCTRL_MAX
+};
+typedef struct imx23_clkctrl_state {
+    SysBusDevice busdev;
+    MemoryRegion iomem;
+    uint32_t r[HW_CLKCTRL_MAX];
+} imx23_clkctrl_state;
+
+static uint64_t imx23_clkctrl_read(
+        void *opaque, hwaddr offset, unsigned size)
+{
+    imx23_clkctrl_state *s = (imx23_clkctrl_state *) opaque;
+    uint32_t res = 0;
+
+    switch (offset >> 4) {
+        case 0 ... HW_CLKCTRL_MAX:
+            res = s->r[offset >> 4];
+            break;
+        default:
+            qemu_log_mask(LOG_GUEST_ERROR,
+                    "%s: bad offset 0x%x\n", __func__, (int) offset);
+            break;
+    }
+    return res;
+}
+
+static void imx23_clkctrl_write(void *opaque, hwaddr offset,
+        uint64_t value, unsigned size)
+{
+    imx23_clkctrl_state *s = (imx23_clkctrl_state *) opaque;
+
+    switch (offset >> 4) {
+        case 0 ... HW_CLKCTRL_MAX:
+            if ((offset >> 4) == HW_CLKCTRL_RESET)
+                printf("QEMU: %s OS reset, ignored\n", __func__);
+            mxs_write(&s->r[offset >> 4], offset, value, size);
+            break;
+        default:
+            qemu_log_mask(LOG_GUEST_ERROR,
+                    "%s: bad offset 0x%x\n", __func__, (int) offset);
+            break;
+    }
+}
+
+static const MemoryRegionOps imx23_clkctrl_ops = {
+    .read = imx23_clkctrl_read,
+    .write = imx23_clkctrl_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void imx23_clkctrl_reset(imx23_clkctrl_state *s)
+{
+    memset(s->r, 0, sizeof(s->r));
+    /*
+     * These are default values for most of the clock. the
+     * linux init code does rely on a few of these to be
+     * happy
+     */
+    s->r[HW_CLKCTRL_CPU] = 0x00010001;
+    s->r[HW_CLKCTRL_HBUS] = 0x00000001;
+    s->r[HW_CLKCTRL_XBUS] = 0x00000001;
+    s->r[HW_CLKCTRL_XTAL] = 0x70000001;
+    s->r[HW_CLKCTRL_PIX] = 0x80000001;
+    s->r[HW_CLKCTRL_SSP] = 0x80000001;
+    s->r[HW_CLKCTRL_GPMI] = 0x80000001;
+    s->r[HW_CLKCTRL_SPDIF] = 0x80000000;
+    s->r[HW_CLKCTRL_EMI] = 0x80000101;
+    s->r[HW_CLKCTRL_SAIF] = 0x80000001;
+    s->r[HW_CLKCTRL_TV] = 0x80000001;
+    s->r[HW_CLKCTRL_ETM] = 0x80000001;
+    s->r[HW_CLKCTRL_FRAC] = 0x92929292;
+    s->r[HW_CLKCTRL_FRAC1] = 0x80000000;
+    s->r[HW_CLKCTRL_CLKSEQ] = 0x0000001f;
+    s->r[HW_CLKCTRL_VERSION] = 0x04000000;
+}
+
+static int imx23_clkctrl_init(SysBusDevice *dev)
+{
+    imx23_clkctrl_state *s = OBJECT_CHECK(imx23_clkctrl_state, dev, "imx23_clkctrl");
+
+    memory_region_init_io(&s->iomem, OBJECT(s), &imx23_clkctrl_ops, s,
+            "imx23_clkctrl", 0x2000);
+    sysbus_init_mmio(dev, &s->iomem);
+    imx23_clkctrl_reset(s);
+    return 0;
+}
+
+static void imx23_clkctrl_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = imx23_clkctrl_init;
+}
+
+static TypeInfo clkctrl_info = {
+    .name          = "imx23_clkctrl",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(imx23_clkctrl_state),
+    .class_init    = imx23_clkctrl_class_init,
+};
+
+static void imx23_clkctrl_register(void)
+{
+    type_register_static(&clkctrl_info);
+}
+
+type_init(imx23_clkctrl_register)
+
+/*
+ * The 'catchall' device block is partly for debugging purpose, and
+ * partly to sort out issues with 'lone registers' that are checked
+ * in blocks that appear to be outside dedicated peripheral space
+ *
+ * One such is the AMBA signature for the PL011 serial port, where
+ * linux relies of finding identifiers when qemu's pl011 doesn't reply
+ *
+ * Similartly, the USB block has a couple of "non EHCI compliant"
+ * registers that are needed to make the EHCI/imx driver happy
+ */
+typedef struct imx23_catchall_state {
+    SysBusDevice busdev;
+    MemoryRegion iomem;
+} imx23_catchall_state;
+
+static uint64_t imx23_catchall_read(
+        void *opaque, hwaddr offset, unsigned size)
+{
+    //  imx23_catchall_state *s = (imx23_catchall_state *)opaque;
+    uint32_t res = 0;
+
+    // AMBA signature is not read by the pl11 serial driver, this is a workaround
+    const uint8_t cid[] = { 0x0d, 0xf0, 0x05, 0xb1 };
+    const uint8_t pid[] = { 0x11, 0x10, 0x34, 0x00 };
+    switch (offset) {
+        case 0x71fe0 ... 0x71fec:
+            res = pid[(offset - 0x71fe0) >> 2];
+            break;
+        case 0x71ff0 ... 0x71ffc:
+            res = cid[(offset - 0x71ff0) >> 2];
+            break;
+        case 0x80120: // HW_USBCTRL_DCIVERSION
+            res = 0x00000001;
+            break;
+        case 0x80124: // HW_USBCTRL_DCCPARAMS non ehci compliant
+            res = 0x00000185; // host & device bits
+            break;
+        default:
+            D(printf("%s %04x (%d) = ", __func__, (int) offset, size);
+            printf("%08x\n", res);)
+            break;
+    }
+    return res;
+}
+
+static void imx23_catchall_write(void *opaque, hwaddr offset,
+        uint64_t value, unsigned size)
+{
+    //  imx23_catchall_state *s = (imx23_catchall_state *)opaque;
+
+    D(printf("%s %04x %08x(%d)\n", __func__, (int) offset, (int) value, size);)
+}
+
+static const MemoryRegionOps imx23_catchall_ops = {
+    .read = imx23_catchall_read,
+    .write = imx23_catchall_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static int imx23_catchall_init(SysBusDevice *dev)
+{
+    imx23_catchall_state *s = OBJECT_CHECK(imx23_catchall_state, dev, "imx23_catchall");
+
+    memory_region_init_io(&s->iomem, OBJECT(s), &imx23_catchall_ops, s,
+            "imx23_catchall", 0x82000);
+    sysbus_init_mmio(dev, &s->iomem);
+    return 0;
+}
+
+static void imx23_catchall_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = imx23_catchall_init;
+}
+
+static TypeInfo catchall_info = {
+    .name          = "imx23_catchall",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(imx23_catchall_state),
+    .class_init    = imx23_catchall_class_init,
+};
+
+static void imx23_catchall_register(void)
+{
+    type_register_static(&catchall_info);
+}
+
+type_init(imx23_catchall_register)
+
+ARMCPU * imx233_init(struct arm_boot_info * board_info);
+
+/*
+ * Creates an "empty" imx23, with the peripherals, and nothing
+ * else attached. Pass in a partially filled up board_info; currently
+ * only the ram_size field is used.
+ */
+ARMCPU * imx233_init(struct arm_boot_info * board_info)
+{
+    ARMCPU *cpu;
+    MemoryRegion *address_space_mem = get_system_memory();
+    MemoryRegion *ram = g_new(MemoryRegion, 1);
+//    qemu_irq *cpu_pic;
+    DeviceState *icoll;
+
+    cpu = cpu_arm_init("arm926");
+    if (!cpu) {
+        fprintf(stderr, "Unable to find CPU definition\n");
+        exit(1);
+    }
+
+    /* On a real system, the first 32k is a `onboard sram' */
+    //  printf("%s ram size : %dMB\n", __func__, (int)ram_size / 1024 / 1024);
+    memory_region_init_ram(ram, NULL, "imx233.ram", board_info->ram_size);
+    vmstate_register_ram_global(ram);
+    memory_region_add_subregion(address_space_mem, 0x0, ram);
+
+    sysbus_create_simple("imx23_catchall", MX23_IO_BASE_ADDR, 0);
+
+//    cpu_pic = arm_pic_init_cpu(cpu);
+
+    sysbus_create_simple("imx23_clkctrl", MX23_CLKCTRL_BASE_ADDR, 0);
+
+    icoll = sysbus_create_varargs("mxs_icoll", MX23_ICOLL_BASE_ADDR,
+            qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
+            qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ), NULL);
+
+    sysbus_create_varargs("mxs_timrot", MX23_TIMROT_BASE_ADDR,
+            qdev_get_gpio_in(icoll, MX23_INT_TIMER0),
+            qdev_get_gpio_in(icoll, MX23_INT_TIMER1),
+            qdev_get_gpio_in(icoll, MX23_INT_TIMER2),
+            qdev_get_gpio_in(icoll, MX23_INT_TIMER3),
+            NULL);
+
+    sysbus_create_simple("imx23_digctl", MX23_DIGCTL_BASE_ADDR, 0);
+    sysbus_create_varargs("imx23_pinctrl", MX23_PINCTRL_BASE_ADDR,
+            qdev_get_gpio_in(icoll, MX23_INT_GPIO0),
+            qdev_get_gpio_in(icoll, MX23_INT_GPIO1),
+            qdev_get_gpio_in(icoll, MX23_INT_GPIO2),
+            NULL);
+
+    sysbus_create_simple("pl011", MX23_DUART_BASE_ADDR,
+            qdev_get_gpio_in(icoll, MX23_INT_DUART));
+    /*
+     *  enable the port, like the bootloader would
+     */
+    {
+        uint32_t enable = 0x301;
+        cpu_physical_memory_rw(MX23_DUART_BASE_ADDR + 0x4 /* CR */,
+                (uint8_t*) &enable, 4, 1);
+    }
+    sysbus_create_varargs("mxs_uart", MX23_AUART1_BASE_ADDR,
+            qdev_get_gpio_in(icoll, MX23_INT_AUART1),
+            NULL);
+    sysbus_create_varargs("mxs_uart", MX23_AUART2_BASE_ADDR,
+            qdev_get_gpio_in(icoll, MX23_INT_AUART2),
+            NULL);
+    sysbus_create_varargs("mxs_rtc", MX23_RTC_BASE_ADDR,
+            qdev_get_gpio_in(icoll, MX23_INT_RTC_ALARM),
+            NULL);
+    sysbus_create_varargs("mxs_usb", MX23_USBCTRL_BASE_ADDR,
+            qdev_get_gpio_in(icoll, MX23_INT_USB_CTRL),
+            NULL);
+    sysbus_create_simple("mxs_usbphy", MX23_USBPHY_BASE_ADDR, 0);
+
+    sysbus_create_varargs("mxs_apbh_dma", MX23_APBH_DMA_BASE_ADDR,
+            qdev_get_gpio_in(icoll, MX23_INT_SSP1_DMA),
+            qdev_get_gpio_in(icoll, MX23_INT_SSP2_DMA),
+            NULL);
+    sysbus_create_varargs("mxs_apbx_dma", MX23_APBX_DMA_BASE_ADDR,
+            qdev_get_gpio_in(icoll, MX23_INT_ADC_DMA),
+            qdev_get_gpio_in(icoll, MX23_INT_DAC_DMA),
+            qdev_get_gpio_in(icoll, MX23_INT_SPDIF_DMA),
+            qdev_get_gpio_in(icoll, MX23_INT_I2C_DMA),
+            qdev_get_gpio_in(icoll, MX23_INT_SAIF1_DMA),
+            qdev_get_gpio_in(icoll, MX23_INT_AUART1_RX_DMA),
+            qdev_get_gpio_in(icoll, MX23_INT_AUART1_TX_DMA),
+            qdev_get_gpio_in(icoll, MX23_INT_AUART2_RX_DMA),
+            qdev_get_gpio_in(icoll, MX23_INT_AUART2_TX_DMA),
+            qdev_get_gpio_in(icoll, MX23_INT_SAIF2_DMA),
+            NULL);
+    sysbus_create_varargs("mxs_ssp", MX23_SSP1_BASE_ADDR,
+            qdev_get_gpio_in(icoll, MX23_INT_SSP1_DMA),
+            qdev_get_gpio_in(icoll, MX23_INT_SSP1_ERROR),
+            NULL);
+    sysbus_create_varargs("mxs_ssp", MX23_SSP2_BASE_ADDR,
+            qdev_get_gpio_in(icoll, MX23_INT_SSP2_DMA),
+            qdev_get_gpio_in(icoll, MX23_INT_SSP2_ERROR),
+            NULL);
+
+    return cpu;
+}
+
-- 
1.8.5.1

  parent reply	other threads:[~2013-12-11 13:59 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-11 13:56 [Qemu-devel] [PATCH 00/13] Freescale mxs/imx23 + Olimex Olinuxino support Michel Pollet
2013-12-11 13:56 ` [Qemu-devel] [PATCH 01/13] mxs/imx23: Add main header file Michel Pollet
2013-12-11 13:56 ` [Qemu-devel] [PATCH 02/13] mxs: Add CONFIG_MXS to the arm-softmmu config Michel Pollet
2014-01-06 15:08   ` Peter Maydell
2013-12-11 13:56 ` [Qemu-devel] [PATCH 03/13] mxs/imx23: Add uart driver Michel Pollet
2014-01-06 15:19   ` Peter Maydell
2014-01-11  7:39     ` Peter Crosthwaite
2013-12-11 13:56 ` [Qemu-devel] [PATCH 04/13] mxs/imx23: Add DMA driver Michel Pollet
2014-01-06 15:35   ` Peter Maydell
2014-01-10  0:52     ` Peter Crosthwaite
2014-01-10  0:54       ` Peter Crosthwaite
2014-01-10 10:55       ` Peter Maydell
2013-12-11 13:56 ` [Qemu-devel] [PATCH 05/13] mxs/imx23: Add the interrupt collector Michel Pollet
2014-01-06 15:41   ` Peter Maydell
2014-01-11  8:29   ` Peter Crosthwaite
2013-12-11 13:56 ` [Qemu-devel] [PATCH 06/13] mxs/imx23: Add digctl driver Michel Pollet
2014-01-06 15:46   ` Peter Maydell
2014-01-08 18:39     ` M P
2014-01-08 18:55       ` Peter Maydell
2014-01-11  8:44         ` Peter Crosthwaite
2014-01-11  8:39   ` Peter Crosthwaite
2013-12-11 13:56 ` [Qemu-devel] [PATCH 07/13] mxs/imx23: Implements the pin mux, GPIOs Michel Pollet
2014-01-06 15:52   ` Peter Maydell
2014-01-08 18:16     ` M P
2013-12-11 13:56 ` [Qemu-devel] [PATCH 08/13] mxs/imx23: Add SSP/SPI driver Michel Pollet
2014-01-11  9:08   ` Peter Crosthwaite
2013-12-11 13:56 ` [Qemu-devel] [PATCH 09/13] mxs/imx23: Add the RTC block Michel Pollet
2014-01-11  9:16   ` Peter Crosthwaite
2013-12-11 13:56 ` [Qemu-devel] [PATCH 10/13] mxs/imx23: Add the timers Michel Pollet
2013-12-11 13:56 ` [Qemu-devel] [PATCH 11/13] mxs/imx23: Add the USB driver Michel Pollet
2014-01-11  9:57   ` Peter Crosthwaite
2013-12-11 13:56 ` Michel Pollet [this message]
2013-12-11 13:56 ` [Qemu-devel] [PATCH 13/13] mxs/imx23: Adds support for an Olinuxino board Michel Pollet
2013-12-13 12:53 ` [Qemu-devel] [PATCH 00/13] Freescale mxs/imx23 + Olimex Olinuxino support M P
2013-12-13 13:29   ` Peter Maydell
2013-12-13 13:45     ` M P

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1386770192-19585-13-git-send-email-buserror@gmail.com \
    --to=buserror@gmail.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).