Commit c6c99c3f175fa3f7e0d27c57c32b7029648a7407

Authored by aurel32
1 parent 5567025f

GT64XXX: fix endianness issues:

- Byte swapping for internal GT64XXX registers is controlled by the bit
  12 of the Configuration Register and not by the PCI Internal Command
  register.
- The bit 0 of the PCI Internal Command register controls byte swapping
  for PCI access *except for the internal PCI device*, that is when both
  bus and device numbers are 0.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4035 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 14 additions and 5 deletions
hw/gt64xxx.c
@@ -309,7 +309,7 @@ static void gt64120_writel (void *opaque, target_phys_addr_t addr, @@ -309,7 +309,7 @@ static void gt64120_writel (void *opaque, target_phys_addr_t addr,
309 GT64120State *s = opaque; 309 GT64120State *s = opaque;
310 uint32_t saddr; 310 uint32_t saddr;
311 311
312 - if (!(s->regs[GT_PCI0_CMD] & 1)) 312 + if (!(s->regs[GT_CPU] & 0x00001000))
313 val = bswap32(val); 313 val = bswap32(val);
314 314
315 saddr = (addr & 0xfff) >> 2; 315 saddr = (addr & 0xfff) >> 2;
@@ -530,7 +530,10 @@ static void gt64120_writel (void *opaque, target_phys_addr_t addr, @@ -530,7 +530,10 @@ static void gt64120_writel (void *opaque, target_phys_addr_t addr,
530 s->pci->config_reg = val & 0x80fffffc; 530 s->pci->config_reg = val & 0x80fffffc;
531 break; 531 break;
532 case GT_PCI0_CFGDATA: 532 case GT_PCI0_CFGDATA:
533 - pci_host_data_writel(s->pci, 0, val); 533 + if (!(s->regs[GT_PCI0_CMD] & 1) && (s->pci->config_reg & 0x00fff800))
  534 + val = bswap32(val);
  535 + if (s->pci->config_reg & (1u << 31))
  536 + pci_data_write(s->pci->bus, s->pci->config_reg, val, 4);
534 break; 537 break;
535 538
536 /* Interrupts */ 539 /* Interrupts */
@@ -767,7 +770,12 @@ static uint32_t gt64120_readl (void *opaque, @@ -767,7 +770,12 @@ static uint32_t gt64120_readl (void *opaque,
767 val = s->pci->config_reg; 770 val = s->pci->config_reg;
768 break; 771 break;
769 case GT_PCI0_CFGDATA: 772 case GT_PCI0_CFGDATA:
770 - val = pci_host_data_readl(s->pci, 0); 773 + if (!(s->pci->config_reg & (1 << 31)))
  774 + val = 0xffffffff;
  775 + else
  776 + val = pci_data_read(s->pci->bus, s->pci->config_reg, 4);
  777 + if (!(s->regs[GT_PCI0_CMD] & 1) && (s->pci->config_reg & 0x00fff800))
  778 + val = bswap32(val);
771 break; 779 break;
772 780
773 case GT_PCI0_CMD: 781 case GT_PCI0_CMD:
@@ -840,7 +848,7 @@ static uint32_t gt64120_readl (void *opaque, @@ -840,7 +848,7 @@ static uint32_t gt64120_readl (void *opaque,
840 break; 848 break;
841 } 849 }
842 850
843 - if (!(s->regs[GT_PCI0_CMD] & 1)) 851 + if (!(s->regs[GT_CPU] & 0x00001000))
844 val = bswap32(val); 852 val = bswap32(val);
845 853
846 return val; 854 return val;
@@ -1069,7 +1077,6 @@ static void gt64120_reset(void *opaque) @@ -1069,7 +1077,6 @@ static void gt64120_reset(void *opaque)
1069 s->regs[GT_PCI1_CFGADDR] = 0x00000000; 1077 s->regs[GT_PCI1_CFGADDR] = 0x00000000;
1070 s->regs[GT_PCI1_CFGDATA] = 0x00000000; 1078 s->regs[GT_PCI1_CFGDATA] = 0x00000000;
1071 s->regs[GT_PCI0_CFGADDR] = 0x00000000; 1079 s->regs[GT_PCI0_CFGADDR] = 0x00000000;
1072 - s->regs[GT_PCI0_CFGDATA] = 0x00000000;  
1073 1080
1074 /* Interrupt registers are all zeroed at reset */ 1081 /* Interrupt registers are all zeroed at reset */
1075 1082
@@ -1114,8 +1121,10 @@ PCIBus *pci_gt64120_init(qemu_irq *pic) @@ -1114,8 +1121,10 @@ PCIBus *pci_gt64120_init(qemu_irq *pic)
1114 1121
1115 (void)&pci_host_data_writeb; /* avoid warning */ 1122 (void)&pci_host_data_writeb; /* avoid warning */
1116 (void)&pci_host_data_writew; /* avoid warning */ 1123 (void)&pci_host_data_writew; /* avoid warning */
  1124 + (void)&pci_host_data_writel; /* avoid warning */
1117 (void)&pci_host_data_readb; /* avoid warning */ 1125 (void)&pci_host_data_readb; /* avoid warning */
1118 (void)&pci_host_data_readw; /* avoid warning */ 1126 (void)&pci_host_data_readw; /* avoid warning */
  1127 + (void)&pci_host_data_readl; /* avoid warning */
1119 1128
1120 s = qemu_mallocz(sizeof(GT64120State)); 1129 s = qemu_mallocz(sizeof(GT64120State));
1121 s->pci = qemu_mallocz(sizeof(GT64120PCIState)); 1130 s->pci = qemu_mallocz(sizeof(GT64120PCIState));