Commit 3df3f6fd7b5d45bae588ceb17233187ba5ec5c8a

Authored by bellard
1 parent 2c6ab832

odd memory access fix


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@993 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 26 additions and 47 deletions
hw/ne2000.c
... ... @@ -440,6 +440,24 @@ static inline uint32_t ne2000_mem_readl(NE2000State *s, uint32_t addr)
440 440 }
441 441 }
442 442  
  443 +static inline void ne2000_dma_update(NE2000State *s, int len)
  444 +{
  445 + s->rsar += len;
  446 + /* wrap */
  447 + /* XXX: check what to do if rsar > stop */
  448 + if (s->rsar == s->stop)
  449 + s->rsar = s->start;
  450 +
  451 + if (s->rcnt <= len) {
  452 + s->rcnt = 0;
  453 + /* signal end of transfert */
  454 + s->isr |= ENISR_RDC;
  455 + ne2000_update_irq(s);
  456 + } else {
  457 + s->rcnt -= len;
  458 + }
  459 +}
  460 +
443 461 static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
444 462 {
445 463 NE2000State *s = opaque;
... ... @@ -448,25 +466,15 @@ static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
448 466 printf("NE2000: asic write val=0x%04x\n", val);
449 467 #endif
450 468 if (s->rcnt == 0)
451   - return;
  469 + return;
452 470 if (s->dcfg & 0x01) {
453 471 /* 16 bit access */
454 472 ne2000_mem_writew(s, s->rsar, val);
455   - s->rsar += 2;
456   - s->rcnt -= 2;
  473 + ne2000_dma_update(s, 2);
457 474 } else {
458 475 /* 8 bit access */
459 476 ne2000_mem_writeb(s, s->rsar, val);
460   - s->rsar++;
461   - s->rcnt--;
462   - }
463   - /* wrap */
464   - if (s->rsar == s->stop)
465   - s->rsar = s->start;
466   - if (s->rcnt == 0) {
467   - /* signal end of transfert */
468   - s->isr |= ENISR_RDC;
469   - ne2000_update_irq(s);
  477 + ne2000_dma_update(s, 1);
470 478 }
471 479 }
472 480  
... ... @@ -478,21 +486,11 @@ static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr)
478 486 if (s->dcfg & 0x01) {
479 487 /* 16 bit access */
480 488 ret = ne2000_mem_readw(s, s->rsar);
481   - s->rsar += 2;
482   - s->rcnt -= 2;
  489 + ne2000_dma_update(s, 2);
483 490 } else {
484 491 /* 8 bit access */
485 492 ret = ne2000_mem_readb(s, s->rsar);
486   - s->rsar++;
487   - s->rcnt--;
488   - }
489   - /* wrap */
490   - if (s->rsar == s->stop)
491   - s->rsar = s->start;
492   - if (s->rcnt == 0) {
493   - /* signal end of transfert */
494   - s->isr |= ENISR_RDC;
495   - ne2000_update_irq(s);
  493 + ne2000_dma_update(s, 1);
496 494 }
497 495 #ifdef DEBUG_NE2000
498 496 printf("NE2000: asic read val=0x%04x\n", ret);
... ... @@ -508,19 +506,10 @@ static void ne2000_asic_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
508 506 printf("NE2000: asic writel val=0x%04x\n", val);
509 507 #endif
510 508 if (s->rcnt == 0)
511   - return;
  509 + return;
512 510 /* 32 bit access */
513 511 ne2000_mem_writel(s, s->rsar, val);
514   - s->rsar += 4;
515   - s->rcnt -= 4;
516   - /* wrap */
517   - if (s->rsar == s->stop)
518   - s->rsar = s->start;
519   - if (s->rcnt == 0) {
520   - /* signal end of transfert */
521   - s->isr |= ENISR_RDC;
522   - ne2000_update_irq(s);
523   - }
  512 + ne2000_dma_update(s, 4);
524 513 }
525 514  
526 515 static uint32_t ne2000_asic_ioport_readl(void *opaque, uint32_t addr)
... ... @@ -530,17 +519,7 @@ static uint32_t ne2000_asic_ioport_readl(void *opaque, uint32_t addr)
530 519  
531 520 /* 32 bit access */
532 521 ret = ne2000_mem_readl(s, s->rsar);
533   - s->rsar += 4;
534   - s->rcnt -= 4;
535   -
536   - /* wrap */
537   - if (s->rsar == s->stop)
538   - s->rsar = s->start;
539   - if (s->rcnt == 0) {
540   - /* signal end of transfert */
541   - s->isr |= ENISR_RDC;
542   - ne2000_update_irq(s);
543   - }
  522 + ne2000_dma_update(s, 4);
544 523 #ifdef DEBUG_NE2000
545 524 printf("NE2000: asic readl val=0x%04x\n", ret);
546 525 #endif
... ...