[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86: Emulate accesses to PCI window registers cf8/cfc to synchronise



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1207916395 -3600
# Node ID 80ba1b4270321baa58b0e8064fb472f2c2462b8d
# Parent  082d3886fded0ba361eafff82cda651acffc53cd
x86: Emulate accesses to PCI window registers cf8/cfc to synchronise
with accesses by teh hypervisor itself. All users of cf8/cfc go
through new access functions which take the appropriate spinlock.

Based on a patch by Haitao Shan <haitao.shan@xxxxxxxxx>

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/drivers/passthrough/pci-direct.h        |   48 -----
 xen/arch/x86/Makefile                       |    1 
 xen/arch/x86/cpu/amd.c                      |   18 -
 xen/arch/x86/domain_build.c                 |    2 
 xen/arch/x86/pci.c                          |  118 ++++++++++++
 xen/arch/x86/traps.c                        |  259 +++++++++++++++++-----------
 xen/drivers/passthrough/amd/iommu_detect.c  |   37 +---
 xen/drivers/passthrough/amd/iommu_init.c    |    2 
 xen/drivers/passthrough/amd/pci_amd_iommu.c |    6 
 xen/drivers/passthrough/vtd/dmar.c          |   18 -
 xen/drivers/passthrough/vtd/intremap.c      |    2 
 xen/drivers/passthrough/vtd/iommu.c         |   28 +--
 xen/drivers/passthrough/vtd/qinval.c        |    2 
 xen/drivers/passthrough/vtd/utils.c         |   32 +--
 xen/include/asm-x86/domain.h                |    1 
 xen/include/xen/pci.h                       |   29 +++
 16 files changed, 374 insertions(+), 229 deletions(-)

diff -r 082d3886fded -r 80ba1b427032 xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile     Fri Apr 11 09:14:03 2008 +0100
+++ b/xen/arch/x86/Makefile     Fri Apr 11 13:19:55 2008 +0100
@@ -31,6 +31,7 @@ obj-y += mpparse.o
 obj-y += mpparse.o
 obj-y += nmi.o
 obj-y += numa.o
+obj-y += pci.o
 obj-y += physdev.o
 obj-y += rwlock.o
 obj-y += setup.o
diff -r 082d3886fded -r 80ba1b427032 xen/arch/x86/cpu/amd.c
--- a/xen/arch/x86/cpu/amd.c    Fri Apr 11 09:14:03 2008 +0100
+++ b/xen/arch/x86/cpu/amd.c    Fri Apr 11 13:19:55 2008 +0100
@@ -3,6 +3,7 @@
 #include <xen/bitops.h>
 #include <xen/mm.h>
 #include <xen/smp.h>
+#include <xen/pci.h>
 #include <asm/io.h>
 #include <asm/msr.h>
 #include <asm/processor.h>
@@ -66,19 +67,6 @@ static int c1_ramping_may_cause_clock_dr
        return 1;
 }
 
-/* PCI access functions. Should be safe to use 0xcf8/0xcfc port accesses here. 
*/
-static u8 pci_read_byte(u32 bus, u32 dev, u32 fn, u32 reg)
-{
-       outl((1U<<31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3), 
0xcf8);
-       return inb(0xcfc + (reg & 3));
-}
-
-static void pci_write_byte(u32 bus, u32 dev, u32 fn, u32 reg, u8 val)
-{
-       outl((1U<<31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3), 
0xcf8);
-       outb(val, 0xcfc + (reg & 3));
-}
-
 /*
  * Disable C1-Clock ramping if enabled in PMM7.CpuLowPwrEnh on 8th-generation
  * cores only. Assume BIOS has setup all Northbridges equivalently.
@@ -90,12 +78,12 @@ static void disable_c1_ramping(void)
 
        for (node=0; node < NR_CPUS; node++) {
                /* PMM7: bus=0, dev=0x18+node, function=0x3, register=0x87. */
-               pmm7 = pci_read_byte(0, 0x18+node, 0x3, 0x87);
+               pmm7 = pci_conf_read8(0, 0x18+node, 0x3, 0x87);
                /* Invalid read means we've updated every Northbridge. */
                if (pmm7 == 0xFF)
                        break;
                pmm7 &= 0xFC; /* clear pmm7[1:0] */
-               pci_write_byte(0, 0x18+node, 0x3, 0x87, pmm7);
+               pci_conf_write8(0, 0x18+node, 0x3, 0x87, pmm7);
                printk ("AMD: Disabling C1 Clock Ramping Node #%x\n", node);
        }
 }
