diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c index 8df536d6be44e1da8c8ae9b3d28bd19b6dcee33e..3ed20665da6d36a5dce81125077a17655ae69a54 100644 --- a/hw/axis_dev88.c +++ b/hw/axis_dev88.c @@ -257,7 +257,7 @@ void axisdev88_init (ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { CPUState *env; - struct etraxfs_pic *pic; + qemu_irq *irq, *nmi; void *etraxfs_dmac; struct etraxfs_dma_client *eth[2] = {NULL, NULL}; int kernel_size; @@ -295,18 +295,20 @@ void axisdev88_init (ram_addr_t ram_size, cpu_register_physical_memory(0x3001a000, 0x5c, gpio_regs); - pic = etraxfs_pic_init(env, 0x3001c000); + irq = etraxfs_pic_init(env, 0x3001c000); + nmi = irq + 30; + etraxfs_dmac = etraxfs_dmac_init(env, 0x30000000, 10); for (i = 0; i < 10; i++) { /* On ETRAX, odd numbered channels are inputs. */ - etraxfs_dmac_connect(etraxfs_dmac, i, pic->irq + 7 + i, i & 1); + etraxfs_dmac_connect(etraxfs_dmac, i, irq + 7 + i, i & 1); } /* Add the two ethernet blocks. */ - eth[0] = etraxfs_eth_init(&nd_table[0], env, pic->irq + 25, 0x30034000, 1); + eth[0] = etraxfs_eth_init(&nd_table[0], env, irq + 25, 0x30034000, 1); if (nb_nics > 1) eth[1] = etraxfs_eth_init(&nd_table[1], env, - pic->irq + 26, 0x30036000, 2); + irq + 26, 0x30036000, 2); /* The DMA Connector block is missing, hardwire things for now. */ etraxfs_dmac_connect_client(etraxfs_dmac, 0, eth[0]); @@ -317,12 +319,12 @@ void axisdev88_init (ram_addr_t ram_size, } /* 2 timers. */ - etraxfs_timer_init(env, pic->irq + 0x1b, pic->nmi + 1, 0x3001e000); - etraxfs_timer_init(env, pic->irq + 0x1b, pic->nmi + 1, 0x3005e000); + etraxfs_timer_init(env, irq + 0x1b, nmi + 1, 0x3001e000); + etraxfs_timer_init(env, irq + 0x1b, nmi + 1, 0x3005e000); for (i = 0; i < 4; i++) { if (serial_hds[i]) { - etraxfs_ser_init(env, pic->irq + 0x14 + i, + etraxfs_ser_init(env, irq + 0x14 + i, serial_hds[i], 0x30026000 + i * 0x2000); } } diff --git a/hw/etraxfs.c b/hw/etraxfs.c index ad82132c3b58e37b57886f609c2df6bf84c2233f..52428d144f05b8347210834b72d0ad23e1aa7b94 100644 --- a/hw/etraxfs.c +++ b/hw/etraxfs.c @@ -52,7 +52,7 @@ void bareetraxfs_init (ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { CPUState *env; - struct etraxfs_pic *pic; + qemu_irq *irq, *nmi; void *etraxfs_dmac; struct etraxfs_dma_client *eth[2] = {NULL, NULL}; int kernel_size; @@ -86,18 +86,20 @@ void bareetraxfs_init (ram_addr_t ram_size, FLASH_SIZE >> 16, 1, 2, 0x0000, 0x0000, 0x0000, 0x0000, 0x555, 0x2aa); - pic = etraxfs_pic_init(env, 0x3001c000); + irq = etraxfs_pic_init(env, 0x3001c000); + nmi = irq + 30; + etraxfs_dmac = etraxfs_dmac_init(env, 0x30000000, 10); for (i = 0; i < 10; i++) { /* On ETRAX, odd numbered channels are inputs. */ - etraxfs_dmac_connect(etraxfs_dmac, i, pic->irq + 7 + i, i & 1); + etraxfs_dmac_connect(etraxfs_dmac, i, irq + 7 + i, i & 1); } /* Add the two ethernet blocks. */ - eth[0] = etraxfs_eth_init(&nd_table[0], env, pic->irq + 25, 0x30034000, 1); + eth[0] = etraxfs_eth_init(&nd_table[0], env, irq + 25, 0x30034000, 1); if (nb_nics > 1) eth[1] = etraxfs_eth_init(&nd_table[1], env, - pic->irq + 26, 0x30036000, 2); + irq + 26, 0x30036000, 2); /* The DMA Connector block is missing, hardwire things for now. */ etraxfs_dmac_connect_client(etraxfs_dmac, 0, eth[0]); @@ -108,12 +110,12 @@ void bareetraxfs_init (ram_addr_t ram_size, } /* 2 timers. */ - etraxfs_timer_init(env, pic->irq + 0x1b, pic->nmi + 1, 0x3001e000); - etraxfs_timer_init(env, pic->irq + 0x1b, pic->nmi + 1, 0x3005e000); + etraxfs_timer_init(env, irq + 0x1b, nmi + 1, 0x3001e000); + etraxfs_timer_init(env, irq + 0x1b, nmi + 1, 0x3005e000); for (i = 0; i < 4; i++) { if (serial_hds[i]) { - etraxfs_ser_init(env, pic->irq + 0x14 + i, + etraxfs_ser_init(env, irq + 0x14 + i, serial_hds[i], 0x30026000 + i * 0x2000); } } diff --git a/hw/etraxfs.h b/hw/etraxfs.h index 17dca29a446a25ba5062c7c9816de971c7ba3b78..247cb695f89bf617e67666f772e9bbabc5e56a36 100644 --- a/hw/etraxfs.h +++ b/hw/etraxfs.h @@ -24,16 +24,7 @@ #include "etraxfs_dma.h" -struct etraxfs_pic -{ - qemu_irq *irq; - qemu_irq *nmi; - qemu_irq *guru; - - void *internal; -}; - -struct etraxfs_pic *etraxfs_pic_init(CPUState *env, target_phys_addr_t base); +qemu_irq *etraxfs_pic_init(CPUState *env, target_phys_addr_t base); void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, qemu_irq *nmi, target_phys_addr_t base); void *etraxfs_eth_init(NICInfo *nd, CPUState *env, diff --git a/hw/etraxfs_pic.c b/hw/etraxfs_pic.c index 49e991c718d3f70d795262f1edae7e62830bd18f..622d655ac319d008b06316497c873b4423d77f1e 100644 --- a/hw/etraxfs_pic.c +++ b/hw/etraxfs_pic.c @@ -118,16 +118,6 @@ void irq_info(Monitor *mon) { } -static void irq_handler(void *opaque, int irq, int level) -{ - struct fs_pic_state *fs = (void *)opaque; - irq -= 1; - fs->regs[R_R_VECT] &= ~(1 << irq); - fs->regs[R_R_VECT] |= (!!level << irq); - - pic_update(fs); -} - static void nmi_handler(void *opaque, int irq, int level) { struct fs_pic_state *fs = (void *)opaque; @@ -146,27 +136,30 @@ static void nmi_handler(void *opaque, int irq, int level) cpu_reset_interrupt(env, CPU_INTERRUPT_NMI); } -static void guru_handler(void *opaque, int irq, int level) +static void irq_handler(void *opaque, int irq, int level) { - hw_error("%s unsupported exception\n", __func__); + struct fs_pic_state *fs = (void *)opaque; + + if (irq >= 30) + return nmi_handler(opaque, irq, level); + + irq -= 1; + fs->regs[R_R_VECT] &= ~(1 << irq); + fs->regs[R_R_VECT] |= (!!level << irq); + pic_update(fs); } -struct etraxfs_pic *etraxfs_pic_init(CPUState *env, target_phys_addr_t base) +qemu_irq *etraxfs_pic_init(CPUState *env, target_phys_addr_t base) { struct fs_pic_state *fs = NULL; - struct etraxfs_pic *pic = NULL; + qemu_irq *irq; int intr_vect_regs; - pic = qemu_mallocz(sizeof *pic); - pic->internal = fs = qemu_mallocz(sizeof *fs); - + fs = qemu_mallocz(sizeof *fs); fs->env = env; - pic->irq = qemu_allocate_irqs(irq_handler, fs, 30); - pic->nmi = qemu_allocate_irqs(nmi_handler, fs, 2); - pic->guru = qemu_allocate_irqs(guru_handler, fs, 1); + irq = qemu_allocate_irqs(irq_handler, fs, 32); intr_vect_regs = cpu_register_io_memory(0, pic_read, pic_write, fs); cpu_register_physical_memory(base, R_MAX * 4, intr_vect_regs); - - return pic; + return irq; }