]> git.proxmox.com Git - qemu.git/commitdiff
unicore32-softmmu: Add puv3 dma support
authorGuan Xuetao <gxt@mprc.pku.edu.cn>
Fri, 10 Aug 2012 06:42:32 +0000 (14:42 +0800)
committerBlue Swirl <blauwirbel@gmail.com>
Sat, 11 Aug 2012 09:37:01 +0000 (09:37 +0000)
This patch adds puv3 dma (Direct Memory Access) support,
include dma device simulation for kernel booting.

v1->v2: Add initialization to ret in puv3_dma_read.

Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
hw/Makefile.objs
hw/puv3.c
hw/puv3_dma.c [new file with mode: 0644]

index d84b2215d42a3b43a8b2c4fe83629f2cfecf2d76..3ba5dd0c6b377b68201de3f3deeda148a6bc988d 100644 (file)
@@ -71,6 +71,7 @@ hw-obj-$(CONFIG_PUV3) += puv3_intc.o
 hw-obj-$(CONFIG_PUV3) += puv3_ost.o
 hw-obj-$(CONFIG_PUV3) += puv3_gpio.o
 hw-obj-$(CONFIG_PUV3) += puv3_pm.o
+hw-obj-$(CONFIG_PUV3) += puv3_dma.o
 
 # PCI watchdog devices
 hw-obj-$(CONFIG_PCI) += wdt_i6300esb.o
index 3a14b274879c54b8567464b51e8d61c0b5a7f8b3..9acfc5a38b3974f3999ec6a562850712f390c937 100644 (file)
--- a/hw/puv3.c
+++ b/hw/puv3.c
@@ -49,6 +49,7 @@ static void puv3_soc_init(CPUUniCore32State *env)
 
     /* Initialize minimal necessary devices for kernel booting */
     sysbus_create_simple("puv3_pm", PUV3_PM_BASE, NULL);
+    sysbus_create_simple("puv3_dma", PUV3_DMA_BASE, NULL);
     sysbus_create_simple("puv3_ost", PUV3_OST_BASE, irqs[PUV3_IRQS_OST0]);
     sysbus_create_varargs("puv3_gpio", PUV3_GPIO_BASE,
             irqs[PUV3_IRQS_GPIOLOW0], irqs[PUV3_IRQS_GPIOLOW1],
diff --git a/hw/puv3_dma.c b/hw/puv3_dma.c
new file mode 100644 (file)
index 0000000..85b97bf
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * DMA device simulation in PKUnity SoC
+ *
+ * Copyright (C) 2010-2012 Guan Xuetao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation, or any later version.
+ * See the COPYING file in the top-level directory.
+ */
+#include "hw.h"
+#include "sysbus.h"
+
+#undef DEBUG_PUV3
+#include "puv3.h"
+
+#define PUV3_DMA_CH_NR          (6)
+#define PUV3_DMA_CH_MASK        (0xff)
+#define PUV3_DMA_CH(offset)     ((offset) >> 8)
+
+typedef struct {
+    SysBusDevice busdev;
+    MemoryRegion iomem;
+    uint32_t reg_CFG[PUV3_DMA_CH_NR];
+} PUV3DMAState;
+
+static uint64_t puv3_dma_read(void *opaque, target_phys_addr_t offset,
+        unsigned size)
+{
+    PUV3DMAState *s = opaque;
+    uint32_t ret = 0;
+
+    assert(PUV3_DMA_CH(offset) < PUV3_DMA_CH_NR);
+
+    switch (offset & PUV3_DMA_CH_MASK) {
+    case 0x10:
+        ret = s->reg_CFG[PUV3_DMA_CH(offset)];
+        break;
+    default:
+        DPRINTF("Bad offset 0x%x\n", offset);
+    }
+    DPRINTF("offset 0x%x, value 0x%x\n", offset, ret);
+
+    return ret;
+}
+
+static void puv3_dma_write(void *opaque, target_phys_addr_t offset,
+        uint64_t value, unsigned size)
+{
+    PUV3DMAState *s = opaque;
+
+    assert(PUV3_DMA_CH(offset) < PUV3_DMA_CH_NR);
+
+    switch (offset & PUV3_DMA_CH_MASK) {
+    case 0x10:
+        s->reg_CFG[PUV3_DMA_CH(offset)] = value;
+        break;
+    default:
+        DPRINTF("Bad offset 0x%x\n", offset);
+    }
+    DPRINTF("offset 0x%x, value 0x%x\n", offset, value);
+}
+
+static const MemoryRegionOps puv3_dma_ops = {
+    .read = puv3_dma_read,
+    .write = puv3_dma_write,
+    .impl = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static int puv3_dma_init(SysBusDevice *dev)
+{
+    PUV3DMAState *s = FROM_SYSBUS(PUV3DMAState, dev);
+    int i;
+
+    for (i = 0; i < PUV3_DMA_CH_NR; i++) {
+        s->reg_CFG[i] = 0x0;
+    }
+
+    memory_region_init_io(&s->iomem, &puv3_dma_ops, s, "puv3_dma",
+            PUV3_REGS_OFFSET);
+    sysbus_init_mmio(dev, &s->iomem);
+
+    return 0;
+}
+
+static void puv3_dma_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = puv3_dma_init;
+}
+
+static const TypeInfo puv3_dma_info = {
+    .name = "puv3_dma",
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PUV3DMAState),
+    .class_init = puv3_dma_class_init,
+};
+
+static void puv3_dma_register_type(void)
+{
+    type_register_static(&puv3_dma_info);
+}
+
+type_init(puv3_dma_register_type)