Commit 6b59fc74b5b811664e4621e65b64e39c501249be

Authored by aurel32
1 parent 5fedc612

e1000: fix endianness issues

This patch fixes endianness issues in the e1000 nic emulation, which
currently only works on little endian hosts with little endian targets.

Byte swapping does not depend on host endianness, so this patch remove
the use of cpu_to_le32 and le32_to_cpu functions. It depends on the path
from the CPU to the device, which is currently and *wrongly* implemented
in Qemu as a byteswap on big endian targets. This patch does the same
as in other devices emulation as all the currently implemented targets
work with this implementation.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4046 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 16 additions and 7 deletions
hw/e1000.c
... ... @@ -720,8 +720,11 @@ e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
720 720 E1000State *s = opaque;
721 721 unsigned int index = ((addr - s->mmio_base) & 0x1ffff) >> 2;
722 722  
  723 +#ifdef TARGET_WORDS_BIGENDIAN
  724 + val = bswap32(val);
  725 +#endif
723 726 if (index < NWRITEOPS && macreg_writeops[index])
724   - macreg_writeops[index](s, index, le32_to_cpu(val));
  727 + macreg_writeops[index](s, index, val);
725 728 else if (index < NREADOPS && macreg_readops[index])
726 729 DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04x\n", index<<2, val);
727 730 else
... ... @@ -734,7 +737,7 @@ e1000_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
734 737 {
735 738 // emulate hw without byte enables: no RMW
736 739 e1000_mmio_writel(opaque, addr & ~3,
737   - cpu_to_le32(le16_to_cpu(val & 0xffff) << (8*(addr & 3))));
  740 + (val & 0xffff) << (8*(addr & 3)));
738 741 }
739 742  
740 743 static void
... ... @@ -742,7 +745,7 @@ e1000_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
742 745 {
743 746 // emulate hw without byte enables: no RMW
744 747 e1000_mmio_writel(opaque, addr & ~3,
745   - cpu_to_le32((val & 0xff) << (8*(addr & 3))));
  748 + (val & 0xff) << (8*(addr & 3)));
746 749 }
747 750  
748 751 static uint32_t
... ... @@ -752,7 +755,13 @@ e1000_mmio_readl(void *opaque, target_phys_addr_t addr)
752 755 unsigned int index = ((addr - s->mmio_base) & 0x1ffff) >> 2;
753 756  
754 757 if (index < NREADOPS && macreg_readops[index])
755   - return cpu_to_le32(macreg_readops[index](s, index));
  758 + {
  759 + uint32_t val = macreg_readops[index](s, index);
  760 +#ifdef TARGET_WORDS_BIGENDIAN
  761 + val = bswap32(val);
  762 +#endif
  763 + return val;
  764 + }
756 765 DBGOUT(UNKNOWN, "MMIO unknown read addr=0x%08x\n", index<<2);
757 766 return 0;
758 767 }
... ... @@ -760,15 +769,15 @@ e1000_mmio_readl(void *opaque, target_phys_addr_t addr)
760 769 static uint32_t
761 770 e1000_mmio_readb(void *opaque, target_phys_addr_t addr)
762 771 {
763   - return (le32_to_cpu(e1000_mmio_readl(opaque, addr & ~3)) >>
  772 + return ((e1000_mmio_readl(opaque, addr & ~3)) >>
764 773 (8 * (addr & 3))) & 0xff;
765 774 }
766 775  
767 776 static uint32_t
768 777 e1000_mmio_readw(void *opaque, target_phys_addr_t addr)
769 778 {
770   - return cpu_to_le16((le32_to_cpu(e1000_mmio_readl(opaque, addr & ~3)) >>
771   - (8 * (addr & 3))) & 0xffff);
  779 + return ((e1000_mmio_readl(opaque, addr & ~3)) >>
  780 + (8 * (addr & 3))) & 0xffff;
772 781 }
773 782  
774 783 int mac_regtosave[] = {
... ...