Split DMA controller in two

Fix register size related bugs


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2869 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
blueswir1 2007-05-26 17:39:43 +00:00
parent db7b5426a4
commit 5aca8c3b2f
10 changed files with 87 additions and 82 deletions

View File

@ -30,6 +30,7 @@
* In addition to Crystal CS4231 there is a DMA controller on Sparc. * In addition to Crystal CS4231 there is a DMA controller on Sparc.
*/ */
#define CS_MAXADDR 0x3f #define CS_MAXADDR 0x3f
#define CS_SIZE (CS_MAXADDR + 1)
#define CS_REGS 16 #define CS_REGS 16
#define CS_DREGS 32 #define CS_DREGS 32
#define CS_MAXDREG (CS_DREGS - 1) #define CS_MAXDREG (CS_DREGS - 1)
@ -173,7 +174,7 @@ void cs_init(target_phys_addr_t base, int irq, void *intctl)
return; return;
cs_io_memory = cpu_register_io_memory(0, cs_mem_read, cs_mem_write, s); cs_io_memory = cpu_register_io_memory(0, cs_mem_read, cs_mem_write, s);
cpu_register_physical_memory(base, CS_MAXADDR, cs_io_memory); cpu_register_physical_memory(base, CS_SIZE, cs_io_memory);
register_savevm("cs4231", base, 1, cs_save, cs_load, s); register_savevm("cs4231", base, 1, cs_save, cs_load, s);
qemu_register_reset(cs_reset, s); qemu_register_reset(cs_reset, s);
cs_reset(s); cs_reset(s);

View File

