The GT64XXX code has some endianness issues on big endian as shown by lspci: 00:00.0 Network and computing encryption device: Unknown device 2046:ab11 (rev 06) 00:0a.0 ISA bridge: Intel Corporation 82371AB/EB/MB PIIX4 ISA ...
The first device ID is obviously wrong. This patch attempts to 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. PCI access is now done directly via pci_data_read/write and not via pci_host_data_readl/writel as the later functions assume that the host always handle PCI data in its own endianness. Signed-off-by: Aurelien Jarno <[EMAIL PROTECTED]> --- hw/gt64xxx.c | 19 ++++++++++++++----- 1 files changed, 14 insertions(+), 5 deletions(-) diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c index 46d6a76..8e8adad 100644 --- a/hw/gt64xxx.c +++ b/hw/gt64xxx.c @@ -309,7 +309,7 @@ static void gt64120_writel (void *opaque, target_phys_addr_t addr, GT64120State *s = opaque; uint32_t saddr; - if (!(s->regs[GT_PCI0_CMD] & 1)) + if (!(s->regs[GT_CPU] & 0x00001000)) val = bswap32(val); saddr = (addr & 0xfff) >> 2; @@ -530,7 +530,10 @@ static void gt64120_writel (void *opaque, target_phys_addr_t addr, s->pci->config_reg = val & 0x80fffffc; break; case GT_PCI0_CFGDATA: - pci_host_data_writel(s->pci, 0, val); + if (!(s->regs[GT_PCI0_CMD] & 1) && (s->pci->config_reg & 0x00fff800)) + val = bswap32(val); + if (s->pci->config_reg & (1u << 31)) + pci_data_write(s->pci->bus, s->pci->config_reg, val, 4); break; /* Interrupts */ @@ -767,7 +770,12 @@ static uint32_t gt64120_readl (void *opaque, val = s->pci->config_reg; break; case GT_PCI0_CFGDATA: - val = pci_host_data_readl(s->pci, 0); + if (!(s->pci->config_reg & (1 << 31))) + val = 0xffffffff; + else + val = pci_data_read(s->pci->bus, s->pci->config_reg, 4); + if (!(s->regs[GT_PCI0_CMD] & 1) && (s->pci->config_reg & 0x00fff800)) + val = bswap32(val); break; case GT_PCI0_CMD: @@ -840,7 +848,7 @@ static uint32_t gt64120_readl (void *opaque, break; } - if (!(s->regs[GT_PCI0_CMD] & 1)) + if (!(s->regs[GT_CPU] & 0x00001000)) val = bswap32(val); return val; @@ -1069,7 +1077,6 @@ static void gt64120_reset(void *opaque) s->regs[GT_PCI1_CFGADDR] = 0x00000000; s->regs[GT_PCI1_CFGDATA] = 0x00000000; s->regs[GT_PCI0_CFGADDR] = 0x00000000; - s->regs[GT_PCI0_CFGDATA] = 0x00000000; /* Interrupt registers are all zeroed at reset */ @@ -1114,8 +1121,10 @@ PCIBus *pci_gt64120_init(qemu_irq *pic) (void)&pci_host_data_writeb; /* avoid warning */ (void)&pci_host_data_writew; /* avoid warning */ + (void)&pci_host_data_writel; /* avoid warning */ (void)&pci_host_data_readb; /* avoid warning */ (void)&pci_host_data_readw; /* avoid warning */ + (void)&pci_host_data_readl; /* avoid warning */ s = qemu_mallocz(sizeof(GT64120State)); s->pci = qemu_mallocz(sizeof(GT64120PCIState)); -- 1.5.4.3 -- .''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [EMAIL PROTECTED] | [EMAIL PROTECTED] `- people.debian.org/~aurel32 | www.aurel32.net