diff -r 082d3886fded -r 80ba1b427032 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Fri Apr 11 09:14:03 2008 +0100
+++ b/xen/arch/x86/domain_build.c       Fri Apr 11 13:19:55 2008 +0100
@@ -957,6 +957,8 @@ int __init construct_dom0(
     rc |= ioports_deny_access(dom0, 0x40, 0x43);
     /* PIT Channel 2 / PC Speaker Control. */
     rc |= ioports_deny_access(dom0, 0x61, 0x61);
+    /* PCI configuration spaces. */
+    rc |= ioports_deny_access(dom0, 0xcf8, 0xcff);
     /* Command-line I/O ranges. */
     process_dom0_ioports_disable();
 
diff -r 082d3886fded -r 80ba1b427032 xen/arch/x86/pci.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/pci.c        Fri Apr 11 13:19:55 2008 +0100
@@ -0,0 +1,118 @@
+/******************************************************************************
+ * pci.c
+ * 
+ * PCI access functions.
+ */
+
+#include <xen/config.h>
+#include <xen/pci.h>
+#include <xen/spinlock.h>
+#include <asm/io.h>
+
+#define PCI_CONF_ADDRESS(bus, dev, func, reg) \
+    (0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3))
+
+static DEFINE_SPINLOCK(pci_config_lock);
+
+uint32_t pci_conf_read(uint32_t cf8, uint8_t offset, uint8_t bytes)
+{
+    unsigned long flags;
+    uint32_t value;
+
+    BUG_ON((offset + bytes) > 4);
+
+    spin_lock_irqsave(&pci_config_lock, flags);
+
+    outl(cf8, 0xcf8);
+
+    switch ( bytes )
+    {
+    case 1:
+        value = inb(0xcfc + offset);
+        break;
+    case 2:
+        value = inw(0xcfc + offset);
+        break;
+    case 4:
+        value = inl(0xcfc + offset);
+        break;
+    default:
+        value = 0;
+        BUG();
+    }
+
+    spin_unlock_irqrestore(&pci_config_lock, flags);
+
+    return value;
+}
+
+void pci_conf_write(uint32_t cf8, uint8_t offset, uint8_t bytes, uint32_t data)
+{
+    unsigned long flags;
+
+    BUG_ON((offset + bytes) > 4);
+
+    spin_lock_irqsave(&pci_config_lock, flags);
+
+    outl(cf8, 0xcf8);
+
+    switch ( bytes )
+    {
+    case 1:
+        outb((uint8_t)data, 0xcfc + offset);
+        break;
+    case 2:
+        outw((uint16_t)data, 0xcfc + offset);
+        break;
+    case 4:
+        outl(data, 0xcfc + offset);
+        break;
+    }
+
+    spin_unlock_irqrestore(&pci_config_lock, flags);
+}
+
+uint8_t pci_conf_read8(
+    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg)
+{
+    BUG_ON((bus > 255) || (dev > 31) || (func > 7) || (reg > 255));
+    return pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 3, 1);
+}
+
+uint16_t pci_conf_read16(
+    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg)
+{
+    BUG_ON((bus > 255) || (dev > 31) || (func > 7) || (reg > 255));
+    return pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 2, 2);
+}
+
+uint32_t pci_conf_read32(
+    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg)
+{
+    BUG_ON((bus > 255) || (dev > 31) || (func > 7) || (reg > 255));
+    return pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg), 0, 4);
+}
+
+void pci_conf_write8(
+    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg,
+    uint8_t data)
+{
+    BUG_ON((bus > 255) || (dev > 31) || (func > 7) || (reg > 255));
+    pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 3, 1, data);
+}
+
+void pci_conf_write16(
+    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg,
+    uint16_t data)
+{
+    BUG_ON((bus > 255) || (dev > 31) || (func > 7) || (reg > 255));
+    pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 2, 2, data);
+}
+
+void pci_conf_write32(
+    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg,
+    uint32_t data)
+{
+    BUG_ON((bus > 255) || (dev > 31) || (func > 7) || (reg > 255));
+    pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg), 0, 4, data);
+}
diff -r 082d3886fded -r 80ba1b427032 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Fri Apr 11 09:14:03 2008 +0100
+++ b/xen/arch/x86/traps.c      Fri Apr 11 13:19:55 2008 +0100
@@ -1353,7 +1353,7 @@ static int read_gate_descriptor(unsigned
 #endif
 
 /* Has the guest requested sufficient permission for this I/O access? */
-static inline int guest_io_okay(
+static int guest_io_okay(
     unsigned int port, unsigned int bytes,
     struct vcpu *v, struct cpu_user_regs *regs)
 {
@@ -1395,19 +1395,130 @@ static inline int guest_io_okay(
 }
 
 /* Has the administrator granted sufficient permission for this I/O access? */
-static inline int admin_io_okay(
+static int admin_io_okay(
     unsigned int port, unsigned int bytes,
     struct vcpu *v, struct cpu_user_regs *regs)
 {
     return ioports_access_permitted(v->domain, port, port + bytes - 1);
 }
 
-#define guest_inb_okay(_p, _d, _r) admin_io_okay(_p, 1, _d, _r)
-#define guest_inw_okay(_p, _d, _r) admin_io_okay(_p, 2, _d, _r)
-#define guest_inl_okay(_p, _d, _r) admin_io_okay(_p, 4, _d, _r)
-#define guest_outb_okay(_p, _d, _r) admin_io_okay(_p, 1, _d, _r)
-#define guest_outw_okay(_p, _d, _r) admin_io_okay(_p, 2, _d, _r)
-#define guest_outl_okay(_p, _d, _r) admin_io_okay(_p, 4, _d, _r)
+static uint32_t guest_io_read(
+    unsigned int port, unsigned int bytes,
+    struct vcpu *v, struct cpu_user_regs *regs)
+{
+    extern uint32_t pci_conf_read(
+        uint32_t cf8, uint8_t offset, uint8_t bytes);
+
+    uint32_t data = 0;
+    unsigned int shift = 0;
+
+    if ( admin_io_okay(port, bytes, v, regs) )
+    {
+        switch ( bytes )
+        {
+        case 1: return inb(port);
+        case 2: return inw(port);
+        case 4: return inl(port);
+        }
+    }
+
+    while ( bytes != 0 )
+    {
+        unsigned int size = 1;
+        uint32_t sub_data = 0xff;
+
+        if ( (port == 0x42) || (port == 0x43) || (port == 0x61) )
+        {
+            sub_data = pv_pit_handler(port, 0, 0);
+        }
+        else if ( (port & 0xfffc) == 0xcf8 )
+        {
+            size = min(bytes, 4 - (port & 3));
+            sub_data = v->domain->arch.pci_cf8 >> ((port & 3) * 8);
+        }
+        else if ( ((port & 0xfffc) == 0xcfc) && IS_PRIV(v->domain) )
+        {
+            size = min(bytes, 4 - (port & 3));
+            if ( size == 3 )
+                size = 2;
+            sub_data = pci_conf_read(v->domain->arch.pci_cf8, port & 3, size);
+        }
+
+        if ( size == 4 )
+            return sub_data;
+
+        data |= (sub_data & ((1u << (size * 8)) - 1)) << shift;
+        shift += size * 8;
+        port += size;
+        bytes -= size;
+    }
+
+    return data;
+}
+
+static void guest_io_write(
+    unsigned int port, unsigned int bytes, uint32_t data,
+    struct vcpu *v, struct cpu_user_regs *regs)
+{
+    extern void pci_conf_write(
+        uint32_t cf8, uint8_t offset, uint8_t bytes, uint32_t data);
+
+    if ( admin_io_okay(port, bytes, v, regs) )
+    {
+        switch ( bytes ) {
+        case 1:
+            outb((uint8_t)data, port);
+            if ( pv_post_outb_hook )
+                pv_post_outb_hook(port, (uint8_t)data);
+            break;
+        case 2:
+            outw((uint16_t)data, port);
+            break;
+        case 4:
+            outl(data, port);
+            break;
+        }
+        return;
+    }
+
+    while ( bytes != 0 )
+    {
+        unsigned int size = 1;
+
+        if ( (port == 0x42) || (port == 0x43) || (port == 0x61) )
+        {
+            pv_pit_handler(port, (uint8_t)data, 1);
+        }
+        else if ( (port & 0xfffc) == 0xcf8 )
+        {
+            size = min(bytes, 4 - (port & 3));
+            if ( size == 4 )
+            {
+                v->domain->arch.pci_cf8 = data;
+            }
+            else
+            {
+                uint32_t mask = ((1u << (size * 8)) - 1) << ((port & 3) * 8);
+                v->domain->arch.pci_cf8 &= ~mask;
+                v->domain->arch.pci_cf8 |= (data << ((port & 3) * 8)) & mask;
+            }
+        }
+        else if ( ((port & 0xfffc) == 0xcfc) && IS_PRIV(v->domain) )
+        {
+            size = min(bytes, 4 - (port & 3));
+            if ( size == 3 )
+                size = 2;
+            pci_conf_write(v->domain->arch.pci_cf8, port & 3, size, data);
+        }
+
+        if ( size == 4 )
+            return;
+
+        port += size;
+        bytes -= size;
+        data >>= size * 8;
+    }
+}
 
 /* I/O emulation support. Helper routines for, and type of, the stack stub.*/
 void host_to_guest_gpr_switch(struct cpu_user_regs *)
@@ -1526,7 +1637,7 @@ static int emulate_privileged_op(struct 
 
     /* REX prefix. */
     if ( rex & 8 ) /* REX.W */
-        op_bytes = 4; /* emulating only opcodes not supporting 64-bit operands 
*/
+        op_bytes = 4; /* emulate only opcodes not supporting 64-bit operands */
     modrm_reg = (rex & 4) << 1;  /* REX.R */
     /* REX.X does not need to be decoded. */
     modrm_rm  = (rex & 1) << 3;  /* REX.B */
@@ -1555,7 +1666,8 @@ static int emulate_privileged_op(struct 
         {
             if ( !read_descriptor(data_sel, v, regs,
                                   &data_base, &data_limit, &ar,
-                                  
_SEGMENT_WR|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P) )
+                                  _SEGMENT_WR|_SEGMENT_S|_SEGMENT_DPL|
+                                  _SEGMENT_P) )
                 goto fail;
             if ( !(ar & _SEGMENT_S) ||
                  !(ar & _SEGMENT_P) ||
@@ -1602,69 +1714,39 @@ static int emulate_privileged_op(struct 
         case 0x6c: /* INSB */
             op_bytes = 1;
         case 0x6d: /* INSW/INSL */
-            if ( data_limit < op_bytes - 1 ||
-                 rd_ad(edi) > data_limit - (op_bytes - 1) ||
+            if ( (data_limit < (op_bytes - 1)) ||
+                 (rd_ad(edi) > (data_limit - (op_bytes - 1))) ||
                  !guest_io_okay(port, op_bytes, v, regs) )
                 goto fail;
-            switch ( op_bytes )
-            {
-            case 1:
-                /* emulate PIT counter 2 */
-                data = (u8)(guest_inb_okay(port, v, regs) ? inb(port) : 
-                       ((port == 0x42 || port == 0x43 || port == 0x61) ?
-                       pv_pit_handler(port, 0, 0) : ~0)); 
-                break;
-            case 2:
-                data = (u16)(guest_inw_okay(port, v, regs) ? inw(port) : ~0);
-                break;
-            case 4:
-                data = (u32)(guest_inl_okay(port, v, regs) ? inl(port) : ~0);
-                break;
-            }
-            if ( (rc = copy_to_user((void *)data_base + rd_ad(edi), &data, 
op_bytes)) != 0 )
+            data = guest_io_read(port, op_bytes, v, regs);
+            if ( (rc = copy_to_user((void *)data_base + rd_ad(edi),
+                                    &data, op_bytes)) != 0 )
             {
                 propagate_page_fault(data_base + rd_ad(edi) + op_bytes - rc,
                                      PFEC_write_access);
                 return EXCRET_fault_fixed;
             }
-            wr_ad(edi, regs->edi + (int)((regs->eflags & EF_DF) ? -op_bytes : 
op_bytes));
+            wr_ad(edi, regs->edi + (int)((regs->eflags & EF_DF)
+                                         ? -op_bytes : op_bytes));
             break;
 
         case 0x6e: /* OUTSB */
             op_bytes = 1;
         case 0x6f: /* OUTSW/OUTSL */
-            if ( data_limit < op_bytes - 1 ||
-                 rd_ad(esi) > data_limit - (op_bytes - 1) ||
-                 !guest_io_okay(port, op_bytes, v, regs) )
+            if ( (data_limit < (op_bytes - 1)) ||
+                 (rd_ad(esi) > (data_limit - (op_bytes - 1))) ||
+                  !guest_io_okay(port, op_bytes, v, regs) )
                 goto fail;
-            rc = copy_from_user(&data, (void *)data_base + rd_ad(esi), 
op_bytes);
-            if ( rc != 0 )
+            if ( (rc = copy_from_user(&data, (void *)data_base + rd_ad(esi),
+                                      op_bytes)) != 0 )
             {
-                propagate_page_fault(data_base + rd_ad(esi) + op_bytes - rc, 
0);
+                propagate_page_fault(data_base + rd_ad(esi)
+                                     + op_bytes - rc, 0);
                 return EXCRET_fault_fixed;
             }
-            switch ( op_bytes )
-            {
-            case 1:
-                if ( guest_outb_okay(port, v, regs) )
-                {
-                    outb((u8)data, port);
-                    if ( pv_post_outb_hook )
-                        pv_post_outb_hook(port, data);
-                }
-                else if ( port == 0x42 || port == 0x43 || port == 0x61 )
-                    pv_pit_handler(port, data, 1);
-                break;
-            case 2:
-                if ( guest_outw_okay(port, v, regs) )
-                    outw((u16)data, port);
-                break;
-            case 4:
-                if ( guest_outl_okay(port, v, regs) )
-                    outl((u32)data, port);
-                break;
-            }
-            wr_ad(esi, regs->esi + (int)((regs->eflags & EF_DF) ? -op_bytes : 
op_bytes));
+            guest_io_write(port, op_bytes, data, v, regs);
+            wr_ad(esi, regs->esi + (int)((regs->eflags & EF_DF)
+                                         ? -op_bytes : op_bytes));
             break;
         }
 
@@ -1728,31 +1810,17 @@ static int emulate_privileged_op(struct 
     exec_in:
         if ( !guest_io_okay(port, op_bytes, v, regs) )
             goto fail;
-        switch ( op_bytes )
-        {
-        case 1:
-            if ( guest_inb_okay(port, v, regs) )
-                io_emul(regs);
-            else if ( port == 0x42 || port == 0x43 || port == 0x61 )
-            {
-                regs->eax &= ~0xffUL;
-                regs->eax |= pv_pit_handler(port, 0, 0);
-            } 
+        if ( admin_io_okay(port, op_bytes, v, regs) )
+        {
+            io_emul(regs);            
+        }
+        else
+        {
+            if ( op_bytes == 4 )
+                regs->eax = 0;
             else
-                regs->eax |= (u8)~0;
-            break;
-        case 2:
-            if ( guest_inw_okay(port, v, regs) )
-                io_emul(regs);
-            else
-                regs->eax |= (u16)~0;
-            break;
-        case 4:
-            if ( guest_inl_okay(port, v, regs) )
-                io_emul(regs);
-            else
-                regs->eax = (u32)~0;
-            break;
+                regs->eax &= ~((1u << (op_bytes * 8)) - 1);
+            regs->eax |= guest_io_read(port, op_bytes, v, regs);
         }
         bpmatch = check_guest_io_breakpoint(v, port, op_bytes);
         goto done;
@@ -1771,26 +1839,15 @@ static int emulate_privileged_op(struct 
     exec_out:
         if ( !guest_io_okay(port, op_bytes, v, regs) )
             goto fail;
-        switch ( op_bytes )
-        {
-        case 1:
-            if ( guest_outb_okay(port, v, regs) )
-            {
-                io_emul(regs);
-                if ( pv_post_outb_hook )
-                    pv_post_outb_hook(port, regs->eax);
-            }
-            else if ( port == 0x42 || port == 0x43 || port == 0x61 )
-                pv_pit_handler(port, regs->eax, 1);
-            break;
-        case 2:
-            if ( guest_outw_okay(port, v, regs) )
-                io_emul(regs);
-            break;
-        case 4:
-            if ( guest_outl_okay(port, v, regs) )
-                io_emul(regs);
-            break;
+        if ( admin_io_okay(port, op_bytes, v, regs) )
+        {
+            io_emul(regs);            
+            if ( (op_bytes == 1) && pv_post_outb_hook )
+                pv_post_outb_hook(port, regs->eax);
+        }
+        else
+        {
+            guest_io_write(port, op_bytes, regs->eax, v, regs);
         }
         bpmatch = check_guest_io_breakpoint(v, port, op_bytes);
         goto done;
diff -r 082d3886fded -r 80ba1b427032 xen/drivers/passthrough/amd/iommu_detect.c
--- a/xen/drivers/passthrough/amd/iommu_detect.c        Fri Apr 11 09:14:03 
2008 +0100
+++ b/xen/drivers/passthrough/amd/iommu_detect.c        Fri Apr 11 13:19:55 
2008 +0100
@@ -21,9 +21,9 @@
 #include <xen/config.h>
 #include <xen/errno.h>
 #include <xen/iommu.h>
+#include <xen/pci.h>
 #include <asm/amd-iommu.h>
 #include <asm/hvm/svm/amd-iommu-proto.h>
-#include "../pci-direct.h"
 #include "../pci_regs.h"
 
 static int __init valid_bridge_bus_config(
@@ -31,9 +31,9 @@ static int __init valid_bridge_bus_confi
 {
     int pri_bus;
 
-    pri_bus = read_pci_config_byte(bus, dev, func, PCI_PRIMARY_BUS);
-    *sec_bus = read_pci_config_byte(bus, dev, func, PCI_SECONDARY_BUS);
-    *sub_bus = read_pci_config_byte(bus, dev, func, PCI_SUBORDINATE_BUS);
+    pri_bus = pci_conf_read8(bus, dev, func, PCI_PRIMARY_BUS);
+    *sec_bus = pci_conf_read8(bus, dev, func, PCI_SECONDARY_BUS);
+    *sub_bus = pci_conf_read8(bus, dev, func, PCI_SUBORDINATE_BUS);
 
     return ((pri_bus == bus) && (*sec_bus > bus) && (*sub_bus >= *sec_bus));
 }
@@ -59,12 +59,11 @@ int __init get_iommu_last_downstream_bus
         }
         func = PCI_FUNC(devfn);
  
-        if ( !VALID_PCI_VENDOR_ID(
-            read_pci_config_16(bus, dev, func, PCI_VENDOR_ID)) )
+        if ( !VALID_PCI_VENDOR_ID(pci_conf_read16(bus, dev, func,
+                                                  PCI_VENDOR_ID)) )
             continue;
 
-        hdr_type = read_pci_config_byte(bus, dev, func,
-                                        PCI_HEADER_TYPE);
+        hdr_type = pci_conf_read8(bus, dev, func, PCI_HEADER_TYPE);
         if ( func == 0 )
             multi_func = IS_PCI_MULTI_FUNCTION(hdr_type);
 
@@ -92,9 +91,9 @@ int __init get_iommu_capabilities(u8 bus
     u32 cap_header, cap_range, misc_info;
     u64 mmio_bar;
 
-    mmio_bar = (u64)read_pci_config(
+    mmio_bar = (u64)pci_conf_read32(
         bus, dev, func, cap_ptr + PCI_CAP_MMIO_BAR_HIGH_OFFSET) << 32;
-    mmio_bar |= read_pci_config(bus, dev, func,
+    mmio_bar |= pci_conf_read32(bus, dev, func,
                                 cap_ptr + PCI_CAP_MMIO_BAR_LOW_OFFSET);
     iommu->mmio_base_phys = mmio_bar & (u64)~0x3FFF;
 
@@ -108,7 +107,7 @@ int __init get_iommu_capabilities(u8 bus
     iommu->bdf = (bus << 8) | PCI_DEVFN(dev, func);
     iommu->cap_offset = cap_ptr;
 
-    cap_header = read_pci_config(bus, dev, func, cap_ptr);
+    cap_header = pci_conf_read32(bus, dev, func, cap_ptr);
     iommu->revision = get_field_from_reg_u32(
         cap_header, PCI_CAP_REV_MASK, PCI_CAP_REV_SHIFT);
     iommu->iotlb_support = get_field_from_reg_u32(
@@ -118,7 +117,7 @@ int __init get_iommu_capabilities(u8 bus
     iommu->pte_not_present_cached = get_field_from_reg_u32(
         cap_header, PCI_CAP_NP_CACHE_MASK, PCI_CAP_NP_CACHE_SHIFT);
 
-    cap_range = read_pci_config(bus, dev, func,
+    cap_range = pci_conf_read32(bus, dev, func,
                                 cap_ptr + PCI_CAP_RANGE_OFFSET);
     iommu->unit_id = get_field_from_reg_u32(
         cap_range, PCI_CAP_UNIT_ID_MASK, PCI_CAP_UNIT_ID_SHIFT);
@@ -129,7 +128,7 @@ int __init get_iommu_capabilities(u8 bus
     iommu->last_devfn = get_field_from_reg_u32(
         cap_range, PCI_CAP_LAST_DEVICE_MASK, PCI_CAP_LAST_DEVICE_SHIFT);
 
-    misc_info = read_pci_config(bus, dev, func,
+    misc_info = pci_conf_read32(bus, dev, func,
                                 cap_ptr + PCI_MISC_INFO_OFFSET);
     iommu->msi_number = get_field_from_reg_u32(
         misc_info, PCI_CAP_MSI_NUMBER_MASK, PCI_CAP_MSI_NUMBER_SHIFT);
@@ -146,14 +145,13 @@ static int __init scan_caps_for_iommu(
     int count, error = 0;
 
     count = 0;
-    cap_ptr = read_pci_config_byte(bus, dev, func,
-                                   PCI_CAPABILITY_LIST);
+    cap_ptr = pci_conf_read8(bus, dev, func, PCI_CAPABILITY_LIST);
     while ( (cap_ptr >= PCI_MIN_CAP_OFFSET) &&
             (count < PCI_MAX_CAP_BLOCKS) &&
             !error )
     {
         cap_ptr &= PCI_CAP_PTR_MASK;
-        cap_header = read_pci_config(bus, dev, func, cap_ptr);
+        cap_header = pci_conf_read32(bus, dev, func, cap_ptr);
         cap_id = get_field_from_reg_u32(
             cap_header, PCI_CAP_ID_MASK, PCI_CAP_ID_SHIFT);
 
@@ -182,12 +180,11 @@ static int __init scan_functions_for_iom
 
     func = 0;
     count = 1;
-    while ( VALID_PCI_VENDOR_ID(read_pci_config_16(bus, dev, func,
-                                                   PCI_VENDOR_ID)) &&
+    while ( VALID_PCI_VENDOR_ID(pci_conf_read16(bus, dev, func,
+                                                PCI_VENDOR_ID)) &&
             !error && (func < count) )
     {
-        hdr_type = read_pci_config_byte(bus, dev, func,
-                                        PCI_HEADER_TYPE);
+        hdr_type = pci_conf_read8(bus, dev, func, PCI_HEADER_TYPE);
 
         if ( func == 0 && IS_PCI_MULTI_FUNCTION(hdr_type) )
             count = PCI_MAX_FUNC_COUNT;
diff -r 082d3886fded -r 80ba1b427032 xen/drivers/passthrough/amd/iommu_init.c
--- a/xen/drivers/passthrough/amd/iommu_init.c  Fri Apr 11 09:14:03 2008 +0100
+++ b/xen/drivers/passthrough/amd/iommu_init.c  Fri Apr 11 13:19:55 2008 +0100
@@ -20,10 +20,10 @@
 
 #include <xen/config.h>
 #include <xen/errno.h>
+#include <xen/pci.h>
 #include <asm/amd-iommu.h>
 #include <asm/hvm/svm/amd-iommu-proto.h>
 #include <asm-x86/fixmap.h>
-#include "../pci-direct.h"
 #include "../pci_regs.h"
 
 extern int nr_amd_iommus;
diff -r 082d3886fded -r 80ba1b427032 xen/drivers/passthrough/amd/pci_amd_iommu.c
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c       Fri Apr 11 09:14:03 
2008 +0100
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c       Fri Apr 11 13:19:55 
2008 +0100
@@ -18,12 +18,12 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
+#include <xen/sched.h>
+#include <xen/pci.h>
 #include <asm/amd-iommu.h>
 #include <asm/hvm/svm/amd-iommu-proto.h>
 #include <asm/hvm/svm/amd-iommu-acpi.h>
-#include <xen/sched.h>
 #include <asm/mm.h>
-#include "../pci-direct.h"
 #include "../pci_regs.h"
 
 struct list_head amd_iommu_head;
@@ -316,7 +316,7 @@ void __init amd_iommu_setup_dom0_devices
         {
             for ( func = 0; func < 8; func++ )
             {
-                l = read_pci_config(bus, dev, func, PCI_VENDOR_ID);
+                l = pci_conf_read32(bus, dev, func, PCI_VENDOR_ID);
                 /* some broken boards return 0 or ~0 if a slot is empty: */
                 if ( (l == 0xffffffff) || (l == 0x00000000) ||
                      (l == 0x0000ffff) || (l == 0xffff0000) )
diff -r 082d3886fded -r 80ba1b427032 xen/drivers/passthrough/pci-direct.h
--- a/xen/drivers/passthrough/pci-direct.h      Fri Apr 11 09:14:03 2008 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-#ifndef ASM_PCI_DIRECT_H
-#define ASM_PCI_DIRECT_H 1
-
-#include <xen/types.h>
-#include <asm/io.h>
-
-/* Direct PCI access. This is used for PCI accesses in early boot before
-   the PCI subsystem works. */
-
-#define PDprintk(x...)
-
-static inline u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
-{
-    u32 v;
-    outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
-    v = inl(0xcfc);
-    if (v != 0xffffffff)
-        PDprintk("%x reading 4 from %x: %x\n", slot, offset, v);
-    return v;
-}
-
-static inline u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset)
-{
-    u8 v;
-    outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
-    v = inb(0xcfc + (offset&3));
-    PDprintk("%x reading 1 from %x: %x\n", slot, offset, v);
-    return v;
-}
-
-static inline u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset)
-{
-    u16 v;
-    outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
-    v = inw(0xcfc + (offset&2));
-    PDprintk("%x reading 2 from %x: %x\n", slot, offset, v);
-    return v;
-}
-
-static inline void write_pci_config(
-    u8 bus, u8 slot, u8 func, u8 offset, u32 val)
-{
-    PDprintk("%x writing to %x: %x\n", slot, offset, val);
-    outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
-    outl(val, 0xcfc);
-}
-
-#endif
diff -r 082d3886fded -r 80ba1b427032 xen/drivers/passthrough/vtd/dmar.c
--- a/xen/drivers/passthrough/vtd/dmar.c        Fri Apr 11 09:14:03 2008 +0100
+++ b/xen/drivers/passthrough/vtd/dmar.c        Fri Apr 11 13:19:55 2008 +0100
@@ -25,9 +25,9 @@
 #include <xen/acpi.h>
 #include <xen/mm.h>
 #include <xen/xmalloc.h>
+#include <xen/pci.h>
 #include <asm/string.h>
 #include "dmar.h"
-#include "../pci-direct.h"
 #include "../pci_regs.h"
 
 int vtd_enabled;
@@ -233,7 +233,7 @@ static int scope_device_count(void *star
                    / sizeof(struct acpi_pci_path);
         while ( --depth > 0 )
         {
-            bus = read_pci_config_byte(
+            bus = pci_conf_read8(
                 bus, path->dev, path->fn, PCI_SECONDARY_BUS);
             path++;
         }
@@ -250,9 +250,9 @@ static int scope_device_count(void *star
             dprintk(XENLOG_INFO VTDPREFIX,
                     "found bridge: bdf = %x:%x:%x\n",
                     bus, path->dev, path->fn);
-            sec_bus = read_pci_config_byte(
+            sec_bus = pci_conf_read8(
                 bus, path->dev, path->fn, PCI_SECONDARY_BUS);
-            sub_bus = read_pci_config_byte(
+            sub_bus = pci_conf_read8(
                 bus, path->dev, path->fn, PCI_SUBORDINATE_BUS);
 
             while ( sec_bus <= sub_bus )
@@ -261,7 +261,7 @@ static int scope_device_count(void *star
                 {
                     for ( func = 0; func < 8; func++ )
                     {
-                        l = read_pci_config(
+                        l = pci_conf_read32(
                             sec_bus, dev, func, PCI_VENDOR_ID);
 
                         /* some broken boards return 0 or
@@ -355,7 +355,7 @@ static int __init acpi_parse_dev_scope(
 
         while ( --depth > 0 )
         {
-            bus = read_pci_config_byte(
+            bus = pci_conf_read8(
                 bus, path->dev, path->fn, PCI_SECONDARY_BUS);
             path++;
         }
@@ -374,9 +374,9 @@ static int __init acpi_parse_dev_scope(
             dprintk(XENLOG_INFO VTDPREFIX,
                     "found bridge: bus = %x dev = %x func = %x\n",
                     bus, path->dev, path->fn);
-            sec_bus = read_pci_config_byte(
+            sec_bus = pci_conf_read8(
                 bus, path->dev, path->fn, PCI_SECONDARY_BUS);
-            sub_bus = read_pci_config_byte(
+            sub_bus = pci_conf_read8(
                 bus, path->dev, path->fn, PCI_SUBORDINATE_BUS);
 
             while ( sec_bus <= sub_bus )
@@ -385,7 +385,7 @@ static int __init acpi_parse_dev_scope(
                 {
                     for ( func = 0; func < 8; func++ )
                     {
-                        l = read_pci_config(
+                        l = pci_conf_read32(
                             sec_bus, dev, func, PCI_VENDOR_ID);
 
                         /* some broken boards return 0 or
diff -r 082d3886fded -r 80ba1b427032 xen/drivers/passthrough/vtd/intremap.c
--- a/xen/drivers/passthrough/vtd/intremap.c    Fri Apr 11 09:14:03 2008 +0100
+++ b/xen/drivers/passthrough/vtd/intremap.c    Fri Apr 11 13:19:55 2008 +0100
@@ -22,10 +22,10 @@
 #include <xen/sched.h>
 #include <xen/iommu.h>
 #include <xen/time.h>
+#include <xen/pci.h>
 #include "iommu.h"
 #include "dmar.h"
 #include "vtd.h"
-#include "../pci-direct.h"
 #include "../pci_regs.h"
 #include "msi.h"
 #include "extern.h"
diff -r 082d3886fded -r 80ba1b427032 xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c       Fri Apr 11 09:14:03 2008 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c       Fri Apr 11 13:19:55 2008 +0100
@@ -23,13 +23,13 @@
 #include <xen/sched.h>
 #include <xen/xmalloc.h>
 #include <xen/domain_page.h>
-#include <asm/paging.h>
 #include <xen/iommu.h>
 #include <xen/numa.h>
 #include <xen/time.h>
+#include <xen/pci.h>
+#include <asm/paging.h>
 #include "iommu.h"
 #include "dmar.h"
-#include "../pci-direct.h"
 #include "../pci_regs.h"
 #include "msi.h"
 #include "extern.h"
@@ -1228,13 +1228,13 @@ static int __pci_find_next_cap(u8 bus, u
 
     while ( ttl-- )
     {
-        pos = read_pci_config_byte(bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pos);
+        pos = pci_conf_read8(bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pos);
         if ( pos < 0x40 )
             break;
 
         pos &= ~3;
-        id = read_pci_config_byte(bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                                  pos + PCI_CAP_LIST_ID);
+        id = pci_conf_read8(bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+                            pos + PCI_CAP_LIST_ID);
 
         if ( id == 0xff )
             break;
@@ -1258,13 +1258,13 @@ int pdev_type(struct pci_dev *dev)
     u16 class_device;
     u16 status;
 
-    class_device = read_pci_config_16(dev->bus, PCI_SLOT(dev->devfn),
-                                      PCI_FUNC(dev->devfn), PCI_CLASS_DEVICE);
+    class_device = pci_conf_read16(dev->bus, PCI_SLOT(dev->devfn),
+                                   PCI_FUNC(dev->devfn), PCI_CLASS_DEVICE);
     if ( class_device == PCI_CLASS_BRIDGE_PCI )
         return DEV_TYPE_PCI_BRIDGE;
 
-    status = read_pci_config_16(dev->bus, PCI_SLOT(dev->devfn),
-                                PCI_FUNC(dev->devfn), PCI_STATUS);
+    status = pci_conf_read16(dev->bus, PCI_SLOT(dev->devfn),
+                             PCI_FUNC(dev->devfn), PCI_STATUS);
 
     if ( !(status & PCI_STATUS_CAP_LIST) )
         return DEV_TYPE_PCI;
@@ -1292,7 +1292,7 @@ static int domain_context_mapping(
     switch ( type )
     {
     case DEV_TYPE_PCI_BRIDGE:
-        sec_bus = read_pci_config_byte(
+        sec_bus = pci_conf_read8(
             pdev->bus, PCI_SLOT(pdev->devfn),
             PCI_FUNC(pdev->devfn), PCI_SECONDARY_BUS);
 
@@ -1302,7 +1302,7 @@ static int domain_context_mapping(
             bus2bridge[sec_bus].devfn =  pdev->devfn;
         }
 
-        sub_bus = read_pci_config_byte(
+        sub_bus = pci_conf_read8(
             pdev->bus, PCI_SLOT(pdev->devfn),
             PCI_FUNC(pdev->devfn), PCI_SUBORDINATE_BUS);
 
@@ -1425,10 +1425,10 @@ static int domain_context_unmap(
     switch ( type )
     {
     case DEV_TYPE_PCI_BRIDGE:
-        sec_bus = read_pci_config_byte(
+        sec_bus = pci_conf_read8(
             pdev->bus, PCI_SLOT(pdev->devfn),
             PCI_FUNC(pdev->devfn), PCI_SECONDARY_BUS);
-        sub_bus = read_pci_config_byte(
+        sub_bus = pci_conf_read8(
             pdev->bus, PCI_SLOT(pdev->devfn),
             PCI_FUNC(pdev->devfn), PCI_SUBORDINATE_BUS);
 
@@ -1781,7 +1781,7 @@ void __init setup_dom0_devices(void)
         {
             for ( func = 0; func < 8; func++ )
             {
-                l = read_pci_config(bus, dev, func, PCI_VENDOR_ID);
+                l = pci_conf_read32(bus, dev, func, PCI_VENDOR_ID);
                 /* some broken boards return 0 or ~0 if a slot is empty: */
                 if ( (l == 0xffffffff) || (l == 0x00000000) ||
                      (l == 0x0000ffff) || (l == 0xffff0000) )
diff -r 082d3886fded -r 80ba1b427032 xen/drivers/passthrough/vtd/qinval.c
--- a/xen/drivers/passthrough/vtd/qinval.c      Fri Apr 11 09:14:03 2008 +0100
+++ b/xen/drivers/passthrough/vtd/qinval.c      Fri Apr 11 13:19:55 2008 +0100
@@ -22,10 +22,10 @@
 #include <xen/sched.h>
 #include <xen/iommu.h>
 #include <xen/time.h>
+#include <xen/pci.h>
 #include "iommu.h"
 #include "dmar.h"
 #include "vtd.h"
-#include "../pci-direct.h"
 #include "../pci_regs.h"
 #include "msi.h"
 #include "extern.h"
diff -r 082d3886fded -r 80ba1b427032 xen/drivers/passthrough/vtd/utils.c
--- a/xen/drivers/passthrough/vtd/utils.c       Fri Apr 11 09:14:03 2008 +0100
+++ b/xen/drivers/passthrough/vtd/utils.c       Fri Apr 11 13:19:55 2008 +0100
@@ -21,9 +21,9 @@
 #include <xen/delay.h>
 #include <xen/iommu.h>
 #include <xen/time.h>
+#include <xen/pci.h>
 #include "iommu.h"
 #include "dmar.h"
-#include "../pci-direct.h"
 #include "../pci_regs.h"
 #include "msi.h"
 #include "vtd.h"
@@ -37,7 +37,7 @@ int is_usb_device(struct pci_dev *pdev)
     u8 bus = pdev->bus;
     u8 dev = PCI_SLOT(pdev->devfn);
     u8 func = PCI_FUNC(pdev->devfn);
-    u16 class = read_pci_config_16(bus, dev, func, PCI_CLASS_DEVICE);
+    u16 class = pci_conf_read16(bus, dev, func, PCI_CLASS_DEVICE);
     return (class == 0xc03);
 }
 
@@ -46,9 +46,9 @@ int vtd_hw_check(void)
     u16 vendor, device;
     u8 revision, stepping;
 
-    vendor   = read_pci_config_16(0, 0, 0, PCI_VENDOR_ID);
-    device   = read_pci_config_16(0, 0, 0, PCI_DEVICE_ID);
-    revision = read_pci_config_byte(0, 0, 0, PCI_REVISION_ID);
+    vendor   = pci_conf_read16(0, 0, 0, PCI_VENDOR_ID);
+    device   = pci_conf_read16(0, 0, 0, PCI_DEVICE_ID);
+    revision = pci_conf_read8(0, 0, 0, PCI_REVISION_ID);
     stepping = revision & 0xf;
 
     if ( (vendor == INTEL) && (device == SEABURG) )
@@ -103,18 +103,18 @@ static u8 find_cap_offset(u8 bus, u8 dev
     u8 pos = PCI_CAPABILITY_LIST;
     u16 status;
 
-    status = read_pci_config_16(bus, dev, func, PCI_STATUS);
+    status = pci_conf_read16(bus, dev, func, PCI_STATUS);
     if ( (status & PCI_STATUS_CAP_LIST) == 0 )
         return 0;
 
     while ( max_cap-- )
     {
-        pos = read_pci_config_byte(bus, dev, func, pos);
+        pos = pci_conf_read8(bus, dev, func, pos);
         if ( pos < 0x40 )
             break;
 
         pos &= ~3;
-        id = read_pci_config_byte(bus, dev, func, pos + PCI_CAP_LIST_ID);
+        id = pci_conf_read8(bus, dev, func, pos + PCI_CAP_LIST_ID);
 
         if ( id == 0xff )
             break;
@@ -143,13 +143,13 @@ void pdev_flr(u8 bus, u8 devfn)
     pos = find_cap_offset(bus, dev, func, PCI_CAP_ID_EXP);
     if ( pos != 0 )
     {
-        dev_cap = read_pci_config(bus, dev, func, pos + PCI_EXP_DEVCAP);
+        dev_cap = pci_conf_read32(bus, dev, func, pos + PCI_EXP_DEVCAP);
         if ( dev_cap & PCI_EXP_DEVCAP_FLR )
         {
-            write_pci_config(bus, dev, func,
+            pci_conf_write32(bus, dev, func,
                              pos + PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_FLR);
             do {
-                dev_status = read_pci_config(bus, dev, func,
+                dev_status = pci_conf_read32(bus, dev, func,
                                              pos + PCI_EXP_DEVSTA);
             } while ( dev_status & PCI_EXP_DEVSTA_TRPND );
 
@@ -169,23 +169,23 @@ void pdev_flr(u8 bus, u8 devfn)
             int i;
             u32 config[PCI_CONFIG_DWORD_SIZE];
             for ( i = 0; i < PCI_CONFIG_DWORD_SIZE; i++ )
-                config[i] = read_pci_config(bus, dev, func, i*4);
+                config[i] = pci_conf_read32(bus, dev, func, i*4);
 
             /* Enter D3hot without soft reset */
-            pm_ctl = read_pci_config(bus, dev, func, pos + PCI_PM_CTRL);
+            pm_ctl = pci_conf_read32(bus, dev, func, pos + PCI_PM_CTRL);
             pm_ctl |= PCI_PM_CTRL_NO_SOFT_RESET;
             pm_ctl &= ~PCI_PM_CTRL_STATE_MASK;
             pm_ctl |= PCI_D3hot;
-            write_pci_config(bus, dev, func, pos + PCI_PM_CTRL, pm_ctl);
+            pci_conf_write32(bus, dev, func, pos + PCI_PM_CTRL, pm_ctl);
             mdelay(10);
 
             /* From D3hot to D0 */
-            write_pci_config(bus, dev, func, pos + PCI_PM_CTRL, 0);
+            pci_conf_write32(bus, dev, func, pos + PCI_PM_CTRL, 0);
             mdelay(10);
 
             /* Write saved configurations to device */
             for ( i = 0; i < PCI_CONFIG_DWORD_SIZE; i++ )
-                write_pci_config(bus, dev, func, i*4, config[i]);
+                pci_conf_write32(bus, dev, func, i*4, config[i]);
 
             flr = 1;
         }
diff -r 082d3886fded -r 80ba1b427032 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Fri Apr 11 09:14:03 2008 +0100
+++ b/xen/include/asm-x86/domain.h      Fri Apr 11 13:19:55 2008 +0100
@@ -209,6 +209,7 @@ struct arch_domain
 
     /* I/O-port admin-specified access capabilities. */
     struct rangeset *ioport_caps;
+    uint32_t pci_cf8;
 
     struct hvm_domain hvm_domain;
 
diff -r 082d3886fded -r 80ba1b427032 xen/include/xen/pci.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/xen/pci.h     Fri Apr 11 13:19:55 2008 +0100
@@ -0,0 +1,29 @@
+/******************************************************************************
+ * pci.h
+ * 
+ * PCI access functions.
+ */
+
+#ifndef __XEN_PCI_H__
+#define __XEN_PCI_H__
+
+#include <xen/config.h>
+#include <xen/types.h>
+
+uint8_t pci_conf_read8(
+    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg);
+uint16_t pci_conf_read16(
+    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg);
+uint32_t pci_conf_read32(
+    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg);
+void pci_conf_write8(
+    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg,
+    uint8_t data);
+void pci_conf_write16(
+    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg,
+    uint16_t data);
+void pci_conf_write32(
+    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg,
+    uint32_t data);
+
+#endif /* __XEN_PCI_H__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.