@ -41,7 +41,9 @@ do { printf("ESP: " fmt , ##args); } while (0)
#define DPRINTF(fmt, args...) #define DPRINTF(fmt, args...)
#endif #endif
#define ESP_MAXREG 0x3f #define ESP_MASK 0x3f
#define ESP_REGS 16
#define ESP_SIZE (ESP_REGS * 4)
#define TI_BUFSZ 32 #define TI_BUFSZ 32
/* The HBA is ID 7, so for simplicitly limit to 7 devices. */ /* The HBA is ID 7, so for simplicitly limit to 7 devices. */
#define ESP_MAX_DEVS 7 #define ESP_MAX_DEVS 7
@ -50,8 +52,8 @@ typedef struct ESPState ESPState;
struct ESPState { struct ESPState {
BlockDriverState **bd; BlockDriverState **bd;
uint8_t rregs[ESP_MAXREG]; uint8_t rregs[ESP_REGS];
uint8_t wregs[ESP_MAXREG]; uint8_t wregs[ESP_REGS];
int32_t ti_size; int32_t ti_size;
uint32_t ti_rptr, ti_wptr; uint32_t ti_rptr, ti_wptr;
uint8_t ti_buf[TI_BUFSZ]; uint8_t ti_buf[TI_BUFSZ];
@ -327,12 +329,12 @@ static void handle_ti(ESPState *s)
} }
} }
void esp_reset(void *opaque) static void esp_reset(void *opaque)
{ {
ESPState *s = opaque; ESPState *s = opaque;
memset(s->rregs, 0, ESP_MAXREG); memset(s->rregs, 0, ESP_REGS);
memset(s->wregs, 0, ESP_MAXREG); memset(s->wregs, 0, ESP_REGS);
s->rregs[0x0e] = 0x4; // Indicate fas100a s->rregs[0x0e] = 0x4; // Indicate fas100a
s->ti_size = 0; s->ti_size = 0;
s->ti_rptr = 0; s->ti_rptr = 0;
@ -346,7 +348,7 @@ static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
ESPState *s = opaque; ESPState *s = opaque;
uint32_t saddr; uint32_t saddr;
saddr = (addr & ESP_MAXREG) >> 2; saddr = (addr & ESP_MASK) >> 2;
DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]); DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]);
switch (saddr) { switch (saddr) {
case 2: case 2:
@ -384,7 +386,7 @@ static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
ESPState *s = opaque; ESPState *s = opaque;
uint32_t saddr; uint32_t saddr;
saddr = (addr & ESP_MAXREG) >> 2; saddr = (addr & ESP_MASK) >> 2;
DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr], val); DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr], val);
switch (saddr) { switch (saddr) {
case 0: case 0:
@ -501,8 +503,8 @@ static void esp_save(QEMUFile *f, void *opaque)
{ {
ESPState *s = opaque; ESPState *s = opaque;
qemu_put_buffer(f, s->rregs, ESP_MAXREG); qemu_put_buffer(f, s->rregs, ESP_REGS);
qemu_put_buffer(f, s->wregs, ESP_MAXREG); qemu_put_buffer(f, s->wregs, ESP_REGS);
qemu_put_be32s(f, &s->ti_size); qemu_put_be32s(f, &s->ti_size);
qemu_put_be32s(f, &s->ti_rptr); qemu_put_be32s(f, &s->ti_rptr);
qemu_put_be32s(f, &s->ti_wptr); qemu_put_be32s(f, &s->ti_wptr);
@ -523,8 +525,8 @@ static int esp_load(QEMUFile *f, void *opaque, int version_id)
if (version_id != 3) if (version_id != 3)
return -EINVAL; // Cannot emulate 2 return -EINVAL; // Cannot emulate 2
qemu_get_buffer(f, s->rregs, ESP_MAXREG); qemu_get_buffer(f, s->rregs, ESP_REGS);
qemu_get_buffer(f, s->wregs, ESP_MAXREG); qemu_get_buffer(f, s->wregs, ESP_REGS);
qemu_get_be32s(f, &s->ti_size); qemu_get_be32s(f, &s->ti_size);
qemu_get_be32s(f, &s->ti_rptr); qemu_get_be32s(f, &s->ti_rptr);
qemu_get_be32s(f, &s->ti_wptr); qemu_get_be32s(f, &s->ti_wptr);
@ -574,9 +576,10 @@ void *esp_init(BlockDriverState **bd, target_phys_addr_t espaddr,
s->bd = bd; s->bd = bd;
s->dma_opaque = dma_opaque; s->dma_opaque = dma_opaque;
sparc32_dma_set_reset_data(dma_opaque, esp_reset, s);
esp_io_memory = cpu_register_io_memory(0, esp_mem_read, esp_mem_write, s); esp_io_memory = cpu_register_io_memory(0, esp_mem_read, esp_mem_write, s);
cpu_register_physical_memory(espaddr, ESP_MAXREG*4, esp_io_memory); cpu_register_physical_memory(espaddr, ESP_SIZE, esp_io_memory);
esp_reset(s); esp_reset(s);

View File

@ -1554,7 +1554,7 @@ static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap)
return val; return val;
} }
void pcnet_h_reset(void *opaque) static void pcnet_h_reset(void *opaque)
{ {
PCNetState *s = opaque; PCNetState *s = opaque;
int i; int i;
@ -2032,6 +2032,8 @@ void *lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,
cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d); cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d);
d->dma_opaque = dma_opaque; d->dma_opaque = dma_opaque;
sparc32_dma_set_reset_data(dma_opaque, pcnet_h_reset, d);
cpu_register_physical_memory(leaddr, 4, lance_io_memory); cpu_register_physical_memory(leaddr, 4, lance_io_memory);
d->irq = irq; d->irq = irq;

View File

@ -58,7 +58,9 @@ typedef struct SLAVIO_INTCTLState {
} SLAVIO_INTCTLState; } SLAVIO_INTCTLState;
#define INTCTL_MAXADDR 0xf #define INTCTL_MAXADDR 0xf
#define INTCTL_SIZE (INTCTL_MAXADDR + 1)
#define INTCTLM_MAXADDR 0x13 #define INTCTLM_MAXADDR 0x13
#define INTCTLM_SIZE (INTCTLM_MAXADDR + 1)
#define INTCTLM_MASK 0x1f #define INTCTLM_MASK 0x1f
static void slavio_check_interrupts(void *opaque); static void slavio_check_interrupts(void *opaque);
@ -386,11 +388,12 @@ void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg,
s->intbit_to_level = intbit_to_level; s->intbit_to_level = intbit_to_level;
for (i = 0; i < MAX_CPUS; i++) { for (i = 0; i < MAX_CPUS; i++) {
slavio_intctl_io_memory = cpu_register_io_memory(0, slavio_intctl_mem_read, slavio_intctl_mem_write, s); slavio_intctl_io_memory = cpu_register_io_memory(0, slavio_intctl_mem_read, slavio_intctl_mem_write, s);
cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_MAXADDR, slavio_intctl_io_memory); cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_SIZE,
slavio_intctl_io_memory);
} }
slavio_intctlm_io_memory = cpu_register_io_memory(0, slavio_intctlm_mem_read, slavio_intctlm_mem_write, s); slavio_intctlm_io_memory = cpu_register_io_memory(0, slavio_intctlm_mem_read, slavio_intctlm_mem_write, s);
cpu_register_physical_memory(addrg, INTCTLM_MAXADDR, slavio_intctlm_io_memory); cpu_register_physical_memory(addrg, INTCTLM_SIZE, slavio_intctlm_io_memory);
register_savevm("slavio_intctl", addr, 1, slavio_intctl_save, slavio_intctl_load, s); register_savevm("slavio_intctl", addr, 1, slavio_intctl_save, slavio_intctl_load, s);
qemu_register_reset(slavio_intctl_reset, s); qemu_register_reset(slavio_intctl_reset, s);

