Commit 3df3f6fd7b5d45bae588ceb17233187ba5ec5c8a
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 | ... | ... |