diff options
author | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-05-26 17:39:43 +0000 |
---|---|---|
committer | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-05-26 17:39:43 +0000 |
commit | 5aca8c3b2fbada188ff86781fba24685d346cef9 (patch) | |
tree | d3cc0526e7c45b23dfddf42a123d4261f87a93b4 /hw | |
parent | db7b5426a4b424249b4aba3496bf14da69a6625b (diff) |
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
Diffstat (limited to 'hw')
-rw-r--r-- | hw/cs4231.c | 3 | ||||
-rw-r--r-- | hw/esp.c | 29 | ||||
-rw-r--r-- | hw/pcnet.c | 4 | ||||
-rw-r--r-- | hw/slavio_intctl.c | 7 | ||||
-rw-r--r-- | hw/slavio_misc.c | 22 | ||||
-rw-r--r-- | hw/slavio_serial.c | 7 | ||||
-rw-r--r-- | hw/slavio_timer.c | 3 | ||||
-rw-r--r-- | hw/sparc32_dma.c | 72 | ||||
-rw-r--r-- | hw/sun4m.c | 13 |
9 files changed, 84 insertions, 76 deletions
diff --git a/hw/cs4231.c b/hw/cs4231.c index 6df881d41b..390ef746f6 100644 --- a/hw/cs4231.c +++ b/hw/cs4231.c @@ -30,6 +30,7 @@ * In addition to Crystal CS4231 there is a DMA controller on Sparc. */ #define CS_MAXADDR 0x3f +#define CS_SIZE (CS_MAXADDR + 1) #define CS_REGS 16 #define CS_DREGS 32 #define CS_MAXDREG (CS_DREGS - 1) @@ -173,7 +174,7 @@ void cs_init(target_phys_addr_t base, int irq, void *intctl) return; 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); qemu_register_reset(cs_reset, s); cs_reset(s); @@ -41,7 +41,9 @@ do { printf("ESP: " fmt , ##args); } while (0) #define DPRINTF(fmt, args...) #endif -#define ESP_MAXREG 0x3f +#define ESP_MASK 0x3f +#define ESP_REGS 16 +#define ESP_SIZE (ESP_REGS * 4) #define TI_BUFSZ 32 /* The HBA is ID 7, so for simplicitly limit to 7 devices. */ #define ESP_MAX_DEVS 7 @@ -50,8 +52,8 @@ typedef struct ESPState ESPState; struct ESPState { BlockDriverState **bd; - uint8_t rregs[ESP_MAXREG]; - uint8_t wregs[ESP_MAXREG]; + uint8_t rregs[ESP_REGS]; + uint8_t wregs[ESP_REGS]; int32_t ti_size; uint32_t ti_rptr, ti_wptr; 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; - memset(s->rregs, 0, ESP_MAXREG); - memset(s->wregs, 0, ESP_MAXREG); + memset(s->rregs, 0, ESP_REGS); + memset(s->wregs, 0, ESP_REGS); s->rregs[0x0e] = 0x4; // Indicate fas100a s->ti_size = 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; 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]); switch (saddr) { case 2: @@ -384,7 +386,7 @@ static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) ESPState *s = opaque; 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); switch (saddr) { case 0: @@ -501,8 +503,8 @@ static void esp_save(QEMUFile *f, void *opaque) { ESPState *s = opaque; - qemu_put_buffer(f, s->rregs, ESP_MAXREG); - qemu_put_buffer(f, s->wregs, ESP_MAXREG); + qemu_put_buffer(f, s->rregs, ESP_REGS); + qemu_put_buffer(f, s->wregs, ESP_REGS); qemu_put_be32s(f, &s->ti_size); qemu_put_be32s(f, &s->ti_rptr); 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) return -EINVAL; // Cannot emulate 2 - qemu_get_buffer(f, s->rregs, ESP_MAXREG); - qemu_get_buffer(f, s->wregs, ESP_MAXREG); + qemu_get_buffer(f, s->rregs, ESP_REGS); + qemu_get_buffer(f, s->wregs, ESP_REGS); qemu_get_be32s(f, &s->ti_size); qemu_get_be32s(f, &s->ti_rptr); 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->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); - cpu_register_physical_memory(espaddr, ESP_MAXREG*4, esp_io_memory); + cpu_register_physical_memory(espaddr, ESP_SIZE, esp_io_memory); esp_reset(s); diff --git a/hw/pcnet.c b/hw/pcnet.c index 12d973479c..4c4278ffa3 100644 --- a/hw/pcnet.c +++ b/hw/pcnet.c @@ -1554,7 +1554,7 @@ static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap) return val; } -void pcnet_h_reset(void *opaque) +static void pcnet_h_reset(void *opaque) { PCNetState *s = opaque; 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); 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); d->irq = irq; diff --git a/hw/slavio_intctl.c b/hw/slavio_intctl.c index 2d1f6552e0..7f93b22e32 100644 --- a/hw/slavio_intctl.c +++ b/hw/slavio_intctl.c @@ -58,7 +58,9 @@ typedef struct SLAVIO_INTCTLState { } SLAVIO_INTCTLState; #define INTCTL_MAXADDR 0xf +#define INTCTL_SIZE (INTCTL_MAXADDR + 1) #define INTCTLM_MAXADDR 0x13 +#define INTCTLM_SIZE (INTCTLM_MAXADDR + 1) #define INTCTLM_MASK 0x1f 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; 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); - 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); - 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); qemu_register_reset(slavio_intctl_reset, s); diff --git a/hw/slavio_misc.c b/hw/slavio_misc.c index 1007238240..e8a4ea4d41 100644 --- a/hw/slavio_misc.c +++ b/hw/slavio_misc.c @@ -47,7 +47,7 @@ typedef struct MiscState { uint8_t diag, mctrl, sysctrl; } MiscState; -#define MISC_MAXADDR 1 +#define MISC_SIZE 1 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 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 - 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 - 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 - 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 - 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 - 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 - 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; diff --git a/hw/slavio_serial.c b/hw/slavio_serial.c index 3da40eb6cf..0a2c873300 100644 --- a/hw/slavio_serial.c +++ b/hw/slavio_serial.c @@ -102,6 +102,7 @@ struct SerialState { }; #define SERIAL_MAXADDR 7 +#define SERIAL_SIZE (SERIAL_MAXADDR + 1) static void handle_kbd_command(ChannelState *s, int val); static int serial_can_receive(void *opaque); @@ -178,7 +179,7 @@ static void slavio_serial_reset_chn(ChannelState *s) int i; s->reg = 0; - for (i = 0; i < SERIAL_MAXADDR; i++) { + for (i = 0; i < SERIAL_SIZE; i++) { s->rregs[i] = 0; s->wregs[i] = 0; } @@ -598,7 +599,7 @@ SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq, return NULL; 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[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; 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_kbd_event_handler(sunkbd_event, &s->chn[1]); diff --git a/hw/slavio_timer.c b/hw/slavio_timer.c index e8b435f1c0..6bc293e672 100644 --- a/hw/slavio_timer.c +++ b/hw/slavio_timer.c @@ -59,6 +59,7 @@ typedef struct SLAVIO_TIMERState { } SLAVIO_TIMERState; #define TIMER_MAXADDR 0x1f +#define TIMER_SIZE (TIMER_MAXADDR + 1) // Update count, set irq, update expire_time // 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_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); qemu_register_reset(slavio_timer_reset, s); slavio_timer_reset(s); diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c index e1baee8b88..de14998768 100644 --- a/hw/sparc32_dma.c +++ b/hw/sparc32_dma.c @@ -41,22 +41,25 @@ do { printf("DMA: " fmt , ##args); } while (0) #define DPRINTF(fmt, args...) #endif -#define DMA_REGS 8 -#define DMA_MAXADDR (DMA_REGS * 4 - 1) +#define DMA_REGS 4 +#define DMA_SIZE (4 * sizeof(uint32_t)) +#define DMA_MAXADDR (DMA_SIZE - 1) #define DMA_VER 0xa0000000 #define DMA_INTR 1 #define DMA_INTREN 0x10 #define DMA_WRITE_MEM 0x100 #define DMA_LOADED 0x04000000 +#define DMA_DRAIN_FIFO 0x40 #define DMA_RESET 0x80 typedef struct DMAState DMAState; struct DMAState { uint32_t dmaregs[DMA_REGS]; - qemu_irq espirq, leirq; - void *iommu, *esp_opaque, *lance_opaque; + qemu_irq irq; + void *iommu, *dev_opaque; + void (*dev_reset)(void *dev_opaque); 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", s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]); - addr |= s->dmaregs[7]; + addr |= s->dmaregs[3]; if (do_bswap) { sparc_iommu_memory_read(s->iommu, addr, buf, len); } 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", s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]); - addr |= s->dmaregs[7]; + addr |= s->dmaregs[3]; if (do_bswap) { sparc_iommu_memory_write(s->iommu, addr, buf, len); } else { @@ -118,7 +121,7 @@ void espdma_raise_irq(void *opaque) DPRINTF("Raise ESP IRQ\n"); s->dmaregs[0] |= DMA_INTR; - qemu_irq_raise(s->espirq); + qemu_irq_raise(s->irq); } void espdma_clear_irq(void *opaque) @@ -127,7 +130,7 @@ void espdma_clear_irq(void *opaque) s->dmaregs[0] &= ~DMA_INTR; 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) @@ -158,7 +161,8 @@ static uint32_t dma_mem_readl(void *opaque, target_phys_addr_t addr) uint32_t saddr; 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]; } @@ -169,37 +173,26 @@ static void dma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) uint32_t saddr; 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) { case 0: if (!(val & DMA_INTREN)) { - DPRINTF("Lower ESP IRQ\n"); - qemu_irq_lower(s->espirq); + DPRINTF("Lower IRQ\n"); + qemu_irq_lower(s->irq); } if (val & DMA_RESET) { - esp_reset(s->esp_opaque); - } else if (val & 0x40) { - val &= ~0x40; + s->dev_reset(s->dev_opaque); + } else if (val & DMA_DRAIN_FIFO) { + val &= ~DMA_DRAIN_FIFO; } else if (val == 0) - val = 0x40; + val = DMA_DRAIN_FIFO; val &= 0x0fffffff; val |= DMA_VER; break; case 1: s->dmaregs[0] |= DMA_LOADED; 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: break; } @@ -222,9 +215,8 @@ static void dma_reset(void *opaque) { DMAState *s = opaque; - memset(s->dmaregs, 0, DMA_REGS * 4); + memset(s->dmaregs, 0, DMA_SIZE); s->dmaregs[0] = DMA_VER; - s->dmaregs[4] = DMA_VER; } 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; unsigned int i; - if (version_id != 1) + if (version_id != 2) return -EINVAL; for (i = 0; i < DMA_REGS; 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; } -void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq espirq, - qemu_irq leirq, void *iommu) +void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq irq, void *iommu) { DMAState *s; int dma_io_memory; @@ -259,24 +250,23 @@ void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq espirq, if (!s) return NULL; - s->espirq = espirq; - s->leirq = leirq; + s->irq = irq; s->iommu = iommu; 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); return s; } -void sparc32_dma_set_reset_data(void *opaque, void *esp_opaque, - void *lance_opaque) +void sparc32_dma_set_reset_data(void *opaque, void (*dev_reset)(void *opaque), + void *dev_opaque) { DMAState *s = opaque; - s->esp_opaque = esp_opaque; - s->lance_opaque = lance_opaque; + s->dev_reset = dev_reset; + s->dev_opaque = dev_opaque; } diff --git a/hw/sun4m.c b/hw/sun4m.c index 313e5b4aa1..10473baa49 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -262,7 +262,7 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size, { CPUState *env, *envs[MAX_CPUS]; 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; 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++) { slavio_intctl_set_cpu(slavio_intctl, i, envs[i]); } - dma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq], - slavio_irq[hwdef->le_irq], iommu); + espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq], + iommu); + ledma = sparc32_dma_init(hwdef->dma_base + 16ULL, + slavio_irq[hwdef->le_irq], iommu); if (graphic_depth != 8 && graphic_depth != 24) { 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].model == NULL || 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]); } else { 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], serial_hds[1], serial_hds[0]); 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++) { 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]); if (hwdef->cs_base != (target_phys_addr_t)-1) 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, |