View File

@ -47,7 +47,7 @@ typedef struct MiscState {
uint8_t diag, mctrl, sysctrl; uint8_t diag, mctrl, sysctrl;
} MiscState; } MiscState;
#define MISC_MAXADDR 1 #define MISC_SIZE 1
static void slavio_misc_update_irq(void *opaque) static void slavio_misc_update_irq(void *opaque)
{ {
@ -224,19 +224,25 @@ void *slavio_misc_init(target_phys_addr_t base, target_phys_addr_t power_base,
slavio_misc_io_memory = cpu_register_io_memory(0, slavio_misc_mem_read, slavio_misc_mem_write, s); slavio_misc_io_memory = cpu_register_io_memory(0, slavio_misc_mem_read, slavio_misc_mem_write, s);
// Slavio control // Slavio control
cpu_register_physical_memory(base + 0x1800000, MISC_MAXADDR, slavio_misc_io_memory); cpu_register_physical_memory(base + 0x1800000, MISC_SIZE,
slavio_misc_io_memory);
// AUX 1 // AUX 1
cpu_register_physical_memory(base + 0x1900000, MISC_MAXADDR, slavio_misc_io_memory); cpu_register_physical_memory(base + 0x1900000, MISC_SIZE,
slavio_misc_io_memory);
// AUX 2 // AUX 2
cpu_register_physical_memory(base + 0x1910000, MISC_MAXADDR, slavio_misc_io_memory); cpu_register_physical_memory(base + 0x1910000, MISC_SIZE,
slavio_misc_io_memory);
// Diagnostics // Diagnostics
cpu_register_physical_memory(base + 0x1a00000, MISC_MAXADDR, slavio_misc_io_memory); cpu_register_physical_memory(base + 0x1a00000, MISC_SIZE,
slavio_misc_io_memory);
// Modem control // Modem control
cpu_register_physical_memory(base + 0x1b00000, MISC_MAXADDR, slavio_misc_io_memory); cpu_register_physical_memory(base + 0x1b00000, MISC_SIZE,
slavio_misc_io_memory);
// System control // System control
cpu_register_physical_memory(base + 0x1f00000, MISC_MAXADDR, slavio_misc_io_memory); cpu_register_physical_memory(base + 0x1f00000, MISC_SIZE,
slavio_misc_io_memory);
// Power management // Power management
cpu_register_physical_memory(power_base, MISC_MAXADDR, slavio_misc_io_memory); cpu_register_physical_memory(power_base, MISC_SIZE, slavio_misc_io_memory);
s->irq = irq; s->irq = irq;

View File

@ -102,6 +102,7 @@ struct SerialState {
}; };
#define SERIAL_MAXADDR 7 #define SERIAL_MAXADDR 7
#define SERIAL_SIZE (SERIAL_MAXADDR + 1)
static void handle_kbd_command(ChannelState *s, int val); static void handle_kbd_command(ChannelState *s, int val);
static int serial_can_receive(void *opaque); static int serial_can_receive(void *opaque);
@ -178,7 +179,7 @@ static void slavio_serial_reset_chn(ChannelState *s)
int i; int i;
s->reg = 0; s->reg = 0;
for (i = 0; i < SERIAL_MAXADDR; i++) { for (i = 0; i < SERIAL_SIZE; i++) {
s->rregs[i] = 0; s->rregs[i] = 0;
s->wregs[i] = 0; s->wregs[i] = 0;
} }
@ -598,7 +599,7 @@ SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq,
return NULL; return NULL;
slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s); slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory); cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
s->chn[0].chr = chr1; s->chn[0].chr = chr1;
s->chn[1].chr = chr2; s->chn[1].chr = chr2;
@ -723,7 +724,7 @@ void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq)
s->chn[1].type = kbd; s->chn[1].type = kbd;
slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s); slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory); cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, "QEMU Sun Mouse"); qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, "QEMU Sun Mouse");
qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]); qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);

