Revision 6f57bbf4 hw/sparc32_dma.c

b/hw/sparc32_dma.c
3 3
 *
4 4
 * Copyright (c) 2006 Fabrice Bellard
5 5
 *
6
 * Modifications:
7
 *  2010-Feb-14 Artyom Tarasenko : reworked irq generation
8
 *
6 9
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 10
 * of this software and associated documentation files (the "Software"), to deal
8 11
 * in the Software without restriction, including without limitation the rights
......
125 128
{
126 129
    DMAState *s = opaque;
127 130
    if (level) {
128
        DPRINTF("Raise IRQ\n");
129 131
        s->dmaregs[0] |= DMA_INTR;
130
        qemu_irq_raise(s->irq);
132
        if (s->dmaregs[0] & DMA_INTREN) {
133
            DPRINTF("Raise IRQ\n");
134
            qemu_irq_raise(s->irq);
135
        }
131 136
    } else {
132
        s->dmaregs[0] &= ~DMA_INTR;
133
        DPRINTF("Lower IRQ\n");
134
        qemu_irq_lower(s->irq);
137
        if (s->dmaregs[0] & DMA_INTR) {
138
            s->dmaregs[0] &= ~DMA_INTR;
139
            if (s->dmaregs[0] & DMA_INTREN) {
140
                DPRINTF("Lower IRQ\n");
141
                qemu_irq_lower(s->irq);
142
            }
143
        }
135 144
    }
136 145
}
137 146

  
......
142 151
    DPRINTF("DMA read, direction: %c, addr 0x%8.8x\n",
143 152
            s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]);
144 153
    sparc_iommu_memory_read(s->iommu, s->dmaregs[1], buf, len);
145
    s->dmaregs[0] |= DMA_INTR;
146 154
    s->dmaregs[1] += len;
147 155
}
148 156

  
......
153 161
    DPRINTF("DMA write, direction: %c, addr 0x%8.8x\n",
154 162
            s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]);
155 163
    sparc_iommu_memory_write(s->iommu, s->dmaregs[1], buf, len);
156
    s->dmaregs[0] |= DMA_INTR;
157 164
    s->dmaregs[1] += len;
158 165
}
159 166

  
......
179 186
            s->dmaregs[saddr], val);
180 187
    switch (saddr) {
181 188
    case 0:
182
        if (!(val & DMA_INTREN)) {
183
            DPRINTF("Lower IRQ\n");
184
            qemu_irq_lower(s->irq);
189
        if (val & DMA_INTREN) {
190
            if (val & DMA_INTR) {
191
                DPRINTF("Raise IRQ\n");
192
                qemu_irq_raise(s->irq);
193
            }
194
        } else {
195
            if (s->dmaregs[0] & (DMA_INTR | DMA_INTREN)) {
196
                DPRINTF("Lower IRQ\n");
197
                qemu_irq_lower(s->irq);
198
            }
185 199
        }
186 200
        if (val & DMA_RESET) {
187 201
            qemu_irq_raise(s->dev_reset);

Also available in: Unified diff