diff -NurpP --minimal qemu-cvs-06.02.2004/vl.c qemu-cvs-06.02.2004-hack/vl.c --- qemu-cvs-06.02.2004/vl.c 2004-02-04 00:37:12.000000000 +0100 +++ qemu-cvs-06.02.2004-hack/vl.c 2004-02-07 01:10:01.000000000 +0100 @@ -1817,10 +1817,10 @@ void serial_init(void) /***********************************************************/ /* ne2000 emulation */ +// #define DEBUG_NE2000 #if defined (TARGET_I386) -#define NE2000_IOPORT 0x300 -#define NE2000_IRQ 9 +#define NE2000_MAX_NIC 4 #define MAX_ETH_FRAME_SIZE 1514 @@ -1918,15 +1918,35 @@ typedef struct NE2000State { uint8_t curpag; uint8_t mult[8]; /* multicast mask array */ uint8_t mem[NE2000_MEM_SIZE]; + uint8_t irq; } NE2000State; -NE2000State ne2000_state; +NE2000State ne2000_state[NE2000_MAX_NIC]; int net_fd = -1; char network_script[1024]; -void ne2000_reset(void) +uint32_t ne2000_io[] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 }; +int ne2000_irq[] = { 9, 10, 11, 3, 4, 5 }; + +static inline int ne2000_addr_to_nic(uint32_t addr) { - NE2000State *s = &ne2000_state; + uint32_t base = (addr & ~0x1f); + int nic; + + for (nic=0; nicisr = ENISR_RESET; @@ -1944,6 +1964,7 @@ void ne2000_reset(void) s->mem[2 * i] = s->mem[i]; s->mem[2 * i + 1] = s->mem[i]; } + s->irq = ne2000_irq[nic]; } void ne2000_update_irq(NE2000State *s) @@ -1951,9 +1972,9 @@ void ne2000_update_irq(NE2000State *s) int isr; isr = s->isr & s->imr; if (isr) - pic_set_irq(NE2000_IRQ, 1); + pic_set_irq(s->irq, 1); else - pic_set_irq(NE2000_IRQ, 0); + pic_set_irq(s->irq, 0); } int net_init(void) @@ -2068,12 +2089,13 @@ void ne2000_receive(NE2000State *s, uint void ne2000_ioport_write(CPUState *env, uint32_t addr, uint32_t val) { - NE2000State *s = &ne2000_state; + int nic = ne2000_addr_to_nic(addr); + NE2000State *s = &ne2000_state[nic]; int offset, page; addr &= 0xf; #ifdef DEBUG_NE2000 - printf("NE2000: write addr=0x%x val=0x%02x\n", addr, val); + printf("NE2000[%d]: write addr=0x%x val=0x%02x\n", nic, addr, val); #endif if (addr == E8390_CMD) { /* control register */ @@ -2153,7 +2175,8 @@ void ne2000_ioport_write(CPUState *env, uint32_t ne2000_ioport_read(CPUState *env, uint32_t addr) { - NE2000State *s = &ne2000_state; + int nic = ne2000_addr_to_nic(addr); + NE2000State *s = &ne2000_state[nic]; int offset, page, ret; addr &= 0xf; @@ -2187,18 +2210,19 @@ uint32_t ne2000_ioport_read(CPUState *en } } #ifdef DEBUG_NE2000 - printf("NE2000: read addr=0x%x val=%02x\n", addr, ret); + printf("NE2000[%d]: read addr=0x%x val=%02x\n", nic, addr, ret); #endif return ret; } void ne2000_asic_ioport_write(CPUState *env, uint32_t addr, uint32_t val) { - NE2000State *s = &ne2000_state; + int nic = ne2000_addr_to_nic(addr); + NE2000State *s = &ne2000_state[nic]; uint8_t *p; #ifdef DEBUG_NE2000 - printf("NE2000: asic write val=0x%04x\n", val); + printf("NE2000[%d]: asic write val=0x%04x\n", nic, val); #endif p = s->mem + s->rsar; if (s->dcfg & 0x01) { @@ -2225,7 +2249,8 @@ void ne2000_asic_ioport_write(CPUState * uint32_t ne2000_asic_ioport_read(CPUState *env, uint32_t addr) { - NE2000State *s = &ne2000_state; + int nic = ne2000_addr_to_nic(addr); + NE2000State *s = &ne2000_state[nic]; uint8_t *p; int ret; @@ -2250,7 +2275,7 @@ uint32_t ne2000_asic_ioport_read(CPUStat ne2000_update_irq(s); } #ifdef DEBUG_NE2000 - printf("NE2000: asic read val=0x%04x\n", ret); + printf("NE2000[%d]: asic read val=0x%04x\n", nic, ret); #endif return ret; } @@ -2262,23 +2287,32 @@ void ne2000_reset_ioport_write(CPUState uint32_t ne2000_reset_ioport_read(CPUState *env, uint32_t addr) { - ne2000_reset(); + int nic = ne2000_addr_to_nic(addr); + ne2000_reset(nic); return 0; } void ne2000_init(void) { - register_ioport_write(NE2000_IOPORT, 16, ne2000_ioport_write, 1); - register_ioport_read(NE2000_IOPORT, 16, ne2000_ioport_read, 1); + int nic; + + for (nic=0; nic < NE2000_MAX_NIC; nic++) { + uint32_t base = ne2000_nic_to_addr(nic); - register_ioport_write(NE2000_IOPORT + 0x10, 1, ne2000_asic_ioport_write, 1); - register_ioport_read(NE2000_IOPORT + 0x10, 1, ne2000_asic_ioport_read, 1); - register_ioport_write(NE2000_IOPORT + 0x10, 2, ne2000_asic_ioport_write, 2); - register_ioport_read(NE2000_IOPORT + 0x10, 2, ne2000_asic_ioport_read, 2); + register_ioport_write(base, 16, ne2000_ioport_write, 1); + register_ioport_read(base, 16, ne2000_ioport_read, 1); - register_ioport_write(NE2000_IOPORT + 0x1f, 1, ne2000_reset_ioport_write, 1); - register_ioport_read(NE2000_IOPORT + 0x1f, 1, ne2000_reset_ioport_read, 1); - ne2000_reset(); + register_ioport_write(base + 0x10, 1, ne2000_asic_ioport_write, 1); + register_ioport_read(base + 0x10, 1, ne2000_asic_ioport_read, 1); + register_ioport_write(base + 0x10, 2, ne2000_asic_ioport_write, 2); + register_ioport_read(base + 0x10, 2, ne2000_asic_ioport_read, 2); + + register_ioport_write(base + 0x1f, 1, ne2000_reset_ioport_write, 1); + register_ioport_read(base + 0x1f, 1, ne2000_reset_ioport_read, 1); + + + ne2000_reset(nic); + } } #endif