View File

@ -59,6 +59,7 @@ typedef struct SLAVIO_TIMERState {
} SLAVIO_TIMERState; } SLAVIO_TIMERState;
#define TIMER_MAXADDR 0x1f #define TIMER_MAXADDR 0x1f
#define TIMER_SIZE (TIMER_MAXADDR + 1)
// Update count, set irq, update expire_time // Update count, set irq, update expire_time
// Convert from ptimer countdown units // Convert from ptimer countdown units
@ -260,7 +261,7 @@ void slavio_timer_init(target_phys_addr_t addr, int irq, int mode,
slavio_timer_io_memory = cpu_register_io_memory(0, slavio_timer_mem_read, slavio_timer_io_memory = cpu_register_io_memory(0, slavio_timer_mem_read,
slavio_timer_mem_write, s); slavio_timer_mem_write, s);
cpu_register_physical_memory(addr, TIMER_MAXADDR, slavio_timer_io_memory); cpu_register_physical_memory(addr, TIMER_SIZE, slavio_timer_io_memory);
register_savevm("slavio_timer", addr, 2, slavio_timer_save, slavio_timer_load, s); register_savevm("slavio_timer", addr, 2, slavio_timer_save, slavio_timer_load, s);
qemu_register_reset(slavio_timer_reset, s); qemu_register_reset(slavio_timer_reset, s);
slavio_timer_reset(s); slavio_timer_reset(s);

View File

@ -41,22 +41,25 @@ do { printf("DMA: " fmt , ##args); } while (0)
#define DPRINTF(fmt, args...) #define DPRINTF(fmt, args...)
#endif #endif
#define DMA_REGS 8 #define DMA_REGS 4
#define DMA_MAXADDR (DMA_REGS * 4 - 1) #define DMA_SIZE (4 * sizeof(uint32_t))
#define DMA_MAXADDR (DMA_SIZE - 1)
#define DMA_VER 0xa0000000 #define DMA_VER 0xa0000000
#define DMA_INTR 1 #define DMA_INTR 1
#define DMA_INTREN 0x10 #define DMA_INTREN 0x10
#define DMA_WRITE_MEM 0x100 #define DMA_WRITE_MEM 0x100
#define DMA_LOADED 0x04000000 #define DMA_LOADED 0x04000000
#define DMA_DRAIN_FIFO 0x40
#define DMA_RESET 0x80 #define DMA_RESET 0x80
typedef struct DMAState DMAState; typedef struct DMAState DMAState;
struct DMAState { struct DMAState {
uint32_t dmaregs[DMA_REGS]; uint32_t dmaregs[DMA_REGS];
qemu_irq espirq, leirq; qemu_irq irq;
void *iommu, *esp_opaque, *lance_opaque; void *iommu, *dev_opaque;
void (*dev_reset)(void *dev_opaque);
qemu_irq *pic; qemu_irq *pic;
}; };
@ -69,7 +72,7 @@ void ledma_memory_read(void *opaque, target_phys_addr_t addr,
DPRINTF("DMA write, direction: %c, addr 0x%8.8x\n", DPRINTF("DMA write, direction: %c, addr 0x%8.8x\n",
s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]); s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]);
addr |= s->dmaregs[7]; addr |= s->dmaregs[3];
if (do_bswap) { if (do_bswap) {
sparc_iommu_memory_read(s->iommu, addr, buf, len); sparc_iommu_memory_read(s->iommu, addr, buf, len);
} else { } else {
@ -91,7 +94,7 @@ void ledma_memory_write(void *opaque, target_phys_addr_t addr,
DPRINTF("DMA read, direction: %c, addr 0x%8.8x\n", DPRINTF("DMA read, direction: %c, addr 0x%8.8x\n",
s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]); s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]);
addr |= s->dmaregs[7]; addr |= s->dmaregs[3];
if (do_bswap) { if (do_bswap) {
sparc_iommu_memory_write(s->iommu, addr, buf, len); sparc_iommu_memory_write(s->iommu, addr, buf, len);
} else { } else {
@ -118,7 +121,7 @@ void espdma_raise_irq(void *opaque)
DPRINTF("Raise ESP IRQ\n"); DPRINTF("Raise ESP IRQ\n");
s->dmaregs[0] |= DMA_INTR; s->dmaregs[0] |= DMA_INTR;
qemu_irq_raise(s->espirq); qemu_irq_raise(s->irq);
} }
void espdma_clear_irq(void *opaque) void espdma_clear_irq(void *opaque)
@ -127,7 +130,7 @@ void espdma_clear_irq(void *opaque)
s->dmaregs[0] &= ~DMA_INTR; s->dmaregs[0] &= ~DMA_INTR;
DPRINTF("Lower ESP IRQ\n"); DPRINTF("Lower ESP IRQ\n");
qemu_irq_lower(s->espirq); qemu_irq_lower(s->irq);
} }
void espdma_memory_read(void *opaque, uint8_t *buf, int len) void espdma_memory_read(void *opaque, uint8_t *buf, int len)
@ -158,7 +161,8 @@ static uint32_t dma_mem_readl(void *opaque, target_phys_addr_t addr)
uint32_t saddr; uint32_t saddr;
saddr = (addr & DMA_MAXADDR) >> 2; saddr = (addr & DMA_MAXADDR) >> 2;
DPRINTF("read dmareg[%d]: 0x%8.8x\n", saddr, s->dmaregs[saddr]); DPRINTF("read dmareg " TARGET_FMT_plx ": 0x%8.8x\n", addr,
s->dmaregs[saddr]);
return s->dmaregs[saddr]; return s->dmaregs[saddr];
} }
@ -169,37 +173,26 @@ static void dma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
uint32_t saddr; uint32_t saddr;
saddr = (addr & DMA_MAXADDR) >> 2; saddr = (addr & DMA_MAXADDR) >> 2;
DPRINTF("write dmareg[%d]: 0x%8.8x -> 0x%8.8x\n", saddr, s->dmaregs[saddr], val); DPRINTF("write dmareg " TARGET_FMT_plx ": 0x%8.8x -> 0x%8.8x\n", addr,
s->dmaregs[saddr], val);
switch (saddr) { switch (saddr) {
case 0: case 0:
if (!(val & DMA_INTREN)) { if (!(val & DMA_INTREN)) {
DPRINTF("Lower ESP IRQ\n"); DPRINTF("Lower IRQ\n");
qemu_irq_lower(s->espirq); qemu_irq_lower(s->irq);
} }
if (val & DMA_RESET) { if (val & DMA_RESET) {
esp_reset(s->esp_opaque); s->dev_reset(s->dev_opaque);
} else if (val & 0x40) { } else if (val & DMA_DRAIN_FIFO) {
val &= ~0x40; val &= ~DMA_DRAIN_FIFO;
} else if (val == 0) } else if (val == 0)
val = 0x40; val = DMA_DRAIN_FIFO;
val &= 0x0fffffff; val &= 0x0fffffff;
val |= DMA_VER; val |= DMA_VER;
break; break;
case 1: case 1:
s->dmaregs[0] |= DMA_LOADED; s->dmaregs[0] |= DMA_LOADED;
break; break;
case 4:
/* ??? Should this mask out the lance IRQ? The NIC may re-assert
this IRQ unexpectedly. */
if (!(val & DMA_INTREN)) {
DPRINTF("Lower Lance IRQ\n");
qemu_irq_lower(s->leirq);
}
if (val & DMA_RESET)
pcnet_h_reset(s->lance_opaque);
val &= 0x0fffffff;
val |= DMA_VER;
break;
default: default:
break; break;
} }
@ -222,9 +215,8 @@ static void dma_reset(void *opaque)
{ {
DMAState *s = opaque; DMAState *s = opaque;
memset(s->dmaregs, 0, DMA_REGS * 4); memset(s->dmaregs, 0, DMA_SIZE);
s->dmaregs[0] = DMA_VER; s->dmaregs[0] = DMA_VER;
s->dmaregs[4] = DMA_VER;
} }
static void dma_save(QEMUFile *f, void *opaque) static void dma_save(QEMUFile *f, void *opaque)
@ -241,7 +233,7 @@ static int dma_load(QEMUFile *f, void *opaque, int version_id)
DMAState *s = opaque; DMAState *s = opaque;
unsigned int i; unsigned int i;
if (version_id != 1) if (version_id != 2)
return -EINVAL; return -EINVAL;
for (i = 0; i < DMA_REGS; i++) for (i = 0; i < DMA_REGS; i++)
qemu_get_be32s(f, &s->dmaregs[i]); qemu_get_be32s(f, &s->dmaregs[i]);
@ -249,8 +241,7 @@ static int dma_load(QEMUFile *f, void *opaque, int version_id)
return 0; return 0;
} }
void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq espirq, void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq irq, void *iommu)
qemu_irq leirq, void *iommu)
{ {
DMAState *s; DMAState *s;
int dma_io_memory; int dma_io_memory;
@ -259,24 +250,23 @@ void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq espirq,
if (!s) if (!s)
return NULL; return NULL;
s->espirq = espirq; s->irq = irq;
s->leirq = leirq;
s->iommu = iommu; s->iommu = iommu;
dma_io_memory = cpu_register_io_memory(0, dma_mem_read, dma_mem_write, s); dma_io_memory = cpu_register_io_memory(0, dma_mem_read, dma_mem_write, s);
cpu_register_physical_memory(daddr, 16 * 2, dma_io_memory); cpu_register_physical_memory(daddr, DMA_SIZE, dma_io_memory);
register_savevm("sparc32_dma", daddr, 1, dma_save, dma_load, s); register_savevm("sparc32_dma", daddr, 2, dma_save, dma_load, s);
qemu_register_reset(dma_reset, s); qemu_register_reset(dma_reset, s);
return s; return s;
} }
void sparc32_dma_set_reset_data(void *opaque, void *esp_opaque, void sparc32_dma_set_reset_data(void *opaque, void (*dev_reset)(void *opaque),
void *lance_opaque) void *dev_opaque)
{ {
DMAState *s = opaque; DMAState *s = opaque;
s->esp_opaque = esp_opaque; s->dev_reset = dev_reset;
s->lance_opaque = lance_opaque; s->dev_opaque = dev_opaque;
} }

