summaryrefslogtreecommitdiff
path: root/hw/sparc32_dma.c
diff options
context:
space:
mode:
authorBlue Swirl <blauwirbel@gmail.com>2010-09-11 16:38:33 +0000
committerBlue Swirl <blauwirbel@gmail.com>2010-09-11 16:38:33 +0000
commit73d7434279e390505164afd02360eebe4b43c7fa (patch)
tree309f298ec1dcba9be54fb0604a92811cc3095dbe /hw/sparc32_dma.c
parent24e0e38b83616ee7b540a270d8c4f24edf94f802 (diff)
downloadqemu-73d7434279e390505164afd02360eebe4b43c7fa.tar.gz
ESP: fix ESP DMA access when DMA is not enabled
Sending ESP a command caused it to trigger DMA immediately even if DMA was not enabled at the DMA controller. Add a signal from DMA controller to ESP to tell ESP about changes in DMA enable bit. Also use the correct function for setting up GPIO outputs. This fixes NetBSD 1.6.1 through 3.0 boot. Thanks to Artyom Tarasenko for extensive debugging of the problem. Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'hw/sparc32_dma.c')
-rw-r--r--hw/sparc32_dma.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
index b52170787b..984ffc3e53 100644
--- a/hw/sparc32_dma.c
+++ b/hw/sparc32_dma.c
@@ -58,6 +58,7 @@
#define DMA_INTR 1
#define DMA_INTREN 0x10
#define DMA_WRITE_MEM 0x100
+#define DMA_EN 0x200
#define DMA_LOADED 0x04000000
#define DMA_DRAIN_FIFO 0x40
#define DMA_RESET 0x80
@@ -72,7 +73,12 @@ struct DMAState {
uint32_t dmaregs[DMA_REGS];
qemu_irq irq;
void *iommu;
- qemu_irq dev_reset;
+ qemu_irq gpio[2];
+};
+
+enum {
+ GPIO_RESET = 0,
+ GPIO_DMA,
};
/* Note: on sparc, the lance 16 bit bus is swapped */
@@ -201,12 +207,21 @@ static void dma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
}
}
if (val & DMA_RESET) {
- qemu_irq_raise(s->dev_reset);
- qemu_irq_lower(s->dev_reset);
+ qemu_irq_raise(s->gpio[GPIO_RESET]);
+ qemu_irq_lower(s->gpio[GPIO_RESET]);
} else if (val & DMA_DRAIN_FIFO) {
val &= ~DMA_DRAIN_FIFO;
} else if (val == 0)
val = DMA_DRAIN_FIFO;
+
+ if (val & DMA_EN && !(s->dmaregs[0] & DMA_EN)) {
+ DPRINTF("Raise DMA enable\n");
+ qemu_irq_raise(s->gpio[GPIO_DMA]);
+ } else if (!(val & DMA_EN) && !!(s->dmaregs[0] & DMA_EN)) {
+ DPRINTF("Lower DMA enable\n");
+ qemu_irq_lower(s->gpio[GPIO_DMA]);
+ }
+
val &= ~DMA_CSR_RO_MASK;
val |= DMA_VER;
s->dmaregs[0] = (s->dmaregs[0] & DMA_CSR_RO_MASK) | val;
@@ -262,7 +277,7 @@ static int sparc32_dma_init1(SysBusDevice *dev)
sysbus_init_mmio(dev, DMA_SIZE, dma_io_memory);
qdev_init_gpio_in(&dev->qdev, dma_set_irq, 1);
- qdev_init_gpio_out(&dev->qdev, &s->dev_reset, 1);
+ qdev_init_gpio_out(&dev->qdev, s->gpio, 2);
return 0;
}