From b9ba577bb21b417fef3d49509e1f2df853769ab0 Mon Sep 17 00:00:00 2001 From: Bart Trojanowski Date: Tue, 19 Feb 2008 21:47:02 -0500 Subject: [PATCH] X86EMU: when emulating PCI access, use the correct device When in x86emu, the PCI emulation routines were being given the TAG of the video device regardless of what the BIOS code that is being emulated asked for. This patch uses the bus:dev:fn numbers that were passed to 0xCF8 when calling the libpciaccess functions after an access to 0xCFC. Thanks to Symbio Technologies for funding my work, and ThinCan for providing hardware :) Signed-off-by: Bart Trojanowski --- hw/xfree86/int10/helper_exec.c | 55 ++++++++++++++++++++++++++++++++++----- 1 files changed, 48 insertions(+), 7 deletions(-) diff --git a/hw/xfree86/int10/helper_exec.c b/hw/xfree86/int10/helper_exec.c index e8bdd53..2179c09 100644 --- a/hw/xfree86/int10/helper_exec.c +++ b/hw/xfree86/int10/helper_exec.c @@ -541,7 +541,42 @@ Mem_wl(CARD32 addr, CARD32 val) static CARD32 PciCfg1Addr = 0; -#define OFFSET(Cfg1Addr) (Cfg1Addr & 0xff) +#define PCI_OFFSET(x) ((x) & 0x000000ff) +#define PCI_TAG(x) ((x) & 0x00ffff00) + +static pci_device* +pci_device_for_cfg_address (CARD32 addr) +{ + struct pci_device *dev = NULL; + PCITAG tag = PCI_TAG(addr); + struct pci_slot_match slot_match = { + .domain = PCI_DOM_FROM_TAG(tag), + .bus = PCI_BUS_FROM_TAG(tag), + .dev = PCI_DEV_FROM_TAG(tag), + .func = PCI_FUNC_FROM_TAG(tag), + .match_data = 0 + }; + + iter = pci_slot_match_iterator_create (&slot_match); + if (iter) + dev = pci_device_next(iter); + if (!dev) { + char buf[128]; // enough to store "%u@%u" + xf86FormatPciBusNumber(tag >> 16, buf); + ErrorF("Failed to find device matching %s:%u:%u\n", + buf, slot_match.dev, slot_match.func); + return NULL; + } + + if (pci_device_next(iter)) { + char buf[128]; // enough to store "%u@%u" + xf86FormatPciBusNumber(tag >> 16, buf); + ErrorF("Multiple devices matching %s:%u:%u\n", + buf, slot_match.dev, slot_match.func); + } + + return dev; +} static int pciCfg1in(CARD16 addr, CARD32 *val) @@ -551,7 +586,8 @@ pciCfg1in(CARD16 addr, CARD32 *val) return 1; } if (addr == 0xCFC) { - pci_device_cfg_read_u32(Int10Current->dev, val, OFFSET(PciCfg1Addr)); + pci_device_cfg_read_u32(pci_device_for_cfg_address(PciCfg1Addr), + val, PCI_OFFSET(PciCfg1Addr)); if (PRINT_PORT && DEBUG_IO_TRACE()) ErrorF(" cfg_inl(%#x) = %8.8x\n", PciCfg1Addr, *val); return 1; @@ -569,7 +605,8 @@ pciCfg1out(CARD16 addr, CARD32 val) if (addr == 0xCFC) { if (PRINT_PORT && DEBUG_IO_TRACE()) ErrorF(" cfg_outl(%#x, %8.8x)\n", PciCfg1Addr, val); - pci_device_cfg_write_u32(Int10Current->dev, val, OFFSET(PciCfg1Addr)); + pci_device_cfg_write_u32(pci_device_for_cfg_address(PciCfg1Addr), + val, PCI_OFFSET(PciCfg1Addr)); return 1; } return 0; @@ -588,7 +625,8 @@ pciCfg1inw(CARD16 addr, CARD16 *val) if ((addr >= 0xCFC) && (addr <= 0xCFF)) { const unsigned offset = addr - 0xCFC; - pci_device_cfg_read_u16(Int10Current->dev, val, OFFSET(PciCfg1Addr) + offset); + pci_device_cfg_read_u16(pci_device_for_cfg_address(PciCfg1Addr), + val, PCI_OFFSET(PciCfg1Addr) + offset); if (PRINT_PORT && DEBUG_IO_TRACE()) ErrorF(" cfg_inw(%#x) = %4.4x\n", PciCfg1Addr + offset, *val); return 1; @@ -612,7 +650,8 @@ pciCfg1outw(CARD16 addr, CARD16 val) if (PRINT_PORT && DEBUG_IO_TRACE()) ErrorF(" cfg_outw(%#x, %4.4x)\n", PciCfg1Addr + offset, val); - pci_device_cfg_write_u16(Int10Current->dev, val, OFFSET(PciCfg1Addr) + offset); + pci_device_cfg_write_u16(pci_device_for_cfg_address(PciCfg1Addr), + val, PCI_OFFSET(PciCfg1Addr) + offset); return 1; } return 0; @@ -631,7 +670,8 @@ pciCfg1inb(CARD16 addr, CARD8 *val) if ((addr >= 0xCFC) && (addr <= 0xCFF)) { const unsigned offset = addr - 0xCFC; - pci_device_cfg_read_u8(Int10Current->dev, val, OFFSET(PciCfg1Addr) + offset); + pci_device_cfg_read_u8(pci_device_for_cfg_address(PciCfg1Addr), + val, PCI_OFFSET(PciCfg1Addr) + offset); if (PRINT_PORT && DEBUG_IO_TRACE()) ErrorF(" cfg_inb(%#x) = %2.2x\n", PciCfg1Addr + offset, *val); return 1; @@ -655,7 +695,8 @@ pciCfg1outb(CARD16 addr, CARD8 val) if (PRINT_PORT && DEBUG_IO_TRACE()) ErrorF(" cfg_outb(%#x, %2.2x)\n", PciCfg1Addr + offset, val); - pci_device_cfg_write_u8(Int10Current->dev, val, OFFSET(PciCfg1Addr) + offset); + pci_device_cfg_write_u8(pci_device_for_cfg_address(PciCfg1Addr), + val, PCI_OFFSET(PciCfg1Addr) + offset); return 1; } return 0; -- 1.5.3.7.1150.g149d432