Commit ee9dbb297db6adcac1df966e160e33b166b5a92a

Authored by bellard
1 parent c20709aa

NE2000 fixes for windows (Renzo Davoli)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@731 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 61 additions and 13 deletions
hw/ne2000.c
@@ -103,7 +103,10 @@ @@ -103,7 +103,10 @@
103 #define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */ 103 #define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */
104 #define ENTSR_OWC 0x80 /* There was an out-of-window collision. */ 104 #define ENTSR_OWC 0x80 /* There was an out-of-window collision. */
105 105
106 -#define NE2000_MEM_SIZE 32768 106 +#define NE2000_PMEM_SIZE (32*1024)
  107 +#define NE2000_PMEM_START (16*1024)
  108 +#define NE2000_PMEM_END (NE2000_PMEM_SIZE+NE2000_PMEM_START)
  109 +#define NE2000_MEM_SIZE NE2000_PMEM_END
107 110
108 typedef struct NE2000State { 111 typedef struct NE2000State {
109 uint8_t cmd; 112 uint8_t cmd;
@@ -244,6 +247,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) @@ -244,6 +247,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
244 /* control register */ 247 /* control register */
245 s->cmd = val; 248 s->cmd = val;
246 if (val & E8390_START) { 249 if (val & E8390_START) {
  250 + s->isr &= ~ENISR_RESET;
247 /* test specific case: zero length transfert */ 251 /* test specific case: zero length transfert */
248 if ((val & (E8390_RREAD | E8390_RWRITE)) && 252 if ((val & (E8390_RREAD | E8390_RWRITE)) &&
249 s->rcnt == 0) { 253 s->rcnt == 0) {
@@ -251,7 +255,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) @@ -251,7 +255,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
251 ne2000_update_irq(s); 255 ne2000_update_irq(s);
252 } 256 }
253 if (val & E8390_TRANS) { 257 if (val & E8390_TRANS) {
254 - net_send_packet(s->nd, s->mem + (s->tpsr << 8), s->tcnt); 258 + qemu_send_packet(s->nd, s->mem + (s->tpsr << 8), s->tcnt);
255 /* signal end of transfert */ 259 /* signal end of transfert */
256 s->tsr = ENTSR_PTX; 260 s->tsr = ENTSR_PTX;
257 s->isr |= ENISR_TX; 261 s->isr |= ENISR_TX;
@@ -300,7 +304,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) @@ -300,7 +304,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
300 s->dcfg = val; 304 s->dcfg = val;
301 break; 305 break;
302 case EN0_ISR: 306 case EN0_ISR:
303 - s->isr &= ~val; 307 + s->isr &= ~(val & 0x7f);
304 ne2000_update_irq(s); 308 ne2000_update_irq(s);
305 break; 309 break;
306 case EN1_PHYS ... EN1_PHYS + 5: 310 case EN1_PHYS ... EN1_PHYS + 5:
@@ -337,6 +341,12 @@ static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) @@ -337,6 +341,12 @@ static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
337 case EN0_ISR: 341 case EN0_ISR:
338 ret = s->isr; 342 ret = s->isr;
339 break; 343 break;
  344 + case EN0_RSARLO:
  345 + ret = s->rsar & 0x00ff;
  346 + break;
  347 + case EN0_RSARHI:
  348 + ret = s->rsar >> 8;
  349 + break;
340 case EN1_PHYS ... EN1_PHYS + 5: 350 case EN1_PHYS ... EN1_PHYS + 5:
341 ret = s->phys[offset - EN1_PHYS]; 351 ret = s->phys[offset - EN1_PHYS];
342 break; 352 break;
@@ -357,24 +367,64 @@ static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) @@ -357,24 +367,64 @@ static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
357 return ret; 367 return ret;
358 } 368 }
359 369
  370 +static inline void ne2000_mem_writeb(NE2000State *s, uint32_t addr,
  371 + uint32_t val)
  372 +{
  373 + if (addr < 32 ||
  374 + (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
  375 + s->mem[addr] = val;
  376 + }
  377 +}
  378 +
  379 +static inline void ne2000_mem_writew(NE2000State *s, uint32_t addr,
  380 + uint32_t val)
  381 +{
  382 + addr &= ~1; /* XXX: check exact behaviour if not even */
  383 + if (addr < 32 ||
  384 + (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
  385 + s->mem[addr] = val;
  386 + s->mem[addr + 1] = val >> 8;
  387 + }
  388 +}
  389 +
  390 +static inline uint32_t ne2000_mem_readb(NE2000State *s, uint32_t addr)
  391 +{
  392 + if (addr < 32 ||
  393 + (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
  394 + return s->mem[addr];
  395 + } else {
  396 + return 0xff;
  397 + }
  398 +}
  399 +
  400 +static inline uint32_t ne2000_mem_readw(NE2000State *s, uint32_t addr)
  401 +{
  402 + addr &= ~1; /* XXX: check exact behaviour if not even */
  403 + if (addr < 32 ||
  404 + (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
  405 + return s->mem[addr] | (s->mem[addr + 1] << 8);
  406 + } else {
  407 + return 0xffff;
  408 + }
  409 +}
  410 +
360 static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) 411 static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
361 { 412 {
362 NE2000State *s = opaque; 413 NE2000State *s = opaque;
363 - uint8_t *p;  
364 414
365 #ifdef DEBUG_NE2000 415 #ifdef DEBUG_NE2000
366 printf("NE2000: asic write val=0x%04x\n", val); 416 printf("NE2000: asic write val=0x%04x\n", val);
367 #endif 417 #endif
368 - p = s->mem + s->rsar; 418 + if (s->rcnt == 0)
  419 + return;
369 if (s->dcfg & 0x01) { 420 if (s->dcfg & 0x01) {
370 /* 16 bit access */ 421 /* 16 bit access */
371 - p[0] = val;  
372 - p[1] = val >> 8; 422 + ne2000_mem_writew(s, s->rsar, val);
373 s->rsar += 2; 423 s->rsar += 2;
374 s->rcnt -= 2; 424 s->rcnt -= 2;
375 } else { 425 } else {
376 /* 8 bit access */ 426 /* 8 bit access */
377 - p[0] = val; 427 + ne2000_mem_writeb(s, s->rsar, val);
378 s->rsar++; 428 s->rsar++;
379 s->rcnt--; 429 s->rcnt--;
380 } 430 }
@@ -391,18 +441,16 @@ static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) @@ -391,18 +441,16 @@ static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
391 static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr) 441 static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr)
392 { 442 {
393 NE2000State *s = opaque; 443 NE2000State *s = opaque;
394 - uint8_t *p;  
395 int ret; 444 int ret;
396 445
397 - p = s->mem + s->rsar;  
398 if (s->dcfg & 0x01) { 446 if (s->dcfg & 0x01) {
399 /* 16 bit access */ 447 /* 16 bit access */
400 - ret = p[0] | (p[1] << 8); 448 + ret = ne2000_mem_readw(s, s->rsar);
401 s->rsar += 2; 449 s->rsar += 2;
402 s->rcnt -= 2; 450 s->rcnt -= 2;
403 } else { 451 } else {
404 /* 8 bit access */ 452 /* 8 bit access */
405 - ret = p[0]; 453 + ret = ne2000_mem_readb(s, s->rsar);
406 s->rsar++; 454 s->rsar++;
407 s->rcnt--; 455 s->rcnt--;
408 } 456 }
@@ -455,5 +503,5 @@ void ne2000_init(int base, int irq, NetDriverState *nd) @@ -455,5 +503,5 @@ void ne2000_init(int base, int irq, NetDriverState *nd)
455 503
456 ne2000_reset(s); 504 ne2000_reset(s);
457 505
458 - qemu_add_fd_read_handler(nd->fd, ne2000_can_receive, ne2000_receive, s); 506 + qemu_add_read_packet(nd, ne2000_can_receive, ne2000_receive, s);
459 } 507 }