View File

@ -262,7 +262,7 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size,
{ {
CPUState *env, *envs[MAX_CPUS]; CPUState *env, *envs[MAX_CPUS];
unsigned int i; unsigned int i;
void *iommu, *dma, *main_esp, *main_lance = NULL; void *iommu, *espdma, *ledma, *main_esp, *main_lance = NULL;
const sparc_def_t *def; const sparc_def_t *def;
qemu_irq *slavio_irq; qemu_irq *slavio_irq;
@ -295,8 +295,10 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size,
for(i = 0; i < smp_cpus; i++) { for(i = 0; i < smp_cpus; i++) {
slavio_intctl_set_cpu(slavio_intctl, i, envs[i]); slavio_intctl_set_cpu(slavio_intctl, i, envs[i]);
} }
dma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq], espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
slavio_irq[hwdef->le_irq], iommu); iommu);
ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
slavio_irq[hwdef->le_irq], iommu);
if (graphic_depth != 8 && graphic_depth != 24) { if (graphic_depth != 8 && graphic_depth != 24) {
fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth); fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
@ -307,7 +309,7 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size,
if (nd_table[0].vlan) { if (nd_table[0].vlan) {
if (nd_table[0].model == NULL if (nd_table[0].model == NULL
|| strcmp(nd_table[0].model, "lance") == 0) { || strcmp(nd_table[0].model, "lance") == 0) {
main_lance = lance_init(&nd_table[0], hwdef->le_base, dma, main_lance = lance_init(&nd_table[0], hwdef->le_base, ledma,
slavio_irq[hwdef->le_irq]); slavio_irq[hwdef->le_irq]);
} else { } else {
fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model); fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
@ -329,7 +331,7 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size,
slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq], slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
serial_hds[1], serial_hds[0]); serial_hds[1], serial_hds[0]);
fdctrl_init(slavio_irq[hwdef->fd_irq], 0, 1, hwdef->fd_base, fd_table); fdctrl_init(slavio_irq[hwdef->fd_irq], 0, 1, hwdef->fd_base, fd_table);
main_esp = esp_init(bs_table, hwdef->esp_base, dma); main_esp = esp_init(bs_table, hwdef->esp_base, espdma);
for (i = 0; i < MAX_DISKS; i++) { for (i = 0; i < MAX_DISKS; i++) {
if (bs_table[i]) { if (bs_table[i]) {
@ -341,7 +343,6 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size,
slavio_irq[hwdef->me_irq]); slavio_irq[hwdef->me_irq]);
if (hwdef->cs_base != (target_phys_addr_t)-1) if (hwdef->cs_base != (target_phys_addr_t)-1)
cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl); cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
sparc32_dma_set_reset_data(dma, main_esp, main_lance);
} }
static void sun4m_load_kernel(long vram_size, int ram_size, int boot_device, static void sun4m_load_kernel(long vram_size, int ram_size, int boot_device,

9
vl.h
View File

@ -1046,7 +1046,6 @@ void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn);
/* pcnet.c */ /* pcnet.c */
void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn); void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn);
void pcnet_h_reset(void *opaque);
void *lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque, void *lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,
qemu_irq irq); qemu_irq irq);
@ -1265,11 +1264,9 @@ void slavio_set_power_fail(void *opaque, int power_failing);
void esp_scsi_attach(void *opaque, BlockDriverState *bd, int id); void esp_scsi_attach(void *opaque, BlockDriverState *bd, int id);
void *esp_init(BlockDriverState **bd, target_phys_addr_t espaddr, void *esp_init(BlockDriverState **bd, target_phys_addr_t espaddr,
void *dma_opaque); void *dma_opaque);
void esp_reset(void *opaque);
/* sparc32_dma.c */ /* sparc32_dma.c */
void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq espirq, void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq irq, void *iommu);
qemu_irq leirq, void *iommu);
void ledma_set_irq(void *opaque, int isr); void ledma_set_irq(void *opaque, int isr);
void ledma_memory_read(void *opaque, target_phys_addr_t addr, void ledma_memory_read(void *opaque, target_phys_addr_t addr,
uint8_t *buf, int len, int do_bswap); uint8_t *buf, int len, int do_bswap);
@ -1279,8 +1276,8 @@ void espdma_raise_irq(void *opaque);
void espdma_clear_irq(void *opaque); void espdma_clear_irq(void *opaque);
void espdma_memory_read(void *opaque, uint8_t *buf, int len); void espdma_memory_read(void *opaque, uint8_t *buf, int len);
void espdma_memory_write(void *opaque, uint8_t *buf, int len); void espdma_memory_write(void *opaque, uint8_t *buf, int len);
void sparc32_dma_set_reset_data(void *opaque, void *esp_opaque, void sparc32_dma_set_reset_data(void *opaque, void (*dev_reset)(void *opaque),
void *lance_opaque); void *dev_opaque);
/* cs4231.c */ /* cs4231.c */
void cs_init(target_phys_addr_t base, int irq, void *intctl); void cs_init(target_phys_addr_t base, int irq, void *intctl);