Commit c6c99c3f175fa3f7e0d27c57c32b7029648a7407
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 | 309 | GT64120State *s = opaque; |
| 310 | 310 | uint32_t saddr; |
| 311 | 311 | |
| 312 | - if (!(s->regs[GT_PCI0_CMD] & 1)) | |
| 312 | + if (!(s->regs[GT_CPU] & 0x00001000)) | |
| 313 | 313 | val = bswap32(val); |
| 314 | 314 | |
| 315 | 315 | saddr = (addr & 0xfff) >> 2; |
| ... | ... | @@ -530,7 +530,10 @@ static void gt64120_writel (void *opaque, target_phys_addr_t addr, |
| 530 | 530 | s->pci->config_reg = val & 0x80fffffc; |
| 531 | 531 | break; |
| 532 | 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 | 537 | break; |
| 535 | 538 | |
| 536 | 539 | /* Interrupts */ |
| ... | ... | @@ -767,7 +770,12 @@ static uint32_t gt64120_readl (void *opaque, |
| 767 | 770 | val = s->pci->config_reg; |
| 768 | 771 | break; |
| 769 | 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 | 779 | break; |
| 772 | 780 | |
| 773 | 781 | case GT_PCI0_CMD: |
| ... | ... | @@ -840,7 +848,7 @@ static uint32_t gt64120_readl (void *opaque, |
| 840 | 848 | break; |
| 841 | 849 | } |
| 842 | 850 | |
| 843 | - if (!(s->regs[GT_PCI0_CMD] & 1)) | |
| 851 | + if (!(s->regs[GT_CPU] & 0x00001000)) | |
| 844 | 852 | val = bswap32(val); |
| 845 | 853 | |
| 846 | 854 | return val; |
| ... | ... | @@ -1069,7 +1077,6 @@ static void gt64120_reset(void *opaque) |
| 1069 | 1077 | s->regs[GT_PCI1_CFGADDR] = 0x00000000; |
| 1070 | 1078 | s->regs[GT_PCI1_CFGDATA] = 0x00000000; |
| 1071 | 1079 | s->regs[GT_PCI0_CFGADDR] = 0x00000000; |
| 1072 | - s->regs[GT_PCI0_CFGDATA] = 0x00000000; | |
| 1073 | 1080 | |
| 1074 | 1081 | /* Interrupt registers are all zeroed at reset */ |
| 1075 | 1082 | |
| ... | ... | @@ -1114,8 +1121,10 @@ PCIBus *pci_gt64120_init(qemu_irq *pic) |
| 1114 | 1121 | |
| 1115 | 1122 | (void)&pci_host_data_writeb; /* avoid warning */ |
| 1116 | 1123 | (void)&pci_host_data_writew; /* avoid warning */ |
| 1124 | + (void)&pci_host_data_writel; /* avoid warning */ | |
| 1117 | 1125 | (void)&pci_host_data_readb; /* avoid warning */ |
| 1118 | 1126 | (void)&pci_host_data_readw; /* avoid warning */ |
| 1127 | + (void)&pci_host_data_readl; /* avoid warning */ | |
| 1119 | 1128 | |
| 1120 | 1129 | s = qemu_mallocz(sizeof(GT64120State)); |
| 1121 | 1130 | s->pci = qemu_mallocz(sizeof(GT64120PCIState)); | ... | ... |