diff options
author | Artyom Tarasenko <atar4qemu@googlemail.com> | 2010-05-22 10:38:56 +0200 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2010-05-22 09:07:46 +0000 |
commit | 65899fe34b09ab4af4b045977460b531ec5c1f73 (patch) | |
tree | 8443a4b3fdb801a2d4d437baef401e910384daa7 /hw | |
parent | ae6b2c4ed956c17456e70efefe13ad0ab7db31de (diff) | |
download | hqemu-65899fe34b09ab4af4b045977460b531ec5c1f73.zip hqemu-65899fe34b09ab4af4b045977460b531ec5c1f73.tar.gz |
sparc32 protect read-only bits in DMA CSR registers
On a real hardware changing read-only bits has no effect
Use a mask common for SCSI and Ethernet registers. The crucial
bit is DMA_INTR, because setting or clearing it may produce
spurious interrupts.
This patch allows booting Solaris 2.3
Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/sparc32_dma.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c index 3ceb851..b521707 100644 --- a/hw/sparc32_dma.c +++ b/hw/sparc32_dma.c @@ -62,6 +62,9 @@ #define DMA_DRAIN_FIFO 0x40 #define DMA_RESET 0x80 +/* XXX SCSI and ethernet should have different read-only bit masks */ +#define DMA_CSR_RO_MASK 0xfe000007 + typedef struct DMAState DMAState; struct DMAState { @@ -187,7 +190,7 @@ static void dma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) switch (saddr) { case 0: if (val & DMA_INTREN) { - if (val & DMA_INTR) { + if (s->dmaregs[0] & DMA_INTR) { DPRINTF("Raise IRQ\n"); qemu_irq_raise(s->irq); } @@ -204,16 +207,17 @@ static void dma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) val &= ~DMA_DRAIN_FIFO; } else if (val == 0) val = DMA_DRAIN_FIFO; - val &= 0x0fffffff; + val &= ~DMA_CSR_RO_MASK; val |= DMA_VER; + s->dmaregs[0] = (s->dmaregs[0] & DMA_CSR_RO_MASK) | val; break; case 1: s->dmaregs[0] |= DMA_LOADED; - break; + /* fall through */ default: + s->dmaregs[saddr] = val; break; } - s->dmaregs[saddr] = val; } static CPUReadMemoryFunc * const dma_mem_read[3] = { |