ESPDMAMemoryReadWriteFunc dma_memory_read;
ESPDMAMemoryReadWriteFunc dma_memory_write;
void *dma_opaque;
+ int dma_enabled;
+ void (*dma_cb)(ESPState *s);
};
#define ESP_TCLO 0x0
}
}
+static void esp_dma_enable(void *opaque, int irq, int level)
+{
+ DeviceState *d = opaque;
+ ESPState *s = container_of(d, ESPState, busdev.qdev);
+
+ if (level) {
+ s->dma_enabled = 1;
+ DPRINTF("Raise enable\n");
+ if (s->dma_cb) {
+ s->dma_cb(s);
+ s->dma_cb = NULL;
+ }
+ } else {
+ DPRINTF("Lower enable\n");
+ s->dma_enabled = 0;
+ }
+}
+
static uint32_t get_cmd(ESPState *s, uint8_t *buf)
{
uint32_t dmalen;
uint8_t buf[32];
int len;
+ if (!s->dma_enabled) {
+ s->dma_cb = handle_satn;
+ return;
+ }
len = get_cmd(s, buf);
if (len)
do_cmd(s, buf);
uint8_t buf[32];
int len;
+ if (!s->dma_enabled) {
+ s->dma_cb = handle_s_without_atn;
+ return;
+ }
len = get_cmd(s, buf);
if (len) {
do_busid_cmd(s, buf, 0);
static void handle_satn_stop(ESPState *s)
{
+ if (!s->dma_enabled) {
+ s->dma_cb = handle_satn_stop;
+ return;
+ }
s->cmdlen = get_cmd(s, s->cmdbuf);
if (s->cmdlen) {
DPRINTF("Set ATN & Stop: cmdlen %d\n", s->cmdlen);
s->ti_wptr = 0;
s->dma = 0;
s->do_cmd = 0;
+ s->dma_cb = NULL;
s->rregs[ESP_CFG1] = 7;
}
}
}
+static void esp_gpio_demux(void *opaque, int irq, int level)
+{
+ switch (irq) {
+ case 0:
+ parent_esp_reset(opaque, irq, level);
+ break;
+ case 1:
+ esp_dma_enable(opaque, irq, level);
+ break;
+ }
+}
+
static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
{
ESPState *s = opaque;
void esp_init(target_phys_addr_t espaddr, int it_shift,
ESPDMAMemoryReadWriteFunc dma_memory_read,
ESPDMAMemoryReadWriteFunc dma_memory_write,
- void *dma_opaque, qemu_irq irq, qemu_irq *reset)
+ void *dma_opaque, qemu_irq irq, qemu_irq *reset,
+ qemu_irq *dma_enable)
{
DeviceState *dev;
SysBusDevice *s;
esp->dma_memory_write = dma_memory_write;
esp->dma_opaque = dma_opaque;
esp->it_shift = it_shift;
+ /* XXX for now until rc4030 has been changed to use DMA enable signal */
+ esp->dma_enabled = 1;
qdev_init_nofail(dev);
s = sysbus_from_qdev(dev);
sysbus_connect_irq(s, 0, irq);
sysbus_mmio_map(s, 0, espaddr);
*reset = qdev_get_gpio_in(dev, 0);
+ *dma_enable = qdev_get_gpio_in(dev, 1);
}
static int esp_init1(SysBusDevice *dev)
esp_io_memory = cpu_register_io_memory(esp_mem_read, esp_mem_write, s);
sysbus_init_mmio(dev, ESP_REGS << s->it_shift, esp_io_memory);
- qdev_init_gpio_in(&dev->qdev, parent_esp_reset, 1);
+ qdev_init_gpio_in(&dev->qdev, esp_gpio_demux, 2);
scsi_bus_new(&s->bus, &dev->qdev, 0, ESP_MAX_DEVS, esp_command_complete);
return scsi_bus_legacy_handle_cmdline(&s->bus);
void esp_init(target_phys_addr_t espaddr, int it_shift,
ESPDMAMemoryReadWriteFunc dma_memory_read,
ESPDMAMemoryReadWriteFunc dma_memory_write,
- void *dma_opaque, qemu_irq irq, qemu_irq *reset);
+ void *dma_opaque, qemu_irq irq, qemu_irq *reset,
+ qemu_irq *dma_enable);
#endif
NICInfo *nd;
PITState *pit;
DriveInfo *fds[MAX_FD];
- qemu_irq esp_reset;
+ qemu_irq esp_reset, dma_enable;
qemu_irq *cpu_exit_irq;
ram_addr_t ram_offset;
ram_addr_t bios_offset;
/* SCSI adapter */
esp_init(0x80002000, 0,
rc4030_dma_read, rc4030_dma_write, dmas[0],
- rc4030[5], &esp_reset);
+ rc4030[5], &esp_reset, &dma_enable);
/* Floppy */
if (drive_get_max_bus(IF_FLOPPY) >= MAX_FD) {
#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
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 */
}
}
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;
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;
}
void *iommu, *espdma, *ledma, *nvram;
qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS],
espdma_irq, ledma_irq;
- qemu_irq esp_reset;
+ qemu_irq esp_reset, dma_enable;
qemu_irq fdc_tc;
qemu_irq *cpu_halt;
unsigned long kernel_size;
exit(1);
}
- esp_reset = qdev_get_gpio_in(espdma, 0);
esp_init(hwdef->esp_base, 2,
espdma_memory_read, espdma_memory_write,
- espdma, espdma_irq, &esp_reset);
+ espdma, espdma_irq, &esp_reset, &dma_enable);
+ qdev_connect_gpio_out(espdma, 0, esp_reset);
+ qdev_connect_gpio_out(espdma, 1, dma_enable);
if (hwdef->cs_base) {
sysbus_create_simple("SUNW,CS4231", hwdef->cs_base,
void *iounits[MAX_IOUNITS], *espdma, *ledma, *nvram;
qemu_irq *cpu_irqs[MAX_CPUS], sbi_irq[32], sbi_cpu_irq[MAX_CPUS],
espdma_irq, ledma_irq;
- qemu_irq esp_reset;
+ qemu_irq esp_reset, dma_enable;
unsigned long kernel_size;
void *fw_cfg;
DeviceState *dev;
exit(1);
}
- esp_reset = qdev_get_gpio_in(espdma, 0);
esp_init(hwdef->esp_base, 2,
espdma_memory_read, espdma_memory_write,
- espdma, espdma_irq, &esp_reset);
+ espdma, espdma_irq, &esp_reset, &dma_enable);
+
+ qdev_connect_gpio_out(espdma, 0, esp_reset);
+ qdev_connect_gpio_out(espdma, 1, dma_enable);
kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
RAM_size);
{
void *iommu, *espdma, *ledma, *nvram;
qemu_irq *cpu_irqs, slavio_irq[8], espdma_irq, ledma_irq;
- qemu_irq esp_reset;
+ qemu_irq esp_reset, dma_enable;
qemu_irq fdc_tc;
unsigned long kernel_size;
DriveInfo *fd[MAX_FD];
exit(1);
}
- esp_reset = qdev_get_gpio_in(espdma, 0);
esp_init(hwdef->esp_base, 2,
espdma_memory_read, espdma_memory_write,
- espdma, espdma_irq, &esp_reset);
+ espdma, espdma_irq, &esp_reset, &dma_enable);
+
+ qdev_connect_gpio_out(espdma, 0, esp_reset);
+ qdev_connect_gpio_out(espdma, 1, dma_enable);
kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
RAM_size);