From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.30) id 1B7B1L-0007mQ-PO for qemu-devel@nongnu.org; Sat, 27 Mar 2004 05:26:31 -0500 Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.30) id 1B7B0o-0007FS-KY for qemu-devel@nongnu.org; Sat, 27 Mar 2004 05:26:29 -0500 Received: from [130.136.10.114] (helo=pob.cs.unibo.it) by monty-python.gnu.org with esmtp (Exim 4.30) id 1B7B0o-0007CM-0V for qemu-devel@nongnu.org; Sat, 27 Mar 2004 05:25:58 -0500 Date: Sat, 27 Mar 2004 11:25:50 +0100 Message-ID: <20040327102550.GA24310@cs.unibo.it> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="fdj2RfSjLxBAspz7" Content-Disposition: inline From: renzo@cs.unibo.it (Renzo Davoli) Subject: [Qemu-devel] ne2000 patches (now it works on win98) Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, fabrice@bellard.org --fdj2RfSjLxBAspz7 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline I have found some bugs in the ne2k emulation: - the 32K packet buffer is at address 16k (i.e. in the range 16k-48k) (actually it is in the range 0-32k) - there was no control of out-of-range access to the packet buffer (the ugly win packet driver tests the ne2k memory by writing a pattern at different addresses, no control=segmentation fault!) - ioport_write EN0_ISR: the highest order bit (reset flag) must keep untouched it is reset by the start command. - the win driver needs the EN0_RSARLO and EN0_RSARHI management in the ioport_read routine (this very ugly win98_se driver instead of keeping a variable with the current address rereads the address from the interface, very smart ;-) I have been able to start and run win98 with vde. After the switch from the clouded sky to the light blue background it seems that the O.S. waits for a timeout (maybe something related to the DHCP negotiation of the address -- my DHCP server is remote into a tunnel). But,.... it works. (Also with multiple interfaces, -- Win98 is able to use just one at a time, though). The file here attached is the patch for hw/ne2000.c source file. I have created a 48K memory but in the reality only the first 32 bytes + the range 16k-48k is used, with an extra "if" the interface memory can be compacted. Fabrice, I'd have some requests for the code.... I would like irq and iomem as well as MAC address for net interfaces to be reconfigurable. Now I cannot put two qemu machines on the same virtual net as they pretend to have the same MAC. Two questions: - it is better to add command line options or a configuration file would help? It seems to me that you like command line options instead of configuration files: the pro is that the options are not hidden, the cons is that for complex configuration the command line can grow to unmanageable limits - do you like me to write the code? it is just a coordination issue, it is useless for both to write the same code. ciao and "happy hacking". renzo --fdj2RfSjLxBAspz7 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="ne2000.c.diff" *** ne2000.orig.c Sat Mar 27 10:24:32 2004 --- ne2000.c Sat Mar 27 10:07:00 2004 *************** *** 123,129 **** #define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */ #define ENTSR_OWC 0x80 /* There was an out-of-window collision. */ ! #define NE2000_MEM_SIZE 32768 typedef struct NE2000State { uint8_t cmd; --- 123,134 ---- #define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */ #define ENTSR_OWC 0x80 /* There was an out-of-window collision. */ ! //#define NE2000_MEM_SIZE 32768 ! //#define NE2000_MEM_SIZE 65536 ! #define NE2000_PMEM_SIZE (32*1024) ! #define NE2000_PMEM_START (16*1024) ! #define NE2000_PMEM_END (NE2000_PMEM_SIZE+NE2000_PMEM_START) ! #define NE2000_MEM_SIZE NE2000_PMEM_END typedef struct NE2000State { uint8_t cmd; *************** *** 260,265 **** --- 265,271 ---- /* control register */ s->cmd = val; if (val & E8390_START) { + s->isr &= ~ENISR_RESET; /* test specific case: zero length transfert */ if ((val & (E8390_RREAD | E8390_RWRITE)) && s->rcnt == 0) { *************** *** 316,322 **** s->dcfg = val; break; case EN0_ISR: ! s->isr &= ~val; ne2000_update_irq(s); break; case EN1_PHYS ... EN1_PHYS + 5: --- 322,328 ---- s->dcfg = val; break; case EN0_ISR: ! s->isr &= ~(val & 0x7f); ne2000_update_irq(s); break; case EN1_PHYS ... EN1_PHYS + 5: *************** *** 353,358 **** --- 359,370 ---- case EN0_ISR: ret = s->isr; break; + case EN0_RSARLO: + ret = s->rsar & 0x00ff; + break; + case EN0_RSARHI: + ret = s->rsar >> 8; + break; case EN1_PHYS ... EN1_PHYS + 5: ret = s->phys[offset - EN1_PHYS]; break; *************** *** 363,368 **** --- 375,381 ---- ret = s->mult[offset - EN1_MULT]; break; default: + /* printf("not implemented\n"); RD*/ ret = 0x00; break; } *************** *** 379,398 **** uint8_t *p; #ifdef DEBUG_NE2000 ! printf("NE2000: asic write val=0x%04x\n", val); #endif p = s->mem + s->rsar; ! if (s->dcfg & 0x01) { ! /* 16 bit access */ ! p[0] = val; ! p[1] = val >> 8; ! s->rsar += 2; ! s->rcnt -= 2; } else { ! /* 8 bit access */ ! p[0] = val; ! s->rsar++; ! s->rcnt--; } /* wrap */ if (s->rsar == s->stop) --- 392,418 ---- uint8_t *p; #ifdef DEBUG_NE2000 ! printf("NE2000: asic write addr=%x rsar=%x val=0x%04x\n", addr, s->rsar, val); #endif p = s->mem + s->rsar; ! if (s->rcnt == 0) ! return; ! if (s->rsar < 32 || (s->rsar >= NE2000_PMEM_START && s->rsar < NE2000_MEM_SIZE)) { /*RD*/ ! if (s->dcfg & 0x01) { ! /* 16 bit access */ ! p[0] = val; ! p[1] = val >> 8; ! s->rsar += 2; ! s->rcnt -= 2; ! } else { ! /* 8 bit access */ ! p[0] = val; ! s->rsar++; ! s->rcnt--; ! } } else { ! s->rcnt=0; /*RD*/ ! s->rsar += 1 + (s->dcfg & 0x01); } /* wrap */ if (s->rsar == s->stop) *************** *** 411,426 **** int ret; p = s->mem + s->rsar; ! if (s->dcfg & 0x01) { ! /* 16 bit access */ ! ret = p[0] | (p[1] << 8); ! s->rsar += 2; ! s->rcnt -= 2; } else { ! /* 8 bit access */ ! ret = p[0]; ! s->rsar++; ! s->rcnt--; } /* wrap */ if (s->rsar == s->stop) --- 431,451 ---- int ret; p = s->mem + s->rsar; ! if (s->rsar < 32 || (s->rsar >= NE2000_PMEM_START && s->rsar < NE2000_MEM_SIZE)) { /*RD*/ ! if (s->dcfg & 0x01) { ! /* 16 bit access */ ! ret = p[0] | (p[1] << 8); ! s->rsar += 2; ! s->rcnt -= 2; ! } else { ! /* 8 bit access */ ! ret = p[0]; ! s->rsar++; ! s->rcnt--; ! } } else { ! s->rsar += 1 + (s->dcfg & 0x01); ! ret = 0x00ff; /*RD*/ } /* wrap */ if (s->rsar == s->stop) *************** *** 431,437 **** ne2000_update_irq(s); } #ifdef DEBUG_NE2000 ! printf("NE2000: asic read val=0x%04x\n", ret); #endif return ret; } --- 456,462 ---- ne2000_update_irq(s); } #ifdef DEBUG_NE2000 ! printf("NE2000: asic read addr=%x rsar=%x val=0x%04x\n", addr, s->rsar, ret); #endif return ret; } --fdj2RfSjLxBAspz7--