* [Qemu-devel] multiple nics in QEMU
@ 2004-02-07 23:17 Herbert Poetzl
2004-02-08 13:28 ` [Qemu-devel] " Fabrice Bellard
0 siblings, 1 reply; 2+ messages in thread
From: Herbert Poetzl @ 2004-02-07 23:17 UTC (permalink / raw)
To: Fabrice Bellard; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 467 bytes --]
Hi Fabrice!
it would be nice to have support for multiple nics
in QEMU, to test network stuff and routing with the
linux kernel for example ...
attached is a patch, which should be considered a
proof of concept code for that, and maybe the first
step, the next would require to adapt the command
line options to make use of this, and to move the
nic_fd into the NE2000 struct, so I didn't do that,
because I do not know your preferences there ...
HTH,
Herbert
[-- Attachment #2: qemu-ethX-hack.diff --]
[-- Type: text/plain, Size: 5654 bytes --]
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; nic<NE2000_MAX_NIC; nic++)
+ if (base == ne2000_io[nic])
+ return nic;
+ return 0;
+}
+
+static inline uint32_t ne2000_nic_to_addr(int nic)
+{
+ return ne2000_io[nic % NE2000_MAX_NIC];
+}
+
+void ne2000_reset(nic)
+{
+ NE2000State *s = &ne2000_state[nic];
int i;
s->isr = 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
^ permalink raw reply [flat|nested] 2+ messages in thread
* [Qemu-devel] Re: multiple nics in QEMU
2004-02-07 23:17 [Qemu-devel] multiple nics in QEMU Herbert Poetzl
@ 2004-02-08 13:28 ` Fabrice Bellard
0 siblings, 0 replies; 2+ messages in thread
From: Fabrice Bellard @ 2004-02-08 13:28 UTC (permalink / raw)
To: Herbert Poetzl; +Cc: qemu-devel
Good Idea. I'll add that in the CVS.
Fabrice.
Herbert Poetzl wrote:
> Hi Fabrice!
>
> it would be nice to have support for multiple nics
> in QEMU, to test network stuff and routing with the
> linux kernel for example ...
>
> attached is a patch, which should be considered a
> proof of concept code for that, and maybe the first
> step, the next would require to adapt the command
> line options to make use of this, and to move the
> nic_fd into the NE2000 struct, so I didn't do that,
> because I do not know your preferences there ...
>
> HTH,
> Herbert
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2004-02-08 13:28 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-02-07 23:17 [Qemu-devel] multiple nics in QEMU Herbert Poetzl
2004-02-08 13:28 ` [Qemu-devel] " Fabrice Bellard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).