direct-io.hg

changeset 15526:13483c74ce04

VT-d - Neocleus pass-through merge
author Guy Zana <guy@neocleus.com>
date Mon Aug 13 17:49:00 2007 -0400 (2007-08-13)
parents 523bd000ea56
children 87a15869d43b
files tools/firmware/hvmloader/32bitbios_support.c tools/firmware/hvmloader/hvmloader.c tools/ioemu/Makefile tools/ioemu/Makefile.target tools/ioemu/hw/dpci.c tools/ioemu/hw/passthrough/dm-access.c tools/ioemu/hw/passthrough/dpciarg.c tools/ioemu/hw/passthrough/legacy.c tools/ioemu/hw/passthrough/pass-through.c tools/ioemu/hw/passthrough/pass-through.h tools/ioemu/hw/pc.c tools/ioemu/hw/pci.c tools/ioemu/pt-libpci/Makefile tools/ioemu/pt-libpci/lib2.2.6/.gitignore tools/ioemu/pt-libpci/lib2.2.6/Makefile tools/ioemu/pt-libpci/lib2.2.6/access.c tools/ioemu/pt-libpci/lib2.2.6/aix-device.c tools/ioemu/pt-libpci/lib2.2.6/config.h tools/ioemu/pt-libpci/lib2.2.6/config.mk tools/ioemu/pt-libpci/lib2.2.6/configure tools/ioemu/pt-libpci/lib2.2.6/dump.c tools/ioemu/pt-libpci/lib2.2.6/example.c tools/ioemu/pt-libpci/lib2.2.6/fbsd-device.c tools/ioemu/pt-libpci/lib2.2.6/filter.c tools/ioemu/pt-libpci/lib2.2.6/generic.c tools/ioemu/pt-libpci/lib2.2.6/header.h tools/ioemu/pt-libpci/lib2.2.6/i386-io-hurd.h tools/ioemu/pt-libpci/lib2.2.6/i386-io-linux.h tools/ioemu/pt-libpci/lib2.2.6/i386-io-sunos.h tools/ioemu/pt-libpci/lib2.2.6/i386-io-windows.h tools/ioemu/pt-libpci/lib2.2.6/i386-ports.c tools/ioemu/pt-libpci/lib2.2.6/internal.h tools/ioemu/pt-libpci/lib2.2.6/libpci.pc.in tools/ioemu/pt-libpci/lib2.2.6/names.c tools/ioemu/pt-libpci/lib2.2.6/nbsd-libpci.c tools/ioemu/pt-libpci/lib2.2.6/obsd-device.c tools/ioemu/pt-libpci/lib2.2.6/pci.h tools/ioemu/pt-libpci/lib2.2.6/pread.h tools/ioemu/pt-libpci/lib2.2.6/proc.c tools/ioemu/pt-libpci/lib2.2.6/sysdep.h tools/ioemu/pt-libpci/lib2.2.6/sysfs.c tools/ioemu/pt-libpci/lib2.2.6/types.h tools/ioemu/pt-libpci/lspci.c tools/ioemu/pt-libpci/pt_libpci.c tools/ioemu/pt-libpci/pt_libpci.h tools/ioemu/pt-libpci/pt_pci_access.c tools/ioemu/pt-libpci/pt_pci_access.h tools/ioemu/pt-libpci/pt_pci_probe.c tools/ioemu/pt-libpci/pt_pci_probe.h tools/ioemu/pt-libpci/pt_pci_tree.c tools/ioemu/pt-libpci/pt_pci_tree.h tools/ioemu/pt-libpci/pt_util.c tools/ioemu/target-i386-dm/exec-dm.c tools/ioemu/target-i386-dm/helper2.c tools/ioemu/target-i386-dm/piix_pci-dm.c tools/ioemu/vl.c tools/ioemu/vl.h tools/libxc/xc_domain.c tools/libxc/xc_hvm_build.c tools/libxc/xc_private.c tools/libxc/xc_private.h tools/libxc/xenctrl.h tools/libxc/xenguest.h tools/libxc/xg_private.c tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/XendConfig.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/image.py tools/python/xen/xm/create.py xen/arch/x86/Makefile xen/arch/x86/domain.c xen/arch/x86/domctl.c xen/arch/x86/e820.c xen/arch/x86/hvm/Makefile xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/intercept.c xen/arch/x86/hvm/io.c xen/arch/x86/hvm/nativedom_access.c xen/arch/x86/hvm/vioapic.c xen/arch/x86/hvm/vmx/intr.c xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/hvm/vmx/vtd/intel-iommu.c xen/arch/x86/hvm/vpic.c xen/arch/x86/io_apic.c xen/arch/x86/irq.c xen/arch/x86/mm.c xen/arch/x86/mm/p2m.c xen/arch/x86/mm/shadow/multi.c xen/arch/x86/mm/shadow/private.h xen/arch/x86/pt/Makefile xen/arch/x86/pt/irq_bind.c xen/arch/x86/pt/mm_early.c xen/arch/x86/pt/pt_init.c xen/arch/x86/pt/pt_irq.c xen/arch/x86/setup.c xen/common/memory.c xen/common/page_alloc.c xen/include/asm-x86/e820.h xen/include/asm-x86/hvm/domain.h xen/include/asm-x86/hvm/io.h xen/include/asm-x86/hvm/iommu.h xen/include/asm-x86/hvm/irq.h xen/include/asm-x86/iommu.h xen/include/asm-x86/mm.h xen/include/asm-x86/p2m.h xen/include/asm-x86/pass-through.h xen/include/public/domctl.h xen/include/public/hvm/e820.h xen/include/public/hvm/hvm_op.h xen/include/public/hvm/params.h xen/include/public/memory.h xen/include/xen/hypercall.h xen/include/xen/irq_bind.h xen/include/xen/mm.h xen/include/xen/mm_early.h xen/include/xen/pt_irq.h
line diff
     1.1 --- a/tools/firmware/hvmloader/32bitbios_support.c	Tue Jul 31 12:36:34 2007 -0700
     1.2 +++ b/tools/firmware/hvmloader/32bitbios_support.c	Mon Aug 13 17:49:00 2007 -0400
     1.3 @@ -76,7 +76,7 @@ static void relocate_32bitbios(char *elf
     1.4       */
     1.5      reloc_size = reloc_off;
     1.6      printf("%d bytes of ROMBIOS high-memory extensions:\n", reloc_size);
     1.7 -    highbiosarea = (char *)(long)e820_malloc(reloc_size);
     1.8 +    highbiosarea = (char *)(long)e820_malloc(reloc_size*20); /* Neocleus - ugly hack */
     1.9      BUG_ON(highbiosarea == NULL);
    1.10      printf("  Relocating to 0x%x-0x%x ... ",
    1.11             (uint32_t)&highbiosarea[0],
     2.1 --- a/tools/firmware/hvmloader/hvmloader.c	Tue Jul 31 12:36:34 2007 -0700
     2.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Mon Aug 13 17:49:00 2007 -0400
     2.3 @@ -241,7 +241,13 @@ static void pci_setup(void)
     2.4                  if ( bar_sz == 0 )
     2.5                      continue;
     2.6  
     2.7 -                if ( (bar_data & PCI_BASE_ADDRESS_SPACE) ==
     2.8 +                if ( bar == 6) 
     2.9 +                {
    2.10 +                    base = &mem_base;
    2.11 +                    bar_sz &= PCI_ROM_ADDRESS_MASK;
    2.12 +                    bar_data &= ~PCI_ROM_ADDRESS_MASK;
    2.13 +                }
    2.14 +                else if ( (bar_data & PCI_BASE_ADDRESS_SPACE) ==
    2.15                       PCI_BASE_ADDRESS_SPACE_MEMORY )
    2.16                  {
    2.17                      base = &mem_base;
    2.18 @@ -260,6 +266,10 @@ static void pci_setup(void)
    2.19                  bar_data |= *base;
    2.20                  *base += bar_sz;
    2.21  
    2.22 +                /* Enable expansion rom */
    2.23 +                if ( bar == 6 )
    2.24 +                    bar_data |= PCI_ROM_ADDRESS_ENABLE;
    2.25 +
    2.26                  pci_writel(devfn, bar_reg, bar_data);
    2.27                  printf("pci dev %02x:%x bar %02x size %08x: %08x\n",
    2.28                         devfn>>3, devfn&7, bar_reg, bar_sz, bar_data);
     3.1 --- a/tools/ioemu/Makefile	Tue Jul 31 12:36:34 2007 -0700
     3.2 +++ b/tools/ioemu/Makefile	Mon Aug 13 17:49:00 2007 -0400
     3.3 @@ -37,7 +37,10 @@ endif
     3.4  
     3.5  TOOLS=
     3.6  
     3.7 -all: $(TOOLS) $(DOCS) recurse-all
     3.8 +all: pt_libpci $(TOOLS) $(DOCS) recurse-all
     3.9 +
    3.10 +pt_libpci:
    3.11 +	$(MAKE) -C pt-libpci
    3.12  
    3.13  subdir-%:
    3.14  	$(MAKE) -C $(subst subdir-,,$@) all
    3.15 @@ -55,6 +58,7 @@ clean:
    3.16  	rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h 
    3.17  	rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS *.pod *~ */*~
    3.18  	$(MAKE) -C tests clean
    3.19 +	$(MAKE) -C pt-libpci clean
    3.20  	for d in $(TARGET_DIRS); do \
    3.21  	[ -d $$d ] && $(MAKE) -C $$d $@ || exit 0 ; \
    3.22          done
    3.23 @@ -102,7 +106,7 @@ test speed test2: all
    3.24  	$(MAKE) -C tests $@
    3.25  
    3.26  TAGS: 
    3.27 -	etags *.[ch] target-i386-dm/*.[ch] hw/*.[ch]
    3.28 +	etags *.[ch] target-i386-dm/*.[ch] hw/*.[ch] hw/pass-through/*.[ch]
    3.29  
    3.30  cscope:
    3.31  	rm -f ./cscope.*
     4.1 --- a/tools/ioemu/Makefile.target	Tue Jul 31 12:36:34 2007 -0700
     4.2 +++ b/tools/ioemu/Makefile.target	Mon Aug 13 17:49:00 2007 -0400
     4.3 @@ -14,10 +14,12 @@ ifeq ($(TARGET_ARCH), sparc64)
     4.4  TARGET_BASE_ARCH:=sparc
     4.5  endif
     4.6  TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH)$(TARGET_SUB)
     4.7 -VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/audio
     4.8 +VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/audio:$(SRC_PATH)/hw/passthrough
     4.9  CPPFLAGS=-I. -I.. -I$(TARGET_PATH) -I$(SRC_PATH)
    4.10  CPPFLAGS+= -I$(XEN_ROOT)/tools/libxc
    4.11  CPPFLAGS+= -I$(XEN_ROOT)/tools/xenstore
    4.12 +# pt-libpci
    4.13 +CPPFLAGS+= -I$(SRC_PATH)/pt-libpci -DPT_LIBPCI
    4.14  ifdef CONFIG_DARWIN_USER
    4.15  VPATH+=:$(SRC_PATH)/darwin-user
    4.16  CPPFLAGS+=-I$(SRC_PATH)/darwin-user -I$(SRC_PATH)/darwin-user/$(TARGET_ARCH)
    4.17 @@ -198,7 +200,6 @@ LIBS+=-lm
    4.18  LIBS+=-L../../libxc -lxenctrl -lxenguest
    4.19  LIBS+=-L../../xenstore -lxenstore
    4.20  LIBS+=-lpthread
    4.21 -LIBS+=-lpci
    4.22  ifndef CONFIG_USER_ONLY
    4.23  LIBS+=-lz
    4.24  endif
    4.25 @@ -241,6 +242,7 @@ endif
    4.26  
    4.27  SRCS:= $(OBJS:.o=.c)
    4.28  OBJS+= libqemu.a
    4.29 +OBJS+= ../pt-libpci/pt_libpci.a
    4.30  
    4.31  # cpu emulator library
    4.32  LIBOBJS=exec.o kqemu.o translate-op.o translate-all.o cpu-exec.o\
    4.33 @@ -396,13 +398,13 @@ VL_OBJS+= fdc.o mc146818rtc.o serial.o p
    4.34  else
    4.35  VL_OBJS+= fdc.o serial.o pc.o
    4.36  endif
    4.37 +VL_OBJS+= pass-through.o legacy.o dm-access.o dpciarg.o
    4.38  VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o
    4.39  VL_OBJS+= usb-uhci.o smbus_eeprom.o
    4.40  VL_OBJS+= piix4acpi.o
    4.41  VL_OBJS+= xenstore.o
    4.42  VL_OBJS+= xen_platform.o
    4.43  VL_OBJS+= tpm_tis.o
    4.44 -VL_OBJS+= dpci.o
    4.45  CPPFLAGS += -DHAS_AUDIO
    4.46  endif
    4.47  ifeq ($(TARGET_BASE_ARCH), ppc)
    4.48 @@ -495,7 +497,7 @@ ifdef CONFIG_WIN32
    4.49  SDL_LIBS := $(filter-out -mwindows, $(SDL_LIBS)) -mconsole
    4.50  endif
    4.51  
    4.52 -$(QEMU_SYSTEM): $(VL_OBJS) libqemu.a
    4.53 +$(QEMU_SYSTEM): $(VL_OBJS) libqemu.a ../pt-libpci/pt_libpci.a
    4.54  	$(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(VL_LIBS)
    4.55  
    4.56  cocoa.o: cocoa.m
     5.1 --- a/tools/ioemu/hw/dpci.c	Tue Jul 31 12:36:34 2007 -0700
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,565 +0,0 @@
     5.4 -/*
     5.5 - * Allen Kay <allen.m.kay@intel.com>
     5.6 - *
     5.7 - * This file implements direct PCI assignment to a HVM guest domain.
     5.8 - *
     5.9 - * Detailed Description:
    5.10 - *
    5.11 - * In general, we do not allow the guest OS to write directly to the
    5.12 - * assigned device's PCI config space.  The reason is that we do not
    5.13 - * want guest OS to change the physical BAR address either during sizing
    5.14 - * of the BAR or actual reassignment of BAR addresses.  At one time,
    5.15 - * we have allowed such direct access and found it caused system hangs.
    5.16 - *
    5.17 - * So the solution we have implemented is to first construct a virtual
    5.18 - * PCI device using real PCI config data of the assigned device.  Once
    5.19 - * this is constructed, it acts as any other existing QEMU virtual PCI
    5.20 - * devices.  The difference is in dpci_write_config() function, writes
    5.21 - * to the command register is passed on to the hardware while other
    5.22 - * fields are emulated - just like other virtual PCI devices.  In addition,
    5.23 - * we have also implemented code to handle guest reassignment of BAR
    5.24 - * addresses using dpci_memory_mapping and dpci_ioport_mapping hypercalls.
    5.25 - */
    5.26 -
    5.27 -#include "vl.h"
    5.28 -#include "pci/header.h"
    5.29 -#include "pci/pci.h"
    5.30 -
    5.31 -#define DEBUG_DIRECT_PCI 1
    5.32 -
    5.33 -#define PCI_VENDOR_ID        0x00    /* 16 bits */
    5.34 -#define PCI_DEVICE_ID        0x02    /* 16 bits */
    5.35 -#define PCI_COMMAND        0x04    /* 16 bits */
    5.36 -#define PCI_COMMAND_IO        0x1    /* Enable response in I/O space */
    5.37 -#define PCI_COMMAND_MEMORY    0x2    /* Enable response in Memory space */
    5.38 -#define PCI_CLASS_DEVICE        0x0a    /* Device class */
    5.39 -#define PCI_INTERRUPT_LINE    0x3c    /* 8 bits */
    5.40 -#define PCI_INTERRUPT_PIN    0x3d    /* 8 bits */
    5.41 -#define PCI_MIN_GNT        0x3e    /* 8 bits */
    5.42 -#define PCI_MAX_LAT        0x3f    /* 8 bits */
    5.43 -
    5.44 -/* just used for simpler irq handling. */
    5.45 -#define PCI_DEVICES_MAX 64
    5.46 -#define PCI_IRQ_WORDS   ((PCI_DEVICES_MAX + 31) / 32)
    5.47 -
    5.48 -extern FILE *logfile;
    5.49 -
    5.50 -static void dpci_update_mappings(PCIDevice *d)
    5.51 -{
    5.52 -    PCIIORegion *r;
    5.53 -    int cmd, i;
    5.54 -    uint32_t last_addr, new_addr, config_ofs;
    5.55 -    
    5.56 -    cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
    5.57 -    for(i = 0; i < PCI_NUM_REGIONS; i++) {
    5.58 -        r = &d->io_regions[i];
    5.59 -        if (i == PCI_ROM_SLOT)
    5.60 -            config_ofs = 0x30;
    5.61 -        else
    5.62 -            config_ofs = 0x10 + i * 4;
    5.63 -        if (r->size != 0) {
    5.64 -            if (r->type & PCI_ADDRESS_SPACE_IO) {
    5.65 -                if (cmd & PCI_COMMAND_IO) {
    5.66 -
    5.67 -                    new_addr = le32_to_cpu(
    5.68 -                        *(uint32_t *)(d->config + config_ofs));
    5.69 -
    5.70 -                    new_addr = new_addr & ~(r->size - 1);
    5.71 -                    last_addr = new_addr + r->size - 1;
    5.72 -
    5.73 -                    /* NOTE: we have only 64K ioports on PC */
    5.74 -                    if (last_addr <= new_addr || new_addr == 0 ||
    5.75 -                        last_addr >= 0x10000) {
    5.76 -                        new_addr = -1;
    5.77 -                    }
    5.78 -                } else {
    5.79 -                    new_addr = -1;
    5.80 -                }
    5.81 -            } else {
    5.82 -                if (cmd & PCI_COMMAND_MEMORY) {
    5.83 -                    new_addr = le32_to_cpu(*(uint32_t *)(d->config + 
    5.84 -                                                         config_ofs));
    5.85 -                    /* the ROM slot has a specific enable bit */
    5.86 -                    if (i == PCI_ROM_SLOT && !(new_addr & 1))
    5.87 -                        goto no_mem_map;
    5.88 -                    new_addr = new_addr & ~(r->size - 1);
    5.89 -                    last_addr = new_addr + r->size - 1;
    5.90 -
    5.91 -                    /* NOTE: we do not support wrapping */
    5.92 -                    /* XXX: as we cannot support really dynamic
    5.93 -                       mappings, we handle specific values as invalid
    5.94 -                       mappings. */
    5.95 -                    if (last_addr <= new_addr || new_addr == 0 ||
    5.96 -                        last_addr == -1) {
    5.97 -                        new_addr = -1;
    5.98 -                    }
    5.99 -                } else {
   5.100 -no_mem_map:         new_addr = -1;
   5.101 -                }
   5.102 -            }
   5.103 -            /* now do the real mapping */
   5.104 -            if (new_addr != r->addr) {
   5.105 -                if (r->addr != -1) {
   5.106 -                    if (r->type & PCI_ADDRESS_SPACE_IO) {
   5.107 -                        int class;
   5.108 -                        /* NOTE: specific hack for IDE in PC case:
   5.109 -                           only one byte must be mapped. */
   5.110 -                        class = d->config[0x0a] | (d->config[0x0b] << 8);
   5.111 -                        if (class == 0x0101 && r->size == 4)
   5.112 -                            isa_unassign_ioport(r->addr + 2, 1);
   5.113 -                        else
   5.114 -                            isa_unassign_ioport(r->addr, r->size);
   5.115 -                    } else
   5.116 -                        cpu_register_physical_memory(r->addr + pci_mem_base, 
   5.117 -                                                     r->size, 
   5.118 -                                                     IO_MEM_UNASSIGNED);
   5.119 -                }
   5.120 -                r->addr = new_addr;
   5.121 -                if (r->addr != -1) {
   5.122 -                    r->map_func(d, i, r->addr, r->size, r->type);
   5.123 -                }
   5.124 -            }
   5.125 -        }
   5.126 -    }
   5.127 -}
   5.128 -
   5.129 -uint32_t dpci_read_config(
   5.130 -    PCIDevice *d, 
   5.131 -    uint32_t address, int len)
   5.132 -{
   5.133 -    uint32_t val;
   5.134 -
   5.135 -    switch(len) {
   5.136 -    case 1:
   5.137 -        val = d->config[address];
   5.138 -        break;
   5.139 -    case 2:
   5.140 -        val = le16_to_cpu(*(uint16_t *)(d->config + address));
   5.141 -        break;
   5.142 -    default:
   5.143 -    case 4:
   5.144 -        val = le32_to_cpu(*(uint32_t *)(d->config + address));
   5.145 -        break;
   5.146 -    }
   5.147 -#ifdef DEBUG_DIRECT_PCI
   5.148 -    fprintf(logfile,
   5.149 -        "dpci_read_config: address = %x len = %x val = %x\n",
   5.150 -        address, len, val);
   5.151 -#endif
   5.152 -    return val;
   5.153 -}
   5.154 -
   5.155 -
   5.156 -void dpci_write_config(
   5.157 -    PCIDevice *d, uint32_t address,
   5.158 -    uint32_t val, int len)
   5.159 -{
   5.160 -    int can_write, i, ret = 0;
   5.161 -    uint32_t end, addr;
   5.162 -    uint32_t request_val = val;
   5.163 -    uint32_t old_bar;
   5.164 -
   5.165 -    if ((address == 0x4) && (len == 2))
   5.166 -        pci_write_word(d->pci_dev, address, val);
   5.167 -
   5.168 -    if (len == 4 && ((address >= 0x10 && address < 0x10 + 4 * 6) || 
   5.169 -                     (address >= 0x30 && address < 0x34)))
   5.170 -    {
   5.171 -        PCIIORegion *r;
   5.172 -        int reg;
   5.173 -
   5.174 -        if ( address >= 0x30 )
   5.175 -            reg = PCI_ROM_SLOT;
   5.176 -        else
   5.177 -            reg = (address - 0x10) >> 2;
   5.178 -
   5.179 -        r = &d->io_regions[reg];
   5.180 -        if (r->size == 0)
   5.181 -            goto default_config;
   5.182 -
   5.183 -        /* compute the stored value */
   5.184 -        if (reg == PCI_ROM_SLOT) {
   5.185 -            /* keep ROM enable bit */
   5.186 -            val &= (~(r->size - 1)) | 1;
   5.187 -        } else {
   5.188 -            val &= ~(r->size - 1);
   5.189 -            val |= r->type;
   5.190 -        }
   5.191 -        old_bar = *(uint32_t *)(d->config + address);
   5.192 -        *(uint32_t *)(d->config + address) = cpu_to_le32(val);
   5.193 -
   5.194 -        /* dynamic pci bar */
   5.195 -        if ( (request_val == -1) && (d->old_bars[reg] == 0))
   5.196 -            d->old_bars[reg] = old_bar ;
   5.197 -        else if ((~val + 1) != r->size) {
   5.198 -            switch (r->type) {
   5.199 -                case PCI_ADDRESS_SPACE_MEM:
   5.200 -                case PCI_ADDRESS_SPACE_MEM_PREFETCH:
   5.201 -                    fprintf(logfile,
   5.202 -                        "xc_domain_memory_mapping: new = %x old = %x size = %x\n",
   5.203 -                        cpu_to_le32(val) >> 12,
   5.204 -                        d->old_bars[reg] >> 12,
   5.205 -                        r->size >> 12);
   5.206 -
   5.207 -                    ret = xc_domain_memory_mapping(xc_handle,
   5.208 -                        domid,
   5.209 -                        cpu_to_le32(val) >> 12,
   5.210 -                        d->old_bars[reg] >> 12,
   5.211 -                        r->size >> 12);
   5.212 -
   5.213 -                    if ( ret < 0 )
   5.214 -                        fprintf(logfile,
   5.215 -                            " xc_domain_memory_mapping error %d\n", ret);
   5.216 -                    break;
   5.217 -                case PCI_ADDRESS_SPACE_IO:
   5.218 -                    fprintf(logfile,
   5.219 -                        "xc_domain_ioport_mapping: val = %x r->size = %x \
   5.220 -                         d->old_bars[%x] = %x\n",
   5.221 -                        val, r->size, reg, d->old_bars[reg]);
   5.222 -
   5.223 -                    ret = xc_domain_ioport_mapping(xc_handle,
   5.224 -                        domid,
   5.225 -                        cpu_to_le32(val),
   5.226 -                        d->old_bars[reg],
   5.227 -                        r->size);
   5.228 -
   5.229 -                    if ( ret < 0 )
   5.230 -                        fprintf(logfile,
   5.231 -                            " xc_domain_ioport_mapping error %d\n", ret);
   5.232 -                    break;
   5.233 -                default:
   5.234 -                    fprintf(logfile,
   5.235 -                        "dpci_write_config: invalid r->type = %x\n", r->type);
   5.236 -            }
   5.237 -        }
   5.238 -        dpci_update_mappings(d);
   5.239 -        return;
   5.240 -    }
   5.241 - default_config:
   5.242 -    /* not efficient, but simple */
   5.243 -    addr = address;
   5.244 -    for(i = 0; i < len; i++) {
   5.245 -        /* default read/write accesses */
   5.246 -        switch(d->config[0x0e]) {
   5.247 -        case 0x00:
   5.248 -        case 0x80:
   5.249 -            switch(addr) {
   5.250 -            case 0x00:
   5.251 -            case 0x01:
   5.252 -            case 0x02:
   5.253 -            case 0x03:
   5.254 -            case 0x08:
   5.255 -            case 0x09:
   5.256 -            case 0x0a:
   5.257 -            case 0x0b:
   5.258 -            case 0x0e:
   5.259 -            case 0x10 ... 0x27: /* base */
   5.260 -            case 0x30 ... 0x33: /* rom */
   5.261 -            case 0x3d:
   5.262 -                can_write = 0;
   5.263 -                break;
   5.264 -            default:
   5.265 -                can_write = 1;
   5.266 -                break;
   5.267 -            }
   5.268 -            break;
   5.269 -        default:
   5.270 -        case 0x01:
   5.271 -            switch(addr) {
   5.272 -            case 0x00:
   5.273 -            case 0x01:
   5.274 -            case 0x02:
   5.275 -            case 0x03:
   5.276 -            case 0x08:
   5.277 -            case 0x09:
   5.278 -            case 0x0a:
   5.279 -            case 0x0b:
   5.280 -            case 0x0e:
   5.281 -            case 0x38 ... 0x3b: /* rom */
   5.282 -            case 0x3d:
   5.283 -                can_write = 0;
   5.284 -                break;
   5.285 -            default:
   5.286 -                can_write = 1;
   5.287 -                break;
   5.288 -            }
   5.289 -            break;
   5.290 -        }
   5.291 -        if (can_write) {
   5.292 -            d->config[addr] = val;
   5.293 -        }
   5.294 -        addr++;
   5.295 -        val >>= 8;
   5.296 -    }
   5.297 -    end = address + len;
   5.298 -
   5.299 -    /* if command register is modified, we must modify mappings */
   5.300 -    if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) {
   5.301 -        dpci_update_mappings(d);
   5.302 -    }
   5.303 -}
   5.304 -
   5.305 -void dpci_ioport_map(
   5.306 -    PCIDevice *pci_dev, int region_num, 
   5.307 -    uint32_t addr, uint32_t size, int type)
   5.308 -{
   5.309 -    fprintf(logfile, "dpci_ioport_map: entered\n");
   5.310 -}
   5.311 -
   5.312 -void dpci_mmio_map(
   5.313 -    PCIDevice *pci_dev, int region_num, 
   5.314 -    uint32_t addr, uint32_t size, int type)
   5.315 -{
   5.316 -    fprintf(logfile, "dpci_mmio_map: entered\n");
   5.317 -}
   5.318 -
   5.319 -static int pci_devs(const char *direct_pci)
   5.320 -{
   5.321 -    int count = 0;
   5.322 -    const char *c;
   5.323 -
   5.324 -    /* skip first "[" character */
   5.325 -    c = direct_pci + 1;
   5.326 -    while ((c = strchr(c, '[')) != NULL) {
   5.327 -        c++;
   5.328 -        count++;
   5.329 -    }
   5.330 -    return (count);
   5.331 -}
   5.332 -
   5.333 -static char *token;
   5.334 -int next_token(char *direct_pci)
   5.335 -{
   5.336 -    if (token == NULL)
   5.337 -        token = strtok(direct_pci, ",");
   5.338 -    else 
   5.339 -        token = strtok(NULL, ",");
   5.340 -    token = strchr(token, 'x');
   5.341 -    token = token + 1;
   5.342 -    return ((int) strtol(token, NULL, 16));
   5.343 -}
   5.344 -
   5.345 -static void next_bdf(
   5.346 -    char *direct_pci, int *seg,
   5.347 -    int *bus, int *dev, int *func)
   5.348 -{
   5.349 -    *seg  = next_token(direct_pci);
   5.350 -    *bus  = next_token(direct_pci);
   5.351 -    *dev  = next_token(direct_pci);
   5.352 -    *func = next_token(direct_pci);
   5.353 -}
   5.354 -
   5.355 -#define PCI_CONFIG_SIZE 0x3c
   5.356 -#define PCI_BAR_ENTRIES 0x6
   5.357 -#define DIRECT_PCI 1
   5.358 -struct pci_config_cf8 {
   5.359 -    union {
   5.360 -        unsigned int value;
   5.361 -        struct {
   5.362 -            unsigned int reserved1:2;
   5.363 -            unsigned int reg:6;
   5.364 -            unsigned int func:3;
   5.365 -            unsigned int dev:5;
   5.366 -            unsigned int bus:8;
   5.367 -            unsigned int reserved2:7;
   5.368 -            unsigned int enable:1;
   5.369 -        };
   5.370 -    };
   5.371 -};
   5.372 - 
   5.373 -static int find_cap_offset(
   5.374 -    struct pci_dev *pdev, int cap)
   5.375 -{
   5.376 -    int id;
   5.377 -    int max_cap = 48;
   5.378 -    int pos = PCI_CAPABILITY_LIST;
   5.379 -    int status;
   5.380 -
   5.381 -    status = pci_read_byte(pdev, PCI_STATUS);
   5.382 -    if ((status & PCI_STATUS_CAP_LIST) == 0)
   5.383 -        return 0;
   5.384 -
   5.385 -    while (max_cap--) {
   5.386 -        pos = pci_read_byte(pdev, pos);
   5.387 -        if (pos < 0x40)
   5.388 -            break;
   5.389 -        fprintf(logfile, "find_cap_offset: pos = %x\n", pos);
   5.390 -
   5.391 -        pos &= ~3;
   5.392 -        id = pci_read_byte(pdev, pos + PCI_CAP_LIST_ID);
   5.393 -        fprintf(logfile,
   5.394 -            "find_cap_offset: id = %x PCI_CAP_ID_EXP = %x\n",
   5.395 -            id, PCI_CAP_ID_EXP);
   5.396 -
   5.397 -        if (id == 0xff)
   5.398 -            break;
   5.399 -        if (id == cap)
   5.400 -            return pos;
   5.401 -
   5.402 -        pos += PCI_CAP_LIST_NEXT;
   5.403 -        fprintf(logfile,
   5.404 -            "find_cap_offset: pos = %x PCI_CAP_LIST_NEXT = %x\n",
   5.405 -            pos, PCI_CAP_LIST_NEXT);
   5.406 -    }
   5.407 -    return 0;
   5.408 -}
   5.409 -
   5.410 -#define PCI_EXP_DEVCAP_FLR    (1 << 28)
   5.411 -#define PCI_EXP_DEVCTL_FLR     0x1b
   5.412 -
   5.413 -void pdev_flr(struct pci_dev *pdev)
   5.414 -{
   5.415 -    int pos;
   5.416 -    int dev_cap;
   5.417 -    int dev_status;
   5.418 -
   5.419 -    pos = find_cap_offset(pdev, PCI_CAP_ID_EXP);
   5.420 -    fprintf(logfile, "pdev_flr: pos = %x\n", pos);
   5.421 -    if (pos) {
   5.422 -        dev_cap = pci_read_long(pdev, pos + PCI_EXP_DEVCAP);
   5.423 -        fprintf(logfile, "pdev_flr: dev_cap = %x\n", dev_cap);
   5.424 -        if (dev_cap & PCI_EXP_DEVCAP_FLR) {
   5.425 -            fprintf(logfile, "pdev_flr: writing %x to %x\n",
   5.426 -                    pos + PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_FLR);
   5.427 -            pci_write_word(pdev, pos + PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_FLR);
   5.428 -            do {
   5.429 -                dev_status = pci_read_long(pdev, pos + PCI_EXP_DEVSTA);
   5.430 -            } while (dev_status & PCI_EXP_DEVSTA_TRPND);
   5.431 -        }
   5.432 -    }
   5.433 -    fprintf(logfile, "pdev_flr: done\n");
   5.434 -}
   5.435 -
   5.436 -void pdev_read_pmcap(struct pci_dev *pdev, PCIDevice *d)
   5.437 -{
   5.438 -    int pos;
   5.439 -
   5.440 -    /* read power management capability */
   5.441 -    pos = find_cap_offset(pdev, PCI_CAP_ID_PM);
   5.442 -
   5.443 -    if (pos > 0) {
   5.444 -        d->config[PCI_CAPABILITY_LIST] = pos;
   5.445 -        d->config[pos] = pci_read_byte(pdev, pos);
   5.446 -        pos++;
   5.447 -
   5.448 -        /* set next cap pointer to 0 to terminate the link list */
   5.449 -        d->config[pos] = 0;
   5.450 -        pos++;
   5.451 -        d->config[pos] = pci_read_byte(pdev, pos);
   5.452 -        pos++;
   5.453 -        d->config[pos] = pci_read_byte(pdev, pos);
   5.454 -        pos++;
   5.455 -        d->config[pos] = pci_read_byte(pdev, pos);
   5.456 -        pos++;
   5.457 -        d->config[pos] = pci_read_byte(pdev, pos);
   5.458 -        pos++;
   5.459 -        d->config[pos] = pci_read_byte(pdev, pos);
   5.460 -        pos++;
   5.461 -        d->config[pos] = pci_read_byte(pdev, pos);
   5.462 -        pos++;
   5.463 -    }
   5.464 -}
   5.465 -
   5.466 -/*
   5.467 - * This function gets PCI config info of the assigned device
   5.468 - * and construct a virtual PCI device on the virtual PCI
   5.469 - * bus - similar to other virtual PCI devices such as
   5.470 - * PCnet.
   5.471 - */
   5.472 -void dpci_init(PCIBus *pci_bus, char *direct_pci)
   5.473 -{
   5.474 -    PCIDevice *d;
   5.475 -    int dev_count;
   5.476 -    int seg, bus, dev, func;
   5.477 -    struct pci_access *pci_access;
   5.478 -    struct pci_dev *pci_dev;
   5.479 -    struct pci_config_cf8 machine_bdf;
   5.480 -    int i, ret = 0;
   5.481 -    
   5.482 -    dev_count = pci_devs(direct_pci);
   5.483 -    pci_access = pci_alloc();
   5.484 -    if (pci_access == NULL)
   5.485 -        fprintf(logfile, "pci_access is NULL\n");
   5.486 -    pci_init(pci_access);
   5.487 -    pci_scan_bus(pci_access);
   5.488 -
   5.489 -    while (dev_count--) {
   5.490 -        next_bdf(direct_pci, &seg, &bus, &dev, &func);
   5.491 -        fprintf(logfile,
   5.492 -            "dpci_init:%d: seg = %x bus = %x dev = %x func = %x\n",
   5.493 -            dev_count, seg, bus, dev, func);
   5.494 -
   5.495 -        d = (PCIDevice *)pci_register_device(pci_bus, "DIRECT PCI",
   5.496 -            sizeof(PCIDevice), -1, dpci_read_config, dpci_write_config);
   5.497 -
   5.498 -        for (pci_dev = pci_access->devices; pci_dev != NULL;
   5.499 -            pci_dev = pci_dev->next)
   5.500 -        {
   5.501 -            if ((bus == pci_dev->bus) && (dev == pci_dev->dev)
   5.502 -                && (func == pci_dev->func))
   5.503 -                break;
   5.504 -        }
   5.505 -        d->pci_dev = pci_dev;
   5.506 -
   5.507 -        /* fill-in pci config info from physical device */
   5.508 -        for (i = 0; i < PCI_CONFIG_SIZE; i++)
   5.509 -            d->config[i] = pci_read_byte(pci_dev, i);
   5.510 -        d->config[0x3d] = 1;   // interrupt pin 0
   5.511 -
   5.512 -        /* read PM capability */
   5.513 -        pdev_read_pmcap(pci_dev, d);
   5.514 -
   5.515 -        /* issue PCIe FLR */
   5.516 -        pdev_flr(pci_dev);
   5.517 -
   5.518 -        /* tell XEN vmm to change iommu settings */
   5.519 -        machine_bdf.reg = 0;
   5.520 -        machine_bdf.bus = pci_dev->bus;
   5.521 -        machine_bdf.dev = pci_dev->dev;
   5.522 -        machine_bdf.func = pci_dev->func;
   5.523 -        ret = xc_assign_device(xc_handle, domid, machine_bdf.value);
   5.524 -        if ( ret < 0 )
   5.525 -            fprintf(logfile, " xc_domain_assign_device error %d\n", ret);
   5.526 -
   5.527 -        /* Should be fixed. Need to distiguish legacy or MSI capable devices 
   5.528 -         * Now we use pciback to hide the device, and the guest should not 
   5.529 -         * enable MSI capability
   5.530 -         */
   5.531 -        ret = xc_irq_mapping(xc_handle, domid, pci_dev->irq,
   5.532 -                       d->devfn >> 3, d->config[0x3d]-1);
   5.533 -        if ( ret < 0 )
   5.534 -            fprintf(logfile, " xc_domain_irq_mapping error %d\n", ret);
   5.535 -
   5.536 -#ifdef DEBUG_DIRECT_PCI
   5.537 -        for (i = 0x10; i < 0x34; i += 8) {
   5.538 -            fprintf(logfile, "%x %x %x %x %x %x %x %x\n", 
   5.539 -                    d->config[i+0], d->config[i+1], d->config[i+2], 
   5.540 -                    d->config[i+3], d->config[i+4], d->config[i+5], 
   5.541 -                    d->config[i+6], d->config[i+7]); 
   5.542 -        }
   5.543 -#endif
   5.544 -
   5.545 -        /*
   5.546 -         * Call pci_register_io_region() as it will initialize io_regions
   5.547 -         * field in PCIDevice structure.  These fields are later used in
   5.548 -         * dpci_write_config() for getting BAR sizes etc.
   5.549 -         */
   5.550 -        for (i = 0; i < PCI_BAR_ENTRIES; i++) {
   5.551 -            if (pci_dev->base_addr[i]) {
   5.552 -                int type = *((uint32_t*)(d->config + PCI_BASE_ADDRESS_0) + i);
   5.553 -                if (type & PCI_ADDRESS_SPACE_IO)
   5.554 -                    pci_register_io_region(
   5.555 -                        (PCIDevice *)d, i, pci_dev->size[i],
   5.556 -                        PCI_ADDRESS_SPACE_IO, dpci_ioport_map);
   5.557 -                else if (type & PCI_ADDRESS_SPACE_MEM_PREFETCH)
   5.558 -                    pci_register_io_region(
   5.559 -                        (PCIDevice *)d, i, pci_dev->size[i], 
   5.560 -                        PCI_ADDRESS_SPACE_MEM_PREFETCH, dpci_mmio_map);
   5.561 -                else
   5.562 -                    pci_register_io_region(
   5.563 -                        (PCIDevice *)d, i, pci_dev->size[i], 
   5.564 -                        PCI_ADDRESS_SPACE_MEM, dpci_mmio_map);
   5.565 -            }
   5.566 -        }
   5.567 -    }
   5.568 -}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/ioemu/hw/passthrough/dm-access.c	Mon Aug 13 17:49:00 2007 -0400
     6.3 @@ -0,0 +1,402 @@
     6.4 +/* Copyright (c) 2007, Neocleus */
     6.5 +#include <sys/mman.h>
     6.6 +#include <sys/io.h>
     6.7 +
     6.8 +#include "pass-through.h"
     6.9 +#include "pt_pci_access.h"
    6.10 +#include "vl.h"
    6.11 +
    6.12 +extern FILE * logfile;
    6.13 +
    6.14 +/* mmap handle */
    6.15 +int pt_phys_ram_fd;
    6.16 +
    6.17 +CPUReadMemoryFunc * pt_mmio_read_cb[3] = {
    6.18 +    pt_mmio_readb,
    6.19 +    pt_mmio_readw,
    6.20 +    pt_mmio_readl
    6.21 +};
    6.22 +
    6.23 +CPUWriteMemoryFunc * pt_mmio_write_cb[3] = {
    6.24 +    pt_mmio_writeb,
    6.25 +    pt_mmio_writew,
    6.26 +    pt_mmio_writel
    6.27 +};
    6.28 +
    6.29 +void pt_mmio_writeb(void * opaque, target_phys_addr_t e_phys, uint32_t value)
    6.30 +{
    6.31 +    uint32_t r_virt = 0;
    6.32 +    pt_region_t * r_access = (pt_region_t  *)opaque;
    6.33 +
    6.34 +    r_virt = r_access->access.virtual_address + ((uint32_t)e_phys - r_access->e_physbase);
    6.35 +
    6.36 +    if ( r_access->do_logging )
    6.37 +    {
    6.38 +        fprintf(logfile,"pt_mmio_writeb: e_physbase=%08x e_phys=%08x r_virt=%08x value=%08x\n",
    6.39 +            r_access->e_physbase, (uint32_t)e_phys, r_virt, value);
    6.40 +    }
    6.41 +    
    6.42 +    pt_mmio_write(r_virt, value, 1);
    6.43 +}
    6.44 +
    6.45 +void pt_mmio_writew(void * opaque, target_phys_addr_t e_phys, uint32_t value)
    6.46 +{
    6.47 +    uint32_t r_virt = 0;
    6.48 +    pt_region_t * r_access = (pt_region_t  *)opaque;
    6.49 +
    6.50 +    r_virt = r_access->access.virtual_address + ((uint32_t)e_phys - r_access->e_physbase);
    6.51 +
    6.52 +    if ( r_access->do_logging )
    6.53 +    {
    6.54 +        fprintf(logfile,"pt_mmio_writew: e_physbase=%08x e_phys=%08x r_virt=%08x value=%08x\n",
    6.55 +            r_access->e_physbase, (uint32_t)e_phys, r_virt, value);
    6.56 +    }
    6.57 +    
    6.58 +    pt_mmio_write(r_virt, value, 2);			
    6.59 +}
    6.60 +
    6.61 +void pt_mmio_writel(void *opaque, target_phys_addr_t e_phys, uint32_t value)
    6.62 +{
    6.63 +    uint32_t r_virt = 0;
    6.64 +    pt_region_t * r_access = (pt_region_t  *)opaque;
    6.65 +
    6.66 +    r_virt = r_access->access.virtual_address + ((uint32_t)e_phys - r_access->e_physbase);
    6.67 +
    6.68 +    if ( r_access->do_logging )
    6.69 +    {
    6.70 +        fprintf(logfile,"pt_mmio_writel: e_physbase=%08x e_phys=%08x r_virt=%08x value=%08x\n",
    6.71 +        r_access->e_physbase, (uint32_t)e_phys, r_virt, value);
    6.72 +    }
    6.73 +    
    6.74 +    pt_mmio_write(r_virt, value, 4);		
    6.75 +}
    6.76 +
    6.77 +uint32_t pt_mmio_readb(void * opaque, target_phys_addr_t e_phys)
    6.78 +{
    6.79 +    uint32_t r_virt = 0;
    6.80 +    uint32_t value = 0;
    6.81 +    pt_region_t * r_access = (pt_region_t  *)opaque;
    6.82 +
    6.83 +    r_virt = r_access->access.virtual_address + ((uint32_t)e_phys - r_access->e_physbase);
    6.84 +    value = pt_mmio_read(r_virt, 1);
    6.85 +
    6.86 +    if ( r_access->do_logging )
    6.87 +    {
    6.88 +        fprintf(logfile,"pt_mmio_readb:  e_physbase=%08x e_phys=%08x r_virt=%08x value=%08x\n", 
    6.89 +            r_access->e_physbase, (uint32_t)e_phys, r_virt, value);
    6.90 +    }
    6.91 +    
    6.92 +    return (value);
    6.93 +}
    6.94 +
    6.95 +uint32_t pt_mmio_readw(void * opaque, target_phys_addr_t e_phys)
    6.96 +{
    6.97 +    uint32_t r_virt = 0;
    6.98 +    uint32_t value = 0;
    6.99 +    pt_region_t * r_access = (pt_region_t  *)opaque;
   6.100 +
   6.101 +    r_virt = r_access->access.virtual_address + ((uint32_t)e_phys - r_access->e_physbase);
   6.102 +    value = pt_mmio_read(r_virt, 2);
   6.103 +
   6.104 +    if ( r_access->do_logging )
   6.105 +    {
   6.106 +        fprintf(logfile,"pt_mmio_readw:  e_physbase=%08x e_phys=%08x r_virt=%08x value=%08x\n",
   6.107 +            r_access->e_physbase, (uint32_t)e_phys, r_virt, value);
   6.108 +    }
   6.109 +    
   6.110 +    return (value);
   6.111 +}
   6.112 +
   6.113 +uint32_t pt_mmio_readl(void * opaque, target_phys_addr_t e_phys)
   6.114 +{
   6.115 +    uint32_t r_virt = 0;
   6.116 +    uint32_t value = 0;
   6.117 +    pt_region_t * r_access = (pt_region_t  *)opaque;
   6.118 +
   6.119 +    r_virt = r_access->access.virtual_address + ((uint32_t)e_phys - r_access->e_physbase);
   6.120 +    value = pt_mmio_read(r_virt, 4);
   6.121 +
   6.122 +    if ( r_access->do_logging )
   6.123 +    {
   6.124 +        fprintf(logfile,"pt_mmio_readl:  e_physbase=%08x e_phys=%08x r_virt=%08x value=%08x\n",
   6.125 +            r_access->e_physbase, (uint32_t)e_phys, r_virt, value);
   6.126 +    }
   6.127 +    
   6.128 +    return (value);
   6.129 +}
   6.130 +
   6.131 +void pt_ioport_writeb(void *opaque, uint32_t addr, uint32_t value)
   6.132 +{
   6.133 +    uint32_t r_pio = 0;
   6.134 +    pt_region_t * r_access = (pt_region_t  *)opaque;
   6.135 +
   6.136 +    r_pio = (addr - r_access->e_physbase) + r_access->access.ioport_base;
   6.137 +
   6.138 +    if ( r_access->do_logging )
   6.139 +    {
   6.140 +        fprintf(logfile,"pt_ioport_writeb: r_pio=%08x e_physbase=%08x access.ioport_base=%08x value=%08x\n",
   6.141 +            r_pio,  r_access->e_physbase, r_access->access.ioport_base, value);
   6.142 +    }
   6.143 +    
   6.144 +    pt_pio_write(r_pio, value, 1);
   6.145 +}
   6.146 +
   6.147 +void pt_ioport_writew(void *opaque, uint32_t addr, uint32_t value)
   6.148 +{
   6.149 +    uint32_t r_pio = 0;
   6.150 +    pt_region_t * r_access = (pt_region_t  *)opaque;
   6.151 +
   6.152 +    r_pio = (addr - r_access->e_physbase) + r_access->access.ioport_base;
   6.153 +
   6.154 +    if ( r_access->do_logging )
   6.155 +    {
   6.156 +        fprintf(logfile,"pt_ioport_writew: r_pio=%08x e_physbase=%08x access.ioport_base=%08x value=%08x\n",
   6.157 +            r_pio,  r_access->e_physbase, r_access->access.ioport_base, value);
   6.158 +    }
   6.159 +    
   6.160 +    pt_pio_write(r_pio, value, 2);
   6.161 +}
   6.162 +
   6.163 +void pt_ioport_writel(void *opaque, uint32_t addr, uint32_t value)
   6.164 +{
   6.165 +    uint32_t r_pio = 0;
   6.166 +    pt_region_t * r_access = (pt_region_t  *)opaque;
   6.167 +
   6.168 +    r_pio = (addr - r_access->e_physbase) + r_access->access.ioport_base;
   6.169 +
   6.170 +    if ( r_access->do_logging )
   6.171 +    {
   6.172 +        fprintf(logfile,"pt_ioport_writel: r_pio=%08x e_physbase=%08x access.ioport_base=%08x value=%08x\n",
   6.173 +            r_pio,  r_access->e_physbase, r_access->access.ioport_base, value);
   6.174 +    }
   6.175 +    
   6.176 +    pt_pio_write(r_pio, value, 4);
   6.177 +}
   6.178 +
   6.179 +uint32_t pt_ioport_readb(void *opaque, uint32_t addr)
   6.180 +{
   6.181 +
   6.182 +    uint32_t r_pio = 0;
   6.183 +    uint32_t value = 0;
   6.184 +    pt_region_t * r_access = (pt_region_t  *)opaque;
   6.185 +    
   6.186 +    r_pio = (addr - r_access->e_physbase) + r_access->access.ioport_base;
   6.187 +
   6.188 +    value = pt_pio_read(r_pio, 1);
   6.189 +
   6.190 +    if ( r_access->do_logging )
   6.191 +    {
   6.192 +        fprintf(logfile,"pt_ioport_readb:  r_pio=%08x e_physbase=%08x access.ioport_base=%08x value=%08x\n",
   6.193 +            r_pio,  r_access->e_physbase, r_access->access.ioport_base, value);
   6.194 +    }
   6.195 +    
   6.196 +    return (value);
   6.197 +}
   6.198 +
   6.199 +uint32_t pt_ioport_readw(void *opaque, uint32_t addr)
   6.200 +{
   6.201 +
   6.202 +    uint32_t r_pio = 0;
   6.203 +    uint32_t value = 0;
   6.204 +    pt_region_t * r_access = (pt_region_t  *)opaque;
   6.205 +    
   6.206 +    r_pio = (addr - r_access->e_physbase) + r_access->access.ioport_base;
   6.207 +
   6.208 +    value = pt_pio_read(r_pio, 2);
   6.209 +
   6.210 +    if ( r_access->do_logging )
   6.211 +    {
   6.212 +        fprintf(logfile,"pt_ioport_readw:  r_pio=%08x e_physbase=%08x access.ioport_base=%08x value=%08x\n",
   6.213 +            r_pio,  r_access->e_physbase, r_access->access.ioport_base, value);
   6.214 +    }
   6.215 +    
   6.216 +    return (value);	
   6.217 +}
   6.218 +
   6.219 +uint32_t pt_ioport_readl(void *opaque, uint32_t addr)
   6.220 +{
   6.221 +
   6.222 +    uint32_t r_pio = 0;
   6.223 +    uint32_t value = 0;
   6.224 +    pt_region_t * r_access = (pt_region_t  *)opaque;
   6.225 +    
   6.226 +    r_pio = (addr - r_access->e_physbase) + r_access->access.ioport_base;
   6.227 +
   6.228 +    value = pt_pio_read(r_pio, 4);
   6.229 +
   6.230 +    if ( r_access->do_logging )
   6.231 +    {
   6.232 +        fprintf(logfile,"pt_ioport_readl:  r_pio=%08x e_physbase=%08x access.ioport_base=%08x value=%08x\n",
   6.233 +            r_pio,  r_access->e_physbase, r_access->access.ioport_base, value);
   6.234 +    }
   6.235 +    
   6.236 +    return (value);
   6.237 +}
   6.238 +
   6.239 +
   6.240 +void pt_ioport_map_dm(PCIDevice *pci_dev, int i, 
   6.241 +                       uint32_t addr, uint32_t size, int type)
   6.242 +{
   6.243 +    pt_dev_t * r_dev = (pt_dev_t *)pci_dev;
   6.244 +    uint32_t old_ebase = r_dev->bases[i].e_physbase;
   6.245 +    uint8_t first_map = !(r_dev->bases[i].e_size != 0);
   6.246 +    int ret = 0;
   6.247 +    
   6.248 +    fprintf(logfile,"pt_ioport_map: e_addr=0x%x access.ioport_base=0x%x type=0x%x len=%d region_num=%d \n", 
   6.249 +        addr, r_dev->bases[i].access.ioport_base, type, size, i);
   6.250 +
   6.251 +    /* Update access */
   6.252 +    r_dev->bases[i].e_physbase = addr;
   6.253 +    r_dev->bases[i].e_size= size;
   6.254 +
   6.255 +    if ( size == 0 ) 
   6.256 +    {
   6.257 +        fprintf(logfile, "pt_ioport_map failed: size = 0!\n"); 
   6.258 +        return;
   6.259 +    }
   6.260 +    
   6.261 +    if ( !first_map )
   6.262 +        isa_unassign_ioport(old_ebase, r_dev->bases[i].e_size);
   6.263 +
   6.264 +    /* Create new mapping */
   6.265 +    ret |= register_ioport_write(addr, size, 1, pt_ioport_writeb, (void*)&(r_dev->bases[i]));
   6.266 +    ret |= register_ioport_read( addr, size, 1, pt_ioport_readb,  (void*)&(r_dev->bases[i]));
   6.267 +
   6.268 +    ret |= register_ioport_write(addr, size, 2, pt_ioport_writew, (void*)&(r_dev->bases[i]));
   6.269 +    ret |= register_ioport_read( addr, size, 2, pt_ioport_readw,  (void*)&(r_dev->bases[i]));
   6.270 +
   6.271 +    ret |= register_ioport_write(addr, size, 4, pt_ioport_writel, (void*)&(r_dev->bases[i]));
   6.272 +    ret |= register_ioport_read( addr, size, 4, pt_ioport_readl,  (void*)&(r_dev->bases[i]));
   6.273 +
   6.274 +    if ( 0 != ret )
   6.275 +        fprintf(logfile, "pt_ioport_map: failed!\n");
   6.276 +        
   6.277 +}
   6.278 +
   6.279 +void pt_iomem_map_dm(PCIDevice *d, int i,
   6.280 +			       uint32_t e_phys, uint32_t e_size, int type)
   6.281 +{
   6.282 +    pt_dev_t * r_dev  = (pt_dev_t *)d; 
   6.283 +
   6.284 +    r_dev->bases[i].e_physbase = e_phys;
   6.285 +    r_dev->bases[i].e_size= e_size;
   6.286 +
   6.287 +    fprintf(logfile, "pt_iomem_map: e_phys=%08x r_virt=%08x type=%d len=%08x region_number=%d \n",
   6.288 +    	e_phys, r_dev->bases[i].access.virtual_address, type, e_size, i);
   6.289 +
   6.290 +    if ( e_size == 0 ) 
   6.291 +    {
   6.292 +        fprintf(logfile, "pt_iomem_map failed: e_size = 0!\n");
   6.293 +        return;
   6.294 +    }
   6.295 +
   6.296 +    cpu_register_physical_memory(e_phys, e_size, r_dev->bases[i].memory_index);
   6.297 +}
   6.298 +
   6.299 +int pt_register_region_dm(pci_phys_dev_t * phys_dev, pt_dev_t * pci_dev, int i)
   6.300 +{
   6.301 +    pci_region_t * r;
   6.302 +
   6.303 +    if ( i >= PCI_NUM_REGIONS)
   6.304 +        return -1;
   6.305 +
   6.306 +    /* PCI ROM Region */
   6.307 +    if ( i == PCI_ROM_SLOT ) 
   6.308 +    {
   6.309 +        /* Check if ROM found */
   6.310 +        if ( (phys_dev->rom_size == 0) || (phys_dev->rom_base_addr == 0) )
   6.311 +            return -1;
   6.312 +
   6.313 +        /* MMAP BAR address */
   6.314 +        pci_dev->bases[i].e_physbase = phys_dev->rom_base_addr;
   6.315 +        pci_dev->bases[i].access.virtual_address = (uint32_t) mmap(NULL, 
   6.316 +            (phys_dev->rom_size + 0xFFF) & 0xFFFFF000, 
   6.317 +            PROT_WRITE | PROT_READ, MAP_SHARED,  
   6.318 +            pt_phys_ram_fd,
   6.319 +            (off_t) (phys_dev->rom_base_addr & 0xFFFFF000));
   6.320 +
   6.321 +        if ( (uint32_t)-1 == pci_dev->bases[i].access.virtual_address ) 
   6.322 +        {
   6.323 +            fprintf(logfile,"pt_register_region_dm: Couldn't mmap expansion ROM 0x%x!\n", (uint32_t)(phys_dev->rom_base_addr));
   6.324 +            return -1;
   6.325 +        }
   6.326 +
   6.327 +        /* Add offset (in case the region is not page aligned) */
   6.328 +        pci_dev->bases[i].access.virtual_address += (phys_dev->rom_base_addr & 0xFFF);
   6.329 +
   6.330 +        pci_dev->bases[i].do_logging = PT_LOG_ACCESS_MMIO;
   6.331 +
   6.332 +        pci_dev->bases[i].memory_index = cpu_register_io_memory(0, 
   6.333 +                pt_mmio_read_cb, pt_mmio_write_cb, (void *)&(pci_dev->bases[i]));
   6.334 +                
   6.335 +        pci_register_io_region((PCIDevice *)pci_dev, PCI_ROM_SLOT, phys_dev->rom_size, 
   6.336 +                       PCI_ADDRESS_SPACE_MEM_PREFETCH, pt_iomem_map);
   6.337 +
   6.338 +        fprintf(logfile,"pt_register_region_dm: Expansion ROM registered (size=0x%08x base_addr=0x%08x)\n",
   6.339 +            phys_dev->rom_size, phys_dev->rom_base_addr);
   6.340 +            
   6.341 +    }
   6.342 +    else /* PIO/MMIO Region */
   6.343 +    {
   6.344 +        r = &phys_dev->regions[i];
   6.345 +
   6.346 +        if ( !IS_VALID_REGION(r) )
   6.347 +            return -1;
   6.348 +
   6.349 +        if ( (r->type == PT_PCI_ADDRESS_SPACE_MEM) ||
   6.350 +             (r->type == PT_PCI_ADDRESS_SPACE_MEM_PREFETCH) )
   6.351 +        {
   6.352 +            /* MMAP BAR address */
   6.353 +            pci_dev->bases[i].e_physbase = r->base_addr;
   6.354 +            pci_dev->bases[i].access.virtual_address = (uint32_t) mmap(NULL, 
   6.355 +                (r->size + 0xFFF) & 0xFFFFF000, 
   6.356 +                PROT_WRITE | PROT_READ, MAP_SHARED,  
   6.357 +                pt_phys_ram_fd,
   6.358 +                (off_t) (r->base_addr & 0xFFFFF000));
   6.359 +
   6.360 +            if ( (uint32_t)-1 == pci_dev->bases[i].access.virtual_address )
   6.361 +            {
   6.362 +                fprintf(logfile,"pt_register_region_dm: Couldn't mmap 0x%x!\n", (uint32_t)(r->base_addr));
   6.363 +                return -1;	
   6.364 +            }
   6.365 +
   6.366 +            /* Add offset (in case the region is not page aligned) */
   6.367 +            pci_dev->bases[i].access.virtual_address += (r->base_addr & 0xFFF);
   6.368 +            
   6.369 +            pci_dev->bases[i].do_logging = PT_LOG_ACCESS_MMIO;
   6.370 +                        
   6.371 +            pci_dev->bases[i].memory_index = cpu_register_io_memory(0, 
   6.372 +                    pt_mmio_read_cb, pt_mmio_write_cb,(void *)&(pci_dev->bases[i]));
   6.373 +
   6.374 +            pci_register_io_region((PCIDevice *) pci_dev, i, r->size, r->type, pt_iomem_map);
   6.375 +
   6.376 +        }
   6.377 +        else if ( r->type == PT_PCI_ADDRESS_SPACE_IO )
   6.378 +        {
   6.379 +            pci_dev->bases[i].e_physbase = r->base_addr;
   6.380 +            pci_dev->bases[i].access.ioport_base = r->base_addr;
   6.381 +            pci_dev->bases[i].memory_index = 0; // not relevant for port io
   6.382 +            pci_dev->bases[i].do_logging = PT_LOG_ACCESS_PIO;
   6.383 +            pci_register_io_region((PCIDevice *) pci_dev, i, r->size, r->type, pt_ioport_map);
   6.384 +        }
   6.385 +
   6.386 +        fprintf(logfile,"pt_register_region_dm: IO region registered (size=0x%08x type=%-34s index=%d base_addr=0x%08x)\n",
   6.387 +            r->size, PT_GET_TYPE_STR(r->type), i, r->base_addr);
   6.388 +    }
   6.389 +
   6.390 +    return 0;
   6.391 +}
   6.392 +
   6.393 +int pt_init_mmio_access_dm(void)
   6.394 +{
   6.395 +    /* open /dev/mem for mapping mmio */
   6.396 +    if ( (pt_phys_ram_fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0 ) 
   6.397 +    {
   6.398 +        fprintf(logfile,"pt_init_mmio_access_dm: couldn't open /dev/mem!\n");
   6.399 +        return -1;
   6.400 +    }
   6.401 +
   6.402 +    return 0;
   6.403 +}
   6.404 +
   6.405 +
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/tools/ioemu/hw/passthrough/dpciarg.c	Mon Aug 13 17:49:00 2007 -0400
     7.3 @@ -0,0 +1,39 @@
     7.4 +#include "vl.h"
     7.5 +#include "pass-through.h"
     7.6 +
     7.7 +char * token;
     7.8 +
     7.9 +int pci_devs(const char *direct_pci)
    7.10 +{
    7.11 +    int count = 0;
    7.12 +    const char *c;
    7.13 +
    7.14 +    /* skip first "[" character */
    7.15 +    c = direct_pci + 1;
    7.16 +    while ((c = strchr(c, '[')) != NULL) {
    7.17 +        c++;
    7.18 +        count++;
    7.19 +    }
    7.20 +    return (count);
    7.21 +}
    7.22 +
    7.23 +int next_token(char *direct_pci)
    7.24 +{
    7.25 +    if (token == NULL)
    7.26 +        token = strtok(direct_pci, ",");
    7.27 +    else 
    7.28 +        token = strtok(NULL, ",");
    7.29 +    token = strchr(token, 'x');
    7.30 +    token = token + 1;
    7.31 +    return ((int) strtol(token, NULL, 16));
    7.32 +}
    7.33 +
    7.34 +void next_bdf(char *direct_pci, int *seg,
    7.35 +              int *bus, int *dev, int *func)
    7.36 +{
    7.37 +    *seg  = next_token(direct_pci);
    7.38 +    *bus  = next_token(direct_pci);
    7.39 +    *dev  = next_token(direct_pci);
    7.40 +    *func = next_token(direct_pci);
    7.41 +}
    7.42 +
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/tools/ioemu/hw/passthrough/legacy.c	Mon Aug 13 17:49:00 2007 -0400
     8.3 @@ -0,0 +1,126 @@
     8.4 +/*
     8.5 + * Copyright (c) 2007, Neocleus / Intel
     8.6 + *
     8.7 + * Alex Novik <alex@neocleus.com>
     8.8 + * Allen Kay <allen.m.kay@intel.com>
     8.9 + * Guy Zana <guy@neocleus.com>
    8.10 + *
    8.11 + */
    8.12 +#include <sys/mman.h>
    8.13 +#include <sys/io.h>
    8.14 +#include "pass-through.h"
    8.15 +#include "pt_libpci.h"
    8.16 +
    8.17 +extern CPUReadMemoryFunc * pt_mmio_read_cb[3];
    8.18 +extern CPUReadMemoryFunc * pt_mmio_write_cb[3];
    8.19 +extern int pt_phys_ram_fd;
    8.20 +
    8.21 +int register_pt_legacy_mmio_region_dm(uint32_t mmio_addr, uint32_t length, uint8_t do_logging)
    8.22 +{
    8.23 +    pt_region_t * r_access;
    8.24 +
    8.25 +    /* TBD: free! */
    8.26 +    r_access = qemu_mallocz(sizeof(pt_region_t));
    8.27 +    r_access->e_physbase = mmio_addr;
    8.28 +    r_access->e_size = length;
    8.29 +    r_access->access.virtual_address = (uint32_t) mmap(NULL, 
    8.30 +        (length + 0xFFF) & 0xFFFFF000, 
    8.31 +        PROT_WRITE | PROT_READ, MAP_SHARED,  
    8.32 +        pt_phys_ram_fd,
    8.33 +        (off_t) (mmio_addr & 0xFFFFF000));
    8.34 +
    8.35 +    if ( (uint32_t)-1 == r_access->access.virtual_address ) 
    8.36 +    {
    8.37 +        fprintf(logfile,"Error: Couldn't mmap 0x%x!\n", (uint32_t)(mmio_addr & 0xFFFFF000));
    8.38 +        return -1;
    8.39 +    }
    8.40 +
    8.41 +    /* Add offset */
    8.42 +    r_access->access.virtual_address += mmio_addr & 0xFFF;
    8.43 +
    8.44 +    /* Logging */
    8.45 +    r_access->do_logging = do_logging;
    8.46 +    
    8.47 +    /* Register memory access callbacks */
    8.48 +    r_access->memory_index = cpu_register_io_memory(0, pt_mmio_read_cb, pt_mmio_write_cb, (void *)r_access);
    8.49 +    if ( (uint32_t)-1 == r_access->memory_index )
    8.50 +    {
    8.51 +        fprintf(logfile,"Error: Couldn't register legacy mmio region 0x%08x!\n", mmio_addr);
    8.52 +        return -1;
    8.53 +    }
    8.54 +
    8.55 +    cpu_register_physical_memory(mmio_addr, length, r_access->memory_index);
    8.56 +
    8.57 +    fprintf(logfile,"MMIO 0x%08x-0x%08x mapped successfuly!\n", mmio_addr, mmio_addr+length);
    8.58 +    return 0;
    8.59 +}
    8.60 +
    8.61 +int register_pt_legacy_pio_region_dm(uint32_t pio_start, uint32_t length, uint8_t do_logging) 
    8.62 +{
    8.63 +    pt_region_t * r_access;
    8.64 +    int rc = 0;
    8.65 +
    8.66 +    /* TODO: free! */
    8.67 +    r_access = qemu_mallocz(sizeof(pt_region_t));
    8.68 +    r_access->e_physbase = pio_start;
    8.69 +    r_access->access.ioport_base = pio_start;
    8.70 +    r_access->e_size = length;    
    8.71 +
    8.72 +    /* Logging */
    8.73 +    r_access->do_logging = do_logging;
    8.74 +
    8.75 +    /* Register callbacks */
    8.76 +    rc |= register_ioport_write(pio_start, length, 1, pt_ioport_writeb, (void *)r_access);
    8.77 +    rc |= register_ioport_read( pio_start, length, 1, pt_ioport_readb, (void *)r_access);
    8.78 +
    8.79 +    if ( length >=2 ) 
    8.80 +    {
    8.81 +        rc |= register_ioport_write(pio_start, length, 2, pt_ioport_writew, (void*)r_access);    
    8.82 +        rc |= register_ioport_read( pio_start, length, 2, pt_ioport_readw, (void*)r_access);
    8.83 +    }
    8.84 +
    8.85 +    if ( length >= 4 ) 
    8.86 +    {
    8.87 +        rc |= register_ioport_write(pio_start, length, 4, pt_ioport_writel, (void*)r_access);
    8.88 +        rc |= register_ioport_read( pio_start, length, 4, pt_ioport_readl, (void*)r_access);
    8.89 +    }
    8.90 + 
    8.91 +    fprintf(logfile,"PIO 0x%04x-0x%04x mapped successfuly!\n", pio_start, pio_start+length);
    8.92 +    return rc;
    8.93 +}
    8.94 +
    8.95 +
    8.96 +int register_pt_legacy_mmio_region_hypervisor(uint32_t mmio_addr, uint32_t length, uint8_t do_logging)
    8.97 +{
    8.98 +
    8.99 +    int ret;
   8.100 +    ret = xc_domain_memory_mapping(xc_handle,
   8.101 +                           domid,
   8.102 +                           mmio_addr >> 12,
   8.103 +                           mmio_addr >> 12,
   8.104 +                           length >> 12,
   8.105 +                           DPCI_ADD_MAPPING);
   8.106 +
   8.107 +    if ( 0 == ret )
   8.108 +        fprintf(logfile,"MMIO 0x%08x-0x%08x mapped successfuly!\n", mmio_addr, mmio_addr+length);
   8.109 +        
   8.110 +    return ret;
   8.111 +}
   8.112 +
   8.113 +int register_pt_legacy_pio_region_hypervisor(uint32_t pio_start, uint32_t length, uint8_t do_logging) 
   8.114 +{
   8.115 +
   8.116 +    int ret;
   8.117 +    ret = xc_domain_ioport_mapping(xc_handle,
   8.118 +                                   domid,
   8.119 +                                   pio_start,
   8.120 +                                   pio_start,
   8.121 +                                   length,
   8.122 +                                   DPCI_ADD_MAPPING);
   8.123 +
   8.124 +    if ( 0 == ret )
   8.125 +        fprintf(logfile,"PIO 0x%04x-0x%04x mapped successfuly!\n", pio_start, pio_start+length);
   8.126 +        
   8.127 +    return ret;
   8.128 +}
   8.129 +
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/tools/ioemu/hw/passthrough/pass-through.c	Mon Aug 13 17:49:00 2007 -0400
     9.3 @@ -0,0 +1,408 @@
     9.4 +/*
     9.5 + * Copyright (c) 2007, Neocleus / Intel
     9.6 + *
     9.7 + * Alex Novik <alex@neocleus.com>
     9.8 + * Allen Kay <allen.m.kay@intel.com>
     9.9 + * Guy Zana <guy@neocleus.com>
    9.10 + *
    9.11 + * This file implements direct PCI assignment to a HVM guest domain.
    9.12 + *
    9.13 + */
    9.14 +#include "vl.h"
    9.15 +#include "pass-through.h"
    9.16 +
    9.17 +#include "pt_libpci.h"
    9.18 +#include "pt_pci_probe.h"
    9.19 +#include "pt_pci_access.h"
    9.20 +#include "pt_pci_tree.h"
    9.21 +
    9.22 +extern FILE * logfile;
    9.23 +
    9.24 +/* Being called anytime a mmio region has been updated */
    9.25 +void pt_iomem_map_hypervisor(PCIDevice *d, int i,
    9.26 +			                 uint32_t e_phys, uint32_t e_size, int type)
    9.27 +{
    9.28 +    pt_dev_t * r_dev  = (pt_dev_t *)d; 
    9.29 +    uint32_t old_ebase = r_dev->bases[i].e_physbase;
    9.30 +    uint8_t first_map = (r_dev->bases[i].e_size == 0);
    9.31 +    int ret = 0;
    9.32 +
    9.33 +    r_dev->bases[i].e_physbase = e_phys;
    9.34 +    r_dev->bases[i].e_size= e_size;
    9.35 +
    9.36 +    fprintf(logfile, "pt_iomem_map: e_phys=%08x access.machine_address=%08x type=%d len=%08x region_number=%d \n",
    9.37 +    	e_phys, r_dev->bases[i].access.machine_address, type, e_size, i);
    9.38 +
    9.39 +    if ( e_size == 0 ) 
    9.40 +    {
    9.41 +        fprintf(logfile, "pt_iomem_map failed: e_size = 0!\n");
    9.42 +        return ;
    9.43 +    }
    9.44 +
    9.45 +    if ( !first_map ) 
    9.46 +    {    
    9.47 +        /* Remove old mapping */
    9.48 +        ret = xc_domain_memory_mapping(xc_handle,
    9.49 +                                   domid,
    9.50 +                                   old_ebase >> 12,
    9.51 +                                   r_dev->bases[i].access.machine_address >> 12,
    9.52 +                                   (e_size+0xFFF) >> 12,
    9.53 +                                   DPCI_REMOVE_MAPPING);
    9.54 +
    9.55 +        if ( 0 != ret ) 
    9.56 +        {
    9.57 +            fprintf(logfile, "pt_iomem_map: remove old mapping failed!\n");
    9.58 +            return;
    9.59 +        }
    9.60 +                               
    9.61 +    }
    9.62 +
    9.63 +    /* Create new mapping */
    9.64 +    ret = xc_domain_memory_mapping(xc_handle,
    9.65 +                               domid,
    9.66 +                               r_dev->bases[i].e_physbase >> 12,
    9.67 +                               r_dev->bases[i].access.machine_address >> 12,
    9.68 +                               (e_size+0xFFF) >> 12,
    9.69 +                               DPCI_ADD_MAPPING);
    9.70 +
    9.71 +    if ( 0 != ret )
    9.72 +        fprintf(logfile, "pt_iomem_map: create new mapping failed!\n");
    9.73 +
    9.74 +}
    9.75 +
    9.76 +                       
    9.77 +void pt_ioport_map_hypervisor(PCIDevice *pci_dev, int i, 
    9.78 +                       uint32_t addr, uint32_t size, int type)
    9.79 +{
    9.80 +    pt_dev_t * r_dev = (pt_dev_t *)pci_dev;
    9.81 +    uint32_t old_ebase = r_dev->bases[i].e_physbase;
    9.82 +    uint8_t first_map = !(r_dev->bases[i].e_size != 0);
    9.83 +    int ret = 0;
    9.84 +    
    9.85 +    fprintf(logfile,"pt_ioport_map: e_addr=0x%x access.ioport_base=0x%x type=0x%x len=%d region_number=%d\n", 
    9.86 +        addr, r_dev->bases[i].access.ioport_base, type, size, i);
    9.87 +
    9.88 +    /* update access */
    9.89 +    r_dev->bases[i].e_physbase = addr;
    9.90 +    r_dev->bases[i].e_size= size;
    9.91 +
    9.92 +    if ( size == 0 )
    9.93 +    {
    9.94 +        fprintf(logfile, "pt_ioport_map failed: size = 0!\n");
    9.95 +        return;
    9.96 +    }
    9.97 +
    9.98 +    if ( !first_map )
    9.99 +    {
   9.100 +        /* Remove old mapping */
   9.101 +        ret = xc_domain_ioport_mapping(xc_handle,
   9.102 +                                       domid,
   9.103 +                                       old_ebase,
   9.104 +                                       r_dev->bases[i].access.ioport_base,
   9.105 +                                       size,
   9.106 +                                       DPCI_REMOVE_MAPPING);
   9.107 +
   9.108 +        if ( 0 != ret ) 
   9.109 +        {
   9.110 +            fprintf(logfile, "pt_ioport_map: remove old mapping failed!\n");
   9.111 +            return;
   9.112 +        }
   9.113 +    }
   9.114 +                                   
   9.115 +    /* Add new mapping */
   9.116 +    ret = xc_domain_ioport_mapping(xc_handle,
   9.117 +                                   domid,
   9.118 +                                   addr,
   9.119 +                                   r_dev->bases[i].access.ioport_base,
   9.120 +                                   size,
   9.121 +                                   DPCI_ADD_MAPPING);
   9.122 +                                   
   9.123 +    if ( 0 != ret )
   9.124 +        fprintf(logfile, "pt_ioport_map: create new mapping failed!\n");    
   9.125 +
   9.126 +}
   9.127 +
   9.128 +static void update_rom_enable_bit(  uint8_t b, uint8_t d, uint8_t f, 
   9.129 +                                    uint32_t rom_address, uint32_t new_val)
   9.130 +{
   9.131 +    uint32_t bar_data = 0;
   9.132 +
   9.133 +    bar_data = pci_read_long(b, d, f, rom_address);
   9.134 +    bar_data &= ~1UL;
   9.135 +    bar_data |= (new_val & 1);
   9.136 +    pci_write_long(b, d, f, rom_address, bar_data);
   9.137 +}
   9.138 +
   9.139 +static void pt_pci_write_config(PCIDevice * d, uint32_t address, uint32_t val, 
   9.140 +                                int len)
   9.141 +{
   9.142 +    pt_dev_t * r_dev = (pt_dev_t *)d;
   9.143 +
   9.144 +#ifdef PT_DEBUG_PCI_CONFIG    
   9.145 +    fprintf(logfile, "pt_pci_write_config (%x.%x): address=%04x val=0x%08x len=%d\n",
   9.146 +       ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7), (uint16_t) address, val, len);
   9.147 +#endif 
   9.148 +
   9.149 +    /* Pre-write hooking */
   9.150 +    switch (address) {
   9.151 +    case 0x30:                  /* ROM base */
   9.152 +        update_rom_enable_bit(r_dev->b, r_dev->d, r_dev->f, address, val);
   9.153 +    case 0x34:                  /* Capabilities pointer */
   9.154 +    case 0x3C:                  /* Interrupt Line */
   9.155 +    case 0x10 ... 0x27:          /* BARs */
   9.156 +        pci_default_write_config(d, address, val, len);
   9.157 +        return;
   9.158 +    }
   9.159 +
   9.160 +    /* PCI config pass-through */
   9.161 +    switch (len){
   9.162 +    case 1:
   9.163 +        pci_write_byte(r_dev->b, r_dev->d, r_dev->f, address, val);						
   9.164 +        break;
   9.165 +    case 2:
   9.166 +        pci_write_word(r_dev->b, r_dev->d, r_dev->f, address, val);					
   9.167 +        break;
   9.168 +    case 4:	
   9.169 +        pci_write_long(r_dev->b, r_dev->d, r_dev->f, address, val);						
   9.170 +        break;
   9.171 +    }
   9.172 +
   9.173 +    /* Post-write hooking */
   9.174 +    switch (address) {
   9.175 +    case 0x04:                  /* CMD register (enable IO access trap) */
   9.176 +        pci_default_write_config(d, address, val, len);
   9.177 +        break;  
   9.178 +    }
   9.179 +    
   9.180 +}
   9.181 +
   9.182 +static uint32_t pt_pci_read_config(PCIDevice * d, uint32_t address, int len)
   9.183 +{
   9.184 +
   9.185 +    pt_dev_t * r_dev = (pt_dev_t *)d;
   9.186 +    uint32_t val=0;                               
   9.187 +
   9.188 +    /* Pre-hooking */
   9.189 +    switch (address) {
   9.190 +    case 0x10 ... 0x27:          /* BARs */
   9.191 +    case 0x30:                  /* ROM base */
   9.192 +    case 0x34:                  /* Capabilities pointer */
   9.193 +    case 0x3C:                  /* Interrupt Line */    
   9.194 +        val = pci_default_read_config(d, address, len);
   9.195 +        goto exit;
   9.196 +    }
   9.197 +    
   9.198 +    switch (len) {
   9.199 +    case 1:
   9.200 +        val = pci_read_byte(r_dev->b, r_dev->d, r_dev->f, address);
   9.201 +        break;
   9.202 +    case 2:
   9.203 +        val = pci_read_word(r_dev->b, r_dev->d, r_dev->f, address);
   9.204 +        break;
   9.205 +    case 4:
   9.206 +        val = pci_read_long(r_dev->b, r_dev->d, r_dev->f, address);
   9.207 +        break;
   9.208 +    }
   9.209 +
   9.210 +exit:
   9.211 +       
   9.212 +#ifdef PCI_KILL_NEW_CAPABILITIES
   9.213 +    /* kill the special capabilities */
   9.214 +    if ((address ==0x4) && (len == 4)) {
   9.215 +        val &= ~0x100000;
   9.216 +    } else if (address ==0x6) {
   9.217 +        val &= ~0x10;
   9.218 +    }
   9.219 +#endif
   9.220 +
   9.221 +#ifdef PT_DEBUG_PCI_CONFIG
   9.222 +    fprintf(logfile, "pt_pci_read_config  (%x.%x): address=%04x val=0x%08x len=%d\n",
   9.223 +       (d->devfn >> 3) & 0x1F, (d->devfn & 0x7), address, val, len);
   9.224 +#endif
   9.225 +
   9.226 +    return (val);
   9.227 +}
   9.228 +
   9.229 +int pt_register_region_hypervisor(pci_phys_dev_t * phys_dev, pt_dev_t * pci_dev, int i)
   9.230 +{
   9.231 +    pci_region_t * r;
   9.232 +
   9.233 +    if ( i >= PCI_NUM_REGIONS)
   9.234 +        return -1;
   9.235 +
   9.236 +    /* PCI ROM Region */
   9.237 +    if ( i == PCI_ROM_SLOT ) 
   9.238 +    {
   9.239 +        /* Check if ROM found */
   9.240 +        if ( (phys_dev->rom_size == 0) || (phys_dev->rom_base_addr == 0) )
   9.241 +            return -1;
   9.242 +            
   9.243 +        pci_dev->bases[PCI_ROM_SLOT].e_physbase = phys_dev->rom_base_addr;
   9.244 +        pci_dev->bases[PCI_ROM_SLOT].access.machine_address = phys_dev->rom_base_addr;
   9.245 +        
   9.246 +        pci_register_io_region((PCIDevice *)pci_dev, PCI_ROM_SLOT, phys_dev->rom_size, 
   9.247 +                       PCI_ADDRESS_SPACE_MEM_PREFETCH, pt_iomem_map);
   9.248 +
   9.249 +        fprintf(logfile,"pt_register_region_hypervisor: Expansion ROM registered (size=0x%08x base_addr=0x%016x)\n",
   9.250 +            (uint32_t)(phys_dev->rom_size), (uint64_t)(phys_dev->rom_base_addr));
   9.251 +    }
   9.252 +    else /* Regular PIO/MMIO Region */
   9.253 +    {
   9.254 +        r = &phys_dev->regions[i];
   9.255 +
   9.256 +        if ( !IS_VALID_REGION(r) )
   9.257 +            return -1;
   9.258 +
   9.259 +        if ( (r->type == PT_PCI_ADDRESS_SPACE_MEM) ||
   9.260 +             (r->type == PT_PCI_ADDRESS_SPACE_MEM_PREFETCH) )
   9.261 +        {
   9.262 +            pci_dev->bases[i].e_physbase = r->base_addr;
   9.263 +            pci_dev->bases[i].access.machine_address = r->base_addr;
   9.264 +            pci_register_io_region((PCIDevice *) pci_dev, i, r->size, r->type, pt_iomem_map);
   9.265 +        }
   9.266 +        else if ( r->type == PT_PCI_ADDRESS_SPACE_IO )
   9.267 +        {
   9.268 +            pci_dev->bases[i].e_physbase = r->base_addr;
   9.269 +            pci_dev->bases[i].access.ioport_base = r->base_addr;
   9.270 +            pci_dev->bases[i].memory_index = 0; // not relevant for port io
   9.271 +            pci_register_io_region((PCIDevice *) pci_dev, i, r->size,  r->type, pt_ioport_map);
   9.272 +        }
   9.273 +
   9.274 +        fprintf(logfile,"pt_register_region: IO region registered (size=0x%08x type=%-34s index=%d base_addr=0x%016x)\n",
   9.275 +            (uint32_t)(r->size), PT_GET_TYPE_STR(r->type), i, (uint64_t)(r->base_addr));
   9.276 +    }
   9.277 +
   9.278 +    return 0;
   9.279 +}
   9.280 +
   9.281 +
   9.282 +int pt_register_regions(pci_phys_dev_t * real_device, pt_dev_t * pci_dev)
   9.283 +{
   9.284 +    int i=0;
   9.285 +       
   9.286 +    for (i=0; i < real_device->region_number; i++)
   9.287 +        pt_register_region(real_device, pci_dev, i);
   9.288 +
   9.289 +    /* Register Expansion ROM */    
   9.290 +    if ( (real_device->rom_size != 0) && (real_device->rom_base_addr != 0) )
   9.291 +        pt_register_region(real_device, pci_dev, PCI_ROM_SLOT);
   9.292 +
   9.293 +    return 0;
   9.294 +}
   9.295 +
   9.296 +pt_dev_t * register_real_device(PCIBus * e_bus, const char * e_dev_name, int e_devfn, 
   9.297 +                                            uint8_t r_bus, uint8_t r_dev, uint8_t r_func, uint32_t machine_irq,
   9.298 +                                            uint8_t * config, uint32_t config_len)
   9.299 +{
   9.300 +    pt_dev_t * pci_dev = NULL;
   9.301 +    pci_phys_dev_t * real_device = NULL;
   9.302 +    uint8_t e_device, e_intx;
   9.303 +    int rc;
   9.304 +
   9.305 +    fprintf(logfile,"Registering real physical device %s (devfn=0x%x)...\n", e_dev_name, e_devfn);
   9.306 +    
   9.307 +    real_device = pt_devfn_probe(r_bus, r_dev, r_func, PT_PCI_SCAN_FORCE_AUTO);
   9.308 +    if ( NULL == real_device ) 
   9.309 +    {
   9.310 +        fprintf(logfile,"Error: Couldn't lookup real device (%s) in tree!\n", e_dev_name);
   9.311 +        return NULL;	
   9.312 +    }
   9.313 +
   9.314 +    pt_print_device(logfile, real_device);
   9.315 +
   9.316 +    pci_dev = (pt_dev_t *) pci_register_device(e_bus, e_dev_name, sizeof(pt_dev_t),
   9.317 +                        e_devfn, pt_pci_read_config, pt_pci_write_config);
   9.318 +    
   9.319 +    if ( NULL == pci_dev )
   9.320 +    {
   9.321 +        fprintf(logfile,"Error: Couldn't register real device %s\n", e_dev_name);
   9.322 +        return NULL;
   9.323 +    }
   9.324 +
   9.325 +    /* issue PCIe FLR */
   9.326 +    pdev_flr(pci_dev);    
   9.327 +
   9.328 +    pci_dev->b = r_bus;
   9.329 +    pci_dev->d = r_dev;
   9.330 +    pci_dev->f = r_func;
   9.331 +    
   9.332 +    /* handle real device's MMIO/PIO BARs */
   9.333 +    rc = pt_register_regions(real_device, pci_dev);
   9.334 +    if ( rc != 0 )
   9.335 +        return NULL;
   9.336 +
   9.337 +    /* Initialize PCI configuration */
   9.338 +    if ( NULL != config ) 
   9.339 +    {
   9.340 +        memset(pci_dev->dev.config, 0, PCI_CONFIG_SIZE);
   9.341 +        memcpy(pci_dev->dev.config, config, config_len);
   9.342 +    }
   9.343 +    else 
   9.344 +        pci_read_data(r_bus, r_dev, r_func, pci_dev->dev.config, 0, PCI_CONFIG_SIZE);
   9.345 +    
   9.346 +    /* Handle interrupt */
   9.347 +    e_device = (pci_dev->dev.devfn >> 3) & 0x1f;
   9.348 +    e_intx = pci_dev->dev.config[0x3d]-1;
   9.349 +
   9.350 +    if ( PT_MACHINE_IRQ_AUTO == machine_irq )
   9.351 +        machine_irq = real_device->irq;
   9.352 +
   9.353 +    /* bind machine_irq to device */
   9.354 +    if ( 0 != machine_irq ) 
   9.355 +    {
   9.356 +        rc = xc_domain_bind_pt_pci_irq(xc_handle, (uint32_t) domid, machine_irq, 0, e_device, e_intx);
   9.357 +        if ( rc < 0 )
   9.358 +        {
   9.359 +            /* TBD: unregister device in case of an error */
   9.360 +            fprintf(logfile,"register_real_device: Binding of interrupt failed! rc=%d\n", rc);
   9.361 +        }
   9.362 +    } 
   9.363 +    else {
   9.364 +        /* Disable PCI intx assertion (turn on bit10 of devctl) */
   9.365 +        pci_dev->dev.config[0x05] |= 0x04;
   9.366 +        pci_write_word(r_bus, r_dev, r_func, 
   9.367 +                       0x04, *(uint16_t *)(&pci_dev->dev.config[0x04]));
   9.368 +    }
   9.369 +
   9.370 +    fprintf(logfile,"Real physical device (%02x:%02x.%x) \"%s\" registered successfuly!\n", 
   9.371 +        r_bus, r_dev, r_func, e_dev_name);
   9.372 +
   9.373 +    return pci_dev;
   9.374 +}
   9.375 +
   9.376 +int pt_init(PCIBus * e_bus, char *direct_pci)
   9.377 +{
   9.378 +    int rc, i;
   9.379 +    int seg, b, d, f;
   9.380 +    pt_libpci_rc_t res;
   9.381 +    pt_dev_t * pt_dev;
   9.382 +
   9.383 +    res = pt_libpci_init(logfile);
   9.384 +    if ( res != PT_RC_SUCCESS ) 
   9.385 +    {
   9.386 +        fprintf(logfile,"pt_init: pt_libpci_init failed!\n");			
   9.387 +        return -1;
   9.388 +    }
   9.389 +    
   9.390 +    if ( pt_init_mmio_access() < 0 )
   9.391 +        return -1;
   9.392 +
   9.393 +    for (i=0; i < pci_devs(direct_pci); i++)
   9.394 +    {
   9.395 +        /* Get next dpci device bdf (bus, device, function) */
   9.396 +        next_bdf(direct_pci, &seg, &b, &d, &f);
   9.397 +
   9.398 +        /* Register real device on emulated bus */
   9.399 +        pt_dev = register_real_device(e_bus, "Passthru", PT_VIRT_DEVFN_AUTO,
   9.400 +            b, d, f, PT_MACHINE_IRQ_AUTO, NULL, 0);
   9.401 +
   9.402 +        if ( NULL == pt_dev ) 
   9.403 +        {
   9.404 +            fprintf(logfile,"pt_init: Registration failed (%02x:%02x.%x)\n", b, d, f);
   9.405 +            return -1;
   9.406 +        }
   9.407 +    }
   9.408 +    
   9.409 +    /* Success */
   9.410 +    return 0;
   9.411 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tools/ioemu/hw/passthrough/pass-through.h	Mon Aug 13 17:49:00 2007 -0400
    10.3 @@ -0,0 +1,130 @@
    10.4 +/*
    10.5 + * Copyright (c) 2007, Neocleus / Intel
    10.6 + *
    10.7 + * Alex Novik <alex@neocleus.com>
    10.8 + * Allen Kay <allen.m.kay@intel.com>
    10.9 + * Guy Zana <guy@neocleus.com>
   10.10 + *
   10.11 + */
   10.12 +#ifndef __PASSTHROUGH_H__
   10.13 +#define __PASSTHROUGH_H__
   10.14 +
   10.15 +#include <sys/mman.h>
   10.16 +
   10.17 +#include "vl.h"
   10.18 +#include "pt_libpci.h"
   10.19 +#include "pt_pci_probe.h"
   10.20 +#include "pt_pci_access.h"
   10.21 +#include "pt_pci_tree.h"
   10.22 +
   10.23 +/* Log acesss */
   10.24 +#define PT_LOG_ACCESS_PIO        (0)
   10.25 +#define PT_LOG_ACCESS_MMIO       (0)
   10.26 +
   10.27 +/* Some compilation flags */
   10.28 +// #define PT_DEBUG_PCI_CONFIG
   10.29 +// #define PCI_KILL_NEW_CAPABILITIES
   10.30 +
   10.31 +/* 
   10.32 +    PT_USE_DM_ACCESS Tells whether to access the hardware from dom0,
   10.33 +    or from the hypervisor using hypercalls.
   10.34 +
   10.35 +    Accessing MMIO regions from dom0 is done by mmaping the real 
   10.36 +    physical address
   10.37 +*/
   10.38 +//#define PT_USE_DM_ACCESS
   10.39 +
   10.40 +#define PT_MACHINE_IRQ_AUTO (0xFFFFFFFF)
   10.41 +#define PT_VIRT_DEVFN_AUTO  (-1)
   10.42 +
   10.43 +typedef struct pt_region_s {
   10.44 +    /* Virtual phys base & size */
   10.45 +    uint32_t e_physbase;
   10.46 +    uint32_t e_size;
   10.47 +    /* Index of region in qemu */
   10.48 +    uint32_t memory_index;
   10.49 +    /* Log access to this region? */
   10.50 +    uint8_t do_logging;
   10.51 +    /* Translation of the emulated address */
   10.52 +    union {
   10.53 +        uint32_t machine_address;
   10.54 +        uint32_t virtual_address;
   10.55 +        uint32_t ioport_base;
   10.56 +    } access;
   10.57 +} pt_region_t;
   10.58 +
   10.59 +/*
   10.60 +    This structure holds the context of the mapping functions 
   10.61 +    and data that is relevant for qemu device management
   10.62 +*/
   10.63 +typedef struct pt_dev_s {
   10.64 +    PCIDevice dev;
   10.65 +    uint8_t b, d, f;
   10.66 +    pt_region_t bases[PCI_NUM_REGIONS];
   10.67 +} pt_dev_t;
   10.68 +
   10.69 +/* Argument parsing */
   10.70 +int pci_devs(const char *direct_pci);
   10.71 +int next_token(char *direct_pci);
   10.72 +void next_bdf(char *direct_pci, int *seg,
   10.73 +              int *bus, int *dev, int *func);
   10.74 +
   10.75 +/* MMIO/PIO access functions (through dom0) */
   10.76 +uint32_t pt_mmio_readb(void * opaque, target_phys_addr_t e_phys);
   10.77 +uint32_t pt_mmio_readw(void * opaque, target_phys_addr_t e_phys);
   10.78 +uint32_t pt_mmio_readl(void * opaque, target_phys_addr_t e_phys);
   10.79 +void pt_mmio_writeb(void * opaque, target_phys_addr_t e_phys, uint32_t value);
   10.80 +void pt_mmio_writew(void * opaque, target_phys_addr_t e_phys, uint32_t value);
   10.81 +void pt_mmio_writel(void * opaque, target_phys_addr_t e_phys, uint32_t value);
   10.82 +uint32_t pt_ioport_readb(void *opaque, uint32_t addr);
   10.83 +uint32_t pt_ioport_readw(void *opaque, uint32_t addr);
   10.84 +uint32_t pt_ioport_readl(void *opaque, uint32_t addr);
   10.85 +void  pt_ioport_writeb(void *opaque, uint32_t addr, uint32_t value);
   10.86 +void  pt_ioport_writew(void *opaque, uint32_t addr, uint32_t value);
   10.87 +void  pt_ioport_writel(void *opaque, uint32_t addr, uint32_t value);
   10.88 +
   10.89 +/* PIO/MMIO mapping functions (access resources through the hypervisor) */
   10.90 +void pt_ioport_map_hypervisor(PCIDevice *pci_dev, int i, 
   10.91 +                              uint32_t addr, uint32_t size, int type);
   10.92 +void pt_iomem_map_hypervisor(PCIDevice *d, int i,
   10.93 +                             uint32_t e_phys, uint32_t e_size, int type);
   10.94 +/* PIO/MMIO mapping functions (access resources through the device model) */
   10.95 +void pt_ioport_map_dm(PCIDevice *pci_dev, int i, 
   10.96 +                      uint32_t addr, uint32_t size, int type);
   10.97 +void pt_iomem_map_dm(PCIDevice *d, int i,
   10.98 +                     uint32_t e_phys, uint32_t e_size, int type);
   10.99 +
  10.100 +/* Legacy registration functions */
  10.101 +int register_pt_legacy_pio_region_hypervisor(uint32_t pio_start, uint32_t length, uint8_t do_logging);
  10.102 +int register_pt_legacy_mmio_region_hypervisor(uint32_t mmio_addr, uint32_t length, uint8_t do_logging);
  10.103 +int register_pt_legacy_pio_region_dm(uint32_t pio_start, uint32_t length, uint8_t do_logging);
  10.104 +int register_pt_legacy_mmio_region_dm(uint32_t mmio_addr, uint32_t length, uint8_t do_logging);
  10.105 +int pt_init_mmio_access_dm(void);
  10.106 +
  10.107 +/* Pass-through PCI device registration on the e_bus */
  10.108 +int pt_register_region_hypervisor(pci_phys_dev_t * phys_dev, pt_dev_t * pci_dev, int i);
  10.109 +int pt_register_region_dm(pci_phys_dev_t * phys_dev, pt_dev_t * pci_dev, int i);
  10.110 +pt_dev_t * register_real_device(PCIBus * e_bus, const char * e_dev_name, int e_devfn, 
  10.111 +                                            uint8_t r_bus, uint8_t r_dev, uint8_t r_func, uint32_t machine_irq,
  10.112 +                                            uint8_t * config, uint32_t config_len);
  10.113 +
  10.114 +#if defined ( PT_USE_DM_ACCESS )
  10.115 +#define pt_init_mmio_access pt_init_mmio_access_dm
  10.116 +#define pt_ioport_map pt_ioport_map_dm
  10.117 +#define pt_iomem_map pt_iomem_map_dm
  10.118 +#define pt_register_region pt_register_region_dm
  10.119 +#define register_pt_legacy_pio_region register_pt_legacy_pio_region_dm
  10.120 +#define register_pt_legacy_mmio_region register_pt_legacy_mmio_region_dm
  10.121 +#else
  10.122 +#define pt_init_mmio_access(args...) (0)
  10.123 +#define pt_ioport_map pt_ioport_map_hypervisor
  10.124 +#define pt_iomem_map pt_iomem_map_hypervisor
  10.125 +#define pt_register_region pt_register_region_hypervisor
  10.126 +#define register_pt_legacy_pio_region register_pt_legacy_pio_region_hypervisor
  10.127 +#define register_pt_legacy_mmio_region register_pt_legacy_mmio_region_hypervisor
  10.128 +#endif
  10.129 +
  10.130 +int pt_init(PCIBus * e_bus, char * direct_pci);
  10.131 +
  10.132 +#endif /* __PASSTHROUGH_H__ */
  10.133 +
    11.1 --- a/tools/ioemu/hw/pc.c	Tue Jul 31 12:36:34 2007 -0700
    11.2 +++ b/tools/ioemu/hw/pc.c	Mon Aug 13 17:49:00 2007 -0400
    11.3 @@ -480,6 +480,7 @@ static void pc_init1(uint64_t ram_size, 
    11.4      int piix3_devfn = -1;
    11.5      CPUState *env;
    11.6      NICInfo *nd;
    11.7 +    int rc;
    11.8  
    11.9      linux_boot = (kernel_filename != NULL);
   11.10  
   11.11 @@ -665,6 +666,17 @@ static void pc_init1(uint64_t ram_size, 
   11.12          }
   11.13      }
   11.14  
   11.15 +    /* Pass-through Initialization */
   11.16 +    if ( pci_enabled && direct_pci )
   11.17 +    {
   11.18 +        rc = pt_init(pci_bus, direct_pci); 
   11.19 +        if ( rc < 0 )
   11.20 +        {
   11.21 +            fprintf(logfile, "Error: Initialization failed for pass-through devices\n");
   11.22 +            exit(1);
   11.23 +        }
   11.24 +    }
   11.25 +
   11.26      rtc_state = rtc_init(0x70, 8);
   11.27  
   11.28      register_ioport_read(0x92, 1, 1, ioport92_read, NULL);
   11.29 @@ -751,9 +763,6 @@ static void pc_init1(uint64_t ram_size, 
   11.30          usb_uhci_init(pci_bus, piix3_devfn + (acpi_enabled ? 3 : 2));
   11.31      }
   11.32  
   11.33 -    if (pci_enabled && direct_pci)
   11.34 -        dpci_init(pci_bus, direct_pci);
   11.35 -    
   11.36  #ifndef CONFIG_DM
   11.37      if (pci_enabled && acpi_enabled) {
   11.38          uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
    12.1 --- a/tools/ioemu/hw/pci.c	Tue Jul 31 12:36:34 2007 -0700
    12.2 +++ b/tools/ioemu/hw/pci.c	Mon Aug 13 17:49:00 2007 -0400
    12.3 @@ -151,9 +151,7 @@ void pci_register_io_region(PCIDevice *p
    12.4      } else {
    12.5          addr = 0x10 + region_num * 4;
    12.6      }
    12.7 -
    12.8 -    if ((map_func != dpci_ioport_map) && (map_func != dpci_mmio_map))
    12.9 -        *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
   12.10 +    *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
   12.11  }
   12.12  
   12.13  target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/tools/ioemu/pt-libpci/Makefile	Mon Aug 13 17:49:00 2007 -0400
    13.3 @@ -0,0 +1,32 @@
    13.4 +# source files.
    13.5 +SRC = pt_libpci.c pt_pci_access.c pt_pci_probe.c pt_pci_tree.c pt_util.c access.c sysfs.c
    13.6 +VPATH += lib2.2.6/
    13.7 +
    13.8 +OBJ = $(SRC:.c=.o)
    13.9 +
   13.10 +OUT = pt_libpci.a
   13.11 +
   13.12 +# include directories
   13.13 +INCLUDES = -I.
   13.14 +
   13.15 +#defines
   13.16 +DEFINES = -DPT_LIBPCI
   13.17 +
   13.18 +# C compiler flags 
   13.19 +CCFLAGS = -O2 
   13.20 +
   13.21 +# compiler
   13.22 +CCC = gcc
   13.23 +
   13.24 +$(OUT): $(OBJ)
   13.25 +	ar rcs $(OUT) $(OBJ)
   13.26 +	ranlib $@
   13.27 +
   13.28 +%.o : %.c
   13.29 +	$(CCC) $(CCFLAGS) $(INCLUDES) $(DEFINES) -c $< -o $@
   13.30 +
   13.31 +lspci: $(OUT)
   13.32 +	$(CCC) $(INCLUDES) $(CCFLAGS) $(DEFINES) lspci.c pt_libpci.a -o lspci
   13.33 +
   13.34 +.PHONY clean:
   13.35 +	rm -f $(OBJ) $(OUT) lspci
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/.gitignore	Mon Aug 13 17:49:00 2007 -0400
    14.3 @@ -0,0 +1,3 @@
    14.4 +config.h
    14.5 +config.mk
    14.6 +libpci.pc
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/Makefile	Mon Aug 13 17:49:00 2007 -0400
    15.3 @@ -0,0 +1,85 @@
    15.4 +# Makefile for The PCI Library
    15.5 +# (c) 1999 Martin Mares <mj@ucw.cz>
    15.6 +
    15.7 +include config.mk
    15.8 +
    15.9 +OBJS=access.o generic.o dump.o names.o filter.o
   15.10 +INCL=internal.h pci.h config.h header.h sysdep.h types.h
   15.11 +
   15.12 +PCILIB=libpci.a
   15.13 +PCILIBPC=libpci.pc
   15.14 +
   15.15 +ifdef PCI_HAVE_PM_LINUX_SYSFS
   15.16 +OBJS += sysfs.o
   15.17 +endif
   15.18 +
   15.19 +ifdef PCI_HAVE_PM_LINUX_PROC
   15.20 +OBJS += proc.o
   15.21 +endif
   15.22 +
   15.23 +ifdef PCI_HAVE_PM_INTEL_CONF
   15.24 +OBJS += i386-ports.o
   15.25 +endif
   15.26 +
   15.27 +ifdef PCI_HAVE_PM_DUMP
   15.28 +OBJS += dump.o
   15.29 +endif
   15.30 +
   15.31 +ifdef PCI_HAVE_PM_SYSCALLS
   15.32 +OBJS += syscalls.o
   15.33 +endif
   15.34 +
   15.35 +ifdef PCI_HAVE_PM_FBSD_DEVICE
   15.36 +OBJS += fbsd-device.o
   15.37 +CFLAGS += -I/usr/src/sys
   15.38 +ifdef FREEBSD_SYS
   15.39 +CFLAGS += -I${FREEBSD_SYS}
   15.40 +endif
   15.41 +endif
   15.42 +
   15.43 +ifdef PCI_HAVE_PM_OBSD_DEVICE
   15.44 +OBJS += obsd-device.o
   15.45 +endif
   15.46 +
   15.47 +ifdef PCI_HAVE_PM_AIX_DEVICE
   15.48 +OBJS += aix-device.o
   15.49 +endif
   15.50 +
   15.51 +ifdef PCI_HAVE_PM_NBSD_LIBPCI
   15.52 +OBJS += nbsd-libpci.o
   15.53 +PCILIB=libpciutils.a
   15.54 +endif
   15.55 +
   15.56 +all: $(PCILIB) $(PCILIBPC)
   15.57 +
   15.58 +$(PCILIB): $(OBJS)
   15.59 +	rm -f $@
   15.60 +	ar rcs $@ $^
   15.61 +	ranlib $@
   15.62 +
   15.63 +$(PCILIBPC): $(PCILIBPC).in
   15.64 +	sed <$< >$@ -e 's,@PREFIX@,$(PREFIX),' \
   15.65 +		-e 's,@INCDIR@,$(INCDIR),' \
   15.66 +		-e 's,@LIBDIR@,$(LIBDIR),' \
   15.67 +		-e 's,@IDSDIR@,$(IDSDIR),' \
   15.68 +		-e 's,@VERSION@,$(VERSION),' \
   15.69 +		-e 's,@LIBZ@,$(LIBZ),'
   15.70 +
   15.71 +access.o: access.c $(INCL)
   15.72 +i386-ports.o: i386-ports.c $(INCL) i386-io-hurd.h i386-io-linux.h i386-io-sunos.h
   15.73 +proc.o: proc.c $(INCL) pread.h
   15.74 +sysfs.o: sysfs.c $(INCL) pread.h
   15.75 +generic.o: generic.c $(INCL)
   15.76 +syscalls.o: syscalls.c $(INCL)
   15.77 +obsd-device.o: obsd-device.c $(INCL)
   15.78 +fbsd-device.o: fbsd-device.c $(INCL)
   15.79 +aix-device.o: aix-device.c $(INCL)
   15.80 +dump.o: dump.c $(INCL)
   15.81 +names.o: names.c $(INCL)
   15.82 +filter.o: filter.c $(INCL)
   15.83 +nbsd-libpci.o: nbsd-libpci.c $(INCL)
   15.84 +
   15.85 +example: example.c $(PCILIB)
   15.86 +
   15.87 +clean:
   15.88 +	rm -f $(PCILIB) $(PCILIBPC) $(OBJS) example config.h config.mk
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/access.c	Mon Aug 13 17:49:00 2007 -0400
    16.3 @@ -0,0 +1,345 @@
    16.4 +/*
    16.5 + *	The PCI Library -- User Access
    16.6 + *
    16.7 + *	Copyright (c) 1997--2003 Martin Mares <mj@ucw.cz>
    16.8 + *
    16.9 + *	Can be freely distributed and used under the terms of the GNU GPL.
   16.10 + */
   16.11 +
   16.12 +#include <stdio.h>
   16.13 +#include <stdlib.h>
   16.14 +#include <stdarg.h>
   16.15 +#include <string.h>
   16.16 +
   16.17 +#include "internal.h"
   16.18 +
   16.19 +static struct pci_methods *pci_methods[PCI_ACCESS_MAX] = {
   16.20 +  NULL,
   16.21 +#ifdef PCI_HAVE_PM_LINUX_SYSFS
   16.22 +  &pm_linux_sysfs,
   16.23 +#else
   16.24 +  NULL,
   16.25 +#endif
   16.26 +#ifdef PCI_HAVE_PM_LINUX_PROC
   16.27 +  &pm_linux_proc,
   16.28 +#else
   16.29 +  NULL,
   16.30 +#endif
   16.31 +#ifdef PCI_HAVE_PM_INTEL_CONF
   16.32 +  &pm_intel_conf1,
   16.33 +  &pm_intel_conf2,
   16.34 +#else
   16.35 +  NULL,
   16.36 +  NULL,
   16.37 +#endif
   16.38 +#ifdef PCI_HAVE_PM_FBSD_DEVICE
   16.39 +  &pm_fbsd_device,
   16.40 +#else
   16.41 +  NULL,
   16.42 +#endif
   16.43 +#ifdef PCI_HAVE_PM_AIX_DEVICE
   16.44 +  &pm_aix_device,
   16.45 +#else
   16.46 +  NULL,
   16.47 +#endif
   16.48 +#ifdef PCI_HAVE_PM_NBSD_LIBPCI
   16.49 +  &pm_nbsd_libpci,
   16.50 +#else
   16.51 +  NULL,
   16.52 +#endif
   16.53 +#ifdef PCI_HAVE_PM_OBSD_DEVICE
   16.54 +  &pm_obsd_device,
   16.55 +#else
   16.56 +  NULL,
   16.57 +#endif
   16.58 +#ifdef PCI_HAVE_PM_DUMP
   16.59 +  &pm_dump,
   16.60 +#else
   16.61 +  NULL,
   16.62 +#endif
   16.63 +};
   16.64 +
   16.65 +struct pci_access *
   16.66 +pci_alloc(void)
   16.67 +{
   16.68 +  struct pci_access *a = malloc(sizeof(struct pci_access));
   16.69 +  int i;
   16.70 +
   16.71 +  memset(a, 0, sizeof(*a));
   16.72 +#ifndef PT_LIBPCI  
   16.73 +  pci_set_name_list_path(a, PCI_PATH_IDS_DIR "/" PCI_IDS, 0);
   16.74 +  for(i=0; i<PCI_ACCESS_MAX; i++)
   16.75 +    if (pci_methods[i] && pci_methods[i]->config)
   16.76 +      pci_methods[i]->config(a);
   16.77 +#endif
   16.78 +
   16.79 +  return a;
   16.80 +}
   16.81 +
   16.82 +void *
   16.83 +pci_malloc(struct pci_access *a, int size)
   16.84 +{
   16.85 +  void *x = malloc(size);
   16.86 +
   16.87 +  if (!x)
   16.88 +    a->error("Out of memory (allocation of %d bytes failed)", size);
   16.89 +  return x;
   16.90 +}
   16.91 +
   16.92 +void
   16.93 +pci_mfree(void *x)
   16.94 +{
   16.95 +  if (x)
   16.96 +    free(x);
   16.97 +}
   16.98 +
   16.99 +static void
  16.100 +pci_generic_error(char *msg, ...)
  16.101 +{
  16.102 +  va_list args;
  16.103 +
  16.104 +  va_start(args, msg);
  16.105 +  fputs("pcilib: ", stderr);
  16.106 +  vfprintf(stderr, msg, args);
  16.107 +  fputc('\n', stderr);
  16.108 +  exit(1);
  16.109 +}
  16.110 +
  16.111 +static void
  16.112 +pci_generic_warn(char *msg, ...)
  16.113 +{
  16.114 +  va_list args;
  16.115 +
  16.116 +  va_start(args, msg);
  16.117 +  fputs("pcilib: ", stderr);
  16.118 +  vfprintf(stderr, msg, args);
  16.119 +  fputc('\n', stderr);
  16.120 +}
  16.121 +
  16.122 +static void
  16.123 +pci_generic_debug(char *msg, ...)
  16.124 +{
  16.125 +  va_list args;
  16.126 +
  16.127 +  va_start(args, msg);
  16.128 +  vfprintf(stdout, msg, args);
  16.129 +  va_end(args);
  16.130 +}
  16.131 +
  16.132 +static void
  16.133 +pci_null_debug(char *msg UNUSED, ...)
  16.134 +{
  16.135 +}
  16.136 +
  16.137 +void
  16.138 +pci_init(struct pci_access *a)
  16.139 +{
  16.140 +  if (!a->error)
  16.141 +    a->error = pci_generic_error;
  16.142 +  if (!a->warning)
  16.143 +    a->warning = pci_generic_warn;
  16.144 +  if (!a->debug)
  16.145 +    a->debug = pci_generic_debug;
  16.146 +  if (!a->debugging)
  16.147 +    a->debug = pci_null_debug;
  16.148 +
  16.149 +  if (a->method)
  16.150 +    {
  16.151 +      if (a->method >= PCI_ACCESS_MAX || !pci_methods[a->method])
  16.152 +	a->error("This access method is not supported.");
  16.153 +      a->methods = pci_methods[a->method];
  16.154 +    }
  16.155 +  else
  16.156 +    {
  16.157 +      unsigned int i;
  16.158 +      for(i=0; i<PCI_ACCESS_MAX; i++)
  16.159 +	if (pci_methods[i])
  16.160 +	  {
  16.161 +	    a->debug("Trying method %d...", i);
  16.162 +	    if (pci_methods[i]->detect(a))
  16.163 +	      {
  16.164 +		a->debug("...OK\n");
  16.165 +		a->methods = pci_methods[i];
  16.166 +		a->method = i;
  16.167 +		break;
  16.168 +	      }
  16.169 +	    a->debug("...No.\n");
  16.170 +	  }
  16.171 +      if (!a->methods)
  16.172 +	a->error("Cannot find any working access method.");
  16.173 +    }
  16.174 +  a->debug("Decided to use %s\n", a->methods->name);
  16.175 +  a->methods->init(a);
  16.176 +}
  16.177 +
  16.178 +void
  16.179 +pci_cleanup(struct pci_access *a)
  16.180 +{
  16.181 +  struct pci_dev *d, *e;
  16.182 +
  16.183 +  for(d=a->devices; d; d=e)
  16.184 +    {
  16.185 +      e = d->next;
  16.186 +      pci_free_dev(d);
  16.187 +    }
  16.188 +  if (a->methods)
  16.189 +    a->methods->cleanup(a);
  16.190 +#ifndef PT_LIBPCI
  16.191 +  pci_free_name_list(a);
  16.192 +  pci_set_name_list_path(a, NULL, 0);
  16.193 +#endif
  16.194 +  pci_mfree(a);
  16.195 +}
  16.196 +
  16.197 +void
  16.198 +pci_scan_bus(struct pci_access *a)
  16.199 +{
  16.200 +  a->methods->scan(a);
  16.201 +}
  16.202 +
  16.203 +struct pci_dev *
  16.204 +pci_alloc_dev(struct pci_access *a)
  16.205 +{
  16.206 +  struct pci_dev *d = pci_malloc(a, sizeof(struct pci_dev));
  16.207 +
  16.208 +  memset(d, 0, sizeof(*d));
  16.209 +  d->access = a;
  16.210 +  d->methods = a->methods;
  16.211 +  d->hdrtype = -1;
  16.212 +  if (d->methods->init_dev)
  16.213 +    d->methods->init_dev(d);
  16.214 +  return d;
  16.215 +}
  16.216 +
  16.217 +int
  16.218 +pci_link_dev(struct pci_access *a, struct pci_dev *d)
  16.219 +{
  16.220 +  d->next = a->devices;
  16.221 +  a->devices = d;
  16.222 +
  16.223 +  return 1;
  16.224 +}
  16.225 +
  16.226 +struct pci_dev *
  16.227 +pci_get_dev(struct pci_access *a, int domain, int bus, int dev, int func)
  16.228 +{
  16.229 +  struct pci_dev *d = pci_alloc_dev(a);
  16.230 +
  16.231 +  d->domain = domain;
  16.232 +  d->bus = bus;
  16.233 +  d->dev = dev;
  16.234 +  d->func = func;
  16.235 +  return d;
  16.236 +}
  16.237 +
  16.238 +void pci_free_dev(struct pci_dev *d)
  16.239 +{
  16.240 +  if (d->methods->cleanup_dev)
  16.241 +    d->methods->cleanup_dev(d);
  16.242 +  pci_mfree(d);
  16.243 +}
  16.244 +
  16.245 +#ifndef PT_LIBPCI
  16.246 +static inline void
  16.247 +pci_read_data(struct pci_dev *d, void *buf, int pos, int len)
  16.248 +{
  16.249 +  if (pos & (len-1))
  16.250 +    d->access->error("Unaligned read: pos=%02x, len=%d", pos, len);
  16.251 +  if (pos + len <= d->cache_len)
  16.252 +    memcpy(buf, d->cache + pos, len);
  16.253 +  else if (!d->methods->read(d, pos, buf, len))
  16.254 +    memset(buf, 0xff, len);
  16.255 +}
  16.256 +
  16.257 +byte
  16.258 +pci_read_byte(struct pci_dev *d, int pos)
  16.259 +{
  16.260 +  byte buf;
  16.261 +  pci_read_data(d, &buf, pos, 1);
  16.262 +  return buf;
  16.263 +}
  16.264 +
  16.265 +word
  16.266 +pci_read_word(struct pci_dev *d, int pos)
  16.267 +{
  16.268 +  word buf;
  16.269 +  pci_read_data(d, &buf, pos, 2);
  16.270 +  return le16_to_cpu(buf);
  16.271 +}
  16.272 +
  16.273 +u32
  16.274 +pci_read_long(struct pci_dev *d, int pos)
  16.275 +{
  16.276 +  u32 buf;
  16.277 +  pci_read_data(d, &buf, pos, 4);
  16.278 +  return le32_to_cpu(buf);
  16.279 +}
  16.280 +
  16.281 +int
  16.282 +pci_read_block(struct pci_dev *d, int pos, byte *buf, int len)
  16.283 +{
  16.284 +  return d->methods->read(d, pos, buf, len);
  16.285 +}
  16.286 +
  16.287 +static inline int
  16.288 +pci_write_data(struct pci_dev *d, void *buf, int pos, int len)
  16.289 +{
  16.290 +  if (pos & (len-1))
  16.291 +    d->access->error("Unaligned write: pos=%02x,len=%d", pos, len);
  16.292 +  if (pos + len <= d->cache_len)
  16.293 +    memcpy(d->cache + pos, buf, len);
  16.294 +  return d->methods->write(d, pos, buf, len);
  16.295 +}
  16.296 +
  16.297 +int
  16.298 +pci_write_byte(struct pci_dev *d, int pos, byte data)
  16.299 +{
  16.300 +  return pci_write_data(d, &data, pos, 1);
  16.301 +}
  16.302 +
  16.303 +int
  16.304 +pci_write_word(struct pci_dev *d, int pos, word data)
  16.305 +{
  16.306 +  word buf = cpu_to_le16(data);
  16.307 +  return pci_write_data(d, &buf, pos, 2);
  16.308 +}
  16.309 +
  16.310 +int
  16.311 +pci_write_long(struct pci_dev *d, int pos, u32 data)
  16.312 +{
  16.313 +  u32 buf = cpu_to_le32(data);
  16.314 +  return pci_write_data(d, &buf, pos, 4);
  16.315 +}
  16.316 +
  16.317 +int
  16.318 +pci_write_block(struct pci_dev *d, int pos, byte *buf, int len)
  16.319 +{
  16.320 +  if (pos < d->cache_len)
  16.321 +    {
  16.322 +      int l = (pos + len >= d->cache_len) ? (d->cache_len - pos) : len;
  16.323 +      memcpy(d->cache + pos, buf, l);
  16.324 +    }
  16.325 +  return d->methods->write(d, pos, buf, len);
  16.326 +}
  16.327 +
  16.328 +#endif /* !PT_LIBPCI */
  16.329 +
  16.330 +int
  16.331 +pci_fill_info(struct pci_dev *d, int flags)
  16.332 +{
  16.333 +  if (flags & PCI_FILL_RESCAN)
  16.334 +    {
  16.335 +      flags &= ~PCI_FILL_RESCAN;
  16.336 +      d->known_fields = 0;
  16.337 +    }
  16.338 +  if (flags & ~d->known_fields)
  16.339 +    d->known_fields |= d->methods->fill_info(d, flags & ~d->known_fields);
  16.340 +  return d->known_fields;
  16.341 +}
  16.342 +
  16.343 +void
  16.344 +pci_setup_cache(struct pci_dev *d, byte *cache, int len)
  16.345 +{
  16.346 +  d->cache = cache;
  16.347 +  d->cache_len = len;
  16.348 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/aix-device.c	Mon Aug 13 17:49:00 2007 -0400
    17.3 @@ -0,0 +1,279 @@
    17.4 +/*
    17.5 + *	The PCI Library -- AIX /dev/pci[0-n] access
    17.6 + *
    17.7 + *	Copyright (c) 1999 Jari Kirma <kirma@cs.hut.fi>
    17.8 + *
    17.9 + *	Can be freely distributed and used under the terms of the GNU GPL.
   17.10 + */
   17.11 +
   17.12 +/*
   17.13 + *      Read functionality of this driver is briefly tested, and seems
   17.14 + *      to supply basic information correctly, but I promise no more.
   17.15 + */
   17.16 +
   17.17 +#include <stdio.h>
   17.18 +#include <stdlib.h>
   17.19 +#include <string.h>
   17.20 +#include <unistd.h>
   17.21 +#include <fcntl.h>
   17.22 +
   17.23 +#include <sys/types.h>
   17.24 +#include <sys/mdio.h>
   17.25 +
   17.26 +#include "internal.h"
   17.27 +
   17.28 +#define AIX_LSDEV_CMD "/usr/sbin/lsdev -C -c bus -t pci\\* -S available -F name"
   17.29 +#define AIX_ODMGET_CMD \
   17.30 +  "/usr/bin/odmget -q 'name=%s and attribute=bus_number' CuAt | \
   17.31 +   /usr/bin/awk '$1 == \"value\" { print $3 }'"
   17.32 +
   17.33 +
   17.34 +/* AIX PCI bus device information */
   17.35 +
   17.36 +typedef struct aix_pci_bus {
   17.37 +    char *bus_name;
   17.38 +    int   bus_number;
   17.39 +    int   bus_fd;
   17.40 +} aix_pci_bus;
   17.41 +
   17.42 +#define PCI_BUS_MAX 16		/* arbitrary choice */
   17.43 +static aix_pci_bus pci_buses[PCI_BUS_MAX];
   17.44 +static int pci_bus_count = 0;
   17.45 +
   17.46 +
   17.47 +/* Utility Routines */
   17.48 +
   17.49 +static aix_pci_bus *
   17.50 +aix_find_bus(struct pci_access *a, int bus_number)
   17.51 +{
   17.52 +  int i;
   17.53 +
   17.54 +  for (i = 0; i < pci_bus_count; i++)
   17.55 +    {
   17.56 +      if (pci_buses[i].bus_number == bus_number)
   17.57 +        {
   17.58 +          return &pci_buses[i];
   17.59 +        }
   17.60 +    }
   17.61 +
   17.62 +  a->error("aix_find_bus: bus number %d not found", bus_number);
   17.63 +}
   17.64 +
   17.65 +static int
   17.66 +aix_bus_open(struct pci_access *a, int bus_number)
   17.67 +{
   17.68 +  aix_pci_bus *bp = aix_find_bus(a, bus_number);
   17.69 +
   17.70 +  if (bp->bus_fd < 0)
   17.71 +    {
   17.72 +      char devbuf[256];
   17.73 +      int mode = a->writeable ? O_RDWR : O_RDONLY;
   17.74 +
   17.75 +      snprintf(devbuf, sizeof (devbuf), "/dev/%s", bp->bus_name);
   17.76 +      bp->bus_fd = open(devbuf, mode, 0);
   17.77 +      if (bp->bus_fd < 0)
   17.78 +        {
   17.79 +          a->error("aix_open_bus: %s open failed", devbuf);
   17.80 +        }
   17.81 +    }
   17.82 +
   17.83 +  return bp->bus_fd;
   17.84 +}
   17.85 +
   17.86 +static int
   17.87 +aix_bus_number(char *name)
   17.88 +{
   17.89 +  int bus_number;
   17.90 +  FILE *odmget_pipe;
   17.91 +  char command[256];
   17.92 +  char buf[256];
   17.93 +  char *bp;
   17.94 +  char *ep;
   17.95 +
   17.96 +  snprintf(command, sizeof (command), AIX_ODMGET_CMD, name);
   17.97 +  odmget_pipe = popen(command, "r");
   17.98 +  if (odmget_pipe == NULL)
   17.99 +    {
  17.100 +      /* popen failed */
  17.101 +      return -1;
  17.102 +    }
  17.103 +
  17.104 +  if (fgets(buf, sizeof (buf) - 1, odmget_pipe) != NULL)
  17.105 +    {
  17.106 +      bp = buf + 1;	/* skip leading double quote */
  17.107 +      bus_number = strtol(bp, &ep, 0);
  17.108 +      if (bp == ep)
  17.109 +        {
  17.110 +          /* strtol failed */
  17.111 +          bus_number = -1;
  17.112 +        }
  17.113 +    }
  17.114 +  else
  17.115 +    {
  17.116 +      /* first PCI bus_number is not recorded in ODM CuAt; default to 0 */
  17.117 +      bus_number = 0;
  17.118 +    }
  17.119 +
  17.120 +  (void) pclose(odmget_pipe);
  17.121 +
  17.122 +  return bus_number;
  17.123 +}
  17.124 +
  17.125 +
  17.126 +/* Method entries */
  17.127 +
  17.128 +static void
  17.129 +aix_config(struct pci_access *a)
  17.130 +{
  17.131 +  a->method_params[PCI_ACCESS_AIX_DEVICE] = NULL;
  17.132 +}
  17.133 +
  17.134 +static int
  17.135 +aix_detect(struct pci_access *a)
  17.136 +{
  17.137 +  int len;
  17.138 +  int mode = a->writeable ? W_OK : R_OK;
  17.139 +  char *command = AIX_LSDEV_CMD;
  17.140 +  FILE *lsdev_pipe;
  17.141 +  char buf[256];
  17.142 +  char *name;
  17.143 +
  17.144 +  lsdev_pipe = popen(command, "r");
  17.145 +  if (lsdev_pipe == NULL)
  17.146 +    {
  17.147 +      a->error("aix_config: popen(\"%s\") failed", command);
  17.148 +    }
  17.149 +
  17.150 +  while (fgets(buf, sizeof (buf) - 1, lsdev_pipe) != NULL)
  17.151 +    {
  17.152 +      len = strlen(buf);
  17.153 +      while (buf[len-1] == '\n' || buf[len-1] == '\r')
  17.154 +          len--;
  17.155 +      buf[len] = '\0';				/* clobber the newline */
  17.156 +
  17.157 +      name = (char *) pci_malloc(a, len + 1);
  17.158 +      strcpy(name, buf);
  17.159 +      pci_buses[pci_bus_count].bus_name = name;
  17.160 +      pci_buses[pci_bus_count].bus_number = 0;
  17.161 +      pci_buses[pci_bus_count].bus_fd = -1;
  17.162 +      if (!pci_bus_count)
  17.163 +          a->debug("...using %s", name);
  17.164 +      else
  17.165 +          a->debug(", %s", name);
  17.166 +      pci_bus_count++;
  17.167 +      if (pci_bus_count >= PCI_BUS_MAX)
  17.168 +          break;
  17.169 +    }
  17.170 +
  17.171 +  (void) pclose(lsdev_pipe);
  17.172 +
  17.173 +  return pci_bus_count;
  17.174 +}
  17.175 +
  17.176 +static void
  17.177 +aix_init(struct pci_access *a)
  17.178 +{
  17.179 +  char *name;
  17.180 +  int i;
  17.181 +
  17.182 +  for (i = 0; i < pci_bus_count; i++)
  17.183 +    {
  17.184 +      name = pci_buses[i].bus_name;
  17.185 +      pci_buses[i].bus_number = aix_bus_number(name);
  17.186 +    }
  17.187 +}
  17.188 +
  17.189 +static void
  17.190 +aix_cleanup(struct pci_access *a)
  17.191 +{
  17.192 +  aix_pci_bus *bp;
  17.193 +
  17.194 +  while (pci_bus_count-- > 0)
  17.195 +    {
  17.196 +      bp = &pci_buses[pci_bus_count];
  17.197 +      (void) free(bp->bus_name);
  17.198 +      if (bp->bus_fd >= 0)
  17.199 +        {
  17.200 +          (void) close(bp->bus_fd);
  17.201 +          bp->bus_fd = -1;
  17.202 +        }
  17.203 +    }
  17.204 +}
  17.205 +
  17.206 +void
  17.207 +aix_scan(struct pci_access *a)
  17.208 +{
  17.209 +  int i;
  17.210 +  int bus_number;
  17.211 +  byte busmap[256];
  17.212 +
  17.213 +  memset(busmap, 0, sizeof(busmap));
  17.214 +  for (i = 0; i < pci_bus_count; i++)
  17.215 +    {
  17.216 +      bus_number = pci_buses[i].bus_number;
  17.217 +      if (!busmap[bus_number])
  17.218 +        {
  17.219 +          pci_generic_scan_bus(a, busmap, bus_number);
  17.220 +        }
  17.221 +    }
  17.222 +}
  17.223 +
  17.224 +static int
  17.225 +aix_read(struct pci_dev *d, int pos, byte *buf, int len)
  17.226 +{
  17.227 +  struct mdio mdio;
  17.228 +  int fd;
  17.229 +
  17.230 +  if (pos + len > 256)
  17.231 +    return 0;
  17.232 +
  17.233 +  fd = aix_bus_open(d->access, d->bus);
  17.234 +  mdio.md_addr = (ulong) pos;
  17.235 +  mdio.md_size = len;
  17.236 +  mdio.md_incr = MV_BYTE;
  17.237 +  mdio.md_data = (char *) buf;
  17.238 +  mdio.md_sla = PCI_DEVFN(d->dev, d->func);
  17.239 +
  17.240 +  if (ioctl(fd, MIOPCFGET, &mdio) < 0)
  17.241 +    d->access->error("aix_read: ioctl(MIOPCFGET) failed");
  17.242 +
  17.243 +  return 1;
  17.244 +}
  17.245 +
  17.246 +static int
  17.247 +aix_write(struct pci_dev *d, int pos, byte *buf, int len)
  17.248 +{
  17.249 +  struct mdio mdio;
  17.250 +  int fd;
  17.251 +
  17.252 +  if (pos + len > 256)
  17.253 +    return 0;
  17.254 +
  17.255 +  fd = aix_bus_open(d->access, d->bus);
  17.256 +  mdio.md_addr = (ulong) pos;
  17.257 +  mdio.md_size = len;
  17.258 +  mdio.md_incr = MV_BYTE;
  17.259 +  mdio.md_data = (char *) buf;
  17.260 +  mdio.md_sla = PCI_DEVFN(d->dev, d->func);
  17.261 +
  17.262 +  if (ioctl(fd, MIOPCFPUT, &mdio) < 0)
  17.263 +    {
  17.264 +      d->access->error("aix_write: ioctl(MIOPCFPUT) failed");
  17.265 +    }
  17.266 +
  17.267 +  return 1;
  17.268 +}
  17.269 +
  17.270 +struct pci_methods pm_aix_device = {
  17.271 +  "AIX-device",
  17.272 +  aix_config,
  17.273 +  aix_detect,
  17.274 +  aix_init,
  17.275 +  aix_cleanup,
  17.276 +  aix_scan,
  17.277 +  pci_generic_fill_info,
  17.278 +  aix_read,
  17.279 +  aix_write,
  17.280 +  NULL,                                 /* dev_init */
  17.281 +  NULL                                  /* dev_cleanup */
  17.282 +};
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/config.h	Mon Aug 13 17:49:00 2007 -0400
    18.3 @@ -0,0 +1,14 @@
    18.4 +#define PCI_ARCH_I386
    18.5 +#define PCI_OS_LINUX
    18.6 +#define PCI_HAVE_PM_LINUX_SYSFS
    18.7 +//#define PCI_HAVE_PM_LINUX_PROC
    18.8 +#define PCI_HAVE_LINUX_BYTEORDER_H
    18.9 +//#define PCI_PATH_PROC_BUS_PCI "/proc/bus/pci"
   18.10 +#define PCI_PATH_SYS_BUS_PCI "/sys/bus/pci"
   18.11 +//#define PCI_HAVE_PM_INTEL_CONF
   18.12 +#define PCI_HAVE_64BIT_ADDRESS
   18.13 +//#define PCI_HAVE_PM_DUMP
   18.14 +#define PCI_COMPRESSED_IDS
   18.15 +#define PCI_IDS "pci.ids.gz"
   18.16 +#define PCI_PATH_IDS_DIR "/usr/share"
   18.17 +#define PCILIB_VERSION "0.0"
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/config.mk	Mon Aug 13 17:49:00 2007 -0400
    19.3 @@ -0,0 +1,16 @@
    19.4 +LIBZ=-lz
    19.5 +LDFLAGS+=$(LIBZ)
    19.6 +PCI_ARCH_I386=1
    19.7 +PCI_OS_LINUX=1
    19.8 +PCI_HAVE_PM_LINUX_SYSFS=1
    19.9 +PCI_HAVE_PM_LINUX_PROC=1
   19.10 +PCI_HAVE_LINUX_BYTEORDER_H=1
   19.11 +PCI_PATH_PROC_BUS_PCI=/proc/bus/pci
   19.12 +PCI_PATH_SYS_BUS_PCI=/sys/bus/pci
   19.13 +PCI_HAVE_PM_INTEL_CONF=1
   19.14 +PCI_HAVE_64BIT_ADDRESS=1
   19.15 +PCI_HAVE_PM_DUMP=1
   19.16 +PCI_COMPRESSED_IDS=1
   19.17 +PCI_IDS=pci.ids.gz
   19.18 +PCI_PATH_IDS_DIR=/usr/share
   19.19 +PCILIB_VERSION=0.0
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/configure	Mon Aug 13 17:49:00 2007 -0400
    20.3 @@ -0,0 +1,132 @@
    20.4 +#!/bin/sh
    20.5 +
    20.6 +echo_n() {
    20.7 +	if [ -n "$BASH" ]
    20.8 +	then
    20.9 +		echo -n "$*"
   20.10 +	else
   20.11 +		echo "$*\c"
   20.12 +	fi
   20.13 +}
   20.14 +
   20.15 +echo_n "Configuring libpci for your system..."
   20.16 +idsdir=${1:-/usr/share}
   20.17 +version=${2:-0.0}
   20.18 +sys=`uname -s`
   20.19 +rel=`uname -r`
   20.20 +if [ "$sys" = "AIX" -a -x /usr/bin/oslevel -a -x /usr/sbin/lsattr ]
   20.21 +then
   20.22 +	rel=`/usr/bin/oslevel`
   20.23 +	proc=`/usr/sbin/lsdev -C -c processor -S available -F name | head -1`
   20.24 +	cpu=`/usr/sbin/lsattr -F value -l $proc -a type | sed 's/_.*//'`
   20.25 +else
   20.26 +	cpu=`uname -m | sed 's/^i.86$/i386/;s/^sun4u$/sparc64/;s/^i86pc$/i386/'`
   20.27 +fi
   20.28 +if [ "$sys" = "GNU/kFreeBSD" ]
   20.29 +then
   20.30 +	sys=freebsd
   20.31 +fi
   20.32 +host=${3:-$cpu-$sys}
   20.33 +# CAVEAT: tr on Solaris is a bit weird and the extra [] is otherwise harmless.
   20.34 +host=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)$/\1--\2/' | tr '[A-Z]' '[a-z]'`
   20.35 +cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
   20.36 +sys=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
   20.37 +rel=${4:-$rel}
   20.38 +echo " $host $rel"
   20.39 +zlib=$5
   20.40 +
   20.41 +c=config.h
   20.42 +m=config.mk
   20.43 +echo >$c "#define PCI_ARCH_`echo $cpu | tr '[a-z]' '[A-Z]'`"
   20.44 +echo >>$c "#define PCI_OS_`echo $sys | tr '[a-z]' '[A-Z]'`"
   20.45 +rm -f $m
   20.46 +
   20.47 +echo_n "Looking for access methods..."
   20.48 +
   20.49 +case $sys in
   20.50 +	linux*)
   20.51 +		echo_n " sysfs proc"
   20.52 +		echo >>$c '#define PCI_HAVE_PM_LINUX_SYSFS'
   20.53 +		echo >>$c '#define PCI_HAVE_PM_LINUX_PROC'
   20.54 +		echo >>$c '#define PCI_HAVE_LINUX_BYTEORDER_H'
   20.55 +		echo >>$c '#define PCI_PATH_PROC_BUS_PCI "/proc/bus/pci"'
   20.56 +		echo >>$c '#define PCI_PATH_SYS_BUS_PCI "/sys/bus/pci"'
   20.57 +		case $cpu in
   20.58 +				i386)		echo_n " i386-ports"
   20.59 +						echo >>$c '#define PCI_HAVE_PM_INTEL_CONF'
   20.60 +						;;
   20.61 +		esac
   20.62 +		echo >>$c '#define PCI_HAVE_64BIT_ADDRESS'
   20.63 +		;;
   20.64 +	sunos)
   20.65 +		case $cpu in
   20.66 +				i386)		echo_n " i386-ports"
   20.67 +						echo >>$c "#define PCI_HAVE_PM_INTEL_CONF"
   20.68 +						;;
   20.69 +				*)
   20.70 +						echo " The PCI library is does not support Solaris for this architecture: $cpu"
   20.71 +						exit 1
   20.72 +						;;
   20.73 +		esac
   20.74 +		echo >>$c '#define PCI_HAVE_STDINT_H'
   20.75 +		;;
   20.76 +	freebsd)
   20.77 +		echo_n " fbsd-device"
   20.78 +		echo >>$c '#define PCI_HAVE_PM_FBSD_DEVICE'
   20.79 +		echo >>$c '#define PCI_PATH_FBSD_DEVICE "/dev/pci"'
   20.80 +		;;
   20.81 +        openbsd)
   20.82 +	        echo_n " obsd-device"
   20.83 +		echo >>$c '#define PCI_HAVE_PM_OBSD_DEVICE'
   20.84 +		echo >>$c '#define PCI_PATH_OBSD_DEVICE "/dev/pci"'
   20.85 +		;;
   20.86 +	aix)
   20.87 +		echo_n " aix-device"
   20.88 +		echo >>$c '#define PCI_HAVE_PM_AIX_DEVICE'
   20.89 +		echo >>$m 'CFLAGS=-g'
   20.90 +		echo >>$m 'INSTALL=installbsd'
   20.91 +		echo >>$m 'DIRINSTALL=mkdir -p'
   20.92 +		;;
   20.93 +	netbsd)
   20.94 +		echo_n " nbsd-libpci"
   20.95 +		echo >>$c '#define PCI_HAVE_PM_NBSD_LIBPCI'
   20.96 +		echo >>$c '#define PCI_PATH_NBSD_DEVICE "/dev/pci0"'
   20.97 +		echo >>$m 'PCILIB=lib/libpciutils.a'
   20.98 +		echo >>$m 'LDFLAGS+=-lpci'
   20.99 +		;;
  20.100 +    	gnu)
  20.101 +		echo_n " i386-ports"
  20.102 +		echo >>$c '#define PCI_HAVE_PM_INTEL_CONF'
  20.103 +		;;
  20.104 +        *)
  20.105 +		echo " Unfortunately, your OS is not supported by the PCI Library"
  20.106 +		exit 1
  20.107 +		;;
  20.108 +esac
  20.109 +
  20.110 +echo >>$c '#define PCI_HAVE_PM_DUMP'
  20.111 +echo " dump"
  20.112 +
  20.113 +echo_n "Checking for zlib support... "
  20.114 +if [ "$zlib" = yes -o "$zlib" = no ] ; then
  20.115 +	echo "$zlib (set manually)"
  20.116 +else
  20.117 +	if [ -f /usr/include/zlib.h ] ; then
  20.118 +		zlib=yes
  20.119 +	else
  20.120 +		zlib=no
  20.121 +	fi
  20.122 +	echo "$zlib (auto-detected)"
  20.123 +fi
  20.124 +if [ "$zlib" = yes ] ; then
  20.125 +	echo >>$c '#define PCI_COMPRESSED_IDS'
  20.126 +	echo >>$c '#define PCI_IDS "pci.ids.gz"'
  20.127 +	echo >>$m 'LIBZ=-lz'
  20.128 +	echo >>$m 'LDFLAGS+=$(LIBZ)'
  20.129 +else
  20.130 +	echo >>$c '#define PCI_IDS "pci.ids"'
  20.131 +fi
  20.132 +echo >>$c "#define PCI_PATH_IDS_DIR \"$idsdir\""
  20.133 +
  20.134 +echo >>$c "#define PCILIB_VERSION \"$version\""
  20.135 +sed '/"/{s/^#define \([^ ]*\) "\(.*\)"$/\1=\2/;p;d;};s/^#define \(.*\)/\1=1/' <$c >>$m
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/dump.c	Mon Aug 13 17:49:00 2007 -0400
    21.3 @@ -0,0 +1,170 @@
    21.4 +/*
    21.5 + *	The PCI Library -- Reading of Bus Dumps
    21.6 + *
    21.7 + *	Copyright (c) 1997--2005 Martin Mares <mj@ucw.cz>
    21.8 + *
    21.9 + *	Can be freely distributed and used under the terms of the GNU GPL.
   21.10 + */
   21.11 +
   21.12 +#include <stdio.h>
   21.13 +#include <ctype.h>
   21.14 +#include <string.h>
   21.15 +#include <errno.h>
   21.16 +
   21.17 +#include "internal.h"
   21.18 +
   21.19 +struct dump_data {
   21.20 +  int len, allocated;
   21.21 +  byte data[1];
   21.22 +};
   21.23 +
   21.24 +static int
   21.25 +dump_detect(struct pci_access *a)
   21.26 +{
   21.27 +  return !!a->method_params[PCI_ACCESS_DUMP];
   21.28 +}
   21.29 +
   21.30 +static void
   21.31 +dump_alloc_data(struct pci_dev *dev, int len)
   21.32 +{
   21.33 +  struct dump_data *dd = pci_malloc(dev->access, sizeof(struct dump_data) + len - 1);
   21.34 +  dd->allocated = len;
   21.35 +  dd->len = 0;
   21.36 +  memset(dd->data, 0xff, len);
   21.37 +  dev->aux = dd;
   21.38 +}
   21.39 +
   21.40 +static int
   21.41 +dump_validate(char *s, char *fmt)
   21.42 +{
   21.43 +  while (*fmt)
   21.44 +    {
   21.45 +      if (*fmt == '#' ? !isxdigit(*s) : *fmt != *s)
   21.46 +	return 0;
   21.47 +      *fmt++, *s++;
   21.48 +    }
   21.49 +  return 1;
   21.50 +}
   21.51 +
   21.52 +static void
   21.53 +dump_init(struct pci_access *a)
   21.54 +{
   21.55 +  char *name = a->method_params[PCI_ACCESS_DUMP];
   21.56 +  FILE *f;
   21.57 +  char buf[256];
   21.58 +  struct pci_dev *dev = NULL;
   21.59 +  int len, mn, bn, dn, fn, i, j;
   21.60 +
   21.61 +  if (!a)
   21.62 +    a->error("dump: File name not given.");
   21.63 +  if (!(f = fopen(name, "r")))
   21.64 +    a->error("dump: Cannot open %s: %s", name, strerror(errno));
   21.65 +  while (fgets(buf, sizeof(buf)-1, f))
   21.66 +    {
   21.67 +      char *z = strchr(buf, '\n');
   21.68 +      if (!z)
   21.69 +	a->error("dump: line too long or unterminated");
   21.70 +      *z-- = 0;
   21.71 +      if (z >= buf && *z == '\r')
   21.72 +	*z-- = 0;
   21.73 +      len = z - buf + 1;
   21.74 +      mn = 0;
   21.75 +      if (dump_validate(buf, "##:##.# ") && sscanf(buf, "%x:%x.%d", &bn, &dn, &fn) == 3 ||
   21.76 +	  dump_validate(buf, "####:##:##.# ") && sscanf(buf, "%x:%x:%x.%d", &mn, &bn, &dn, &fn) == 4)
   21.77 +	{
   21.78 +	  dev = pci_get_dev(a, mn, bn, dn, fn);
   21.79 +	  dump_alloc_data(dev, 256);
   21.80 +	  pci_link_dev(a, dev);
   21.81 +	}
   21.82 +      else if (!len)
   21.83 +	dev = NULL;
   21.84 +      else if (dev &&
   21.85 +	       (dump_validate(buf, "##: ") || dump_validate(buf, "###: ")) &&
   21.86 +	       sscanf(buf, "%x: ", &i) == 1)
   21.87 +	{
   21.88 +	  struct dump_data *dd = dev->aux;
   21.89 +	  z = strchr(buf, ' ') + 1;
   21.90 +	  while (isxdigit(z[0]) && isxdigit(z[1]) && (!z[2] || z[2] == ' ') &&
   21.91 +		 sscanf(z, "%x", &j) == 1 && j < 256)
   21.92 +	    {
   21.93 +	      if (i >= 4096)
   21.94 +		a->error("dump: At most 4096 bytes of config space are supported");
   21.95 +	      if (i >= dd->allocated)	/* Need to re-allocate the buffer */
   21.96 +		{
   21.97 +		  dump_alloc_data(dev, 4096);
   21.98 +		  memcpy(((struct dump_data *) dev->aux)->data, dd->data, 256);
   21.99 +		  pci_mfree(dd);
  21.100 +		  dd = dev->aux;
  21.101 +		}
  21.102 +	      dd->data[i++] = j;
  21.103 +	      if (i > dd->len)
  21.104 +		dd->len = i;
  21.105 +	      z += 2;
  21.106 +	      if (*z)
  21.107 +		z++;
  21.108 +	    }
  21.109 +	  if (*z)
  21.110 +	    a->error("dump: Malformed line");
  21.111 +	}
  21.112 +    }
  21.113 +}
  21.114 +
  21.115 +static void
  21.116 +dump_cleanup(struct pci_access *a UNUSED)
  21.117 +{
  21.118 +}
  21.119 +
  21.120 +static void
  21.121 +dump_scan(struct pci_access *a UNUSED)
  21.122 +{
  21.123 +}
  21.124 +
  21.125 +static int
  21.126 +dump_read(struct pci_dev *d, int pos, byte *buf, int len)
  21.127 +{
  21.128 +  struct dump_data *dd;
  21.129 +  if (!(dd = d->aux))
  21.130 +    {
  21.131 +      struct pci_dev *e = d->access->devices;
  21.132 +      while (e && (e->domain != d->domain || e->bus != d->bus || e->dev != d->dev || e->func != d->func))
  21.133 +	e = e->next;
  21.134 +      if (!e)
  21.135 +	return 0;
  21.136 +      dd = e->aux;
  21.137 +    }
  21.138 +  if (pos + len > dd->len)
  21.139 +    return 0;
  21.140 +  memcpy(buf, dd->data + pos, len);
  21.141 +  return 1;
  21.142 +}
  21.143 +
  21.144 +static int
  21.145 +dump_write(struct pci_dev *d UNUSED, int pos UNUSED, byte *buf UNUSED, int len UNUSED)
  21.146 +{
  21.147 +  d->access->error("Writing to dump files is not supported.");
  21.148 +  return 0;
  21.149 +}
  21.150 +
  21.151 +static void
  21.152 +dump_cleanup_dev(struct pci_dev *d)
  21.153 +{
  21.154 +  if (d->aux)
  21.155 +    {
  21.156 +      pci_mfree(d->aux);
  21.157 +      d->aux = NULL;
  21.158 +    }
  21.159 +}
  21.160 +
  21.161 +struct pci_methods pm_dump = {
  21.162 +  "dump",
  21.163 +  NULL,					/* config */
  21.164 +  dump_detect,
  21.165 +  dump_init,
  21.166 +  dump_cleanup,
  21.167 +  dump_scan,
  21.168 +  pci_generic_fill_info,
  21.169 +  dump_read,
  21.170 +  dump_write,
  21.171 +  NULL,					/* init_dev */
  21.172 +  dump_cleanup_dev
  21.173 +};
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/example.c	Mon Aug 13 17:49:00 2007 -0400
    22.3 @@ -0,0 +1,32 @@
    22.4 +/*
    22.5 + *	The PCI Library -- Example of use (simplistic lister of PCI devices)
    22.6 + *
    22.7 + *	Written by Martin Mares and put to public domain. You can do
    22.8 + *	with it anything you want, but I don't give you any warranty.
    22.9 + */
   22.10 +
   22.11 +#include <stdio.h>
   22.12 +
   22.13 +#include "pci.h"
   22.14 +
   22.15 +int main(void)
   22.16 +{
   22.17 +  struct pci_access *pacc;
   22.18 +  struct pci_dev *dev;
   22.19 +  unsigned int c;
   22.20 +
   22.21 +  pacc = pci_alloc();		/* Get the pci_access structure */
   22.22 +  /* Set all options you want -- here we stick with the defaults */
   22.23 +  pci_init(pacc);		/* Initialize the PCI library */
   22.24 +  pci_scan_bus(pacc);		/* We want to get the list of devices */
   22.25 +  for(dev=pacc->devices; dev; dev=dev->next)	/* Iterate over all devices */
   22.26 +    {
   22.27 +      pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_CLASS);	/* Fill in header info we need */
   22.28 +      c = pci_read_byte(dev, PCI_INTERRUPT_PIN);				/* Read config register directly */
   22.29 +      printf("%02x:%02x.%d vendor=%04x device=%04x class=%04x irq=%d (pin %d) base0=%lx\n",
   22.30 +	     dev->bus, dev->dev, dev->func, dev->vendor_id, dev->device_id,
   22.31 +	     dev->device_class, dev->irq, c, dev->base_addr[0]);
   22.32 +    }
   22.33 +  pci_cleanup(pacc);		/* Close everything */
   22.34 +  return 0;
   22.35 +}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/fbsd-device.c	Mon Aug 13 17:49:00 2007 -0400
    23.3 @@ -0,0 +1,165 @@
    23.4 +/*
    23.5 + *	The PCI Library -- FreeBSD /dev/pci access
    23.6 + *
    23.7 + *	Copyright (c) 1999 Jari Kirma <kirma@cs.hut.fi>
    23.8 + *	Updated in 2003 by Samy Al Bahra <samy@kerneled.com>
    23.9 + *
   23.10 + *	Can be freely distributed and used under the terms of the GNU GPL.
   23.11 + */
   23.12 +
   23.13 +#include <fcntl.h>
   23.14 +#include <string.h>
   23.15 +#include <unistd.h>
   23.16 +#include <osreldate.h>
   23.17 +#include <stdint.h>
   23.18 +
   23.19 +#ifdef __FreeBSD_kernel_version
   23.20 +#  ifndef __FreeBSD_version
   23.21 +#    define __FreeBSD_version __FreeBSD_kernel_version
   23.22 +#  endif
   23.23 +#endif
   23.24 +
   23.25 +#if __FreeBSD_version < 500000
   23.26 +#  include <pci/pcivar.h>
   23.27 +#else
   23.28 +#  include <dev/pci/pcivar.h>
   23.29 +#endif
   23.30 +
   23.31 +#if __FreeBSD_version < 430000
   23.32 +#  include <pci/pci_ioctl.h>
   23.33 +#else
   23.34 +#  include <sys/pciio.h>
   23.35 +#endif
   23.36 +
   23.37 +#include "internal.h"
   23.38 +
   23.39 +static void
   23.40 +fbsd_config(struct pci_access *a)
   23.41 +{
   23.42 +  a->method_params[PCI_ACCESS_FBSD_DEVICE] = PCI_PATH_FBSD_DEVICE;
   23.43 +}
   23.44 +
   23.45 +static int
   23.46 +fbsd_detect(struct pci_access *a)
   23.47 +{
   23.48 +  char *name = a->method_params[PCI_ACCESS_FBSD_DEVICE];
   23.49 +
   23.50 +  if (access(name, R_OK))
   23.51 +    {
   23.52 +      a->warning("Cannot open %s", name);
   23.53 +      return 0;
   23.54 +    }
   23.55 +  a->debug("...using %s", name);
   23.56 +  return 1;
   23.57 +}
   23.58 +
   23.59 +static void
   23.60 +fbsd_init(struct pci_access *a)
   23.61 +{
   23.62 +  char *name = a->method_params[PCI_ACCESS_FBSD_DEVICE];
   23.63 +
   23.64 +  a->fd = open(name, O_RDWR, 0);
   23.65 +  if (a->fd < 0)
   23.66 +    {
   23.67 +      a->error("fbsd_init: %s open failed", name);
   23.68 +    }
   23.69 +}
   23.70 +
   23.71 +static void
   23.72 +fbsd_cleanup(struct pci_access *a)
   23.73 +{
   23.74 +  close(a->fd);
   23.75 +}
   23.76 +
   23.77 +static int
   23.78 +fbsd_read(struct pci_dev *d, int pos, byte *buf, int len)
   23.79 +{
   23.80 +  struct pci_io pi;
   23.81 +
   23.82 +  if (!(len == 1 || len == 2 || len == 4))
   23.83 +    {
   23.84 +      return pci_generic_block_read(d, pos, buf, len);
   23.85 +    }
   23.86 +
   23.87 +  if (pos >= 256)
   23.88 +    return 0;
   23.89 +
   23.90 +  pi.pi_sel.pc_bus = d->bus;
   23.91 +  pi.pi_sel.pc_dev = d->dev;
   23.92 +  pi.pi_sel.pc_func = d->func;
   23.93 +
   23.94 +  pi.pi_reg = pos;
   23.95 +  pi.pi_width = len;
   23.96 +
   23.97 +  if (ioctl(d->access->fd, PCIOCREAD, &pi) < 0)
   23.98 +    d->access->error("fbsd_read: ioctl(PCIOCREAD) failed");
   23.99 +
  23.100 +  switch (len)
  23.101 +    {
  23.102 +    case 1:
  23.103 +      buf[0] = (u8) pi.pi_data;
  23.104 +      break;
  23.105 +    case 2:
  23.106 +      ((u16 *) buf)[0] = (u16) pi.pi_data;
  23.107 +      break;
  23.108 +    case 4:
  23.109 +      ((u32 *) buf)[0] = (u32) pi.pi_data;
  23.110 +      break;
  23.111 +    }
  23.112 +  return 1;
  23.113 +}
  23.114 +
  23.115 +static int
  23.116 +fbsd_write(struct pci_dev *d, int pos, byte *buf, int len)
  23.117 +{
  23.118 +  struct pci_io pi;
  23.119 +
  23.120 +  if (!(len == 1 || len == 2 || len == 4))
  23.121 +    {
  23.122 +      return pci_generic_block_write(d, pos, buf, len);
  23.123 +    }
  23.124 +
  23.125 +  if (pos >= 256)
  23.126 +    return 0;
  23.127 +
  23.128 +  pi.pi_sel.pc_bus = d->bus;
  23.129 +  pi.pi_sel.pc_dev = d->dev;
  23.130 +  pi.pi_sel.pc_func = d->func;
  23.131 +
  23.132 +  pi.pi_reg = pos;
  23.133 +  pi.pi_width = len;
  23.134 +
  23.135 +  switch (len)
  23.136 +    {
  23.137 +    case 1:
  23.138 +      pi.pi_data = buf[0];
  23.139 +      break;
  23.140 +    case 2:
  23.141 +      pi.pi_data = ((u16 *) buf)[0];
  23.142 +      break;
  23.143 +    case 4:
  23.144 +      pi.pi_data = ((u32 *) buf)[0];
  23.145 +      break;
  23.146 +    }
  23.147 +
  23.148 +  if (ioctl(d->access->fd, PCIOCWRITE, &pi) < 0)
  23.149 +    {
  23.150 +      d->access->error("fbsd_write: ioctl(PCIOCWRITE) failed");
  23.151 +    }
  23.152 +
  23.153 +  return 1;
  23.154 +}
  23.155 +
  23.156 +struct pci_methods pm_fbsd_device = {
  23.157 +  "FreeBSD-device",
  23.158 +  fbsd_config,
  23.159 +  fbsd_detect,
  23.160 +  fbsd_init,
  23.161 +  fbsd_cleanup,
  23.162 +  pci_generic_scan,
  23.163 +  pci_generic_fill_info,
  23.164 +  fbsd_read,
  23.165 +  fbsd_write,
  23.166 +  NULL,                                 /* dev_init */
  23.167 +  NULL                                  /* dev_cleanup */
  23.168 +};
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/filter.c	Mon Aug 13 17:49:00 2007 -0400
    24.3 @@ -0,0 +1,123 @@
    24.4 +/*
    24.5 + *	The PCI Library -- Device Filtering
    24.6 + *
    24.7 + *	Copyright (c) 1998--2003 Martin Mares <mj@ucw.cz>
    24.8 + *
    24.9 + *	Can be freely distributed and used under the terms of the GNU GPL.
   24.10 + */
   24.11 +
   24.12 +#include <stdlib.h>
   24.13 +#include <string.h>
   24.14 +
   24.15 +#include "internal.h"
   24.16 +
   24.17 +void
   24.18 +pci_filter_init(struct pci_access *a UNUSED, struct pci_filter *f)
   24.19 +{
   24.20 +  f->domain = f->bus = f->slot = f->func = -1;
   24.21 +  f->vendor = f->device = -1;
   24.22 +}
   24.23 +
   24.24 +/* Slot filter syntax: [[[domain]:][bus]:][slot][.[func]] */
   24.25 +
   24.26 +char *
   24.27 +pci_filter_parse_slot(struct pci_filter *f, char *str)
   24.28 +{
   24.29 +  char *colon = strrchr(str, ':');
   24.30 +  char *dot = strchr((colon ? colon + 1 : str), '.');
   24.31 +  char *mid = str;
   24.32 +  char *e, *bus, *colon2;
   24.33 +
   24.34 +  if (colon)
   24.35 +    {
   24.36 +      *colon++ = 0;
   24.37 +      mid = colon;
   24.38 +      colon2 = strchr(str, ':');
   24.39 +      if (colon2)
   24.40 +	{
   24.41 +	  *colon2++ = 0;
   24.42 +	  bus = colon2;
   24.43 +	  if (str[0] && strcmp(str, "*"))
   24.44 +	    {
   24.45 +	      long int x = strtol(str, &e, 16);
   24.46 +	      if ((e && *e) || (x < 0 || x > 0xffff))
   24.47 +		return "Invalid domain number";
   24.48 +	      f->domain = x;
   24.49 +	    }
   24.50 +	}
   24.51 +      else
   24.52 +	bus = str;
   24.53 +      if (bus[0] && strcmp(bus, "*"))
   24.54 +	{
   24.55 +	  long int x = strtol(bus, &e, 16);
   24.56 +	  if ((e && *e) || (x < 0 || x > 0xff))
   24.57 +	    return "Invalid bus number";
   24.58 +	  f->bus = x;
   24.59 +	}
   24.60 +    }
   24.61 +  if (dot)
   24.62 +    *dot++ = 0;
   24.63 +  if (mid[0] && strcmp(mid, "*"))
   24.64 +    {
   24.65 +      long int x = strtol(mid, &e, 16);
   24.66 +      if ((e && *e) || (x < 0 || x > 0x1f))
   24.67 +	return "Invalid slot number";
   24.68 +      f->slot = x;
   24.69 +    }
   24.70 +  if (dot && dot[0] && strcmp(dot, "*"))
   24.71 +    {
   24.72 +      long int x = strtol(dot, &e, 16);
   24.73 +      if ((e && *e) || (x < 0 || x > 7))
   24.74 +	return "Invalid function number";
   24.75 +      f->func = x;
   24.76 +    }
   24.77 +  return NULL;
   24.78 +}
   24.79 +
   24.80 +/* ID filter syntax: [vendor]:[device] */
   24.81 +
   24.82 +char *
   24.83 +pci_filter_parse_id(struct pci_filter *f, char *str)
   24.84 +{
   24.85 +  char *s, *e;
   24.86 +
   24.87 +  if (!*str)
   24.88 +    return NULL;
   24.89 +  s = strchr(str, ':');
   24.90 +  if (!s)
   24.91 +    return "':' expected";
   24.92 +  *s++ = 0;
   24.93 +  if (str[0] && strcmp(str, "*"))
   24.94 +    {
   24.95 +      long int x = strtol(str, &e, 16);
   24.96 +      if ((e && *e) || (x < 0 || x >= 0xffff))
   24.97 +	return "Invalid vendor ID";
   24.98 +      f->vendor = x;
   24.99 +    }
  24.100 +  if (s[0] && strcmp(s, "*"))
  24.101 +    {
  24.102 +      long int x = strtol(s, &e, 16);
  24.103 +      if ((e && *e) || (x < 0 || x >= 0xffff))
  24.104 +	return "Invalid device ID";
  24.105 +      f->device = x;
  24.106 +    }
  24.107 +  return NULL;
  24.108 +}
  24.109 +
  24.110 +int
  24.111 +pci_filter_match(struct pci_filter *f, struct pci_dev *d)
  24.112 +{
  24.113 +  if ((f->domain >= 0 && f->domain != d->domain) ||
  24.114 +      (f->bus >= 0 && f->bus != d->bus) ||
  24.115 +      (f->slot >= 0 && f->slot != d->dev) ||
  24.116 +      (f->func >= 0 && f->func != d->func))
  24.117 +    return 0;
  24.118 +  if (f->device >= 0 || f->vendor >= 0)
  24.119 +    {
  24.120 +      pci_fill_info(d, PCI_FILL_IDENT);
  24.121 +      if ((f->device >= 0 && f->device != d->device_id) ||
  24.122 +	  (f->vendor >= 0 && f->vendor != d->vendor_id))
  24.123 +	return 0;
  24.124 +    }
  24.125 +  return 1;
  24.126 +}
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/generic.c	Mon Aug 13 17:49:00 2007 -0400
    25.3 @@ -0,0 +1,206 @@
    25.4 +/*
    25.5 + *	The PCI Library -- Generic Direct Access Functions
    25.6 + *
    25.7 + *	Copyright (c) 1997--2000 Martin Mares <mj@ucw.cz>
    25.8 + *
    25.9 + *	Can be freely distributed and used under the terms of the GNU GPL.
   25.10 + */
   25.11 +
   25.12 +#include <string.h>
   25.13 +
   25.14 +#include "internal.h"
   25.15 +
   25.16 +void
   25.17 +pci_generic_scan_bus(struct pci_access *a, byte *busmap, int bus)
   25.18 +{
   25.19 +  int dev, multi, ht;
   25.20 +  struct pci_dev *t;
   25.21 +
   25.22 +  a->debug("Scanning bus %02x for devices...\n", bus);
   25.23 +  if (busmap[bus])
   25.24 +    {
   25.25 +      a->warning("Bus %02x seen twice (firmware bug). Ignored.", bus);
   25.26 +      return;
   25.27 +    }
   25.28 +  busmap[bus] = 1;
   25.29 +  t = pci_alloc_dev(a);
   25.30 +  t->bus = bus;
   25.31 +  for(dev=0; dev<32; dev++)
   25.32 +    {
   25.33 +      t->dev = dev;
   25.34 +      multi = 0;
   25.35 +      for(t->func=0; !t->func || multi && t->func<8; t->func++)
   25.36 +	{
   25.37 +	  u32 vd = pci_read_long(t, PCI_VENDOR_ID);
   25.38 +	  struct pci_dev *d;
   25.39 +
   25.40 +	  if (!vd || vd == 0xffffffff)
   25.41 +	    continue;
   25.42 +	  ht = pci_read_byte(t, PCI_HEADER_TYPE);
   25.43 +	  if (!t->func)
   25.44 +	    multi = ht & 0x80;
   25.45 +	  ht &= 0x7f;
   25.46 +	  d = pci_alloc_dev(a);
   25.47 +	  d->bus = t->bus;
   25.48 +	  d->dev = t->dev;
   25.49 +	  d->func = t->func;
   25.50 +	  d->vendor_id = vd & 0xffff;
   25.51 +	  d->device_id = vd >> 16U;
   25.52 +	  d->known_fields = PCI_FILL_IDENT;
   25.53 +	  d->hdrtype = ht;
   25.54 +	  pci_link_dev(a, d);
   25.55 +	  switch (ht)
   25.56 +	    {
   25.57 +	    case PCI_HEADER_TYPE_NORMAL:
   25.58 +	      break;
   25.59 +	    case PCI_HEADER_TYPE_BRIDGE:
   25.60 +	    case PCI_HEADER_TYPE_CARDBUS:
   25.61 +	      pci_generic_scan_bus(a, busmap, pci_read_byte(t, PCI_SECONDARY_BUS));
   25.62 +	      break;
   25.63 +	    default:
   25.64 +	      a->debug("Device %04x:%02x:%02x.%d has unknown header type %02x.\n", d->domain, d->bus, d->dev, d->func, ht);
   25.65 +	    }
   25.66 +	}
   25.67 +    }
   25.68 +  pci_free_dev(t);
   25.69 +}
   25.70 +
   25.71 +void
   25.72 +pci_generic_scan(struct pci_access *a)
   25.73 +{
   25.74 +  byte busmap[256];
   25.75 +
   25.76 +  memset(busmap, 0, sizeof(busmap));
   25.77 +  pci_generic_scan_bus(a, busmap, 0);
   25.78 +}
   25.79 +
   25.80 +int
   25.81 +pci_generic_fill_info(struct pci_dev *d, int flags)
   25.82 +{
   25.83 +  struct pci_access *a = d->access;
   25.84 +
   25.85 +  if ((flags & (PCI_FILL_BASES | PCI_FILL_ROM_BASE)) && d->hdrtype < 0)
   25.86 +    d->hdrtype = pci_read_byte(d, PCI_HEADER_TYPE) & 0x7f;
   25.87 +  if (flags & PCI_FILL_IDENT)
   25.88 +    {
   25.89 +      d->vendor_id = pci_read_word(d, PCI_VENDOR_ID);
   25.90 +      d->device_id = pci_read_word(d, PCI_DEVICE_ID);
   25.91 +    }
   25.92 +  if (flags & PCI_FILL_CLASS)
   25.93 +      d->device_class = pci_read_word(d, PCI_CLASS_DEVICE);
   25.94 +  if (flags & PCI_FILL_IRQ)
   25.95 +    d->irq = pci_read_byte(d, PCI_INTERRUPT_LINE);
   25.96 +  if (flags & PCI_FILL_BASES)
   25.97 +    {
   25.98 +      int cnt = 0, i;
   25.99 +      memset(d->base_addr, 0, sizeof(d->base_addr));
  25.100 +      switch (d->hdrtype)
  25.101 +	{
  25.102 +	case PCI_HEADER_TYPE_NORMAL:
  25.103 +	  cnt = 6;
  25.104 +	  break;
  25.105 +	case PCI_HEADER_TYPE_BRIDGE:
  25.106 +	  cnt = 2;
  25.107 +	  break;
  25.108 +	case PCI_HEADER_TYPE_CARDBUS:
  25.109 +	  cnt = 1;
  25.110 +	  break;
  25.111 +	}
  25.112 +      if (cnt)
  25.113 +	{
  25.114 +	  for(i=0; i<cnt; i++)
  25.115 +	    {
  25.116 +	      u32 x = pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4);
  25.117 +	      if (!x || x == (u32) ~0)
  25.118 +		continue;
  25.119 +	      if ((x & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
  25.120 +		d->base_addr[i] = x;
  25.121 +	      else
  25.122 +		{
  25.123 +		  if ((x & PCI_BASE_ADDRESS_MEM_TYPE_MASK) != PCI_BASE_ADDRESS_MEM_TYPE_64)
  25.124 +		    d->base_addr[i] = x;
  25.125 +		  else if (i >= cnt-1)
  25.126 +		    a->warning("%04x:%02x:%02x.%d: Invalid 64-bit address seen for BAR %d.", d->domain, d->bus, d->dev, d->func, i);
  25.127 +		  else
  25.128 +		    {
  25.129 +		      u32 y = pci_read_long(d, PCI_BASE_ADDRESS_0 + (++i)*4);
  25.130 +#ifdef PCI_HAVE_64BIT_ADDRESS
  25.131 +		      d->base_addr[i-1] = x | (((pciaddr_t) y) << 32);
  25.132 +#else
  25.133 +		      if (y)
  25.134 +			a->warning("%04x:%02x:%02x.%d 64-bit device address ignored.", d->domain, d->bus, d->dev, d->func);
  25.135 +		      else
  25.136 +			d->base_addr[i-1] = x;
  25.137 +#endif
  25.138 +		    }
  25.139 +		}
  25.140 +	    }
  25.141 +	}
  25.142 +    }
  25.143 +  if (flags & PCI_FILL_ROM_BASE)
  25.144 +    {
  25.145 +      int reg = 0;
  25.146 +      d->rom_base_addr = 0;
  25.147 +      switch (d->hdrtype)
  25.148 +	{
  25.149 +	case PCI_HEADER_TYPE_NORMAL:
  25.150 +	  reg = PCI_ROM_ADDRESS;
  25.151 +	  break;
  25.152 +	case PCI_HEADER_TYPE_BRIDGE:
  25.153 +	  reg = PCI_ROM_ADDRESS1;
  25.154 +	  break;
  25.155 +	}
  25.156 +      if (reg)
  25.157 +	{
  25.158 +	  u32 u = pci_read_long(d, reg);
  25.159 +	  if (u != 0xffffffff)
  25.160 +	    d->rom_base_addr = u;
  25.161 +	}
  25.162 +    }
  25.163 +  return flags & ~PCI_FILL_SIZES;
  25.164 +}
  25.165 +
  25.166 +static int
  25.167 +pci_generic_block_op(struct pci_dev *d, int pos, byte *buf, int len,
  25.168 +		 int (*r)(struct pci_dev *d, int pos, byte *buf, int len))
  25.169 +{
  25.170 +  if ((pos & 1) && len >= 1)
  25.171 +    {
  25.172 +      if (!r(d, pos, buf, 1))
  25.173 +	return 0;
  25.174 +      pos++; buf++; len--;
  25.175 +    }
  25.176 +  if ((pos & 3) && len >= 2)
  25.177 +    {
  25.178 +      if (!r(d, pos, buf, 2))
  25.179 +	return 0;
  25.180 +      pos += 2; buf += 2; len -= 2;
  25.181 +    }
  25.182 +  while (len >= 4)
  25.183 +    {
  25.184 +      if (!r(d, pos, buf, 4))
  25.185 +	return 0;
  25.186 +      pos += 4; buf += 4; len -= 4;
  25.187 +    }
  25.188 +  if (len >= 2)
  25.189 +    {
  25.190 +      if (!r(d, pos, buf, 2))
  25.191 +	return 0;
  25.192 +      pos += 2; buf += 2; len -= 2;
  25.193 +    }
  25.194 +  if (len && !r(d, pos, buf, 1))
  25.195 +    return 0;
  25.196 +  return 1;
  25.197 +}
  25.198 +
  25.199 +int
  25.200 +pci_generic_block_read(struct pci_dev *d, int pos, byte *buf, int len)
  25.201 +{
  25.202 +  return pci_generic_block_op(d, pos, buf, len, d->access->methods->read);
  25.203 +}
  25.204 +
  25.205 +int
  25.206 +pci_generic_block_write(struct pci_dev *d, int pos, byte *buf, int len)
  25.207 +{
  25.208 +  return pci_generic_block_op(d, pos, buf, len, d->access->methods->write);
  25.209 +}
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/header.h	Mon Aug 13 17:49:00 2007 -0400
    26.3 @@ -0,0 +1,990 @@
    26.4 +/*
    26.5 + *	The PCI Library -- PCI Header Structure (based on <linux/pci.h>)
    26.6 + *
    26.7 + *	Copyright (c) 1997--2005 Martin Mares <mj@ucw.cz>
    26.8 + *
    26.9 + *	Can be freely distributed and used under the terms of the GNU GPL.
   26.10 + */
   26.11 +
   26.12 +/*
   26.13 + * Under PCI, each device has 256 bytes of configuration address space,
   26.14 + * of which the first 64 bytes are standardized as follows:
   26.15 + */
   26.16 +#define PCI_VENDOR_ID		0x00	/* 16 bits */
   26.17 +#define PCI_DEVICE_ID		0x02	/* 16 bits */
   26.18 +#define PCI_COMMAND		0x04	/* 16 bits */
   26.19 +#define  PCI_COMMAND_IO		0x1	/* Enable response in I/O space */
   26.20 +#define  PCI_COMMAND_MEMORY	0x2	/* Enable response in Memory space */
   26.21 +#define  PCI_COMMAND_MASTER	0x4	/* Enable bus mastering */
   26.22 +#define  PCI_COMMAND_SPECIAL	0x8	/* Enable response to special cycles */
   26.23 +#define  PCI_COMMAND_INVALIDATE	0x10	/* Use memory write and invalidate */
   26.24 +#define  PCI_COMMAND_VGA_PALETTE 0x20	/* Enable palette snooping */
   26.25 +#define  PCI_COMMAND_PARITY	0x40	/* Enable parity checking */
   26.26 +#define  PCI_COMMAND_WAIT 	0x80	/* Enable address/data stepping */
   26.27 +#define  PCI_COMMAND_SERR	0x100	/* Enable SERR */
   26.28 +#define  PCI_COMMAND_FAST_BACK	0x200	/* Enable back-to-back writes */
   26.29 +
   26.30 +#define PCI_STATUS		0x06	/* 16 bits */
   26.31 +#define  PCI_STATUS_CAP_LIST	0x10	/* Support Capability List */
   26.32 +#define  PCI_STATUS_66MHZ	0x20	/* Support 66 Mhz PCI 2.1 bus */
   26.33 +#define  PCI_STATUS_UDF		0x40	/* Support User Definable Features [obsolete] */
   26.34 +#define  PCI_STATUS_FAST_BACK	0x80	/* Accept fast-back to back */
   26.35 +#define  PCI_STATUS_PARITY	0x100	/* Detected parity error */
   26.36 +#define  PCI_STATUS_DEVSEL_MASK	0x600	/* DEVSEL timing */
   26.37 +#define  PCI_STATUS_DEVSEL_FAST	0x000
   26.38 +#define  PCI_STATUS_DEVSEL_MEDIUM 0x200
   26.39 +#define  PCI_STATUS_DEVSEL_SLOW 0x400
   26.40 +#define  PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
   26.41 +#define  PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
   26.42 +#define  PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
   26.43 +#define  PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
   26.44 +#define  PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
   26.45 +
   26.46 +#define PCI_CLASS_REVISION	0x08	/* High 24 bits are class, low 8
   26.47 +					   revision */
   26.48 +#define PCI_REVISION_ID         0x08    /* Revision ID */
   26.49 +#define PCI_CLASS_PROG          0x09    /* Reg. Level Programming Interface */
   26.50 +#define PCI_CLASS_DEVICE        0x0a    /* Device class */
   26.51 +
   26.52 +#define PCI_CACHE_LINE_SIZE	0x0c	/* 8 bits */
   26.53 +#define PCI_LATENCY_TIMER	0x0d	/* 8 bits */
   26.54 +#define PCI_HEADER_TYPE		0x0e	/* 8 bits */
   26.55 +#define  PCI_HEADER_TYPE_NORMAL	0
   26.56 +#define  PCI_HEADER_TYPE_BRIDGE 1
   26.57 +#define  PCI_HEADER_TYPE_CARDBUS 2
   26.58 +
   26.59 +#define PCI_BIST		0x0f	/* 8 bits */
   26.60 +#define PCI_BIST_CODE_MASK	0x0f	/* Return result */
   26.61 +#define PCI_BIST_START		0x40	/* 1 to start BIST, 2 secs or less */
   26.62 +#define PCI_BIST_CAPABLE	0x80	/* 1 if BIST capable */
   26.63 +
   26.64 +/*
   26.65 + * Base addresses specify locations in memory or I/O space.
   26.66 + * Decoded size can be determined by writing a value of
   26.67 + * 0xffffffff to the register, and reading it back.  Only
   26.68 + * 1 bits are decoded.
   26.69 + */
   26.70 +#define PCI_BASE_ADDRESS_0	0x10	/* 32 bits */
   26.71 +#define PCI_BASE_ADDRESS_1	0x14	/* 32 bits [htype 0,1 only] */
   26.72 +#define PCI_BASE_ADDRESS_2	0x18	/* 32 bits [htype 0 only] */
   26.73 +#define PCI_BASE_ADDRESS_3	0x1c	/* 32 bits */
   26.74 +#define PCI_BASE_ADDRESS_4	0x20	/* 32 bits */
   26.75 +#define PCI_BASE_ADDRESS_5	0x24	/* 32 bits */
   26.76 +#define  PCI_BASE_ADDRESS_SPACE	0x01	/* 0 = memory, 1 = I/O */
   26.77 +#define  PCI_BASE_ADDRESS_SPACE_IO 0x01
   26.78 +#define  PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
   26.79 +#define  PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
   26.80 +#define  PCI_BASE_ADDRESS_MEM_TYPE_32	0x00	/* 32 bit address */
   26.81 +#define  PCI_BASE_ADDRESS_MEM_TYPE_1M	0x02	/* Below 1M [obsolete] */
   26.82 +#define  PCI_BASE_ADDRESS_MEM_TYPE_64	0x04	/* 64 bit address */
   26.83 +#define  PCI_BASE_ADDRESS_MEM_PREFETCH	0x08	/* prefetchable? */
   26.84 +#define  PCI_BASE_ADDRESS_MEM_MASK	(~(pciaddr_t)0x0f)
   26.85 +#define  PCI_BASE_ADDRESS_IO_MASK	(~(pciaddr_t)0x03)
   26.86 +/* bit 1 is reserved if address_space = 1 */
   26.87 +
   26.88 +/* Header type 0 (normal devices) */
   26.89 +#define PCI_CARDBUS_CIS		0x28
   26.90 +#define PCI_SUBSYSTEM_VENDOR_ID	0x2c
   26.91 +#define PCI_SUBSYSTEM_ID	0x2e
   26.92 +#define PCI_ROM_ADDRESS		0x30	/* Bits 31..11 are address, 10..1 reserved */
   26.93 +#define  PCI_ROM_ADDRESS_ENABLE	0x01
   26.94 +#define PCI_ROM_ADDRESS_MASK	(~(pciaddr_t)0x7ff)
   26.95 +
   26.96 +#define PCI_CAPABILITY_LIST	0x34	/* Offset of first capability list entry */
   26.97 +
   26.98 +/* 0x35-0x3b are reserved */
   26.99 +#define PCI_INTERRUPT_LINE	0x3c	/* 8 bits */
  26.100 +#define PCI_INTERRUPT_PIN	0x3d	/* 8 bits */
  26.101 +#define PCI_MIN_GNT		0x3e	/* 8 bits */
  26.102 +#define PCI_MAX_LAT		0x3f	/* 8 bits */
  26.103 +
  26.104 +/* Header type 1 (PCI-to-PCI bridges) */
  26.105 +#define PCI_PRIMARY_BUS		0x18	/* Primary bus number */
  26.106 +#define PCI_SECONDARY_BUS	0x19	/* Secondary bus number */
  26.107 +#define PCI_SUBORDINATE_BUS	0x1a	/* Highest bus number behind the bridge */
  26.108 +#define PCI_SEC_LATENCY_TIMER	0x1b	/* Latency timer for secondary interface */
  26.109 +#define PCI_IO_BASE		0x1c	/* I/O range behind the bridge */
  26.110 +#define PCI_IO_LIMIT		0x1d
  26.111 +#define  PCI_IO_RANGE_TYPE_MASK	0x0f	/* I/O bridging type */
  26.112 +#define  PCI_IO_RANGE_TYPE_16	0x00
  26.113 +#define  PCI_IO_RANGE_TYPE_32	0x01
  26.114 +#define  PCI_IO_RANGE_MASK	~0x0f
  26.115 +#define PCI_SEC_STATUS		0x1e	/* Secondary status register */
  26.116 +#define PCI_MEMORY_BASE		0x20	/* Memory range behind */
  26.117 +#define PCI_MEMORY_LIMIT	0x22
  26.118 +#define  PCI_MEMORY_RANGE_TYPE_MASK 0x0f
  26.119 +#define  PCI_MEMORY_RANGE_MASK	~0x0f
  26.120 +#define PCI_PREF_MEMORY_BASE	0x24	/* Prefetchable memory range behind */
  26.121 +#define PCI_PREF_MEMORY_LIMIT	0x26
  26.122 +#define  PCI_PREF_RANGE_TYPE_MASK 0x0f
  26.123 +#define  PCI_PREF_RANGE_TYPE_32	0x00
  26.124 +#define  PCI_PREF_RANGE_TYPE_64	0x01
  26.125 +#define  PCI_PREF_RANGE_MASK	~0x0f
  26.126 +#define PCI_PREF_BASE_UPPER32	0x28	/* Upper half of prefetchable memory range */
  26.127 +#define PCI_PREF_LIMIT_UPPER32	0x2c
  26.128 +#define PCI_IO_BASE_UPPER16	0x30	/* Upper half of I/O addresses */
  26.129 +#define PCI_IO_LIMIT_UPPER16	0x32
  26.130 +/* 0x34 same as for htype 0 */
  26.131 +/* 0x35-0x3b is reserved */
  26.132 +#define PCI_ROM_ADDRESS1	0x38	/* Same as PCI_ROM_ADDRESS, but for htype 1 */
  26.133 +/* 0x3c-0x3d are same as for htype 0 */
  26.134 +#define PCI_BRIDGE_CONTROL	0x3e
  26.135 +#define  PCI_BRIDGE_CTL_PARITY	0x01	/* Enable parity detection on secondary interface */
  26.136 +#define  PCI_BRIDGE_CTL_SERR	0x02	/* The same for SERR forwarding */
  26.137 +#define  PCI_BRIDGE_CTL_NO_ISA	0x04	/* Disable bridging of ISA ports */
  26.138 +#define  PCI_BRIDGE_CTL_VGA	0x08	/* Forward VGA addresses */
  26.139 +#define  PCI_BRIDGE_CTL_MASTER_ABORT 0x20  /* Report master aborts */
  26.140 +#define  PCI_BRIDGE_CTL_BUS_RESET 0x40	/* Secondary bus reset */
  26.141 +#define  PCI_BRIDGE_CTL_FAST_BACK 0x80	/* Fast Back2Back enabled on secondary interface */
  26.142 +
  26.143 +/* Header type 2 (CardBus bridges) */
  26.144 +/* 0x14-0x15 reserved */
  26.145 +#define PCI_CB_SEC_STATUS	0x16	/* Secondary status */
  26.146 +#define PCI_CB_PRIMARY_BUS	0x18	/* PCI bus number */
  26.147 +#define PCI_CB_CARD_BUS		0x19	/* CardBus bus number */
  26.148 +#define PCI_CB_SUBORDINATE_BUS	0x1a	/* Subordinate bus number */
  26.149 +#define PCI_CB_LATENCY_TIMER	0x1b	/* CardBus latency timer */
  26.150 +#define PCI_CB_MEMORY_BASE_0	0x1c
  26.151 +#define PCI_CB_MEMORY_LIMIT_0	0x20
  26.152 +#define PCI_CB_MEMORY_BASE_1	0x24
  26.153 +#define PCI_CB_MEMORY_LIMIT_1	0x28
  26.154 +#define PCI_CB_IO_BASE_0	0x2c
  26.155 +#define PCI_CB_IO_BASE_0_HI	0x2e
  26.156 +#define PCI_CB_IO_LIMIT_0	0x30
  26.157 +#define PCI_CB_IO_LIMIT_0_HI	0x32
  26.158 +#define PCI_CB_IO_BASE_1	0x34
  26.159 +#define PCI_CB_IO_BASE_1_HI	0x36
  26.160 +#define PCI_CB_IO_LIMIT_1	0x38
  26.161 +#define PCI_CB_IO_LIMIT_1_HI	0x3a
  26.162 +#define  PCI_CB_IO_RANGE_MASK	~0x03
  26.163 +/* 0x3c-0x3d are same as for htype 0 */
  26.164 +#define PCI_CB_BRIDGE_CONTROL	0x3e
  26.165 +#define  PCI_CB_BRIDGE_CTL_PARITY	0x01	/* Similar to standard bridge control register */
  26.166 +#define  PCI_CB_BRIDGE_CTL_SERR		0x02
  26.167 +#define  PCI_CB_BRIDGE_CTL_ISA		0x04
  26.168 +#define  PCI_CB_BRIDGE_CTL_VGA		0x08
  26.169 +#define  PCI_CB_BRIDGE_CTL_MASTER_ABORT	0x20
  26.170 +#define  PCI_CB_BRIDGE_CTL_CB_RESET	0x40	/* CardBus reset */
  26.171 +#define  PCI_CB_BRIDGE_CTL_16BIT_INT	0x80	/* Enable interrupt for 16-bit cards */
  26.172 +#define  PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100	/* Prefetch enable for both memory regions */
  26.173 +#define  PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
  26.174 +#define  PCI_CB_BRIDGE_CTL_POST_WRITES	0x400
  26.175 +#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
  26.176 +#define PCI_CB_SUBSYSTEM_ID	0x42
  26.177 +#define PCI_CB_LEGACY_MODE_BASE	0x44	/* 16-bit PC Card legacy mode base address (ExCa) */
  26.178 +/* 0x48-0x7f reserved */
  26.179 +
  26.180 +/* Capability lists */
  26.181 +
  26.182 +#define PCI_CAP_LIST_ID		0	/* Capability ID */
  26.183 +#define  PCI_CAP_ID_PM		0x01	/* Power Management */
  26.184 +#define  PCI_CAP_ID_AGP		0x02	/* Accelerated Graphics Port */
  26.185 +#define  PCI_CAP_ID_VPD		0x03	/* Vital Product Data */
  26.186 +#define  PCI_CAP_ID_SLOTID	0x04	/* Slot Identification */
  26.187 +#define  PCI_CAP_ID_MSI		0x05	/* Message Signalled Interrupts */
  26.188 +#define  PCI_CAP_ID_CHSWP	0x06	/* CompactPCI HotSwap */
  26.189 +#define  PCI_CAP_ID_PCIX        0x07    /* PCI-X */
  26.190 +#define  PCI_CAP_ID_HT          0x08    /* HyperTransport */
  26.191 +#define  PCI_CAP_ID_VNDR	0x09	/* Vendor specific */
  26.192 +#define  PCI_CAP_ID_DBG		0x0A	/* Debug port */
  26.193 +#define  PCI_CAP_ID_CCRC	0x0B	/* CompactPCI Central Resource Control */
  26.194 +#define  PCI_CAP_ID_SSVID	0x0D	/* Bridge subsystem vendor/device ID */
  26.195 +#define  PCI_CAP_ID_AGP3	0x0E	/* AGP 8x */
  26.196 +#define  PCI_CAP_ID_EXP		0x10	/* PCI Express */
  26.197 +#define  PCI_CAP_ID_MSIX	0x11	/* MSI-X */
  26.198 +#define PCI_CAP_LIST_NEXT	1	/* Next capability in the list */
  26.199 +#define PCI_CAP_FLAGS		2	/* Capability defined flags (16 bits) */
  26.200 +#define PCI_CAP_SIZEOF		4
  26.201 +
  26.202 +/* Capabilities residing in the PCI Express extended configuration space */
  26.203 +
  26.204 +#define PCI_EXT_CAP_ID_AER	0x01	/* Advanced Error Reporting */
  26.205 +#define PCI_EXT_CAP_ID_VC	0x02	/* Virtual Channel */
  26.206 +#define PCI_EXT_CAP_ID_DSN	0x03	/* Device Serial Number */
  26.207 +#define PCI_EXT_CAP_ID_PB	0x04	/* Power Budgeting */
  26.208 +
  26.209 +/* Power Management Registers */
  26.210 +
  26.211 +#define  PCI_PM_CAP_VER_MASK	0x0007	/* Version (2=PM1.1) */
  26.212 +#define  PCI_PM_CAP_PME_CLOCK	0x0008	/* Clock required for PME generation */
  26.213 +#define  PCI_PM_CAP_DSI		0x0020	/* Device specific initialization required */
  26.214 +#define  PCI_PM_CAP_AUX_C_MASK	0x01c0	/* Maximum aux current required in D3cold */
  26.215 +#define  PCI_PM_CAP_D1		0x0200	/* D1 power state support */
  26.216 +#define  PCI_PM_CAP_D2		0x0400	/* D2 power state support */
  26.217 +#define  PCI_PM_CAP_PME_D0	0x0800	/* PME can be asserted from D0 */
  26.218 +#define  PCI_PM_CAP_PME_D1	0x1000	/* PME can be asserted from D1 */
  26.219 +#define  PCI_PM_CAP_PME_D2	0x2000	/* PME can be asserted from D2 */
  26.220 +#define  PCI_PM_CAP_PME_D3_HOT	0x4000	/* PME can be asserted from D3hot */
  26.221 +#define  PCI_PM_CAP_PME_D3_COLD	0x8000	/* PME can be asserted from D3cold */
  26.222 +#define PCI_PM_CTRL		4	/* PM control and status register */
  26.223 +#define  PCI_PM_CTRL_STATE_MASK	0x0003	/* Current power state (D0 to D3) */
  26.224 +#define  PCI_PM_CTRL_PME_ENABLE	0x0100	/* PME pin enable */
  26.225 +#define  PCI_PM_CTRL_DATA_SEL_MASK	0x1e00	/* PM table data index */
  26.226 +#define  PCI_PM_CTRL_DATA_SCALE_MASK	0x6000	/* PM table data scaling factor */
  26.227 +#define  PCI_PM_CTRL_PME_STATUS	0x8000	/* PME pin status */
  26.228 +#define PCI_PM_PPB_EXTENSIONS	6	/* PPB support extensions */
  26.229 +#define  PCI_PM_PPB_B2_B3	0x40	/* If bridge enters D3hot, bus enters: 0=B3, 1=B2 */
  26.230 +#define  PCI_PM_BPCC_ENABLE	0x80	/* Secondary bus is power managed */
  26.231 +#define PCI_PM_DATA_REGISTER	7	/* PM table contents read here */
  26.232 +#define PCI_PM_SIZEOF		8
  26.233 +
  26.234 +/* AGP registers */
  26.235 +
  26.236 +#define PCI_AGP_VERSION		2	/* BCD version number */
  26.237 +#define PCI_AGP_RFU		3	/* Rest of capability flags */
  26.238 +#define PCI_AGP_STATUS		4	/* Status register */
  26.239 +#define  PCI_AGP_STATUS_RQ_MASK	0xff000000	/* Maximum number of requests - 1 */
  26.240 +#define  PCI_AGP_STATUS_ISOCH	0x10000	/* Isochronous transactions supported */
  26.241 +#define  PCI_AGP_STATUS_ARQSZ_MASK	0xe000	/* log2(optimum async req size in bytes) - 4 */
  26.242 +#define  PCI_AGP_STATUS_CAL_MASK	0x1c00	/* Calibration cycle timing */
  26.243 +#define  PCI_AGP_STATUS_SBA	0x0200	/* Sideband addressing supported */
  26.244 +#define  PCI_AGP_STATUS_ITA_COH	0x0100	/* In-aperture accesses always coherent */
  26.245 +#define  PCI_AGP_STATUS_GART64	0x0080	/* 64-bit GART entries supported */
  26.246 +#define  PCI_AGP_STATUS_HTRANS	0x0040	/* If 0, core logic can xlate host CPU accesses thru aperture */
  26.247 +#define  PCI_AGP_STATUS_64BIT	0x0020	/* 64-bit addressing cycles supported */
  26.248 +#define  PCI_AGP_STATUS_FW	0x0010	/* Fast write transfers supported */
  26.249 +#define  PCI_AGP_STATUS_AGP3	0x0008	/* AGP3 mode supported */
  26.250 +#define  PCI_AGP_STATUS_RATE4	0x0004	/* 4x transfer rate supported (RFU in AGP3 mode) */
  26.251 +#define  PCI_AGP_STATUS_RATE2	0x0002	/* 2x transfer rate supported (8x in AGP3 mode) */
  26.252 +#define  PCI_AGP_STATUS_RATE1	0x0001	/* 1x transfer rate supported (4x in AGP3 mode) */
  26.253 +#define PCI_AGP_COMMAND		8	/* Control register */
  26.254 +#define  PCI_AGP_COMMAND_RQ_MASK 0xff000000  /* Master: Maximum number of requests */
  26.255 +#define  PCI_AGP_COMMAND_ARQSZ_MASK	0xe000	/* log2(optimum async req size in bytes) - 4 */
  26.256 +#define  PCI_AGP_COMMAND_CAL_MASK	0x1c00	/* Calibration cycle timing */
  26.257 +#define  PCI_AGP_COMMAND_SBA	0x0200	/* Sideband addressing enabled */
  26.258 +#define  PCI_AGP_COMMAND_AGP	0x0100	/* Allow processing of AGP transactions */
  26.259 +#define  PCI_AGP_COMMAND_GART64	0x0080	/* 64-bit GART entries enabled */
  26.260 +#define  PCI_AGP_COMMAND_64BIT	0x0020 	/* Allow generation of 64-bit addr cycles */
  26.261 +#define  PCI_AGP_COMMAND_FW	0x0010 	/* Enable FW transfers */
  26.262 +#define  PCI_AGP_COMMAND_RATE4	0x0004	/* Use 4x rate (RFU in AGP3 mode) */
  26.263 +#define  PCI_AGP_COMMAND_RATE2	0x0002	/* Use 2x rate (8x in AGP3 mode) */
  26.264 +#define  PCI_AGP_COMMAND_RATE1	0x0001	/* Use 1x rate (4x in AGP3 mode) */
  26.265 +#define PCI_AGP_SIZEOF		12
  26.266 +
  26.267 +/* Slot Identification */
  26.268 +
  26.269 +#define PCI_SID_ESR		2	/* Expansion Slot Register */
  26.270 +#define  PCI_SID_ESR_NSLOTS	0x1f	/* Number of expansion slots available */
  26.271 +#define  PCI_SID_ESR_FIC	0x20	/* First In Chassis Flag */
  26.272 +#define PCI_SID_CHASSIS_NR	3	/* Chassis Number */
  26.273 +
  26.274 +/* Message Signalled Interrupts registers */
  26.275 +
  26.276 +#define PCI_MSI_FLAGS		2	/* Various flags */
  26.277 +#define  PCI_MSI_FLAGS_MASK_BIT	0x100	/* interrupt masking & reporting supported */
  26.278 +#define  PCI_MSI_FLAGS_64BIT	0x080	/* 64-bit addresses allowed */
  26.279 +#define  PCI_MSI_FLAGS_QSIZE	0x070	/* Message queue size configured */
  26.280 +#define  PCI_MSI_FLAGS_QMASK	0x00e	/* Maximum queue size available */
  26.281 +#define  PCI_MSI_FLAGS_ENABLE	0x001	/* MSI feature enabled */
  26.282 +#define PCI_MSI_RFU		3	/* Rest of capability flags */
  26.283 +#define PCI_MSI_ADDRESS_LO	4	/* Lower 32 bits */
  26.284 +#define PCI_MSI_ADDRESS_HI	8	/* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
  26.285 +#define PCI_MSI_DATA_32		8	/* 16 bits of data for 32-bit devices */
  26.286 +#define PCI_MSI_DATA_64		12	/* 16 bits of data for 64-bit devices */
  26.287 +#define PCI_MSI_MASK_BIT_32	12	/* per-vector masking for 32-bit devices */
  26.288 +#define PCI_MSI_MASK_BIT_64	16	/* per-vector masking for 64-bit devices */
  26.289 +#define PCI_MSI_PENDING_32	16	/* per-vector interrupt pending for 32-bit devices */
  26.290 +#define PCI_MSI_PENDING_64	20	/* per-vector interrupt pending for 64-bit devices */
  26.291 +
  26.292 +/* PCI-X */
  26.293 +#define PCI_PCIX_COMMAND                                                2 /* Command register offset */
  26.294 +#define PCI_PCIX_COMMAND_DPERE                                     0x0001 /* Data Parity Error Recover Enable */
  26.295 +#define PCI_PCIX_COMMAND_ERO                                       0x0002 /* Enable Relaxed Ordering */
  26.296 +#define PCI_PCIX_COMMAND_MAX_MEM_READ_BYTE_COUNT                   0x000c /* Maximum Memory Read Byte Count */
  26.297 +#define PCI_PCIX_COMMAND_MAX_OUTSTANDING_SPLIT_TRANS               0x0070
  26.298 +#define PCI_PCIX_COMMAND_RESERVED                                   0xf80
  26.299 +#define PCI_PCIX_STATUS                                                 4 /* Status register offset */
  26.300 +#define PCI_PCIX_STATUS_FUNCTION                               0x00000007
  26.301 +#define PCI_PCIX_STATUS_DEVICE                                 0x000000f8
  26.302 +#define PCI_PCIX_STATUS_BUS                                    0x0000ff00
  26.303 +#define PCI_PCIX_STATUS_64BIT                                  0x00010000
  26.304 +#define PCI_PCIX_STATUS_133MHZ                                 0x00020000
  26.305 +#define PCI_PCIX_STATUS_SC_DISCARDED                           0x00040000 /* Split Completion Discarded */
  26.306 +#define PCI_PCIX_STATUS_UNEXPECTED_SC                          0x00080000 /* Unexpected Split Completion */
  26.307 +#define PCI_PCIX_STATUS_DEVICE_COMPLEXITY                      0x00100000 /* 0 = simple device, 1 = bridge device */
  26.308 +#define PCI_PCIX_STATUS_DESIGNED_MAX_MEM_READ_BYTE_COUNT       0x00600000 /* 0 = 512 bytes, 1 = 1024, 2 = 2048, 3 = 4096 */
  26.309 +#define PCI_PCIX_STATUS_DESIGNED_MAX_OUTSTANDING_SPLIT_TRANS   0x03800000
  26.310 +#define PCI_PCIX_STATUS_DESIGNED_MAX_CUMULATIVE_READ_SIZE      0x1c000000
  26.311 +#define PCI_PCIX_STATUS_RCVD_SC_ERR_MESS                       0x20000000 /* Received Split Completion Error Message */
  26.312 +#define PCI_PCIX_STATUS_266MHZ				       0x40000000 /* 266 MHz capable */
  26.313 +#define PCI_PCIX_STATUS_533MHZ				       0x80000000 /* 533 MHz capable */
  26.314 +#define PCI_PCIX_SIZEOF		4
  26.315 +
  26.316 +/* PCI-X Bridges */
  26.317 +#define PCI_PCIX_BRIDGE_SEC_STATUS                                      2 /* Secondary bus status register offset */
  26.318 +#define PCI_PCIX_BRIDGE_SEC_STATUS_64BIT                           0x0001
  26.319 +#define PCI_PCIX_BRIDGE_SEC_STATUS_133MHZ                          0x0002
  26.320 +#define PCI_PCIX_BRIDGE_SEC_STATUS_SC_DISCARDED                    0x0004 /* Split Completion Discarded on secondary bus */
  26.321 +#define PCI_PCIX_BRIDGE_SEC_STATUS_UNEXPECTED_SC                   0x0008 /* Unexpected Split Completion on secondary bus */
  26.322 +#define PCI_PCIX_BRIDGE_SEC_STATUS_SC_OVERRUN                      0x0010 /* Split Completion Overrun on secondary bus */
  26.323 +#define PCI_PCIX_BRIDGE_SEC_STATUS_SPLIT_REQUEST_DELAYED           0x0020
  26.324 +#define PCI_PCIX_BRIDGE_SEC_STATUS_CLOCK_FREQ                      0x01c0
  26.325 +#define PCI_PCIX_BRIDGE_SEC_STATUS_RESERVED                        0xfe00
  26.326 +#define PCI_PCIX_BRIDGE_STATUS                                          4 /* Primary bus status register offset */
  26.327 +#define PCI_PCIX_BRIDGE_STATUS_FUNCTION                        0x00000007
  26.328 +#define PCI_PCIX_BRIDGE_STATUS_DEVICE                          0x000000f8
  26.329 +#define PCI_PCIX_BRIDGE_STATUS_BUS                             0x0000ff00
  26.330 +#define PCI_PCIX_BRIDGE_STATUS_64BIT                           0x00010000
  26.331 +#define PCI_PCIX_BRIDGE_STATUS_133MHZ                          0x00020000
  26.332 +#define PCI_PCIX_BRIDGE_STATUS_SC_DISCARDED                    0x00040000 /* Split Completion Discarded */
  26.333 +#define PCI_PCIX_BRIDGE_STATUS_UNEXPECTED_SC                   0x00080000 /* Unexpected Split Completion */
  26.334 +#define PCI_PCIX_BRIDGE_STATUS_SC_OVERRUN                      0x00100000 /* Split Completion Overrun */
  26.335 +#define PCI_PCIX_BRIDGE_STATUS_SPLIT_REQUEST_DELAYED           0x00200000
  26.336 +#define PCI_PCIX_BRIDGE_STATUS_RESERVED                        0xffc00000
  26.337 +#define PCI_PCIX_BRIDGE_UPSTREAM_SPLIT_TRANS_CTRL                       8 /* Upstream Split Transaction Register offset */
  26.338 +#define PCI_PCIX_BRIDGE_DOWNSTREAM_SPLIT_TRANS_CTRL                    12 /* Downstream Split Transaction Register offset */
  26.339 +#define PCI_PCIX_BRIDGE_STR_CAPACITY                           0x0000ffff
  26.340 +#define PCI_PCIX_BRIDGE_STR_COMMITMENT_LIMIT                   0xffff0000
  26.341 +#define PCI_PCIX_BRIDGE_SIZEOF 12
  26.342 +
  26.343 +/* HyperTransport (as of spec rev. 2.00) */
  26.344 +#define PCI_HT_CMD		2	/* Command Register */
  26.345 +#define  PCI_HT_CMD_TYP_HI	0xe000	/* Capability Type high part */
  26.346 +#define  PCI_HT_CMD_TYP_HI_PRI	0x0000	/* Slave or Primary Interface */
  26.347 +#define  PCI_HT_CMD_TYP_HI_SEC	0x2000	/* Host or Secondary Interface */
  26.348 +#define  PCI_HT_CMD_TYP		0xf800	/* Capability Type */
  26.349 +#define  PCI_HT_CMD_TYP_SW	0x4000	/* Switch */
  26.350 +#define  PCI_HT_CMD_TYP_IDC	0x8000	/* Interrupt Discovery and Configuration */
  26.351 +#define  PCI_HT_CMD_TYP_RID	0x8800	/* Revision ID */
  26.352 +#define  PCI_HT_CMD_TYP_UIDC	0x9000	/* UnitID Clumping */
  26.353 +#define  PCI_HT_CMD_TYP_ECSA	0x9800	/* Extended Configuration Space Access */
  26.354 +#define  PCI_HT_CMD_TYP_AM	0xa000	/* Address Mapping */
  26.355 +#define  PCI_HT_CMD_TYP_MSIM	0xa800	/* MSI Mapping */
  26.356 +#define  PCI_HT_CMD_TYP_DR	0xb000	/* DirectRoute */
  26.357 +#define  PCI_HT_CMD_TYP_VCS	0xb800	/* VCSet */
  26.358 +#define  PCI_HT_CMD_TYP_RM	0xc000	/* Retry Mode */
  26.359 +#define  PCI_HT_CMD_TYP_X86	0xc800	/* X86 (reserved) */
  26.360 +
  26.361 +					/* Link Control Register */
  26.362 +#define  PCI_HT_LCTR_CFLE	0x0002	/* CRC Flood Enable */
  26.363 +#define  PCI_HT_LCTR_CST	0x0004	/* CRC Start Test */
  26.364 +#define  PCI_HT_LCTR_CFE	0x0008	/* CRC Force Error */
  26.365 +#define  PCI_HT_LCTR_LKFAIL	0x0010	/* Link Failure */
  26.366 +#define  PCI_HT_LCTR_INIT	0x0020	/* Initialization Complete */
  26.367 +#define  PCI_HT_LCTR_EOC	0x0040	/* End of Chain */
  26.368 +#define  PCI_HT_LCTR_TXO	0x0080	/* Transmitter Off */
  26.369 +#define  PCI_HT_LCTR_CRCERR	0x0f00	/* CRC Error */
  26.370 +#define  PCI_HT_LCTR_ISOCEN	0x1000	/* Isochronous Flow Control Enable */
  26.371 +#define  PCI_HT_LCTR_LSEN	0x2000	/* LDTSTOP# Tristate Enable */
  26.372 +#define  PCI_HT_LCTR_EXTCTL	0x4000	/* Extended CTL Time */
  26.373 +#define  PCI_HT_LCTR_64B	0x8000	/* 64-bit Addressing Enable */
  26.374 +
  26.375 +					/* Link Configuration Register */
  26.376 +#define  PCI_HT_LCNF_MLWI	0x0007	/* Max Link Width In */
  26.377 +#define  PCI_HT_LCNF_LW_8B	0x0	/* Link Width 8 bits */
  26.378 +#define  PCI_HT_LCNF_LW_16B	0x1	/* Link Width 16 bits */
  26.379 +#define  PCI_HT_LCNF_LW_32B	0x3	/* Link Width 32 bits */
  26.380 +#define  PCI_HT_LCNF_LW_2B	0x4	/* Link Width 2 bits */
  26.381 +#define  PCI_HT_LCNF_LW_4B	0x5	/* Link Width 4 bits */
  26.382 +#define  PCI_HT_LCNF_LW_NC	0x7	/* Link physically not connected */
  26.383 +#define  PCI_HT_LCNF_DFI	0x0008	/* Doubleword Flow Control In */
  26.384 +#define  PCI_HT_LCNF_MLWO	0x0070	/* Max Link Width Out */
  26.385 +#define  PCI_HT_LCNF_DFO	0x0080	/* Doubleword Flow Control Out */
  26.386 +#define  PCI_HT_LCNF_LWI	0x0700	/* Link Width In */
  26.387 +#define  PCI_HT_LCNF_DFIE	0x0800	/* Doubleword Flow Control In Enable */
  26.388 +#define  PCI_HT_LCNF_LWO	0x7000	/* Link Width Out */
  26.389 +#define  PCI_HT_LCNF_DFOE	0x8000	/* Doubleword Flow Control Out Enable */
  26.390 +
  26.391 +					/* Revision ID Register */
  26.392 +#define  PCI_HT_RID_MIN		0x1f	/* Minor Revision */
  26.393 +#define  PCI_HT_RID_MAJ		0xe0	/* Major Revision */
  26.394 +
  26.395 +					/* Link Frequency/Error Register */
  26.396 +#define  PCI_HT_LFRER_FREQ	0x0f	/* Transmitter Clock Frequency */
  26.397 +#define  PCI_HT_LFRER_200	0x00	/* 200MHz */
  26.398 +#define  PCI_HT_LFRER_300	0x01	/* 300MHz */
  26.399 +#define  PCI_HT_LFRER_400	0x02	/* 400MHz */
  26.400 +#define  PCI_HT_LFRER_500	0x03	/* 500MHz */
  26.401 +#define  PCI_HT_LFRER_600	0x04	/* 600MHz */
  26.402 +#define  PCI_HT_LFRER_800	0x05	/* 800MHz */
  26.403 +#define  PCI_HT_LFRER_1000	0x06	/* 1.0GHz */
  26.404 +#define  PCI_HT_LFRER_1200	0x07	/* 1.2GHz */
  26.405 +#define  PCI_HT_LFRER_1400	0x08	/* 1.4GHz */
  26.406 +#define  PCI_HT_LFRER_1600	0x09	/* 1.6GHz */
  26.407 +#define  PCI_HT_LFRER_VEND	0x0f	/* Vendor-Specific */
  26.408 +#define  PCI_HT_LFRER_ERR	0xf0	/* Link Error */
  26.409 +#define  PCI_HT_LFRER_PROT	0x10	/* Protocol Error */
  26.410 +#define  PCI_HT_LFRER_OV	0x20	/* Overflow Error */
  26.411 +#define  PCI_HT_LFRER_EOC	0x40	/* End of Chain Error */
  26.412 +#define  PCI_HT_LFRER_CTLT	0x80	/* CTL Timeout */
  26.413 +
  26.414 +					/* Link Frequency Capability Register */
  26.415 +#define  PCI_HT_LFCAP_200	0x0001	/* 200MHz */
  26.416 +#define  PCI_HT_LFCAP_300	0x0002	/* 300MHz */
  26.417 +#define  PCI_HT_LFCAP_400	0x0004	/* 400MHz */
  26.418 +#define  PCI_HT_LFCAP_500	0x0008	/* 500MHz */
  26.419 +#define  PCI_HT_LFCAP_600	0x0010	/* 600MHz */
  26.420 +#define  PCI_HT_LFCAP_800	0x0020	/* 800MHz */
  26.421 +#define  PCI_HT_LFCAP_1000	0x0040	/* 1.0GHz */
  26.422 +#define  PCI_HT_LFCAP_1200	0x0080	/* 1.2GHz */
  26.423 +#define  PCI_HT_LFCAP_1400	0x0100	/* 1.4GHz */
  26.424 +#define  PCI_HT_LFCAP_1600	0x0200	/* 1.6GHz */
  26.425 +#define  PCI_HT_LFCAP_VEND	0x8000	/* Vendor-Specific */
  26.426 +
  26.427 +					/* Feature Register */
  26.428 +#define  PCI_HT_FTR_ISOCFC	0x0001	/* Isochronous Flow Control Mode */
  26.429 +#define  PCI_HT_FTR_LDTSTOP	0x0002	/* LDTSTOP# Supported */
  26.430 +#define  PCI_HT_FTR_CRCTM	0x0004	/* CRC Test Mode */
  26.431 +#define  PCI_HT_FTR_ECTLT	0x0008	/* Extended CTL Time Required */
  26.432 +#define  PCI_HT_FTR_64BA	0x0010	/* 64-bit Addressing */
  26.433 +#define  PCI_HT_FTR_UIDRD	0x0020	/* UnitID Reorder Disable */
  26.434 +
  26.435 +					/* Error Handling Register */
  26.436 +#define  PCI_HT_EH_PFLE		0x0001	/* Protocol Error Flood Enable */
  26.437 +#define  PCI_HT_EH_OFLE		0x0002	/* Overflow Error Flood Enable */
  26.438 +#define  PCI_HT_EH_PFE		0x0004	/* Protocol Error Fatal Enable */
  26.439 +#define  PCI_HT_EH_OFE		0x0008	/* Overflow Error Fatal Enable */
  26.440 +#define  PCI_HT_EH_EOCFE	0x0010	/* End of Chain Error Fatal Enable */
  26.441 +#define  PCI_HT_EH_RFE		0x0020	/* Response Error Fatal Enable */
  26.442 +#define  PCI_HT_EH_CRCFE	0x0040	/* CRC Error Fatal Enable */
  26.443 +#define  PCI_HT_EH_SERRFE	0x0080	/* System Error Fatal Enable (B */
  26.444 +#define  PCI_HT_EH_CF		0x0100	/* Chain Fail */
  26.445 +#define  PCI_HT_EH_RE		0x0200	/* Response Error */
  26.446 +#define  PCI_HT_EH_PNFE		0x0400	/* Protocol Error Nonfatal Enable */
  26.447 +#define  PCI_HT_EH_ONFE		0x0800	/* Overflow Error Nonfatal Enable */
  26.448 +#define  PCI_HT_EH_EOCNFE	0x1000	/* End of Chain Error Nonfatal Enable */
  26.449 +#define  PCI_HT_EH_RNFE		0x2000	/* Response Error Nonfatal Enable */
  26.450 +#define  PCI_HT_EH_CRCNFE	0x4000	/* CRC Error Nonfatal Enable */
  26.451 +#define  PCI_HT_EH_SERRNFE	0x8000	/* System Error Nonfatal Enable */
  26.452 +
  26.453 +/* HyperTransport: Slave or Primary Interface */
  26.454 +#define PCI_HT_PRI_CMD		2	/* Command Register */
  26.455 +#define  PCI_HT_PRI_CMD_BUID	0x001f	/* Base UnitID */
  26.456 +#define  PCI_HT_PRI_CMD_UC	0x03e0	/* Unit Count */
  26.457 +#define  PCI_HT_PRI_CMD_MH	0x0400	/* Master Host */
  26.458 +#define  PCI_HT_PRI_CMD_DD	0x0800	/* Default Direction */
  26.459 +#define  PCI_HT_PRI_CMD_DUL	0x1000	/* Drop on Uninitialized Link */
  26.460 +
  26.461 +#define PCI_HT_PRI_LCTR0	4	/* Link Control 0 Register */
  26.462 +#define PCI_HT_PRI_LCNF0	6	/* Link Config 0 Register */
  26.463 +#define PCI_HT_PRI_LCTR1	8	/* Link Control 1 Register */
  26.464 +#define PCI_HT_PRI_LCNF1	10	/* Link Config 1 Register */
  26.465 +#define PCI_HT_PRI_RID		12	/* Revision ID Register */
  26.466 +#define PCI_HT_PRI_LFRER0	13	/* Link Frequency/Error 0 Register */
  26.467 +#define PCI_HT_PRI_LFCAP0	14	/* Link Frequency Capability 0 Register */
  26.468 +#define PCI_HT_PRI_FTR		16	/* Feature Register */
  26.469 +#define PCI_HT_PRI_LFRER1	17	/* Link Frequency/Error 1 Register */
  26.470 +#define PCI_HT_PRI_LFCAP1	18	/* Link Frequency Capability 1 Register */
  26.471 +#define PCI_HT_PRI_ES		20	/* Enumeration Scratchpad Register */
  26.472 +#define PCI_HT_PRI_EH		22	/* Error Handling Register */
  26.473 +#define PCI_HT_PRI_MBU		24	/* Memory Base Upper Register */
  26.474 +#define PCI_HT_PRI_MLU		25	/* Memory Limit Upper Register */
  26.475 +#define PCI_HT_PRI_BN		26	/* Bus Number Register */
  26.476 +#define PCI_HT_PRI_SIZEOF	28
  26.477 +
  26.478 +/* HyperTransport: Host or Secondary Interface */
  26.479 +#define PCI_HT_SEC_CMD		2	/* Command Register */
  26.480 +#define  PCI_HT_SEC_CMD_WR	0x0001	/* Warm Reset */
  26.481 +#define  PCI_HT_SEC_CMD_DE	0x0002	/* Double-Ended */
  26.482 +#define  PCI_HT_SEC_CMD_DN	0x0076	/* Device Number */
  26.483 +#define  PCI_HT_SEC_CMD_CS	0x0080	/* Chain Side */
  26.484 +#define  PCI_HT_SEC_CMD_HH	0x0100	/* Host Hide */
  26.485 +#define  PCI_HT_SEC_CMD_AS	0x0400	/* Act as Slave */
  26.486 +#define  PCI_HT_SEC_CMD_HIECE	0x0800	/* Host Inbound End of Chain Error */
  26.487 +#define  PCI_HT_SEC_CMD_DUL	0x1000	/* Drop on Uninitialized Link */
  26.488 +
  26.489 +#define PCI_HT_SEC_LCTR		4	/* Link Control Register */
  26.490 +#define PCI_HT_SEC_LCNF		6	/* Link Config Register */
  26.491 +#define PCI_HT_SEC_RID		8	/* Revision ID Register */
  26.492 +#define PCI_HT_SEC_LFRER	9	/* Link Frequency/Error Register */
  26.493 +#define PCI_HT_SEC_LFCAP	10	/* Link Frequency Capability Register */
  26.494 +#define PCI_HT_SEC_FTR		12	/* Feature Register */
  26.495 +#define  PCI_HT_SEC_FTR_EXTRS	0x0100	/* Extended Register Set */
  26.496 +#define  PCI_HT_SEC_FTR_UCNFE	0x0200	/* Upstream Configuration Enable */
  26.497 +#define PCI_HT_SEC_ES		16	/* Enumeration Scratchpad Register */
  26.498 +#define PCI_HT_SEC_EH		18	/* Error Handling Register */
  26.499 +#define PCI_HT_SEC_MBU		20	/* Memory Base Upper Register */
  26.500 +#define PCI_HT_SEC_MLU		21	/* Memory Limit Upper Register */
  26.501 +#define PCI_HT_SEC_SIZEOF	24
  26.502 +
  26.503 +/* HyperTransport: Switch */
  26.504 +#define PCI_HT_SW_CMD		2	/* Switch Command Register */
  26.505 +#define  PCI_HT_SW_CMD_VIBERR	0x0080	/* VIB Error */
  26.506 +#define  PCI_HT_SW_CMD_VIBFL	0x0100	/* VIB Flood */
  26.507 +#define  PCI_HT_SW_CMD_VIBFT	0x0200	/* VIB Fatal */
  26.508 +#define  PCI_HT_SW_CMD_VIBNFT	0x0400	/* VIB Nonfatal */
  26.509 +#define PCI_HT_SW_PMASK		4	/* Partition Mask Register */
  26.510 +#define PCI_HT_SW_SWINF		8	/* Switch Info Register */
  26.511 +#define  PCI_HT_SW_SWINF_DP	0x0000001f /* Default Port */
  26.512 +#define  PCI_HT_SW_SWINF_EN	0x00000020 /* Enable Decode */
  26.513 +#define  PCI_HT_SW_SWINF_CR	0x00000040 /* Cold Reset */
  26.514 +#define  PCI_HT_SW_SWINF_PCIDX	0x00000f00 /* Performance Counter Index */
  26.515 +#define  PCI_HT_SW_SWINF_BLRIDX	0x0003f000 /* Base/Limit Range Index */
  26.516 +#define  PCI_HT_SW_SWINF_SBIDX	0x00002000 /* Secondary Base Range Index */
  26.517 +#define  PCI_HT_SW_SWINF_HP	0x00040000 /* Hot Plug */
  26.518 +#define  PCI_HT_SW_SWINF_HIDE	0x00080000 /* Hide Port */
  26.519 +#define PCI_HT_SW_PCD		12	/* Performance Counter Data Register */
  26.520 +#define PCI_HT_SW_BLRD		16	/* Base/Limit Range Data Register */
  26.521 +#define PCI_HT_SW_SBD		20	/* Secondary Base Data Register */
  26.522 +#define PCI_HT_SW_SIZEOF	24
  26.523 +
  26.524 +					/* Counter indices */
  26.525 +#define  PCI_HT_SW_PC_PCR	0x0	/* Posted Command Receive */
  26.526 +#define  PCI_HT_SW_PC_NPCR	0x1	/* Nonposted Command Receive */
  26.527 +#define  PCI_HT_SW_PC_RCR	0x2	/* Response Command Receive */
  26.528 +#define  PCI_HT_SW_PC_PDWR	0x3	/* Posted DW Receive */
  26.529 +#define  PCI_HT_SW_PC_NPDWR	0x4	/* Nonposted DW Receive */
  26.530 +#define  PCI_HT_SW_PC_RDWR	0x5	/* Response DW Receive */
  26.531 +#define  PCI_HT_SW_PC_PCT	0x6	/* Posted Command Transmit */
  26.532 +#define  PCI_HT_SW_PC_NPCT	0x7	/* Nonposted Command Transmit */
  26.533 +#define  PCI_HT_SW_PC_RCT	0x8	/* Response Command Transmit */
  26.534 +#define  PCI_HT_SW_PC_PDWT	0x9	/* Posted DW Transmit */
  26.535 +#define  PCI_HT_SW_PC_NPDWT	0xa	/* Nonposted DW Transmit */
  26.536 +#define  PCI_HT_SW_PC_RDWT	0xb	/* Response DW Transmit */
  26.537 +
  26.538 +					/* Base/Limit Range indices */
  26.539 +#define  PCI_HT_SW_BLR_BASE0_LO	0x0	/* Base 0[31:1], Enable */
  26.540 +#define  PCI_HT_SW_BLR_BASE0_HI	0x1	/* Base 0 Upper */
  26.541 +#define  PCI_HT_SW_BLR_LIM0_LO	0x2	/* Limit 0 Lower */
  26.542 +#define  PCI_HT_SW_BLR_LIM0_HI	0x3	/* Limit 0 Upper */
  26.543 +
  26.544 +					/* Secondary Base indices */
  26.545 +#define  PCI_HT_SW_SB_LO	0x0	/* Secondary Base[31:1], Enable */
  26.546 +#define  PCI_HT_SW_S0_HI	0x1	/* Secondary Base Upper */
  26.547 +
  26.548 +/* HyperTransport: Interrupt Discovery and Configuration */
  26.549 +#define PCI_HT_IDC_IDX		2	/* Index Register */
  26.550 +#define PCI_HT_IDC_DATA		4	/* Data Register */
  26.551 +#define PCI_HT_IDC_SIZEOF	8
  26.552 +
  26.553 +					/* Register indices */
  26.554 +#define  PCI_HT_IDC_IDX_LINT	0x01	/* Last Interrupt Register */
  26.555 +#define   PCI_HT_IDC_LINT	0x00ff0000 /* Last interrupt definition */
  26.556 +#define  PCI_HT_IDC_IDX_IDR	0x10	/* Interrupt Definition Registers */
  26.557 +					/* Low part (at index) */
  26.558 +#define   PCI_HT_IDC_IDR_MASK	0x10000001 /* Mask */
  26.559 +#define   PCI_HT_IDC_IDR_POL	0x10000002 /* Polarity */
  26.560 +#define   PCI_HT_IDC_IDR_II_2	0x1000001c /* IntrInfo[4:2]: Message Type */
  26.561 +#define   PCI_HT_IDC_IDR_II_5	0x10000020 /* IntrInfo[5]: Request EOI */
  26.562 +#define   PCI_HT_IDC_IDR_II_6	0x00ffffc0 /* IntrInfo[23:6] */
  26.563 +#define   PCI_HT_IDC_IDR_II_24	0xff000000 /* IntrInfo[31:24] */
  26.564 +					/* High part (at index + 1) */
  26.565 +#define   PCI_HT_IDC_IDR_II_32	0x00ffffff /* IntrInfo[55:32] */
  26.566 +#define   PCI_HT_IDC_IDR_PASSPW	0x40000000 /* PassPW setting for messages */
  26.567 +#define   PCI_HT_IDC_IDR_WEOI	0x80000000 /* Waiting for EOI */
  26.568 +
  26.569 +/* HyperTransport: Revision ID */
  26.570 +#define PCI_HT_RID_RID		2	/* Revision Register */
  26.571 +#define PCI_HT_RID_SIZEOF	4
  26.572 +
  26.573 +/* HyperTransport: UnitID Clumping */
  26.574 +#define PCI_HT_UIDC_CS		4	/* Clumping Support Register */
  26.575 +#define PCI_HT_UIDC_CE		8	/* Clumping Enable Register */
  26.576 +#define PCI_HT_UIDC_SIZEOF	12
  26.577 +
  26.578 +/* HyperTransport: Extended Configuration Space Access */
  26.579 +#define PCI_HT_ECSA_ADDR	4	/* Configuration Address Register */
  26.580 +#define  PCI_HT_ECSA_ADDR_REG	0x00000ffc /* Register */
  26.581 +#define  PCI_HT_ECSA_ADDR_FUN	0x00007000 /* Function */
  26.582 +#define  PCI_HT_ECSA_ADDR_DEV	0x000f1000 /* Device */
  26.583 +#define  PCI_HT_ECSA_ADDR_BUS	0x0ff00000 /* Bus Number */
  26.584 +#define  PCI_HT_ECSA_ADDR_TYPE	0x10000000 /* Access Type */
  26.585 +#define PCI_HT_ECSA_DATA	8	/* Configuration Data Register */
  26.586 +#define PCI_HT_ECSA_SIZEOF	12
  26.587 +
  26.588 +/* HyperTransport: Address Mapping */
  26.589 +#define PCI_HT_AM_CMD		2	/* Command Register */
  26.590 +#define  PCI_HT_AM_CMD_NDMA	0x000f	/* Number of DMA Mappings */
  26.591 +#define  PCI_HT_AM_CMD_IOSIZ	0x01f0	/* I/O Size */
  26.592 +#define  PCI_HT_AM_CMD_MT	0x0600	/* Map Type */
  26.593 +#define  PCI_HT_AM_CMD_MT_40B	0x0000	/* 40-bit */
  26.594 +#define  PCI_HT_AM_CMD_MT_64B	0x0200	/* 64-bit */
  26.595 +
  26.596 +					/* Window Control Register bits */
  26.597 +#define  PCI_HT_AM_SBW_CTR_COMP	0x1	/* Compat */
  26.598 +#define  PCI_HT_AM_SBW_CTR_NCOH	0x2	/* NonCoherent */
  26.599 +#define  PCI_HT_AM_SBW_CTR_ISOC	0x4	/* Isochronous */
  26.600 +#define  PCI_HT_AM_SBW_CTR_EN	0x8	/* Enable */
  26.601 +
  26.602 +/* HyperTransport: 40-bit Address Mapping */
  26.603 +#define PCI_HT_AM40_SBNPW	4	/* Secondary Bus Non-Prefetchable Window Register */
  26.604 +#define  PCI_HT_AM40_SBW_BASE	0x000fffff /* Window Base */
  26.605 +#define  PCI_HT_AM40_SBW_CTR	0xf0000000 /* Window Control */
  26.606 +#define PCI_HT_AM40_SBPW	8	/* Secondary Bus Prefetchable Window Register */
  26.607 +#define PCI_HT_AM40_DMA_PBASE0	12	/* DMA Window Primary Base 0 Register */
  26.608 +#define PCI_HT_AM40_DMA_CTR0	15	/* DMA Window Control 0 Register */
  26.609 +#define  PCI_HT_AM40_DMA_CTR_CTR 0xf0	/* Window Control */
  26.610 +#define PCI_HT_AM40_DMA_SLIM0	16	/* DMA Window Secondary Limit 0 Register */
  26.611 +#define PCI_HT_AM40_DMA_SBASE0	18	/* DMA Window Secondary Base 0 Register */
  26.612 +#define PCI_HT_AM40_SIZEOF	12	/* size is variable: 12 + 8 * NDMA */
  26.613 +
  26.614 +/* HyperTransport: 64-bit Address Mapping */
  26.615 +#define PCI_HT_AM64_IDX		4	/* Index Register */
  26.616 +#define PCI_HT_AM64_DATA_LO	8	/* Data Lower Register */
  26.617 +#define PCI_HT_AM64_DATA_HI	12	/* Data Upper Register */
  26.618 +#define PCI_HT_AM64_SIZEOF	16
  26.619 +
  26.620 +					/* Register indices */
  26.621 +#define  PCI_HT_AM64_IDX_SBNPW	0x00	/* Secondary Bus Non-Prefetchable Window Register */
  26.622 +#define   PCI_HT_AM64_W_BASE_LO	0xfff00000 /* Window Base Lower */
  26.623 +#define   PCI_HT_AM64_W_CTR	0x0000000f /* Window Control */
  26.624 +#define  PCI_HT_AM64_IDX_SBPW	0x01	/* Secondary Bus Prefetchable Window Register */
  26.625 +#define   PCI_HT_AM64_IDX_PBNPW	0x02	/* Primary Bus Non-Prefetchable Window Register */
  26.626 +#define   PCI_HT_AM64_IDX_DMAPB0 0x04	/* DMA Window Primary Base 0 Register */
  26.627 +#define   PCI_HT_AM64_IDX_DMASB0 0x05	/* DMA Window Secondary Base 0 Register */
  26.628 +#define   PCI_HT_AM64_IDX_DMASL0 0x06	/* DMA Window Secondary Limit 0 Register */
  26.629 +
  26.630 +/* HyperTransport: MSI Mapping */
  26.631 +#define PCI_HT_MSIM_CMD		2	/* Command Register */
  26.632 +#define  PCI_HT_MSIM_CMD_EN	0x0001	/* Mapping Active */
  26.633 +#define  PCI_HT_MSIM_CMD_FIXD	0x0002	/* MSI Mapping Address Fixed */
  26.634 +#define PCI_HT_MSIM_ADDR_LO	4	/* MSI Mapping Address Lower Register */
  26.635 +#define PCI_HT_MSIM_ADDR_HI	8	/* MSI Mapping Address Upper Register */
  26.636 +#define PCI_HT_MSIM_SIZEOF	12
  26.637 +
  26.638 +/* HyperTransport: DirectRoute */
  26.639 +#define PCI_HT_DR_CMD		2	/* Command Register */
  26.640 +#define  PCI_HT_DR_CMD_NDRS	0x000f	/* Number of DirectRoute Spaces */
  26.641 +#define  PCI_HT_DR_CMD_IDX	0x01f0	/* Index */
  26.642 +#define PCI_HT_DR_EN		4	/* Enable Vector Register */
  26.643 +#define PCI_HT_DR_DATA		8	/* Data Register */
  26.644 +#define PCI_HT_DR_SIZEOF	12
  26.645 +
  26.646 +					/* Register indices */
  26.647 +#define  PCI_HT_DR_IDX_BASE_LO	0x00	/* DirectRoute Base Lower Register */
  26.648 +#define   PCI_HT_DR_OTNRD	0x00000001 /* Opposite to Normal Request Direction */
  26.649 +#define   PCI_HT_DR_BL_LO	0xffffff00 /* Base/Limit Lower */
  26.650 +#define  PCI_HT_DR_IDX_BASE_HI	0x01	/* DirectRoute Base Upper Register */
  26.651 +#define  PCI_HT_DR_IDX_LIMIT_LO	0x02	/* DirectRoute Limit Lower Register */
  26.652 +#define  PCI_HT_DR_IDX_LIMIT_HI	0x03	/* DirectRoute Limit Upper Register */
  26.653 +
  26.654 +/* HyperTransport: VCSet */
  26.655 +#define PCI_HT_VCS_SUP		4	/* VCSets Supported Register */
  26.656 +#define PCI_HT_VCS_L1EN		5	/* Link 1 VCSets Enabled Register */
  26.657 +#define PCI_HT_VCS_L0EN		6	/* Link 0 VCSets Enabled Register */
  26.658 +#define PCI_HT_VCS_SBD		8	/* Stream Bucket Depth Register */
  26.659 +#define PCI_HT_VCS_SINT		9	/* Stream Interval Register */
  26.660 +#define PCI_HT_VCS_SSUP		10	/* Number of Streaming VCs Supported Register */
  26.661 +#define  PCI_HT_VCS_SSUP_0	0x00	/* Streaming VC 0 */
  26.662 +#define  PCI_HT_VCS_SSUP_3	0x01	/* Streaming VCs 0-3 */
  26.663 +#define  PCI_HT_VCS_SSUP_15	0x02	/* Streaming VCs 0-15 */
  26.664 +#define PCI_HT_VCS_NFCBD	12	/* Non-FC Bucket Depth Register */
  26.665 +#define PCI_HT_VCS_NFCINT	13	/* Non-FC Bucket Interval Register */
  26.666 +#define PCI_HT_VCS_SIZEOF	16
  26.667 +
  26.668 +/* HyperTransport: Retry Mode */
  26.669 +#define PCI_HT_RM_CTR0		4	/* Control 0 Register */
  26.670 +#define  PCI_HT_RM_CTR_LRETEN	0x01	/* Link Retry Enable */
  26.671 +#define  PCI_HT_RM_CTR_FSER	0x02	/* Force Single Error */
  26.672 +#define  PCI_HT_RM_CTR_ROLNEN	0x04	/* Rollover Nonfatal Enable */
  26.673 +#define  PCI_HT_RM_CTR_FSS	0x08	/* Force Single Stomp */
  26.674 +#define  PCI_HT_RM_CTR_RETNEN	0x10	/* Retry Nonfatal Enable */
  26.675 +#define  PCI_HT_RM_CTR_RETFEN	0x20	/* Retry Fatal Enable */
  26.676 +#define  PCI_HT_RM_CTR_AA	0xc0	/* Allowed Attempts */
  26.677 +#define PCI_HT_RM_STS0		5	/* Status 0 Register */
  26.678 +#define  PCI_HT_RM_STS_RETSNT	0x01	/* Retry Sent */
  26.679 +#define  PCI_HT_RM_STS_CNTROL	0x02	/* Count Rollover */
  26.680 +#define  PCI_HT_RM_STS_SRCV	0x04	/* Stomp Received */
  26.681 +#define PCI_HT_RM_CTR1		6	/* Control 1 Register */
  26.682 +#define PCI_HT_RM_STS1		7	/* Status 1 Register */
  26.683 +#define PCI_HT_RM_CNT0		8	/* Retry Count 0 Register */
  26.684 +#define PCI_HT_RM_CNT1		10	/* Retry Count 1 Register */
  26.685 +#define PCI_HT_RM_SIZEOF	12
  26.686 +
  26.687 +/* PCI Express */
  26.688 +#define PCI_EXP_FLAGS		0x2	/* Capabilities register */
  26.689 +#define PCI_EXP_FLAGS_VERS	0x000f	/* Capability version */
  26.690 +#define PCI_EXP_FLAGS_TYPE	0x00f0	/* Device/Port type */
  26.691 +#define  PCI_EXP_TYPE_ENDPOINT	0x0	/* Express Endpoint */
  26.692 +#define  PCI_EXP_TYPE_LEG_END	0x1	/* Legacy Endpoint */
  26.693 +#define  PCI_EXP_TYPE_ROOT_PORT 0x4	/* Root Port */
  26.694 +#define  PCI_EXP_TYPE_UPSTREAM	0x5	/* Upstream Port */
  26.695 +#define  PCI_EXP_TYPE_DOWNSTREAM 0x6	/* Downstream Port */
  26.696 +#define  PCI_EXP_TYPE_PCI_BRIDGE 0x7	/* PCI/PCI-X Bridge */
  26.697 +#define  PCI_EXP_TYPE_PCIE_BRIDGE 0x8	/* PCI/PCI-X to PCIE Bridge */
  26.698 +#define PCI_EXP_FLAGS_SLOT	0x0100	/* Slot implemented */
  26.699 +#define PCI_EXP_FLAGS_IRQ	0x3e00	/* Interrupt message number */
  26.700 +#define PCI_EXP_DEVCAP		0x4	/* Device capabilities */
  26.701 +#define  PCI_EXP_DEVCAP_PAYLOAD	0x07	/* Max_Payload_Size */
  26.702 +#define  PCI_EXP_DEVCAP_PHANTOM	0x18	/* Phantom functions */
  26.703 +#define  PCI_EXP_DEVCAP_EXT_TAG	0x20	/* Extended tags */
  26.704 +#define  PCI_EXP_DEVCAP_L0S	0x1c0	/* L0s Acceptable Latency */
  26.705 +#define  PCI_EXP_DEVCAP_L1	0xe00	/* L1 Acceptable Latency */
  26.706 +#define  PCI_EXP_DEVCAP_ATN_BUT	0x1000	/* Attention Button Present */
  26.707 +#define  PCI_EXP_DEVCAP_ATN_IND	0x2000	/* Attention Indicator Present */
  26.708 +#define  PCI_EXP_DEVCAP_PWR_IND	0x4000	/* Power Indicator Present */
  26.709 +#define  PCI_EXP_DEVCAP_PWR_VAL	0x3fc0000 /* Slot Power Limit Value */
  26.710 +#define  PCI_EXP_DEVCAP_PWR_SCL	0xc000000 /* Slot Power Limit Scale */
  26.711 +#define PCI_EXP_DEVCTL		0x8	/* Device Control */
  26.712 +#define  PCI_EXP_DEVCTL_CERE	0x0001	/* Correctable Error Reporting En. */
  26.713 +#define  PCI_EXP_DEVCTL_NFERE	0x0002	/* Non-Fatal Error Reporting Enable */
  26.714 +#define  PCI_EXP_DEVCTL_FERE	0x0004	/* Fatal Error Reporting Enable */
  26.715 +#define  PCI_EXP_DEVCTL_URRE	0x0008	/* Unsupported Request Reporting En. */
  26.716 +#define  PCI_EXP_DEVCTL_RELAXED	0x0010	/* Enable Relaxed Ordering */
  26.717 +#define  PCI_EXP_DEVCTL_PAYLOAD	0x00e0	/* Max_Payload_Size */
  26.718 +#define  PCI_EXP_DEVCTL_EXT_TAG	0x0100	/* Extended Tag Field Enable */
  26.719 +#define  PCI_EXP_DEVCTL_PHANTOM	0x0200	/* Phantom Functions Enable */
  26.720 +#define  PCI_EXP_DEVCTL_AUX_PME	0x0400	/* Auxiliary Power PM Enable */
  26.721 +#define  PCI_EXP_DEVCTL_NOSNOOP	0x0800	/* Enable No Snoop */
  26.722 +#define  PCI_EXP_DEVCTL_READRQ	0x7000	/* Max_Read_Request_Size */
  26.723 +#define PCI_EXP_DEVSTA		0xa	/* Device Status */
  26.724 +#define  PCI_EXP_DEVSTA_CED	0x01	/* Correctable Error Detected */
  26.725 +#define  PCI_EXP_DEVSTA_NFED	0x02	/* Non-Fatal Error Detected */
  26.726 +#define  PCI_EXP_DEVSTA_FED	0x04	/* Fatal Error Detected */
  26.727 +#define  PCI_EXP_DEVSTA_URD	0x08	/* Unsupported Request Detected */
  26.728 +#define  PCI_EXP_DEVSTA_AUXPD	0x10	/* AUX Power Detected */
  26.729 +#define  PCI_EXP_DEVSTA_TRPND	0x20	/* Transactions Pending */
  26.730 +#define PCI_EXP_LNKCAP		0xc	/* Link Capabilities */
  26.731 +#define  PCI_EXP_LNKCAP_SPEED	0x0000f	/* Maximum Link Speed */
  26.732 +#define  PCI_EXP_LNKCAP_WIDTH	0x003f0	/* Maximum Link Width */
  26.733 +#define  PCI_EXP_LNKCAP_ASPM	0x00c00	/* Active State Power Management */
  26.734 +#define  PCI_EXP_LNKCAP_L0S	0x07000	/* L0s Acceptable Latency */
  26.735 +#define  PCI_EXP_LNKCAP_L1	0x38000	/* L1 Acceptable Latency */
  26.736 +#define  PCI_EXP_LNKCAP_PORT	0xff000000 /* Port Number */
  26.737 +#define PCI_EXP_LNKCTL		0x10	/* Link Control */
  26.738 +#define  PCI_EXP_LNKCTL_ASPM	0x0003	/* ASPM Control */
  26.739 +#define  PCI_EXP_LNKCTL_RCB	0x0008	/* Read Completion Boundary */
  26.740 +#define  PCI_EXP_LNKCTL_DISABLE	0x0010	/* Link Disable */
  26.741 +#define  PCI_EXP_LNKCTL_RETRAIN	0x0020	/* Retrain Link */
  26.742 +#define  PCI_EXP_LNKCTL_CLOCK	0x0040	/* Common Clock Configuration */
  26.743 +#define  PCI_EXP_LNKCTL_XSYNCH	0x0080	/* Extended Synch */
  26.744 +#define PCI_EXP_LNKSTA		0x12	/* Link Status */
  26.745 +#define  PCI_EXP_LNKSTA_SPEED	0x000f	/* Negotiated Link Speed */
  26.746 +#define  PCI_EXP_LNKSTA_WIDTH	0x03f0	/* Negotiated Link Width */
  26.747 +#define  PCI_EXP_LNKSTA_TR_ERR	0x0400	/* Training Error */
  26.748 +#define  PCI_EXP_LNKSTA_TRAIN	0x0800	/* Link Training */
  26.749 +#define  PCI_EXP_LNKSTA_SL_CLK	0x1000	/* Slot Clock Configuration */
  26.750 +#define PCI_EXP_SLTCAP		0x14	/* Slot Capabilities */
  26.751 +#define  PCI_EXP_SLTCAP_ATNB	0x0001	/* Attention Button Present */
  26.752 +#define  PCI_EXP_SLTCAP_PWRC	0x0002	/* Power Controller Present */
  26.753 +#define  PCI_EXP_SLTCAP_MRL	0x0004	/* MRL Sensor Present */
  26.754 +#define  PCI_EXP_SLTCAP_ATNI	0x0008	/* Attention Indicator Present */
  26.755 +#define  PCI_EXP_SLTCAP_PWRI	0x0010	/* Power Indicator Present */
  26.756 +#define  PCI_EXP_SLTCAP_HPS	0x0020	/* Hot-Plug Surprise */
  26.757 +#define  PCI_EXP_SLTCAP_HPC	0x0040	/* Hot-Plug Capable */
  26.758 +#define  PCI_EXP_SLTCAP_PWR_VAL	0x00007f80 /* Slot Power Limit Value */
  26.759 +#define  PCI_EXP_SLTCAP_PWR_SCL	0x00018000 /* Slot Power Limit Scale */
  26.760 +#define  PCI_EXP_SLTCAP_PSN	0xfff80000 /* Physical Slot Number */
  26.761 +#define PCI_EXP_SLTCTL		0x18	/* Slot Control */
  26.762 +#define  PCI_EXP_SLTCTL_ATNB	0x0001	/* Attention Button Pressed Enable */
  26.763 +#define  PCI_EXP_SLTCTL_PWRF	0x0002	/* Power Fault Detected Enable */
  26.764 +#define  PCI_EXP_SLTCTL_MRLS	0x0004	/* MRL Sensor Changed Enable */
  26.765 +#define  PCI_EXP_SLTCTL_PRSD	0x0008	/* Presence Detect Changed Enable */
  26.766 +#define  PCI_EXP_SLTCTL_CMDC	0x0010	/* Command Completed Interrupt Enable */
  26.767 +#define  PCI_EXP_SLTCTL_HPIE	0x0020	/* Hot-Plug Interrupt Enable */
  26.768 +#define  PCI_EXP_SLTCTL_ATNI	0x00C0	/* Attention Indicator Control */
  26.769 +#define  PCI_EXP_SLTCTL_PWRI	0x0300	/* Power Indicator Control */
  26.770 +#define  PCI_EXP_SLTCTL_PWRC	0x0400	/* Power Controller Control */
  26.771 +#define PCI_EXP_SLTSTA		0x1a	/* Slot Status */
  26.772 +#define PCI_EXP_RTCTL		0x1c	/* Root Control */
  26.773 +#define  PCI_EXP_RTCTL_SECEE	0x1	/* System Error on Correctable Error */
  26.774 +#define  PCI_EXP_RTCTL_SENFEE	0x1	/* System Error on Non-Fatal Error */
  26.775 +#define  PCI_EXP_RTCTL_SEFEE	0x1	/* System Error on Fatal Error */
  26.776 +#define  PCI_EXP_RTCTL_PMEIE	0x1	/* PME Interrupt Enable */
  26.777 +#define PCI_EXP_RTSTA		0x20	/* Root Status */
  26.778 +
  26.779 +/* MSI-X */
  26.780 +#define  PCI_MSIX_ENABLE	0x8000
  26.781 +#define  PCI_MSIX_MASK		0x4000
  26.782 +#define  PCI_MSIX_TABSIZE	0x03ff
  26.783 +#define PCI_MSIX_TABLE		4
  26.784 +#define PCI_MSIX_PBA		8
  26.785 +#define  PCI_MSIX_BIR		0x7
  26.786 +
  26.787 +/* Subsystem vendor/device ID for PCI bridges */
  26.788 +#define PCI_SSVID_VENDOR	4
  26.789 +#define PCI_SSVID_DEVICE	6
  26.790 +
  26.791 +/* Advanced Error Reporting */
  26.792 +#define PCI_ERR_UNCOR_STATUS	4	/* Uncorrectable Error Status */
  26.793 +#define  PCI_ERR_UNC_TRAIN	0x00000001	/* Training */
  26.794 +#define  PCI_ERR_UNC_DLP	0x00000010	/* Data Link Protocol */
  26.795 +#define  PCI_ERR_UNC_POISON_TLP	0x00001000	/* Poisoned TLP */
  26.796 +#define  PCI_ERR_UNC_FCP	0x00002000	/* Flow Control Protocol */
  26.797 +#define  PCI_ERR_UNC_COMP_TIME	0x00004000	/* Completion Timeout */
  26.798 +#define  PCI_ERR_UNC_COMP_ABORT	0x00008000	/* Completer Abort */
  26.799 +#define  PCI_ERR_UNC_UNX_COMP	0x00010000	/* Unexpected Completion */
  26.800 +#define  PCI_ERR_UNC_RX_OVER	0x00020000	/* Receiver Overflow */
  26.801 +#define  PCI_ERR_UNC_MALF_TLP	0x00040000	/* Malformed TLP */
  26.802 +#define  PCI_ERR_UNC_ECRC	0x00080000	/* ECRC Error Status */
  26.803 +#define  PCI_ERR_UNC_UNSUP	0x00100000	/* Unsupported Request */
  26.804 +#define PCI_ERR_UNCOR_MASK	8	/* Uncorrectable Error Mask */
  26.805 +	/* Same bits as above */
  26.806 +#define PCI_ERR_UNCOR_SEVER	12	/* Uncorrectable Error Severity */
  26.807 +	/* Same bits as above */
  26.808 +#define PCI_ERR_COR_STATUS	16	/* Correctable Error Status */
  26.809 +#define  PCI_ERR_COR_RCVR	0x00000001	/* Receiver Error Status */
  26.810 +#define  PCI_ERR_COR_BAD_TLP	0x00000040	/* Bad TLP Status */
  26.811 +#define  PCI_ERR_COR_BAD_DLLP	0x00000080	/* Bad DLLP Status */
  26.812 +#define  PCI_ERR_COR_REP_ROLL	0x00000100	/* REPLAY_NUM Rollover */
  26.813 +#define  PCI_ERR_COR_REP_TIMER	0x00001000	/* Replay Timer Timeout */
  26.814 +#define PCI_ERR_COR_MASK	20	/* Correctable Error Mask */
  26.815 +	/* Same bits as above */
  26.816 +#define PCI_ERR_CAP		24	/* Advanced Error Capabilities */
  26.817 +#define  PCI_ERR_CAP_FEP(x)	((x) & 31)	/* First Error Pointer */
  26.818 +#define  PCI_ERR_CAP_ECRC_GENC	0x00000020	/* ECRC Generation Capable */
  26.819 +#define  PCI_ERR_CAP_ECRC_GENE	0x00000040	/* ECRC Generation Enable */
  26.820 +#define  PCI_ERR_CAP_ECRC_CHKC	0x00000080	/* ECRC Check Capable */
  26.821 +#define  PCI_ERR_CAP_ECRC_CHKE	0x00000100	/* ECRC Check Enable */
  26.822 +#define PCI_ERR_HEADER_LOG	28	/* Header Log Register (16 bytes) */
  26.823 +#define PCI_ERR_ROOT_COMMAND	44	/* Root Error Command */
  26.824 +#define PCI_ERR_ROOT_STATUS	48
  26.825 +#define PCI_ERR_ROOT_COR_SRC	52
  26.826 +#define PCI_ERR_ROOT_SRC	54
  26.827 +
  26.828 +/* Virtual Channel */
  26.829 +#define PCI_VC_PORT_REG1	4
  26.830 +#define PCI_VC_PORT_REG2	8
  26.831 +#define PCI_VC_PORT_CTRL	12
  26.832 +#define PCI_VC_PORT_STATUS	14
  26.833 +#define PCI_VC_RES_CAP		16
  26.834 +#define PCI_VC_RES_CTRL		20
  26.835 +#define PCI_VC_RES_STATUS	26
  26.836 +
  26.837 +/* Power Budgeting */
  26.838 +#define PCI_PWR_DSR		4	/* Data Select Register */
  26.839 +#define PCI_PWR_DATA		8	/* Data Register */
  26.840 +#define  PCI_PWR_DATA_BASE(x)	((x) & 0xff)	    /* Base Power */
  26.841 +#define  PCI_PWR_DATA_SCALE(x)	(((x) >> 8) & 3)    /* Data Scale */
  26.842 +#define  PCI_PWR_DATA_PM_SUB(x)	(((x) >> 10) & 7)   /* PM Sub State */
  26.843 +#define  PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3) /* PM State */
  26.844 +#define  PCI_PWR_DATA_TYPE(x)	(((x) >> 15) & 7)   /* Type */
  26.845 +#define  PCI_PWR_DATA_RAIL(x)	(((x) >> 18) & 7)   /* Power Rail */
  26.846 +#define PCI_PWR_CAP		12	/* Capability */
  26.847 +#define  PCI_PWR_CAP_BUDGET(x)	((x) & 1)	/* Included in system budget */
  26.848 +
  26.849 +/*
  26.850 + * The PCI interface treats multi-function devices as independent
  26.851 + * devices.  The slot/function address of each device is encoded
  26.852 + * in a single byte as follows:
  26.853 + *
  26.854 + *	7:3 = slot
  26.855 + *	2:0 = function
  26.856 + */
  26.857 +#define PCI_DEVFN(slot,func)	((((slot) & 0x1f) << 3) | ((func) & 0x07))
  26.858 +#define PCI_SLOT(devfn)		(((devfn) >> 3) & 0x1f)
  26.859 +#define PCI_FUNC(devfn)		((devfn) & 0x07)
  26.860 +
  26.861 +/* Device classes and subclasses */
  26.862 +
  26.863 +#define PCI_CLASS_NOT_DEFINED		0x0000
  26.864 +#define PCI_CLASS_NOT_DEFINED_VGA	0x0001
  26.865 +
  26.866 +#define PCI_BASE_CLASS_STORAGE		0x01
  26.867 +#define PCI_CLASS_STORAGE_SCSI		0x0100
  26.868 +#define PCI_CLASS_STORAGE_IDE		0x0101
  26.869 +#define PCI_CLASS_STORAGE_FLOPPY	0x0102
  26.870 +#define PCI_CLASS_STORAGE_IPI		0x0103
  26.871 +#define PCI_CLASS_STORAGE_RAID		0x0104
  26.872 +#define PCI_CLASS_STORAGE_ATA		0x0105
  26.873 +#define PCI_CLASS_STORAGE_SATA		0x0106
  26.874 +#define PCI_CLASS_STORAGE_SAS		0x0107
  26.875 +#define PCI_CLASS_STORAGE_OTHER		0x0180
  26.876 +
  26.877 +#define PCI_BASE_CLASS_NETWORK		0x02
  26.878 +#define PCI_CLASS_NETWORK_ETHERNET	0x0200
  26.879 +#define PCI_CLASS_NETWORK_TOKEN_RING	0x0201
  26.880 +#define PCI_CLASS_NETWORK_FDDI		0x0202
  26.881 +#define PCI_CLASS_NETWORK_ATM		0x0203
  26.882 +#define PCI_CLASS_NETWORK_ISDN		0x0204
  26.883 +#define PCI_CLASS_NETWORK_OTHER		0x0280
  26.884 +
  26.885 +#define PCI_BASE_CLASS_DISPLAY		0x03
  26.886 +#define PCI_CLASS_DISPLAY_VGA		0x0300
  26.887 +#define PCI_CLASS_DISPLAY_XGA		0x0301
  26.888 +#define PCI_CLASS_DISPLAY_3D		0x0302
  26.889 +#define PCI_CLASS_DISPLAY_OTHER		0x0380
  26.890 +
  26.891 +#define PCI_BASE_CLASS_MULTIMEDIA	0x04
  26.892 +#define PCI_CLASS_MULTIMEDIA_VIDEO	0x0400
  26.893 +#define PCI_CLASS_MULTIMEDIA_AUDIO	0x0401
  26.894 +#define PCI_CLASS_MULTIMEDIA_PHONE	0x0402
  26.895 +#define PCI_CLASS_MULTIMEDIA_AUDIO_DEV	0x0403
  26.896 +#define PCI_CLASS_MULTIMEDIA_OTHER	0x0480
  26.897 +
  26.898 +#define PCI_BASE_CLASS_MEMORY		0x05
  26.899 +#define  PCI_CLASS_MEMORY_RAM		0x0500
  26.900 +#define  PCI_CLASS_MEMORY_FLASH		0x0501
  26.901 +#define  PCI_CLASS_MEMORY_OTHER		0x0580
  26.902 +
  26.903 +#define PCI_BASE_CLASS_BRIDGE		0x06
  26.904 +#define  PCI_CLASS_BRIDGE_HOST		0x0600
  26.905 +#define  PCI_CLASS_BRIDGE_ISA		0x0601
  26.906 +#define  PCI_CLASS_BRIDGE_EISA		0x0602
  26.907 +#define  PCI_CLASS_BRIDGE_MC		0x0603
  26.908 +#define  PCI_CLASS_BRIDGE_PCI		0x0604
  26.909 +#define  PCI_CLASS_BRIDGE_PCMCIA	0x0605
  26.910 +#define  PCI_CLASS_BRIDGE_NUBUS		0x0606
  26.911 +#define  PCI_CLASS_BRIDGE_CARDBUS	0x0607
  26.912 +#define  PCI_CLASS_BRIDGE_RACEWAY	0x0608
  26.913 +#define  PCI_CLASS_BRIDGE_PCI_SEMI	0x0609
  26.914 +#define  PCI_CLASS_BRIDGE_IB_TO_PCI	0x060a
  26.915 +#define  PCI_CLASS_BRIDGE_OTHER		0x0680
  26.916 +
  26.917 +#define PCI_BASE_CLASS_COMMUNICATION	0x07
  26.918 +#define PCI_CLASS_COMMUNICATION_SERIAL	0x0700
  26.919 +#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701
  26.920 +#define PCI_CLASS_COMMUNICATION_MSERIAL	0x0702
  26.921 +#define PCI_CLASS_COMMUNICATION_MODEM	0x0703
  26.922 +#define PCI_CLASS_COMMUNICATION_OTHER	0x0780
  26.923 +
  26.924 +#define PCI_BASE_CLASS_SYSTEM		0x08
  26.925 +#define PCI_CLASS_SYSTEM_PIC		0x0800
  26.926 +#define PCI_CLASS_SYSTEM_DMA		0x0801
  26.927 +#define PCI_CLASS_SYSTEM_TIMER		0x0802
  26.928 +#define PCI_CLASS_SYSTEM_RTC		0x0803
  26.929 +#define PCI_CLASS_SYSTEM_PCI_HOTPLUG	0x0804
  26.930 +#define PCI_CLASS_SYSTEM_OTHER		0x0880
  26.931 +
  26.932 +#define PCI_BASE_CLASS_INPUT		0x09
  26.933 +#define PCI_CLASS_INPUT_KEYBOARD	0x0900
  26.934 +#define PCI_CLASS_INPUT_PEN		0x0901
  26.935 +#define PCI_CLASS_INPUT_MOUSE		0x0902
  26.936 +#define PCI_CLASS_INPUT_SCANNER		0x0903
  26.937 +#define PCI_CLASS_INPUT_GAMEPORT	0x0904
  26.938 +#define PCI_CLASS_INPUT_OTHER		0x0980
  26.939 +
  26.940 +#define PCI_BASE_CLASS_DOCKING		0x0a
  26.941 +#define PCI_CLASS_DOCKING_GENERIC	0x0a00
  26.942 +#define PCI_CLASS_DOCKING_OTHER		0x0a80
  26.943 +
  26.944 +#define PCI_BASE_CLASS_PROCESSOR	0x0b
  26.945 +#define PCI_CLASS_PROCESSOR_386		0x0b00
  26.946 +#define PCI_CLASS_PROCESSOR_486		0x0b01
  26.947 +#define PCI_CLASS_PROCESSOR_PENTIUM	0x0b02
  26.948 +#define PCI_CLASS_PROCESSOR_ALPHA	0x0b10
  26.949 +#define PCI_CLASS_PROCESSOR_POWERPC	0x0b20
  26.950 +#define PCI_CLASS_PROCESSOR_MIPS	0x0b30
  26.951 +#define PCI_CLASS_PROCESSOR_CO		0x0b40
  26.952 +
  26.953 +#define PCI_BASE_CLASS_SERIAL		0x0c
  26.954 +#define PCI_CLASS_SERIAL_FIREWIRE	0x0c00
  26.955 +#define PCI_CLASS_SERIAL_ACCESS		0x0c01
  26.956 +#define PCI_CLASS_SERIAL_SSA		0x0c02
  26.957 +#define PCI_CLASS_SERIAL_USB		0x0c03
  26.958 +#define PCI_CLASS_SERIAL_FIBER		0x0c04
  26.959 +#define PCI_CLASS_SERIAL_SMBUS		0x0c05
  26.960 +#define PCI_CLASS_SERIAL_INFINIBAND	0x0c06
  26.961 +
  26.962 +#define PCI_BASE_CLASS_WIRELESS		0x0d
  26.963 +#define PCI_CLASS_WIRELESS_IRDA		0x0d00
  26.964 +#define PCI_CLASS_WIRELESS_CONSUMER_IR	0x0d01
  26.965 +#define PCI_CLASS_WIRELESS_RF		0x0d10
  26.966 +#define PCI_CLASS_WIRELESS_OTHER	0x0d80
  26.967 +
  26.968 +#define PCI_BASE_CLASS_INTELLIGENT	0x0e
  26.969 +#define PCI_CLASS_INTELLIGENT_I2O	0x0e00
  26.970 +
  26.971 +#define PCI_BASE_CLASS_SATELLITE	0x0f
  26.972 +#define PCI_CLASS_SATELLITE_TV		0x0f00
  26.973 +#define PCI_CLASS_SATELLITE_AUDIO	0x0f01
  26.974 +#define PCI_CLASS_SATELLITE_VOICE	0x0f03
  26.975 +#define PCI_CLASS_SATELLITE_DATA	0x0f04
  26.976 +
  26.977 +#define PCI_BASE_CLASS_CRYPT		0x10
  26.978 +#define PCI_CLASS_CRYPT_NETWORK		0x1000
  26.979 +#define PCI_CLASS_CRYPT_ENTERTAINMENT	0x1010
  26.980 +#define PCI_CLASS_CRYPT_OTHER		0x1080
  26.981 +
  26.982 +#define PCI_BASE_CLASS_SIGNAL		0x11
  26.983 +#define PCI_CLASS_SIGNAL_DPIO		0x1100
  26.984 +#define PCI_CLASS_SIGNAL_PERF_CTR	0x1101
  26.985 +#define PCI_CLASS_SIGNAL_SYNCHRONIZER	0x1110
  26.986 +#define PCI_CLASS_SIGNAL_OTHER		0x1180
  26.987 +
  26.988 +#define PCI_CLASS_OTHERS		0xff
  26.989 +
  26.990 +/* Several ID's we need in the library */
  26.991 +
  26.992 +#define PCI_VENDOR_ID_INTEL		0x8086
  26.993 +#define PCI_VENDOR_ID_COMPAQ		0x0e11
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/i386-io-hurd.h	Mon Aug 13 17:49:00 2007 -0400
    27.3 @@ -0,0 +1,27 @@
    27.4 +/*
    27.5 + *	The PCI Library -- Access to i386 I/O ports on GNU Hurd
    27.6 + *
    27.7 + *	Copyright (c) 2003 Marco Gerards <metgerards@student.han.nl>
    27.8 + *	Copyright (c) 2003 Martin Mares <mj@ucw.cz>
    27.9 + *	Copyright (c) 2006 Samuel Thibault <samuel.thibault@ens-lyon.org> and
   27.10 + *	                   Thomas Schwinge <tschwinge@gnu.org>
   27.11 + *	Copyright (c) 2007 Thomas Schwinge <tschwinge@gnu.org>
   27.12 + *
   27.13 + *	Can be freely distributed and used under the terms of the GNU GPL.
   27.14 + */
   27.15 +
   27.16 +#include <sys/io.h>
   27.17 +
   27.18 +static inline int
   27.19 +intel_setup_io(struct pci_access *a UNUSED)
   27.20 +{
   27.21 +  return (ioperm (0, 65535, 1) == -1) ? 0 : 1;
   27.22 +}
   27.23 +
   27.24 +static inline int
   27.25 +intel_cleanup_io(struct pci_access *a UNUSED)
   27.26 +{
   27.27 +  ioperm (0, 65535, 0);
   27.28 +
   27.29 +  return -1;
   27.30 +}
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/i386-io-linux.h	Mon Aug 13 17:49:00 2007 -0400
    28.3 @@ -0,0 +1,26 @@
    28.4 +/*
    28.5 + *	The PCI Library -- Access to i386 I/O ports on Linux
    28.6 + *
    28.7 + *	Copyright (c) 1997--2006 Martin Mares <mj@ucw.cz>
    28.8 + *
    28.9 + *	Can be freely distributed and used under the terms of the GNU GPL.
   28.10 + */
   28.11 +
   28.12 +#ifdef __GLIBC__
   28.13 +#include <sys/io.h>
   28.14 +#else
   28.15 +#include <asm/io.h>
   28.16 +#endif
   28.17 +
   28.18 +static int
   28.19 +intel_setup_io(struct pci_access *a UNUSED)
   28.20 +{
   28.21 +  return (iopl(3) < 0) ? 0 : 1;
   28.22 +}
   28.23 +
   28.24 +static inline int
   28.25 +intel_cleanup_io(struct pci_access *a UNUSED)
   28.26 +{
   28.27 +  iopl(3);
   28.28 +  return -1;
   28.29 +}
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/i386-io-sunos.h	Mon Aug 13 17:49:00 2007 -0400
    29.3 @@ -0,0 +1,66 @@
    29.4 +/*
    29.5 + *	The PCI Library -- Access to i386 I/O ports on Solaris
    29.6 + *
    29.7 + *	Copyright (c) 2003 Bill Moore <billm@eng.sun.com>
    29.8 + *	Copyright (c) 2003--2006 Martin Mares <mj@ucw.cz>
    29.9 + *
   29.10 + *	Can be freely distributed and used under the terms of the GNU GPL.
   29.11 + */
   29.12 +
   29.13 +#include <sys/sysi86.h>
   29.14 +#include <sys/psw.h>
   29.15 +
   29.16 +static int
   29.17 +intel_setup_io(struct pci_access *a UNUSED)
   29.18 +{
   29.19 +  return (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0) ? 0 : 1;
   29.20 +}
   29.21 +
   29.22 +static inline int
   29.23 +intel_cleanup_io(struct pci_access *a UNUSED)
   29.24 +{
   29.25 +  /* FIXME: How to switch off I/O port access? */
   29.26 +  return 1;
   29.27 +}
   29.28 +
   29.29 +static inline u8
   29.30 +inb (u16 port)
   29.31 +{
   29.32 +  u8 v;
   29.33 +  __asm__ __volatile__ ("inb (%w1)":"=a" (v):"Nd" (port));
   29.34 +  return v;
   29.35 +}
   29.36 +
   29.37 +static inline u16
   29.38 +inw (u16 port)
   29.39 +{
   29.40 +  u16 v;
   29.41 +  __asm__ __volatile__ ("inw (%w1)":"=a" (v):"Nd" (port));
   29.42 +  return v;
   29.43 +}
   29.44 +
   29.45 +static inline u32
   29.46 +inl (u16 port)
   29.47 +{
   29.48 +  u32 v;
   29.49 +  __asm__ __volatile__ ("inl (%w1)":"=a" (v):"Nd" (port));
   29.50 +  return v;
   29.51 +}
   29.52 +
   29.53 +static inline void
   29.54 +outb (u8 value, u16 port)
   29.55 +{
   29.56 +  __asm__ __volatile__ ("outb (%w1)": :"a" (value), "Nd" (port));
   29.57 +}
   29.58 +
   29.59 +static inline void
   29.60 +outw (u16 value, u16 port)
   29.61 +{
   29.62 +  __asm__ __volatile__ ("outw (%w1)": :"a" (value), "Nd" (port));
   29.63 +}
   29.64 +
   29.65 +static inline void
   29.66 +outl (u32 value, u16 port)
   29.67 +{
   29.68 +  __asm__ __volatile__ ("outl (%w1)": :"a" (value), "Nd" (port));
   29.69 +}
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/i386-io-windows.h	Mon Aug 13 17:49:00 2007 -0400
    30.3 @@ -0,0 +1,61 @@
    30.4 +/*
    30.5 + *	The PCI Library -- Access to i386 I/O ports on Windows
    30.6 + *
    30.7 + *	Copyright (c) 2004 Alexander Stock <stock.alexander@gmx.de>
    30.8 + *	Copyright (c) 2006 Martin Mares <mj@ucw.cz>
    30.9 + *
   30.10 + *	Can be freely distributed and used under the terms of the GNU GPL.
   30.11 + */
   30.12 +
   30.13 +#include <io.h>
   30.14 +#include <conio.h>
   30.15 +#include <windows.h>
   30.16 +
   30.17 +#define outb(x,y) _outp(y,x)
   30.18 +#define outw(x,y) _outpw(y,x)
   30.19 +#define outl(x,y) _outpd(y,x)
   30.20 +
   30.21 +#define inb(x) _inp(x)
   30.22 +#define inw(x) _inpw(x)
   30.23 +#define inl(x) _inpd(x)
   30.24 +
   30.25 +static int
   30.26 +intel_setup_io(struct pci_access *a)
   30.27 +{
   30.28 +  typedef int (*MYPROC)(void);
   30.29 +  MYPROC InitializeWinIo;
   30.30 +  HMODULE lib;
   30.31 +
   30.32 +  intel_iopl_set = 0;
   30.33 +
   30.34 +  lib = LoadLibrary("WinIo.dll");
   30.35 +  if (!lib)
   30.36 +    {
   30.37 +      a->warning("i386-io-windows: Couldn't load WinIo.dll.");
   30.38 +      return 0;
   30.39 +    }
   30.40 +  /* XXX: Is this really needed? --mj */
   30.41 +  GetProcAddress(lib, "InitializeWinIo");
   30.42 +
   30.43 +  InitializeWinIo = (MYPROC) GetProcAddress(lib, "InitializeWinIo");
   30.44 +  if (!InitializeWinIo)
   30.45 +    {
   30.46 +      a->warning("i386-io-windows: Couldn't find InitializeWinIo function.");
   30.47 +      return 0;
   30.48 +    }
   30.49 +
   30.50 +  if (!InitializeWinIo())
   30.51 +    {
   30.52 +      a->warning("i386-io-windows: InitializeWinIo() failed.");
   30.53 +      return 0;
   30.54 +    }
   30.55 +
   30.56 +  return 1;
   30.57 +}
   30.58 +
   30.59 +static inline int
   30.60 +intel_cleanup_io(struct pci_access *a UNUSED)
   30.61 +{
   30.62 +  //TODO: DeInitializeWinIo!
   30.63 +  return 1;
   30.64 +}
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/i386-ports.c	Mon Aug 13 17:49:00 2007 -0400
    31.3 @@ -0,0 +1,281 @@
    31.4 +/*
    31.5 + *	The PCI Library -- Direct Configuration access via i386 Ports
    31.6 + *
    31.7 + *	Copyright (c) 1997--2006 Martin Mares <mj@ucw.cz>
    31.8 + *
    31.9 + *	Can be freely distributed and used under the terms of the GNU GPL.
   31.10 + */
   31.11 +
   31.12 +#define _GNU_SOURCE
   31.13 +
   31.14 +#include "internal.h"
   31.15 +
   31.16 +#include <unistd.h>
   31.17 +
   31.18 +#if defined(PCI_OS_LINUX)
   31.19 +#include "i386-io-linux.h"
   31.20 +#elif defined(PCI_OS_GNU)
   31.21 +#include "i386-io-hurd.h"
   31.22 +#elif defined(PCI_OS_SUNOS)
   31.23 +#include "i386-io-sunos.h"
   31.24 +#elif defined(PCI_OS_WINDOWS)
   31.25 +#include "i386-io-windows.h"
   31.26 +#else
   31.27 +#error Do not know how to access I/O ports on this OS.
   31.28 +#endif
   31.29 +
   31.30 +static int conf12_io_enabled = -1;		/* -1=haven't tried, 0=failed, 1=succeeded */
   31.31 +
   31.32 +static int
   31.33 +conf12_setup_io(struct pci_access *a)
   31.34 +{
   31.35 +  if (conf12_io_enabled < 0)
   31.36 +    conf12_io_enabled = intel_setup_io(a);
   31.37 +  return conf12_io_enabled;
   31.38 +}
   31.39 +
   31.40 +static void
   31.41 +conf12_init(struct pci_access *a)
   31.42 +{
   31.43 +  if (!conf12_setup_io(a))
   31.44 +    a->error("No permission to access I/O ports (you probably have to be root).");
   31.45 +}
   31.46 +
   31.47 +static void
   31.48 +conf12_cleanup(struct pci_access *a UNUSED)
   31.49 +{
   31.50 +  if (conf12_io_enabled > 0)
   31.51 +    conf12_io_enabled = intel_cleanup_io(a);
   31.52 +}
   31.53 +
   31.54 +/*
   31.55 + * Before we decide to use direct hardware access mechanisms, we try to do some
   31.56 + * trivial checks to ensure it at least _seems_ to be working -- we just test
   31.57 + * whether bus 00 contains a host bridge (this is similar to checking
   31.58 + * techniques used in XFree86, but ours should be more reliable since we
   31.59 + * attempt to make use of direct access hints provided by the PCI BIOS).
   31.60 + *
   31.61 + * This should be close to trivial, but it isn't, because there are buggy
   31.62 + * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
   31.63 + */
   31.64 +
   31.65 +static int
   31.66 +intel_sanity_check(struct pci_access *a, struct pci_methods *m)
   31.67 +{
   31.68 +  struct pci_dev d;
   31.69 +
   31.70 +  a->debug("...sanity check");
   31.71 +  d.bus = 0;
   31.72 +  d.func = 0;
   31.73 +  for(d.dev = 0; d.dev < 32; d.dev++)
   31.74 +    {
   31.75 +      u16 class, vendor;
   31.76 +      if (m->read(&d, PCI_CLASS_DEVICE, (byte *) &class, sizeof(class)) &&
   31.77 +	  (class == cpu_to_le16(PCI_CLASS_BRIDGE_HOST) || class == cpu_to_le16(PCI_CLASS_DISPLAY_VGA)) ||
   31.78 +	  m->read(&d, PCI_VENDOR_ID, (byte *) &vendor, sizeof(vendor)) &&
   31.79 +	  (vendor == cpu_to_le16(PCI_VENDOR_ID_INTEL) || vendor == cpu_to_le16(PCI_VENDOR_ID_COMPAQ)))
   31.80 +	{
   31.81 +	  a->debug("...outside the Asylum at 0/%02x/0", d.dev);
   31.82 +	  return 1;
   31.83 +	}
   31.84 +    }
   31.85 +  a->debug("...insane");
   31.86 +  return 0;
   31.87 +}
   31.88 +
   31.89 +/*
   31.90 + *	Configuration type 1
   31.91 + */
   31.92 +
   31.93 +#define CONFIG_CMD(bus, device_fn, where)   (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3))
   31.94 +
   31.95 +static int
   31.96 +conf1_detect(struct pci_access *a)
   31.97 +{
   31.98 +  unsigned int tmp;
   31.99 +  int res = 0;
  31.100 +
  31.101 +  if (!conf12_setup_io(a))
  31.102 +    {
  31.103 +      a->debug("...no I/O permission");
  31.104 +      return 0;
  31.105 +    }
  31.106 +  outb (0x01, 0xCFB);
  31.107 +  tmp = inl (0xCF8);
  31.108 +  outl (0x80000000, 0xCF8);
  31.109 +  if (inl (0xCF8) == 0x80000000)
  31.110 +    res = 1;
  31.111 +  outl (tmp, 0xCF8);
  31.112 +  if (res)
  31.113 +    res = intel_sanity_check(a, &pm_intel_conf1);
  31.114 +  return res;
  31.115 +}
  31.116 +
  31.117 +static int
  31.118 +conf1_read(struct pci_dev *d, int pos, byte *buf, int len)
  31.119 +{
  31.120 +  int addr = 0xcfc + (pos&3);
  31.121 +
  31.122 +  if (pos >= 256)
  31.123 +    return 0;
  31.124 +
  31.125 +  outl(0x80000000 | ((d->bus & 0xff) << 16) | (PCI_DEVFN(d->dev, d->func) << 8) | (pos&~3), 0xcf8);
  31.126 +
  31.127 +  switch (len)
  31.128 +    {
  31.129 +    case 1:
  31.130 +      buf[0] = inb(addr);
  31.131 +      break;
  31.132 +    case 2:
  31.133 +      ((u16 *) buf)[0] = cpu_to_le16(inw(addr));
  31.134 +      break;
  31.135 +    case 4:
  31.136 +      ((u32 *) buf)[0] = cpu_to_le32(inl(addr));
  31.137 +      break;
  31.138 +    default:
  31.139 +      return pci_generic_block_read(d, pos, buf, len);
  31.140 +    }
  31.141 +  return 1;
  31.142 +}
  31.143 +
  31.144 +static int
  31.145 +conf1_write(struct pci_dev *d, int pos, byte *buf, int len)
  31.146 +{
  31.147 +  int addr = 0xcfc + (pos&3);
  31.148 +
  31.149 +  if (pos >= 256)
  31.150 +    return 0;
  31.151 +
  31.152 +  outl(0x80000000 | ((d->bus & 0xff) << 16) | (PCI_DEVFN(d->dev, d->func) << 8) | (pos&~3), 0xcf8);
  31.153 +
  31.154 +  switch (len)
  31.155 +    {
  31.156 +    case 1:
  31.157 +      outb(buf[0], addr);
  31.158 +      break;
  31.159 +    case 2:
  31.160 +      outw(le16_to_cpu(((u16 *) buf)[0]), addr);
  31.161 +      break;
  31.162 +    case 4:
  31.163 +      outl(le32_to_cpu(((u32 *) buf)[0]), addr);
  31.164 +      break;
  31.165 +    default:
  31.166 +      return pci_generic_block_write(d, pos, buf, len);
  31.167 +    }
  31.168 +  return 1;
  31.169 +}
  31.170 +
  31.171 +/*
  31.172 + *	Configuration type 2. Obsolete and brain-damaged, but existing.
  31.173 + */
  31.174 +
  31.175 +static int
  31.176 +conf2_detect(struct pci_access *a)
  31.177 +{
  31.178 +  if (!conf12_setup_io(a))
  31.179 +    {
  31.180 +      a->debug("...no I/O permission");
  31.181 +      return 0;
  31.182 +    }
  31.183 +
  31.184 +  /* This is ugly and tends to produce false positives. Beware. */
  31.185 +
  31.186 +  outb(0x00, 0xCFB);
  31.187 +  outb(0x00, 0xCF8);
  31.188 +  outb(0x00, 0xCFA);
  31.189 +  if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00)
  31.190 +    return intel_sanity_check(a, &pm_intel_conf2);
  31.191 +  else
  31.192 +    return 0;
  31.193 +}
  31.194 +
  31.195 +static int
  31.196 +conf2_read(struct pci_dev *d, int pos, byte *buf, int len)
  31.197 +{
  31.198 +  int addr = 0xc000 | (d->dev << 8) | pos;
  31.199 +
  31.200 +  if (pos >= 256)
  31.201 +    return 0;
  31.202 +
  31.203 +  if (d->dev >= 16)
  31.204 +    /* conf2 supports only 16 devices per bus */
  31.205 +    return 0;
  31.206 +  outb((d->func << 1) | 0xf0, 0xcf8);
  31.207 +  outb(d->bus, 0xcfa);
  31.208 +  switch (len)
  31.209 +    {
  31.210 +    case 1:
  31.211 +      buf[0] = inb(addr);
  31.212 +      break;
  31.213 +    case 2:
  31.214 +      ((u16 *) buf)[0] = cpu_to_le16(inw(addr));
  31.215 +      break;
  31.216 +    case 4:
  31.217 +      ((u32 *) buf)[0] = cpu_to_le32(inl(addr));
  31.218 +      break;
  31.219 +    default:
  31.220 +      outb(0, 0xcf8);
  31.221 +      return pci_generic_block_read(d, pos, buf, len);
  31.222 +    }
  31.223 +  outb(0, 0xcf8);
  31.224 +  return 1;
  31.225 +}
  31.226 +
  31.227 +static int
  31.228 +conf2_write(struct pci_dev *d, int pos, byte *buf, int len)
  31.229 +{
  31.230 +  int addr = 0xc000 | (d->dev << 8) | pos;
  31.231 +
  31.232 +  if (pos >= 256)
  31.233 +    return 0;
  31.234 +
  31.235 +  if (d->dev >= 16)
  31.236 +    d->access->error("conf2_write: only first 16 devices exist.");
  31.237 +  outb((d->func << 1) | 0xf0, 0xcf8);
  31.238 +  outb(d->bus, 0xcfa);
  31.239 +  switch (len)
  31.240 +    {
  31.241 +    case 1:
  31.242 +      outb(buf[0], addr);
  31.243 +      break;
  31.244 +    case 2:
  31.245 +      outw(le16_to_cpu(* (u16 *) buf), addr);
  31.246 +      break;
  31.247 +    case 4:
  31.248 +      outl(le32_to_cpu(* (u32 *) buf), addr);
  31.249 +      break;
  31.250 +    default:
  31.251 +      outb(0, 0xcf8);
  31.252 +      return pci_generic_block_write(d, pos, buf, len);
  31.253 +    }
  31.254 +  outb(0, 0xcf8);
  31.255 +  return 1;
  31.256 +}
  31.257 +
  31.258 +struct pci_methods pm_intel_conf1 = {
  31.259 +  "Intel-conf1",
  31.260 +  NULL,					/* config */
  31.261 +  conf1_detect,
  31.262 +  conf12_init,
  31.263 +  conf12_cleanup,
  31.264 +  pci_generic_scan,
  31.265 +  pci_generic_fill_info,
  31.266 +  conf1_read,
  31.267 +  conf1_write,
  31.268 +  NULL,					/* init_dev */
  31.269 +  NULL					/* cleanup_dev */
  31.270 +};
  31.271 +
  31.272 +struct pci_methods pm_intel_conf2 = {
  31.273 +  "Intel-conf2",
  31.274 +  NULL,					/* config */
  31.275 +  conf2_detect,
  31.276 +  conf12_init,
  31.277 +  conf12_cleanup,
  31.278 +  pci_generic_scan,
  31.279 +  pci_generic_fill_info,
  31.280 +  conf2_read,
  31.281 +  conf2_write,
  31.282 +  NULL,					/* init_dev */
  31.283 +  NULL					/* cleanup_dev */
  31.284 +};
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/internal.h	Mon Aug 13 17:49:00 2007 -0400
    32.3 @@ -0,0 +1,43 @@
    32.4 +/*
    32.5 + *	The PCI Library -- Internal Stuff
    32.6 + *
    32.7 + *	Copyright (c) 1997--2004 Martin Mares <mj@ucw.cz>
    32.8 + *
    32.9 + *	Can be freely distributed and used under the terms of the GNU GPL.
   32.10 + */
   32.11 +
   32.12 +#include "pci.h"
   32.13 +#include "sysdep.h"
   32.14 +
   32.15 +struct pci_methods {
   32.16 +  char *name;
   32.17 +  void (*config)(struct pci_access *);
   32.18 +  int (*detect)(struct pci_access *);
   32.19 +  void (*init)(struct pci_access *);
   32.20 +  void (*cleanup)(struct pci_access *);
   32.21 +  void (*scan)(struct pci_access *);
   32.22 +  int (*fill_info)(struct pci_dev *, int flags);
   32.23 +  int (*read)(struct pci_dev *, int pos, byte *buf, int len);
   32.24 +  int (*write)(struct pci_dev *, int pos, byte *buf, int len);
   32.25 +  void (*init_dev)(struct pci_dev *);
   32.26 +  void (*cleanup_dev)(struct pci_dev *);
   32.27 +#ifdef PT_LIBPCI
   32.28 +  int (*get_object)(struct pci_dev *d, char *object);
   32.29 +#endif
   32.30 +};
   32.31 +
   32.32 +void pci_generic_scan_bus(struct pci_access *, byte *busmap, int bus);
   32.33 +void pci_generic_scan(struct pci_access *);
   32.34 +int pci_generic_fill_info(struct pci_dev *, int flags);
   32.35 +int pci_generic_block_read(struct pci_dev *, int pos, byte *buf, int len);
   32.36 +int pci_generic_block_write(struct pci_dev *, int pos, byte *buf, int len);
   32.37 +
   32.38 +void *pci_malloc(struct pci_access *, int);
   32.39 +void pci_mfree(void *);
   32.40 +
   32.41 +struct pci_dev *pci_alloc_dev(struct pci_access *);
   32.42 +int pci_link_dev(struct pci_access *, struct pci_dev *);
   32.43 +
   32.44 +extern struct pci_methods pm_intel_conf1, pm_intel_conf2, pm_linux_proc,
   32.45 +	pm_fbsd_device, pm_aix_device, pm_nbsd_libpci, pm_obsd_device,
   32.46 +	pm_dump, pm_linux_sysfs;
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/libpci.pc.in	Mon Aug 13 17:49:00 2007 -0400
    33.3 @@ -0,0 +1,10 @@
    33.4 +prefix=@PREFIX@
    33.5 +includedir=@INCDIR@
    33.6 +libdir=@LIBDIR@
    33.7 +idsdir=@IDSDIR@
    33.8 +
    33.9 +Name: libpci
   33.10 +Description: libpci
   33.11 +Version: @VERSION@
   33.12 +Libs: -L${libdir} -lpci @LIBZ@
   33.13 +Cflags: -I${includedir}
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/names.c	Mon Aug 13 17:49:00 2007 -0400
    34.3 @@ -0,0 +1,519 @@
    34.4 +/*
    34.5 + *	The PCI Library -- ID to Name Translation
    34.6 + *
    34.7 + *	Copyright (c) 1997--2006 Martin Mares <mj@ucw.cz>
    34.8 + *
    34.9 + *	Can be freely distributed and used under the terms of the GNU GPL.
   34.10 + */
   34.11 +
   34.12 +#include <stdio.h>
   34.13 +#include <stdlib.h>
   34.14 +#include <stdarg.h>
   34.15 +#include <string.h>
   34.16 +#include <errno.h>
   34.17 +
   34.18 +#include "internal.h"
   34.19 +
   34.20 +#ifdef PCI_COMPRESSED_IDS
   34.21 +#include <zlib.h>
   34.22 +typedef gzFile pci_file;
   34.23 +#define pci_gets(f, l, s)	gzgets(f, l, s)
   34.24 +#define pci_eof(f)		gzeof(f)
   34.25 +
   34.26 +static pci_file pci_open(struct pci_access *a)
   34.27 +{
   34.28 +  pci_file result;
   34.29 +  size_t len;
   34.30 +  char *new_name;
   34.31 +
   34.32 +  result = gzopen(a->id_file_name, "r");
   34.33 +  if (result)
   34.34 +    return result;
   34.35 +  len = strlen(a->id_file_name);
   34.36 +  if (len >= 3 && memcmp(a->id_file_name + len - 3, ".gz", 3) != 0)
   34.37 +    return result;
   34.38 +  new_name = malloc(len - 2);
   34.39 +  memcpy(new_name, a->id_file_name, len - 3);
   34.40 +  new_name[len - 3] = 0;
   34.41 +  pci_set_name_list_path(a, new_name, 1);
   34.42 +  return gzopen(a->id_file_name, "r");
   34.43 +}
   34.44 +
   34.45 +#define pci_close(f)		gzclose(f)
   34.46 +#define PCI_ERROR(f, err)						\
   34.47 +	if (!err) {							\
   34.48 +		int errnum;						\
   34.49 +		err = gzerror(f, &errnum);				\
   34.50 +		if (errnum == Z_ERRNO)	err = "I/O error";		\
   34.51 +		else if (errnum >= 0)	err = NULL;			\
   34.52 +	}
   34.53 +#else
   34.54 +typedef FILE * pci_file;
   34.55 +#define pci_gets(f, l, s)	fgets(l, s, f)
   34.56 +#define pci_eof(f)		feof(f)
   34.57 +#define pci_open(a)		fopen(a->id_file_name, "r")
   34.58 +#define pci_close(f)		fclose(f)
   34.59 +#define PCI_ERROR(f, err)	if (!err && ferror(f))	err = "I/O error";
   34.60 +#endif
   34.61 +
   34.62 +struct id_entry {
   34.63 +  struct id_entry *next;
   34.64 +  u32 id12, id34;
   34.65 +  byte cat;
   34.66 +  char name[1];
   34.67 +};
   34.68 +
   34.69 +enum id_entry_type {
   34.70 +  ID_UNKNOWN,
   34.71 +  ID_VENDOR,
   34.72 +  ID_DEVICE,
   34.73 +  ID_SUBSYSTEM,
   34.74 +  ID_GEN_SUBSYSTEM,
   34.75 +  ID_CLASS,
   34.76 +  ID_SUBCLASS,
   34.77 +  ID_PROGIF
   34.78 +};
   34.79 +
   34.80 +struct id_bucket {
   34.81 +  struct id_bucket *next;
   34.82 +  unsigned int full;
   34.83 +};
   34.84 +
   34.85 +#define MAX_LINE 1024
   34.86 +#define BUCKET_SIZE 8192
   34.87 +#define HASH_SIZE 4099
   34.88 +
   34.89 +#ifdef __GNUC__
   34.90 +#define BUCKET_ALIGNMENT __alignof__(struct id_bucket)
   34.91 +#else
   34.92 +union id_align {
   34.93 +  struct id_bucket *next;
   34.94 +  unsigned int full;
   34.95 +};
   34.96 +#define BUCKET_ALIGNMENT sizeof(union id_align)
   34.97 +#endif
   34.98 +#define BUCKET_ALIGN(n) ((n)+BUCKET_ALIGNMENT-(n)%BUCKET_ALIGNMENT)
   34.99 +
  34.100 +static void *id_alloc(struct pci_access *a, unsigned int size)
  34.101 +{
  34.102 +  struct id_bucket *buck = a->current_id_bucket;
  34.103 +  unsigned int pos;
  34.104 +  if (!buck || buck->full + size > BUCKET_SIZE)
  34.105 +    {
  34.106 +      buck = pci_malloc(a, BUCKET_SIZE);
  34.107 +      buck->next = a->current_id_bucket;
  34.108 +      a->current_id_bucket = buck;
  34.109 +      buck->full = BUCKET_ALIGN(sizeof(struct id_bucket));
  34.110 +    }
  34.111 +  pos = buck->full;
  34.112 +  buck->full = BUCKET_ALIGN(buck->full + size);
  34.113 +  return (byte *)buck + pos;
  34.114 +}
  34.115 +
  34.116 +static inline u32 id_pair(unsigned int x, unsigned int y)
  34.117 +{
  34.118 +  return ((x << 16) | y);
  34.119 +}
  34.120 +
  34.121 +static inline unsigned int id_hash(int cat, u32 id12, u32 id34)
  34.122 +{
  34.123 +  unsigned int h;
  34.124 +
  34.125 +  h = id12 ^ (id34 << 3) ^ (cat << 5);
  34.126 +  return h % HASH_SIZE;
  34.127 +}
  34.128 +
  34.129 +static char *id_lookup(struct pci_access *a, int cat, int id1, int id2, int id3, int id4)
  34.130 +{
  34.131 +  struct id_entry *n;
  34.132 +  u32 id12 = id_pair(id1, id2);
  34.133 +  u32 id34 = id_pair(id3, id4);
  34.134 +
  34.135 +  if (!a->id_hash)
  34.136 +    return NULL;
  34.137 +  n = a->id_hash[id_hash(cat, id12, id34)];
  34.138 +  while (n && (n->id12 != id12 || n->id34 != id34 || n->cat != cat))
  34.139 +    n = n->next;
  34.140 +  return n ? n->name : NULL;
  34.141 +}
  34.142 +
  34.143 +static int id_insert(struct pci_access *a, int cat, int id1, int id2, int id3, int id4, char *text)
  34.144 +{
  34.145 +  u32 id12 = id_pair(id1, id2);
  34.146 +  u32 id34 = id_pair(id3, id4);
  34.147 +  unsigned int h = id_hash(cat, id12, id34);
  34.148 +  struct id_entry *n = a->id_hash[h];
  34.149 +  int len = strlen(text);
  34.150 +
  34.151 +  while (n && (n->id12 != id12 || n->id34 != id34 || n->cat != cat))
  34.152 +    n = n->next;
  34.153 +  if (n)
  34.154 +    return 1;
  34.155 +  n = id_alloc(a, sizeof(struct id_entry) + len);
  34.156 +  n->id12 = id12;
  34.157 +  n->id34 = id34;
  34.158 +  n->cat = cat;
  34.159 +  memcpy(n->name, text, len+1);
  34.160 +  n->next = a->id_hash[h];
  34.161 +  a->id_hash[h] = n;
  34.162 +  return 0;
  34.163 +}
  34.164 +
  34.165 +static int id_hex(char *p, int cnt)
  34.166 +{
  34.167 +  int x = 0;
  34.168 +  while (cnt--)
  34.169 +    {
  34.170 +      x <<= 4;
  34.171 +      if (*p >= '0' && *p <= '9')
  34.172 +	x += (*p - '0');
  34.173 +      else if (*p >= 'a' && *p <= 'f')
  34.174 +	x += (*p - 'a' + 10);
  34.175 +      else if (*p >= 'A' && *p <= 'F')
  34.176 +	x += (*p - 'A' + 10);
  34.177 +      else
  34.178 +	return -1;
  34.179 +      p++;
  34.180 +    }
  34.181 +  return x;
  34.182 +}
  34.183 +
  34.184 +static inline int id_white_p(int c)
  34.185 +{
  34.186 +  return (c == ' ') || (c == '\t');
  34.187 +}
  34.188 +
  34.189 +static const char *id_parse_list(struct pci_access *a, pci_file f, int *lino)
  34.190 +{
  34.191 +  char line[MAX_LINE];
  34.192 +  char *p;
  34.193 +  int id1=0, id2=0, id3=0, id4=0;
  34.194 +  int cat = -1;
  34.195 +  int nest;
  34.196 +  static const char parse_error[] = "Parse error";
  34.197 +
  34.198 +  *lino = 0;
  34.199 +  while (pci_gets(f, line, sizeof(line)))
  34.200 +    {
  34.201 +      (*lino)++;
  34.202 +      p = line;
  34.203 +      while (*p && *p != '\n' && *p != '\r')
  34.204 +	p++;
  34.205 +      if (!*p && !pci_eof(f))
  34.206 +	return "Line too long";
  34.207 +      *p = 0;
  34.208 +      if (p > line && (p[-1] == ' ' || p[-1] == '\t'))
  34.209 +	*--p = 0;
  34.210 +
  34.211 +      p = line;
  34.212 +      while (id_white_p(*p))
  34.213 +	p++;
  34.214 +      if (!*p || *p == '#')
  34.215 +	continue;
  34.216 +
  34.217 +      p = line;
  34.218 +      while (*p == '\t')
  34.219 +	p++;
  34.220 +      nest = p - line;
  34.221 +
  34.222 +      if (!nest)					/* Top-level entries */
  34.223 +	{
  34.224 +	  if (p[0] == 'C' && p[1] == ' ')		/* Class block */
  34.225 +	    {
  34.226 +	      if ((id1 = id_hex(p+2, 2)) < 0 || !id_white_p(p[4]))
  34.227 +		return parse_error;
  34.228 +	      cat = ID_CLASS;
  34.229 +	      p += 5;
  34.230 +	    }
  34.231 +	  else if (p[0] == 'S' && p[1] == ' ')
  34.232 +	    {						/* Generic subsystem block */
  34.233 +	      if ((id1 = id_hex(p+2, 4)) < 0 || p[6])
  34.234 +		return parse_error;
  34.235 +	      if (!id_lookup(a, ID_VENDOR, id1, 0, 0, 0))
  34.236 +		return "Vendor does not exist";
  34.237 +	      cat = ID_GEN_SUBSYSTEM;
  34.238 +	      continue;
  34.239 +	    }
  34.240 +	  else if (p[0] >= 'A' && p[0] <= 'Z' && p[1] == ' ')
  34.241 +	    {						/* Unrecognized block (RFU) */
  34.242 +	      cat = ID_UNKNOWN;
  34.243 +	      continue;
  34.244 +	    }
  34.245 +	  else						/* Vendor ID */
  34.246 +	    {
  34.247 +	      if ((id1 = id_hex(p, 4)) < 0 || !id_white_p(p[4]))
  34.248 +		return parse_error;
  34.249 +	      cat = ID_VENDOR;
  34.250 +	      p += 5;
  34.251 +	    }
  34.252 +	  id2 = id3 = id4 = 0;
  34.253 +	}
  34.254 +      else if (cat == ID_UNKNOWN)			/* Nested entries in RFU blocks are skipped */
  34.255 +	continue;
  34.256 +      else if (nest == 1)				/* Nesting level 1 */
  34.257 +	switch (cat)
  34.258 +	  {
  34.259 +	  case ID_VENDOR:
  34.260 +	  case ID_DEVICE:
  34.261 +	  case ID_SUBSYSTEM:
  34.262 +	    if ((id2 = id_hex(p, 4)) < 0 || !id_white_p(p[4]))
  34.263 +	      return parse_error;
  34.264 +	    p += 5;
  34.265 +	    cat = ID_DEVICE;
  34.266 +	    id3 = id4 = 0;
  34.267 +	    break;
  34.268 +	  case ID_GEN_SUBSYSTEM:
  34.269 +	    if ((id2 = id_hex(p, 4)) < 0 || !id_white_p(p[4]))
  34.270 +	      return parse_error;
  34.271 +	    p += 5;
  34.272 +	    id3 = id4 = 0;
  34.273 +	    break;
  34.274 +	  case ID_CLASS:
  34.275 +	  case ID_SUBCLASS:
  34.276 +	  case ID_PROGIF:
  34.277 +	    if ((id2 = id_hex(p, 2)) < 0 || !id_white_p(p[2]))
  34.278 +	      return parse_error;
  34.279 +	    p += 3;
  34.280 +	    cat = ID_SUBCLASS;
  34.281 +	    id3 = id4 = 0;
  34.282 +	    break;
  34.283 +	  default:
  34.284 +	    return parse_error;
  34.285 +	  }
  34.286 +      else if (nest == 2)				/* Nesting level 2 */
  34.287 +	switch (cat)
  34.288 +	  {
  34.289 +	  case ID_DEVICE:
  34.290 +	  case ID_SUBSYSTEM:
  34.291 +	    if ((id3 = id_hex(p, 4)) < 0 || !id_white_p(p[4]) || (id4 = id_hex(p+5, 4)) < 0 || !id_white_p(p[9]))
  34.292 +	      return parse_error;
  34.293 +	    p += 10;
  34.294 +	    cat = ID_SUBSYSTEM;
  34.295 +	    break;
  34.296 +	  case ID_CLASS:
  34.297 +	  case ID_SUBCLASS:
  34.298 +	  case ID_PROGIF:
  34.299 +	    if ((id3 = id_hex(p, 2)) < 0 || !id_white_p(p[2]))
  34.300 +	      return parse_error;
  34.301 +	    p += 3;
  34.302 +	    cat = ID_PROGIF;
  34.303 +	    id4 = 0;
  34.304 +	    break;
  34.305 +	  default:
  34.306 +	    return parse_error;
  34.307 +	  }
  34.308 +      else						/* Nesting level 3 or more */
  34.309 +	return parse_error;
  34.310 +      while (id_white_p(*p))
  34.311 +	p++;
  34.312 +      if (!*p)
  34.313 +	return parse_error;
  34.314 +      if (id_insert(a, cat, id1, id2, id3, id4, p))
  34.315 +	return "Duplicate entry";
  34.316 +    }
  34.317 +  return NULL;
  34.318 +}
  34.319 +
  34.320 +int
  34.321 +pci_load_name_list(struct pci_access *a)
  34.322 +{
  34.323 +  pci_file f;
  34.324 +  int lino;
  34.325 +  const char *err;
  34.326 +
  34.327 +  pci_free_name_list(a);
  34.328 +  a->hash_load_failed = 1;
  34.329 +  if (!(f = pci_open(a)))
  34.330 +    return 0;
  34.331 +  a->id_hash = pci_malloc(a, sizeof(struct id_entry *) * HASH_SIZE);
  34.332 +  memset(a->id_hash, 0, sizeof(struct id_entry *) * HASH_SIZE);
  34.333 +  err = id_parse_list(a, f, &lino);
  34.334 +  PCI_ERROR(f, err);
  34.335 +  pci_close(f);
  34.336 +  if (err)
  34.337 +    a->error("%s at %s, line %d\n", err, a->id_file_name, lino);
  34.338 +  a->hash_load_failed = 0;
  34.339 +  return 1;
  34.340 +}
  34.341 +
  34.342 +void
  34.343 +pci_free_name_list(struct pci_access *a)
  34.344 +{
  34.345 +  pci_mfree(a->id_hash);
  34.346 +  a->id_hash = NULL;
  34.347 +  while (a->current_id_bucket)
  34.348 +    {
  34.349 +      struct id_bucket *buck = a->current_id_bucket;
  34.350 +      a->current_id_bucket = buck->next;
  34.351 +      pci_mfree(buck);
  34.352 +    }
  34.353 +}
  34.354 +
  34.355 +static char *
  34.356 +id_lookup_subsys(struct pci_access *a, int iv, int id, int isv, int isd)
  34.357 +{
  34.358 +  char *d = NULL;
  34.359 +  if (iv > 0 && id > 0)						/* Per-device lookup */
  34.360 +    d = id_lookup(a, ID_SUBSYSTEM, iv, id, isv, isd);
  34.361 +  if (!d)							/* Generic lookup */
  34.362 +    d = id_lookup(a, ID_GEN_SUBSYSTEM, isv, isd, 0, 0);
  34.363 +  if (!d && iv == isv && id == isd)				/* Check for subsystem == device */
  34.364 +    d = id_lookup(a, ID_DEVICE, iv, id, 0, 0);
  34.365 +  return d;
  34.366 +}
  34.367 +
  34.368 +static char *
  34.369 +format_name(char *buf, int size, int flags, char *name, char *num, char *unknown)
  34.370 +{
  34.371 +  int res;
  34.372 +  if ((flags & PCI_LOOKUP_NO_NUMBERS) && !name)
  34.373 +    return NULL;
  34.374 +  else if (flags & PCI_LOOKUP_NUMERIC)
  34.375 +    res = snprintf(buf, size, "%s", num);
  34.376 +  else if (!name)
  34.377 +    res = snprintf(buf, size, ((flags & PCI_LOOKUP_MIXED) ? "%s [%s]" : "%s %s"), unknown, num);
  34.378 +  else if (!(flags & PCI_LOOKUP_MIXED))
  34.379 +    res = snprintf(buf, size, "%s", name);
  34.380 +  else
  34.381 +    res = snprintf(buf, size, "%s [%s]", name, num);
  34.382 +  if (res < 0 || res >= size)
  34.383 +    return "<pci_lookup_name: buffer too small>";
  34.384 +  else
  34.385 +    return buf;
  34.386 +}
  34.387 +
  34.388 +static char *
  34.389 +format_name_pair(char *buf, int size, int flags, char *v, char *d, char *num)
  34.390 +{
  34.391 +  int res;
  34.392 +  if ((flags & PCI_LOOKUP_NO_NUMBERS) && (!v || !d))
  34.393 +    return NULL;
  34.394 +  if (flags & PCI_LOOKUP_NUMERIC)
  34.395 +    res = snprintf(buf, size, "%s", num);
  34.396 +  else if (flags & PCI_LOOKUP_MIXED)
  34.397 +    {
  34.398 +      if (v && d)
  34.399 +	res = snprintf(buf, size, "%s %s [%s]", v, d, num);
  34.400 +      else if (!v)
  34.401 +	res = snprintf(buf, size, "Unknown device [%s]", num);
  34.402 +      else /* v && !d */
  34.403 +	res = snprintf(buf, size, "%s Unknown device [%s]", v, num);
  34.404 +    }
  34.405 +  else
  34.406 +    {
  34.407 +      if (v && d)
  34.408 +	res = snprintf(buf, size, "%s %s", v, d);
  34.409 +      else if (!v)
  34.410 +	res = snprintf(buf, size, "Unknown device %s", num);
  34.411 +      else /* v && !d */
  34.412 +	res = snprintf(buf, size, "%s Unknown device %s", v, num+5);
  34.413 +    }
  34.414 +  if (res < 0 || res >= size)
  34.415 +    return "<pci_lookup_name: buffer too small>";
  34.416 +  else
  34.417 +    return buf;
  34.418 +}
  34.419 +
  34.420 +char *
  34.421 +pci_lookup_name(struct pci_access *a, char *buf, int size, int flags, ...)
  34.422 +{
  34.423 +  va_list args;
  34.424 +  char *v, *d, *cls, *pif;
  34.425 +  int iv, id, isv, isd, icls, ipif;
  34.426 +  char numbuf[16], pifbuf[32];
  34.427 +
  34.428 +  va_start(args, flags);
  34.429 +
  34.430 +  if (!(flags & PCI_LOOKUP_NO_NUMBERS))
  34.431 +    {
  34.432 +      if (a->numeric_ids > 1)
  34.433 +	flags |= PCI_LOOKUP_MIXED;
  34.434 +      else if (a->numeric_ids)
  34.435 +	flags |= PCI_LOOKUP_NUMERIC;
  34.436 +    }
  34.437 +  if (flags & PCI_LOOKUP_MIXED)
  34.438 +    flags &= ~PCI_LOOKUP_NUMERIC;
  34.439 +
  34.440 +  if (!a->id_hash && !(flags & PCI_LOOKUP_NUMERIC) && !a->hash_load_failed)
  34.441 +    pci_load_name_list(a);
  34.442 +
  34.443 +  switch (flags & 0xffff)
  34.444 +    {
  34.445 +    case PCI_LOOKUP_VENDOR:
  34.446 +      iv = va_arg(args, int);
  34.447 +      sprintf(numbuf, "%04x", iv);
  34.448 +      return format_name(buf, size, flags, id_lookup(a, ID_VENDOR, iv, 0, 0, 0), numbuf, "Unknown vendor");
  34.449 +    case PCI_LOOKUP_DEVICE:
  34.450 +      iv = va_arg(args, int);
  34.451 +      id = va_arg(args, int);
  34.452 +      sprintf(numbuf, "%04x", id);
  34.453 +      return format_name(buf, size, flags, id_lookup(a, ID_DEVICE, iv, id, 0, 0), numbuf, "Unknown device");
  34.454 +    case PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE:
  34.455 +      iv = va_arg(args, int);
  34.456 +      id = va_arg(args, int);
  34.457 +      sprintf(numbuf, "%04x:%04x", iv, id);
  34.458 +      v = id_lookup(a, ID_VENDOR, iv, 0, 0, 0);
  34.459 +      d = id_lookup(a, ID_DEVICE, iv, id, 0, 0);
  34.460 +      return format_name_pair(buf, size, flags, v, d, numbuf);
  34.461 +    case PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR:
  34.462 +      isv = va_arg(args, int);
  34.463 +      sprintf(numbuf, "%04x", isv);
  34.464 +      v = id_lookup(a, ID_VENDOR, isv, 0, 0, 0);
  34.465 +      return format_name(buf, size, flags, v, numbuf, "Unknown vendor");
  34.466 +    case PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_DEVICE:
  34.467 +      iv = va_arg(args, int);
  34.468 +      id = va_arg(args, int);
  34.469 +      isv = va_arg(args, int);
  34.470 +      isd = va_arg(args, int);
  34.471 +      sprintf(numbuf, "%04x", isd);
  34.472 +      return format_name(buf, size, flags, id_lookup_subsys(a, iv, id, isv, isd), numbuf, "Unknown device");
  34.473 +    case PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE | PCI_LOOKUP_SUBSYSTEM:
  34.474 +      iv = va_arg(args, int);
  34.475 +      id = va_arg(args, int);
  34.476 +      isv = va_arg(args, int);
  34.477 +      isd = va_arg(args, int);
  34.478 +      v = id_lookup(a, ID_VENDOR, isv, 0, 0, 0);
  34.479 +      d = id_lookup_subsys(a, iv, id, isv, isd);
  34.480 +      sprintf(numbuf, "%04x:%04x", isv, isd);
  34.481 +      return format_name_pair(buf, size, flags, v, d, numbuf);
  34.482 +    case PCI_LOOKUP_CLASS:
  34.483 +      icls = va_arg(args, int);
  34.484 +      sprintf(numbuf, "%04x", icls);
  34.485 +      cls = id_lookup(a, ID_SUBCLASS, icls >> 8, icls & 0xff, 0, 0);
  34.486 +      if (!cls && (cls = id_lookup(a, ID_CLASS, icls >> 8, 0, 0, 0)))
  34.487 +	{
  34.488 +	  if (!(flags & PCI_LOOKUP_NUMERIC)) /* Include full class number */
  34.489 +	    flags |= PCI_LOOKUP_MIXED;
  34.490 +	}
  34.491 +      return format_name(buf, size, flags, cls, numbuf, ((flags & PCI_LOOKUP_MIXED) ? "Unknown class" : "Class"));
  34.492 +    case PCI_LOOKUP_PROGIF:
  34.493 +      icls = va_arg(args, int);
  34.494 +      ipif = va_arg(args, int);
  34.495 +      sprintf(numbuf, "%02x", ipif);
  34.496 +      pif = id_lookup(a, ID_PROGIF, icls >> 8, icls & 0xff, ipif, 0);
  34.497 +      if (!pif && icls == 0x0101 && !(ipif & 0x70))
  34.498 +	{
  34.499 +	  /* IDE controllers have complex prog-if semantics */
  34.500 +	  sprintf(pifbuf, "%s%s%s%s%s",
  34.501 +		  (ipif & 0x80) ? " Master" : "",
  34.502 +		  (ipif & 0x08) ? " SecP" : "",
  34.503 +		  (ipif & 0x04) ? " SecO" : "",
  34.504 +		  (ipif & 0x02) ? " PriP" : "",
  34.505 +		  (ipif & 0x01) ? " PriO" : "");
  34.506 +	  pif = pifbuf;
  34.507 +	  if (*pif)
  34.508 +	    pif++;
  34.509 +	}
  34.510 +      return format_name(buf, size, flags, pif, numbuf, "ProgIf");
  34.511 +    default:
  34.512 +      return "<pci_lookup_name: invalid request>";
  34.513 +    }
  34.514 +}
  34.515 +
  34.516 +void pci_set_name_list_path(struct pci_access *a, char *name, int to_be_freed)
  34.517 +{
  34.518 +  if (a->free_id_name)
  34.519 +    free(a->id_file_name);
  34.520 +  a->id_file_name = name;
  34.521 +  a->free_id_name = to_be_freed;
  34.522 +}
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/nbsd-libpci.c	Mon Aug 13 17:49:00 2007 -0400
    35.3 @@ -0,0 +1,157 @@
    35.4 +/*
    35.5 + *	The PCI Library -- NetBSD libpci access
    35.6 + *         (based on FreeBSD /dev/pci access)
    35.7 + *
    35.8 + *	Copyright (c) 1999 Jari Kirma <kirma@cs.hut.fi>
    35.9 + *      Copyright (c) 2002 Quentin Garnier <cube@cubidou.net>
   35.10 + *	Copyright (c) 2002 Martin Mares <mj@ucw.cz>
   35.11 + *
   35.12 + *	Can be freely distributed and used under the terms of the GNU GPL.
   35.13 + */
   35.14 +
   35.15 +/*
   35.16 + *      Read functionality of this driver is briefly tested, and seems
   35.17 + *      to supply basic information correctly, but I promise no more.
   35.18 + */
   35.19 +
   35.20 +#include <fcntl.h>
   35.21 +#include <string.h>
   35.22 +#include <unistd.h>
   35.23 +
   35.24 +#include <pci.h>
   35.25 +
   35.26 +#include "internal.h"
   35.27 +
   35.28 +static void
   35.29 +nbsd_config(struct pci_access *a)
   35.30 +{
   35.31 +  a->method_params[PCI_ACCESS_NBSD_LIBPCI] = PCI_PATH_NBSD_DEVICE;
   35.32 +}
   35.33 +
   35.34 +static int
   35.35 +nbsd_detect(struct pci_access *a)
   35.36 +{
   35.37 +  char *name = a->method_params[PCI_ACCESS_NBSD_LIBPCI];
   35.38 +
   35.39 +  if (access(name, R_OK))
   35.40 +    {
   35.41 +      a->warning("Cannot open %s", name);
   35.42 +      return 0;
   35.43 +    }
   35.44 +
   35.45 +  if (!access(name, W_OK))
   35.46 +    {
   35.47 +      a->writeable = O_RDWR;
   35.48 +    }
   35.49 +  a->debug("...using %s", name);
   35.50 +  return 1;
   35.51 +}
   35.52 +
   35.53 +static void
   35.54 +nbsd_init(struct pci_access *a)
   35.55 +{
   35.56 +  char *name = a->method_params[PCI_ACCESS_NBSD_LIBPCI];
   35.57 +  int mode = a->writeable ? O_RDWR : O_RDONLY;
   35.58 +
   35.59 +  a->fd = open(name, mode, 0);
   35.60 +  if (a->fd < 0)
   35.61 +    a->error("nbsd_init: %s open failed", name);
   35.62 +}
   35.63 +
   35.64 +static void
   35.65 +nbsd_cleanup(struct pci_access *a)
   35.66 +{
   35.67 +  close(a->fd);
   35.68 +}
   35.69 +
   35.70 +static int
   35.71 +nbsd_read(struct pci_dev *d, int pos, byte *buf, int len)
   35.72 +{
   35.73 +  pcireg_t val;
   35.74 +  int shift;
   35.75 +
   35.76 +  if (!(len == 1 || len == 2 || len == 4))
   35.77 +    return pci_generic_block_read(d, pos, buf, len);
   35.78 +
   35.79 +  if (pos >= 256)
   35.80 +    return 0;
   35.81 +
   35.82 +  shift = 8*(pos % 4);
   35.83 +  pos &= ~3;
   35.84 +
   35.85 +  if (pcibus_conf_read(d->access->fd, d->bus, d->dev, d->func, pos, &val) < 0)
   35.86 +    d->access->error("nbsd_read: pci_bus_conf_read() failed");
   35.87 +
   35.88 +  switch (len)
   35.89 +    {
   35.90 +    case 1:
   35.91 +      *buf = val >> shift;
   35.92 +      break;
   35.93 +    case 2:
   35.94 +      *(u16*)buf = cpu_to_le16(val >> shift);
   35.95 +      break;
   35.96 +    case 4:
   35.97 +      *(u32*)buf = cpu_to_le32(val);
   35.98 +      break;
   35.99 +    }
  35.100 +  return 1;
  35.101 +}
  35.102 +
  35.103 +static int
  35.104 +nbsd_write(struct pci_dev *d, int pos, byte *buf, int len)
  35.105 +{
  35.106 +  pcireg_t val = 0;
  35.107 +  int shift;
  35.108 +
  35.109 +  if (!(len == 1 || len == 2 || len == 4))
  35.110 +    return pci_generic_block_write(d, pos, buf, len);
  35.111 +
  35.112 +  if (pos >= 256)
  35.113 +    return 0;
  35.114 +
  35.115 +  /*
  35.116 +   *  BEWARE: NetBSD seems to support only 32-bit access, so we have
  35.117 +   *  to emulate byte and word writes by read-modify-write, possibly
  35.118 +   *  causing troubles.
  35.119 +   */
  35.120 +
  35.121 +  shift = 8*(pos % 4);
  35.122 +  pos &= ~3;
  35.123 +  if (len != 4)
  35.124 +    {
  35.125 +      if (pcibus_conf_read(d->access->fd, d->bus, d->dev, d->func, pos, &val) < 0)
  35.126 +	d->access->error("nbsd_write: pci_bus_conf_read() failed");
  35.127 +    }
  35.128 +
  35.129 +  switch (len)
  35.130 +    {
  35.131 +    case 1:
  35.132 +      val = (val & ~(0xff << shift)) | (buf[0] << shift);
  35.133 +      break;
  35.134 +    case 2:
  35.135 +      val = (val & ~(0xffff << shift)) | (le16_to_cpu(*(u16*)buf) << shift);
  35.136 +      break;
  35.137 +    case 4:
  35.138 +      val = le32_to_cpu(*(u32*)buf);
  35.139 +      break;
  35.140 +    }
  35.141 +
  35.142 +  if (pcibus_conf_write(d->access->fd, d->bus, d->dev, d->func, pos, val) < 0)
  35.143 +    d->access->error("nbsd_write: pci_bus_conf_write() failed");
  35.144 +
  35.145 +  return 1;
  35.146 +}
  35.147 +
  35.148 +struct pci_methods pm_nbsd_libpci = {
  35.149 +  "NetBSD-libpci",
  35.150 +  nbsd_config,
  35.151 +  nbsd_detect,
  35.152 +  nbsd_init,
  35.153 +  nbsd_cleanup,
  35.154 +  pci_generic_scan,
  35.155 +  pci_generic_fill_info,
  35.156 +  nbsd_read,
  35.157 +  nbsd_write,
  35.158 +  NULL,                                 /* dev_init */
  35.159 +  NULL                                  /* dev_cleanup */
  35.160 +};
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/obsd-device.c	Mon Aug 13 17:49:00 2007 -0400
    36.3 @@ -0,0 +1,159 @@
    36.4 +/*
    36.5 + *	The PCI Library -- OpenBSD /dev/pci access
    36.6 + *
    36.7 + *	Adapted from fbsd-device.c by Matthieu Herrb <matthieu.herrb@laas.fr>, 2006
    36.8 + *
    36.9 + *	Can be freely distributed and used under the terms of the GNU GPL.
   36.10 + */
   36.11 +
   36.12 +#include <fcntl.h>
   36.13 +#include <string.h>
   36.14 +#include <unistd.h>
   36.15 +#include <errno.h>
   36.16 +#include <sys/endian.h>
   36.17 +#include <sys/types.h>
   36.18 +#include <sys/ioctl.h>
   36.19 +#include <sys/pciio.h>
   36.20 +#include "internal.h"
   36.21 +
   36.22 +static void
   36.23 +obsd_config(struct pci_access *a)
   36.24 +{
   36.25 +  a->method_params[PCI_ACCESS_OBSD_DEVICE] = PCI_PATH_OBSD_DEVICE;
   36.26 +}
   36.27 +
   36.28 +static int
   36.29 +obsd_detect(struct pci_access *a)
   36.30 +{
   36.31 +  char *name = a->method_params[PCI_ACCESS_OBSD_DEVICE];
   36.32 +
   36.33 +  if (access(name, R_OK))
   36.34 +    {
   36.35 +      a->warning("Cannot open %s", name);
   36.36 +      return 0;
   36.37 +    }
   36.38 +  a->debug("...using %s", name);
   36.39 +  return 1;
   36.40 +}
   36.41 +
   36.42 +static void
   36.43 +obsd_init(struct pci_access *a)
   36.44 +{
   36.45 +  char *name = a->method_params[PCI_ACCESS_OBSD_DEVICE];
   36.46 +
   36.47 +  a->fd = open(name, O_RDWR, 0);
   36.48 +  if (a->fd < 0)
   36.49 +    {
   36.50 +      a->error("obsd_init: %s open failed", name);
   36.51 +    }
   36.52 +}
   36.53 +
   36.54 +static void
   36.55 +obsd_cleanup(struct pci_access *a)
   36.56 +{
   36.57 +  close(a->fd);
   36.58 +}
   36.59 +
   36.60 +static int
   36.61 +obsd_read(struct pci_dev *d, int pos, byte *buf, int len)
   36.62 +{
   36.63 +  struct pci_io pi;
   36.64 +  union {
   36.65 +	  u_int32_t u32;
   36.66 +	  u_int16_t u16[2];
   36.67 +	  u_int8_t u8[4];
   36.68 +  } u;
   36.69 +
   36.70 +  if (!(len == 1 || len == 2 || len == 4))
   36.71 +    {
   36.72 +      return pci_generic_block_read(d, pos, buf, len);
   36.73 +    }
   36.74 +
   36.75 +  if (pos >= 256)
   36.76 +    return 0;
   36.77 +
   36.78 +  pi.pi_sel.pc_bus = d->bus;
   36.79 +  pi.pi_sel.pc_dev = d->dev;
   36.80 +  pi.pi_sel.pc_func = d->func;
   36.81 +
   36.82 +  pi.pi_reg = pos - (pos % 4);
   36.83 +  pi.pi_width = 4;
   36.84 +
   36.85 +  if (ioctl(d->access->fd, PCIOCREAD, &pi) < 0) {
   36.86 +	  if (errno == ENXIO) {
   36.87 +		  pi.pi_data = 0xffffffff;
   36.88 +	  } else {
   36.89 +		  d->access->error("obsd_read: ioctl(PCIOCREAD) failed");
   36.90 +	  }
   36.91 +  }
   36.92 +  u.u32 = pi.pi_data;
   36.93 +
   36.94 +  switch (len)
   36.95 +    {
   36.96 +    case 1:
   36.97 +      buf[0] = (u8) u.u8[pos % 4];
   36.98 +      break;
   36.99 +    case 2:
  36.100 +      ((u16 *) buf)[0] = letoh16(u.u16[(pos % 4) / 2]);
  36.101 +      break;
  36.102 +    case 4:
  36.103 +      ((u32 *) buf)[0] = (u32) letoh32(pi.pi_data);
  36.104 +      break;
  36.105 +    }
  36.106 +  return 1;
  36.107 +}
  36.108 +
  36.109 +static int
  36.110 +obsd_write(struct pci_dev *d, int pos, byte *buf, int len)
  36.111 +{
  36.112 +  struct pci_io pi;
  36.113 +
  36.114 +  if (!(len == 1 || len == 2 || len == 4))
  36.115 +    {
  36.116 +      return pci_generic_block_write(d, pos, buf, len);
  36.117 +    }
  36.118 +
  36.119 +  if (pos >= 256)
  36.120 +    return 0;
  36.121 +
  36.122 +  pi.pi_sel.pc_bus = d->bus;
  36.123 +  pi.pi_sel.pc_dev = d->dev;
  36.124 +  pi.pi_sel.pc_func = d->func;
  36.125 +
  36.126 +  pi.pi_reg = pos;
  36.127 +  pi.pi_width = len;
  36.128 +
  36.129 +  switch (len)
  36.130 +    {
  36.131 +    case 1:
  36.132 +      pi.pi_data = buf[0];
  36.133 +      break;
  36.134 +    case 2:
  36.135 +      pi.pi_data = ((u16 *) buf)[0];
  36.136 +      break;
  36.137 +    case 4:
  36.138 +      pi.pi_data = ((u32 *) buf)[0];
  36.139 +      break;
  36.140 +    }
  36.141 +
  36.142 +  if (ioctl(d->access->fd, PCIOCWRITE, &pi) < 0)
  36.143 +    {
  36.144 +      d->access->error("obsd_write: ioctl(PCIOCWRITE) failed");
  36.145 +    }
  36.146 +
  36.147 +  return 1;
  36.148 +}
  36.149 +
  36.150 +struct pci_methods pm_obsd_device = {
  36.151 +  "OpenBSD-device",
  36.152 +  obsd_config,
  36.153 +  obsd_detect,
  36.154 +  obsd_init,
  36.155 +  obsd_cleanup,
  36.156 +  pci_generic_scan,
  36.157 +  pci_generic_fill_info,
  36.158 +  obsd_read,
  36.159 +  obsd_write,
  36.160 +  NULL,                                 /* dev_init */
  36.161 +  NULL                                  /* dev_cleanup */
  36.162 +};
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/pci.h	Mon Aug 13 17:49:00 2007 -0400
    37.3 @@ -0,0 +1,181 @@
    37.4 +/*
    37.5 + *	The PCI Library
    37.6 + *
    37.7 + *	Copyright (c) 1997--2006 Martin Mares <mj@ucw.cz>
    37.8 + *
    37.9 + *	Can be freely distributed and used under the terms of the GNU GPL.
   37.10 + */
   37.11 +
   37.12 +#ifndef _PCI_LIB_H
   37.13 +#define _PCI_LIB_H
   37.14 +
   37.15 +#include "config.h"
   37.16 +#include "header.h"
   37.17 +#include "types.h"
   37.18 +
   37.19 +#define PCI_LIB_VERSION 0x020204
   37.20 +
   37.21 +/*
   37.22 + *	PCI Access Structure
   37.23 + */
   37.24 +
   37.25 +struct pci_methods;
   37.26 +
   37.27 +enum pci_access_type {
   37.28 +  /* Known access methods, remember to update access.c as well */
   37.29 +  PCI_ACCESS_AUTO,			/* Autodetection (params: none) */
   37.30 +  PCI_ACCESS_SYS_BUS_PCI,		/* Linux /sys/bus/pci (params: path) */
   37.31 +  PCI_ACCESS_PROC_BUS_PCI,		/* Linux /proc/bus/pci (params: path) */
   37.32 +  PCI_ACCESS_I386_TYPE1,		/* i386 ports, type 1 (params: none) */
   37.33 +  PCI_ACCESS_I386_TYPE2,		/* i386 ports, type 2 (params: none) */
   37.34 +  PCI_ACCESS_FBSD_DEVICE,		/* FreeBSD /dev/pci (params: path) */
   37.35 +  PCI_ACCESS_AIX_DEVICE,		/* /dev/pci0, /dev/bus0, etc. */
   37.36 +  PCI_ACCESS_NBSD_LIBPCI,		/* NetBSD libpci */
   37.37 +  PCI_ACCESS_OBSD_DEVICE,		/* OpenBSD /dev/pci */
   37.38 +  PCI_ACCESS_DUMP,			/* Dump file (params: filename) */
   37.39 +  PCI_ACCESS_MAX
   37.40 +};
   37.41 +
   37.42 +struct pci_access {
   37.43 +  /* Options you can change: */
   37.44 +  unsigned int method;			/* Access method */
   37.45 +  char *method_params[PCI_ACCESS_MAX];	/* Parameters for the methods */
   37.46 +  int writeable;			/* Open in read/write mode */
   37.47 +  int buscentric;			/* Bus-centric view of the world */
   37.48 +  char *id_file_name;			/* Name of ID list file */
   37.49 +  int free_id_name;			/* Set if id_file_name is malloced */
   37.50 +  int numeric_ids;			/* Enforce PCI_LOOKUP_NUMERIC (>1 => PCI_LOOKUP_MIXED) */
   37.51 +  int debugging;			/* Turn on debugging messages */
   37.52 +
   37.53 +  /* Functions you can override: */
   37.54 +  void (*error)(char *msg, ...);	/* Write error message and quit */
   37.55 +  void (*warning)(char *msg, ...);	/* Write a warning message */
   37.56 +  void (*debug)(char *msg, ...);	/* Write a debugging message */
   37.57 +
   37.58 +  struct pci_dev *devices;		/* Devices found on this bus */
   37.59 +
   37.60 +  /* Fields used internally: */
   37.61 +  struct pci_methods *methods;
   37.62 +  struct id_entry **id_hash;		/* names.c */
   37.63 +  struct id_bucket *current_id_bucket;
   37.64 +  int hash_load_failed;
   37.65 +  int fd;				/* proc: fd */
   37.66 +  int fd_rw;				/* proc: fd opened read-write */
   37.67 +  struct pci_dev *cached_dev;		/* proc: device the fd is for */
   37.68 +#ifdef PT_LIBPCI
   37.69 +  u8 cached_b, cached_d, cached_f;    /* proc: cached device bdf */
   37.70 +#endif
   37.71 +  int fd_pos;				/* proc: current position */
   37.72 +};
   37.73 +
   37.74 +/* Initialize PCI access */
   37.75 +struct pci_access *pci_alloc(void);
   37.76 +void pci_init(struct pci_access *);
   37.77 +void pci_cleanup(struct pci_access *);
   37.78 +
   37.79 +/* Scanning of devices */
   37.80 +void pci_scan_bus(struct pci_access *acc);
   37.81 +struct pci_dev *pci_get_dev(struct pci_access *acc, int domain, int bus, int dev, int func); /* Raw access to specified device */
   37.82 +void pci_free_dev(struct pci_dev *);
   37.83 +
   37.84 +/*
   37.85 + *	Devices
   37.86 + */
   37.87 +
   37.88 +struct pci_dev {
   37.89 +  struct pci_dev *next;			/* Next device in the chain */
   37.90 +  u16 domain;				/* PCI domain (host bridge) */
   37.91 +  u8 bus, dev, func;			/* Bus inside domain, device and function */
   37.92 +
   37.93 +  /* These fields are set by pci_fill_info() */
   37.94 +  int known_fields;			/* Set of info fields already known */
   37.95 +  u16 vendor_id, device_id;		/* Identity of the device */
   37.96 +  u16 device_class;			/* PCI device class */
   37.97 +  int irq;				/* IRQ number */
   37.98 +  pciaddr_t base_addr[6];		/* Base addresses */
   37.99 +  pciaddr_t size[6];			/* Region sizes */
  37.100 +  pciaddr_t rom_base_addr;		/* Expansion ROM base address */
  37.101 +  pciaddr_t rom_size;			/* Expansion ROM size */
  37.102 +
  37.103 +  /* Fields used internally: */
  37.104 +  struct pci_access *access;
  37.105 +  struct pci_methods *methods;
  37.106 +  u8 *cache;				/* Cached config registers */
  37.107 +  int cache_len;
  37.108 +  int hdrtype;				/* Cached low 7 bits of header type, -1 if unknown */
  37.109 +  void *aux;				/* Auxillary data */
  37.110 +};
  37.111 +
  37.112 +#define PCI_ADDR_IO_MASK (~(pciaddr_t) 0x3)
  37.113 +#define PCI_ADDR_MEM_MASK (~(pciaddr_t) 0xf)
  37.114 +
  37.115 +#ifndef PT_LIBPCI
  37.116 +u8 pci_read_byte(struct pci_dev *, int pos); /* Access to configuration space */
  37.117 +u16 pci_read_word(struct pci_dev *, int pos);
  37.118 +u32  pci_read_long(struct pci_dev *, int pos);
  37.119 +int pci_read_block(struct pci_dev *, int pos, u8 *buf, int len);
  37.120 +int pci_write_byte(struct pci_dev *, int pos, u8 data);
  37.121 +int pci_write_word(struct pci_dev *, int pos, u16 data);
  37.122 +int pci_write_long(struct pci_dev *, int pos, u32 data);
  37.123 +int pci_write_block(struct pci_dev *, int pos, u8 *buf, int len);
  37.124 +#endif
  37.125 +int pci_fill_info(struct pci_dev *, int flags); /* Fill in device information */
  37.126 +
  37.127 +#define PCI_FILL_IDENT		1
  37.128 +#define PCI_FILL_IRQ		2
  37.129 +#define PCI_FILL_BASES		4
  37.130 +#define PCI_FILL_ROM_BASE	8
  37.131 +#define PCI_FILL_SIZES		16
  37.132 +#define PCI_FILL_CLASS		32
  37.133 +#define PCI_FILL_RESCAN		0x10000
  37.134 +
  37.135 +void pci_setup_cache(struct pci_dev *, u8 *cache, int len);
  37.136 +
  37.137 +/*
  37.138 + *	Filters
  37.139 + */
  37.140 +
  37.141 +struct pci_filter {
  37.142 +  int domain, bus, slot, func;			/* -1 = ANY */
  37.143 +  int vendor, device;
  37.144 +};
  37.145 +
  37.146 +void pci_filter_init(struct pci_access *, struct pci_filter *);
  37.147 +char *pci_filter_parse_slot(struct pci_filter *, char *);
  37.148 +char *pci_filter_parse_id(struct pci_filter *, char *);
  37.149 +int pci_filter_match(struct pci_filter *, struct pci_dev *);
  37.150 +
  37.151 +/*
  37.152 + *	Conversion of PCI ID's to names (according to the pci.ids file)
  37.153 + *
  37.154 + *	Call pci_lookup_name() to identify different types of ID's:
  37.155 + *
  37.156 + *	VENDOR				(vendorID) -> vendor
  37.157 + *	DEVICE				(vendorID, deviceID) -> device
  37.158 + *	VENDOR | DEVICE			(vendorID, deviceID) -> combined vendor and device
  37.159 + *	SUBSYSTEM | VENDOR		(subvendorID) -> subsystem vendor
  37.160 + *	SUBSYSTEM | DEVICE		(vendorID, deviceID, subvendorID, subdevID) -> subsystem device
  37.161 + *	SUBSYSTEM | VENDOR | DEVICE	(vendorID, deviceID, subvendorID, subdevID) -> combined subsystem v+d
  37.162 + *	SUBSYSTEM | ...			(-1, -1, subvendorID, subdevID) -> generic subsystem
  37.163 + *	CLASS				(classID) -> class
  37.164 + *	PROGIF				(classID, progif) -> programming interface
  37.165 + */
  37.166 +
  37.167 +char *pci_lookup_name(struct pci_access *a, char *buf, int size, int flags, ...);
  37.168 +
  37.169 +int pci_load_name_list(struct pci_access *a);	/* Called automatically by pci_lookup_*() when needed; returns success */
  37.170 +void pci_free_name_list(struct pci_access *a);	/* Called automatically by pci_cleanup() */
  37.171 +void pci_set_name_list_path(struct pci_access *a, char *name, int to_be_freed);
  37.172 +
  37.173 +enum pci_lookup_mode {
  37.174 +  PCI_LOOKUP_VENDOR = 1,		/* Vendor name (args: vendorID) */
  37.175 +  PCI_LOOKUP_DEVICE = 2,		/* Device name (args: vendorID, deviceID) */
  37.176 +  PCI_LOOKUP_CLASS = 4,			/* Device class (args: classID) */
  37.177 +  PCI_LOOKUP_SUBSYSTEM = 8,
  37.178 +  PCI_LOOKUP_PROGIF = 16,		/* Programming interface (args: classID, prog_if) */
  37.179 +  PCI_LOOKUP_NUMERIC = 0x10000,		/* Want only formatted numbers; default if access->numeric_ids is set */
  37.180 +  PCI_LOOKUP_NO_NUMBERS = 0x20000,	/* Return NULL if not found in the database; default is to print numerically */
  37.181 +  PCI_LOOKUP_MIXED = 0x40000,		/* Include both numbers and names */
  37.182 +};
  37.183 +
  37.184 +#endif
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/pread.h	Mon Aug 13 17:49:00 2007 -0400
    38.3 @@ -0,0 +1,66 @@
    38.4 +/*
    38.5 + *	The PCI Library -- Portable interface to pread() and pwrite()
    38.6 + *
    38.7 + *	Copyright (c) 1997--2003 Martin Mares <mj@ucw.cz>
    38.8 + *
    38.9 + *	Can be freely distributed and used under the terms of the GNU GPL.
   38.10 + */
   38.11 +
   38.12 +/*
   38.13 + *  We'd like to use pread/pwrite for configuration space accesses, but
   38.14 + *  unfortunately it isn't simple at all since all libc's until glibc 2.1
   38.15 + *  don't define it.
   38.16 + */
   38.17 +
   38.18 +#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ > 0
   38.19 +/* glibc 2.1 or newer -> pread/pwrite supported automatically */
   38.20 +
   38.21 +#elif defined(i386) && defined(__GLIBC__)
   38.22 +/* glibc 2.0 on i386 -> call syscalls directly */
   38.23 +#include <asm/unistd.h>
   38.24 +#include <syscall-list.h>
   38.25 +#ifndef SYS_pread
   38.26 +#define SYS_pread 180
   38.27 +#endif
   38.28 +static int pread(unsigned int fd, void *buf, size_t size, loff_t where)
   38.29 +{ return syscall(SYS_pread, fd, buf, size, where); }
   38.30 +#ifndef SYS_pwrite
   38.31 +#define SYS_pwrite 181
   38.32 +#endif
   38.33 +static int pwrite(unsigned int fd, void *buf, size_t size, loff_t where)
   38.34 +{ return syscall(SYS_pwrite, fd, buf, size, where); }
   38.35 +
   38.36 +#elif defined(i386)
   38.37 +/* old libc on i386 -> call syscalls directly the old way */
   38.38 +#include <asm/unistd.h>
   38.39 +static _syscall5(int, pread, unsigned int, fd, void *, buf, size_t, size, u32, where_lo, u32, where_hi);
   38.40 +static _syscall5(int, pwrite, unsigned int, fd, void *, buf, size_t, size, u32, where_lo, u32, where_hi);
   38.41 +static int do_read(struct pci_dev *d UNUSED, int fd, void *buf, size_t size, int where) { return pread(fd, buf, size, where, 0); }
   38.42 +static int do_write(struct pci_dev *d UNUSED, int fd, void *buf, size_t size, int where) { return pwrite(fd, buf, size, where, 0); }
   38.43 +#define PCI_HAVE_DO_READ
   38.44 +
   38.45 +#else
   38.46 +/* In all other cases we use lseek/read/write instead to be safe */
   38.47 +#define make_rw_glue(op) \
   38.48 +	static int do_##op(struct pci_dev *d, int fd, void *buf, size_t size, int where)	\
   38.49 +	{											\
   38.50 +	  struct pci_access *a = d->access;							\
   38.51 +	  int r;										\
   38.52 +	  if (a->fd_pos != where && lseek(fd, where, SEEK_SET) < 0)				\
   38.53 +	    return -1;										\
   38.54 +	  r = op(fd, buf, size);								\
   38.55 +	  if (r < 0)										\
   38.56 +	    a->fd_pos = -1;									\
   38.57 +	  else											\
   38.58 +	    a->fd_pos = where + r;								\
   38.59 +	  return r;										\
   38.60 +	}
   38.61 +make_rw_glue(read)
   38.62 +make_rw_glue(write)
   38.63 +#define PCI_HAVE_DO_READ
   38.64 +#endif
   38.65 +
   38.66 +#ifndef PCI_HAVE_DO_READ
   38.67 +#define do_read(d,f,b,l,p) pread(f,b,l,p)
   38.68 +#define do_write(d,f,b,l,p) pwrite(f,b,l,p)
   38.69 +#endif
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/proc.c	Mon Aug 13 17:49:00 2007 -0400
    39.3 @@ -0,0 +1,226 @@
    39.4 +/*
    39.5 + *	The PCI Library -- Configuration Access via /proc/bus/pci
    39.6 + *
    39.7 + *	Copyright (c) 1997--2003 Martin Mares <mj@ucw.cz>
    39.8 + *
    39.9 + *	Can be freely distributed and used under the terms of the GNU GPL.
   39.10 + */
   39.11 +
   39.12 +#define _GNU_SOURCE
   39.13 +
   39.14 +#include <stdio.h>
   39.15 +#include <string.h>
   39.16 +#include <unistd.h>
   39.17 +#include <errno.h>
   39.18 +#include <fcntl.h>
   39.19 +#include <sys/types.h>
   39.20 +
   39.21 +#include "internal.h"
   39.22 +#include "pread.h"
   39.23 +
   39.24 +static void
   39.25 +proc_config(struct pci_access *a)
   39.26 +{
   39.27 +  a->method_params[PCI_ACCESS_PROC_BUS_PCI] = PCI_PATH_PROC_BUS_PCI;
   39.28 +}
   39.29 +
   39.30 +static int
   39.31 +proc_detect(struct pci_access *a)
   39.32 +{
   39.33 +  char *name = a->method_params[PCI_ACCESS_PROC_BUS_PCI];
   39.34 +
   39.35 +  if (access(name, R_OK))
   39.36 +    {
   39.37 +      a->warning("Cannot open %s", name);
   39.38 +      return 0;
   39.39 +    }
   39.40 +  a->debug("...using %s", name);
   39.41 +  return 1;
   39.42 +}
   39.43 +
   39.44 +static void
   39.45 +proc_init(struct pci_access *a)
   39.46 +{
   39.47 +  a->fd = -1;
   39.48 +#ifdef PT_LIBPCI
   39.49 +  a->cached_b = -1;
   39.50 +  a->cached_d = -1;
   39.51 +  a->cached_f = -1;
   39.52 +#endif
   39.53 +}
   39.54 +
   39.55 +static void
   39.56 +proc_cleanup(struct pci_access *a)
   39.57 +{
   39.58 +  if (a->fd >= 0)
   39.59 +    {
   39.60 +      close(a->fd);
   39.61 +      a->fd = -1;
   39.62 +    }
   39.63 +}
   39.64 +
   39.65 +static void
   39.66 +proc_scan(struct pci_access *a)
   39.67 +{
   39.68 +  FILE *f;
   39.69 +  char buf[512];
   39.70 +
   39.71 +  if (snprintf(buf, sizeof(buf), "%s/devices", a->method_params[PCI_ACCESS_PROC_BUS_PCI]) == sizeof(buf))
   39.72 +    a->error("File name too long");
   39.73 +  f = fopen(buf, "r");
   39.74 +  if (!f)
   39.75 +    a->error("Cannot open %s", buf);
   39.76 +  while (fgets(buf, sizeof(buf)-1, f))
   39.77 +    {
   39.78 +      struct pci_dev *d = pci_alloc_dev(a);
   39.79 +      unsigned int dfn, vend, cnt, known;
   39.80 +
   39.81 +#define F " " PCIADDR_T_FMT
   39.82 +      cnt = sscanf(buf, "%x %x %x" F F F F F F F F F F F F F F,
   39.83 +	     &dfn,
   39.84 +	     &vend,
   39.85 +	     &d->irq,
   39.86 +	     &d->base_addr[0],
   39.87 +	     &d->base_addr[1],
   39.88 +	     &d->base_addr[2],
   39.89 +	     &d->base_addr[3],
   39.90 +	     &d->base_addr[4],
   39.91 +	     &d->base_addr[5],
   39.92 +	     &d->rom_base_addr,
   39.93 +	     &d->size[0],
   39.94 +	     &d->size[1],
   39.95 +	     &d->size[2],
   39.96 +	     &d->size[3],
   39.97 +	     &d->size[4],
   39.98 +	     &d->size[5],
   39.99 +	     &d->rom_size);
  39.100 +#undef F
  39.101 +      if (cnt != 9 && cnt != 10 && cnt != 17)
  39.102 +	a->error("proc: parse error (read only %d items)", cnt);
  39.103 +      d->bus = dfn >> 8U;
  39.104 +      d->dev = PCI_SLOT(dfn & 0xff);
  39.105 +      d->func = PCI_FUNC(dfn & 0xff);
  39.106 +      d->vendor_id = vend >> 16U;
  39.107 +      d->device_id = vend & 0xffff;
  39.108 +      known = PCI_FILL_IDENT;
  39.109 +      if (!a->buscentric)
  39.110 +	{
  39.111 +	  known |= PCI_FILL_IRQ | PCI_FILL_BASES;
  39.112 +	  if (cnt >= 10)
  39.113 +	    known |= PCI_FILL_ROM_BASE;
  39.114 +	  if (cnt >= 17)
  39.115 +	    known |= PCI_FILL_SIZES;
  39.116 +	}
  39.117 +      d->known_fields = known;
  39.118 +      pci_link_dev(a, d);
  39.119 +    }
  39.120 +  fclose(f);
  39.121 +}
  39.122 +
  39.123 +static int
  39.124 +proc_setup(struct pci_dev *d, int rw)
  39.125 +{
  39.126 +  struct pci_access *a = d->access;
  39.127 +
  39.128 +#ifndef PT_LIBPCI
  39.129 +  if (a->cached_dev != d || a->fd_rw < rw)
  39.130 +#else
  39.131 +  if (a->cached_b != d->bus || 
  39.132 +      a->cached_d != d->dev ||
  39.133 +      a->cached_f != d->func || 
  39.134 +      a->fd_rw < rw)
  39.135 +#endif
  39.136 +    {
  39.137 +      char buf[1024];
  39.138 +      int e;
  39.139 +      if (a->fd >= 0)
  39.140 +	close(a->fd);
  39.141 +      e = snprintf(buf, sizeof(buf), "%s/%02x/%02x.%d",
  39.142 +		   a->method_params[PCI_ACCESS_PROC_BUS_PCI],
  39.143 +		   d->bus, d->dev, d->func);
  39.144 +      if (e < 0 || e >= (int) sizeof(buf))
  39.145 +	a->error("File name too long");
  39.146 +      a->fd_rw = a->writeable || rw;
  39.147 +      a->fd = open(buf, a->fd_rw ? O_RDWR : O_RDONLY);
  39.148 +      if (a->fd < 0)
  39.149 +	a->warning("Cannot open %s", buf);
  39.150 +#ifndef PT_LIBPCI
  39.151 +      a->cached_dev = d;
  39.152 +#else
  39.153 +      a->cached_b = d->bus;
  39.154 +      a->cached_d = d->dev;
  39.155 +      a->cached_f = d->func;      
  39.156 +#endif
  39.157 +      a->fd_pos = 0;
  39.158 +    }
  39.159 +  return a->fd;
  39.160 +}
  39.161 +
  39.162 +static int
  39.163 +proc_read(struct pci_dev *d, int pos, byte *buf, int len)
  39.164 +{
  39.165 +  int fd = proc_setup(d, 0);
  39.166 +  int res;
  39.167 +
  39.168 +  if (fd < 0)
  39.169 +    return 0;
  39.170 +  res = do_read(d, fd, buf, len, pos);
  39.171 +  if (res < 0)
  39.172 +    {
  39.173 +      d->access->warning("proc_read: read failed: %s", strerror(errno));
  39.174 +      return 0;
  39.175 +    }
  39.176 +  else if (res != len)
  39.177 +    return 0;
  39.178 +  return 1;
  39.179 +}
  39.180 +
  39.181 +static int
  39.182 +proc_write(struct pci_dev *d, int pos, byte *buf, int len)
  39.183 +{
  39.184 +  int fd = proc_setup(d, 1);
  39.185 +  int res;
  39.186 +
  39.187 +  if (fd < 0)
  39.188 +    return 0;
  39.189 +  res = do_write(d, fd, buf, len, pos);
  39.190 +  if (res < 0)
  39.191 +    {
  39.192 +      d->access->warning("proc_write: write failed: %s", strerror(errno));
  39.193 +      return 0;
  39.194 +    }
  39.195 +  else if (res != len)
  39.196 +    {
  39.197 +      d->access->warning("proc_write: tried to write %d bytes at %d, but only %d succeeded", len, pos, res);
  39.198 +      return 0;
  39.199 +    }
  39.200 +  return 1;
  39.201 +}
  39.202 +
  39.203 +static void
  39.204 +proc_cleanup_dev(struct pci_dev *d)
  39.205 +{
  39.206 +  if (d->access->cached_dev == d)
  39.207 +    d->access->cached_dev = NULL;
  39.208 +}
  39.209 +
  39.210 +struct pci_methods pm_linux_proc = {
  39.211 +  "Linux-proc",
  39.212 +  proc_config,
  39.213 +  proc_detect,
  39.214 +  proc_init,
  39.215 +  proc_cleanup,
  39.216 +  proc_scan,
  39.217 +#ifdef PT_LIBPCI
  39.218 +  NULL,
  39.219 +#else
  39.220 +  pci_generic_fill_info,
  39.221 +#endif
  39.222 +  proc_read,
  39.223 +  proc_write,
  39.224 +  NULL,					/* init_dev */
  39.225 +  proc_cleanup_dev
  39.226 +#ifdef PT_LIBPCI
  39.227 +  , NULL
  39.228 +#endif
  39.229 +};
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/sysdep.h	Mon Aug 13 17:49:00 2007 -0400
    40.3 @@ -0,0 +1,92 @@
    40.4 +/*
    40.5 + *	The PCI Library -- System-Dependent Stuff
    40.6 + *
    40.7 + *	Copyright (c) 1997--2004 Martin Mares <mj@ucw.cz>
    40.8 + *
    40.9 + *	Can be freely distributed and used under the terms of the GNU GPL.
   40.10 + */
   40.11 +#ifndef __SYSDEP_H__
   40.12 +#define __SYSDEP_H__
   40.13 +
   40.14 +#ifdef __GNUC__
   40.15 +#define UNUSED __attribute__((unused))
   40.16 +#define NONRET __attribute__((noreturn))
   40.17 +#else
   40.18 +#define UNUSED
   40.19 +#define NONRET
   40.20 +#define inline
   40.21 +#endif
   40.22 +
   40.23 +typedef u8 byte;
   40.24 +typedef u16 word;
   40.25 +
   40.26 +#ifdef PCI_OS_WINDOWS
   40.27 +#define strcasecmp strcmpi
   40.28 +#endif
   40.29 +
   40.30 +#ifdef PCI_HAVE_LINUX_BYTEORDER_H
   40.31 +
   40.32 +#include <asm/byteorder.h>
   40.33 +#define cpu_to_le16 __cpu_to_le16
   40.34 +#define cpu_to_le32 __cpu_to_le32
   40.35 +#define le16_to_cpu __le16_to_cpu
   40.36 +#define le32_to_cpu __le32_to_cpu
   40.37 +
   40.38 +#else
   40.39 +
   40.40 +#ifdef PCI_OS_LINUX
   40.41 +#include <endian.h>
   40.42 +#define BYTE_ORDER __BYTE_ORDER
   40.43 +#define BIG_ENDIAN __BIG_ENDIAN
   40.44 +#endif
   40.45 +
   40.46 +#ifdef PCI_OS_SUNOS
   40.47 +#include <sys/byteorder.h>
   40.48 +#define BIG_ENDIAN 4321
   40.49 +#ifdef _LITTLE_ENDIAN
   40.50 +#define BYTE_ORDER 1234
   40.51 +#else
   40.52 +#define BYTE_ORDER 4321
   40.53 +#endif
   40.54 +#endif
   40.55 +
   40.56 +#ifdef PCI_OS_WINDOWS
   40.57 +#ifdef __MINGW32__
   40.58 +  #include <sys/param.h>
   40.59 +#else
   40.60 +  #include <io.h>
   40.61 +  #define BIG_ENDIAN 4321
   40.62 +  #define LITTLE_ENDIAN	1234
   40.63 +  #define BYTE_ORDER LITTLE_ENDIAN
   40.64 +  #define snprintf _snprintf
   40.65 +#endif
   40.66 +#endif
   40.67 +
   40.68 +#if BYTE_ORDER == BIG_ENDIAN
   40.69 +#define cpu_to_le16 swab16
   40.70 +#define cpu_to_le32 swab32
   40.71 +#define le16_to_cpu swab16
   40.72 +#define le32_to_cpu swab32
   40.73 +
   40.74 +static inline word swab16(word w)
   40.75 +{
   40.76 +  return (w << 8) | ((w >> 8) & 0xff);
   40.77 +}
   40.78 +
   40.79 +static inline u32 swab32(u32 w)
   40.80 +{
   40.81 +  return ((w & 0xff000000) >> 24) |
   40.82 +         ((w & 0x00ff0000) >> 8) |
   40.83 +         ((w & 0x0000ff00) << 8)  |
   40.84 +         ((w & 0x000000ff) << 24);
   40.85 +}
   40.86 +#else
   40.87 +#define cpu_to_le16(x) (x)
   40.88 +#define cpu_to_le32(x) (x)
   40.89 +#define le16_to_cpu(x) (x)
   40.90 +#define le32_to_cpu(x) (x)
   40.91 +#endif
   40.92 +
   40.93 +#endif
   40.94 +
   40.95 +#endif /* __SYSDEP_H__ */
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/sysfs.c	Mon Aug 13 17:49:00 2007 -0400
    41.3 @@ -0,0 +1,289 @@
    41.4 +/*
    41.5 + *	The PCI Library -- Configuration Access via /sys/bus/pci
    41.6 + *
    41.7 + * 	Copyright (c) 2003 Matthew Wilcox <willy@fc.hp.com>
    41.8 + *	Copyright (c) 1997--2003 Martin Mares <mj@ucw.cz>
    41.9 + *
   41.10 + *	Can be freely distributed and used under the terms of the GNU GPL.
   41.11 + */
   41.12 +
   41.13 +#define _GNU_SOURCE
   41.14 +
   41.15 +#include <stdio.h>
   41.16 +#include <stdlib.h>
   41.17 +#include <string.h>
   41.18 +#include <stdarg.h>
   41.19 +#include <unistd.h>
   41.20 +#include <errno.h>
   41.21 +#include <dirent.h>
   41.22 +#include <fcntl.h>
   41.23 +#include <sys/types.h>
   41.24 +
   41.25 +#include "internal.h"
   41.26 +#include "pread.h"
   41.27 +
   41.28 +static void
   41.29 +sysfs_config(struct pci_access *a)
   41.30 +{
   41.31 +  a->method_params[PCI_ACCESS_SYS_BUS_PCI] = PCI_PATH_SYS_BUS_PCI;
   41.32 +}
   41.33 +
   41.34 +static inline char *
   41.35 +sysfs_name(struct pci_access *a)
   41.36 +{
   41.37 +  return a->method_params[PCI_ACCESS_SYS_BUS_PCI];
   41.38 +}
   41.39 +
   41.40 +static int
   41.41 +sysfs_detect(struct pci_access *a)
   41.42 +{
   41.43 +  if (access(sysfs_name(a), R_OK))
   41.44 +    {
   41.45 +      a->debug("...cannot open %s", sysfs_name(a));
   41.46 +      return 0;
   41.47 +    }
   41.48 +  a->debug("...using %s", sysfs_name(a));
   41.49 +  return 1;
   41.50 +}
   41.51 +
   41.52 +static void
   41.53 +sysfs_init(struct pci_access *a)
   41.54 +{
   41.55 +  a->fd = -1;
   41.56 +#ifdef PT_LIBPCI
   41.57 +  a->cached_b = -1;
   41.58 +  a->cached_d = -1;
   41.59 +  a->cached_f = -1;
   41.60 +#endif
   41.61 +}
   41.62 +
   41.63 +static void
   41.64 +sysfs_cleanup(struct pci_access *a)
   41.65 +{
   41.66 +  if (a->fd >= 0)
   41.67 +    {
   41.68 +      close(a->fd);
   41.69 +      a->fd = -1;
   41.70 +    }
   41.71 +}
   41.72 +
   41.73 +#define OBJNAMELEN 1024
   41.74 +static void
   41.75 +sysfs_obj_name(struct pci_dev *d, char *object, char *buf)
   41.76 +{
   41.77 +  int n = snprintf(buf, OBJNAMELEN, "%s/devices/%04x:%02x:%02x.%d/%s",
   41.78 +		   sysfs_name(d->access), d->domain, d->bus, d->dev, d->func, object);
   41.79 +  if (n < 0 || n >= OBJNAMELEN)
   41.80 +    d->access->error("File name too long");
   41.81 +}
   41.82 +
   41.83 +static int
   41.84 +sysfs_get_value(struct pci_dev *d, char *object)
   41.85 +{
   41.86 +  struct pci_access *a = d->access;
   41.87 +  int fd, n;
   41.88 +  char namebuf[OBJNAMELEN], buf[256];
   41.89 +
   41.90 +  sysfs_obj_name(d, object, namebuf);
   41.91 +  fd = open(namebuf, O_RDONLY);
   41.92 +  if (fd < 0)
   41.93 +    a->error("Cannot open %s: %s", namebuf, strerror(errno));
   41.94 +  n = read(fd, buf, sizeof(buf));
   41.95 +  close(fd);
   41.96 +  if (n < 0)
   41.97 +    a->error("Error reading %s: %s", namebuf, strerror(errno));
   41.98 +  if (n >= (int) sizeof(buf))
   41.99 +    a->error("Value in %s too long", namebuf);
  41.100 +  buf[n] = 0;
  41.101 +  return strtol(buf, NULL, 0);
  41.102 +}
  41.103 +
  41.104 +static void
  41.105 +sysfs_get_resources(struct pci_dev *d)
  41.106 +{
  41.107 +  struct pci_access *a = d->access;
  41.108 +  char namebuf[OBJNAMELEN], buf[256];
  41.109 +  FILE *file;
  41.110 +  int i;
  41.111 +
  41.112 +  sysfs_obj_name(d, "resource", namebuf);
  41.113 +  file = fopen(namebuf, "r");
  41.114 +  if (!file)
  41.115 +    a->error("Cannot open %s: %s", namebuf, strerror(errno));
  41.116 +  for (i = 0; i < 7; i++)
  41.117 +    {
  41.118 +      unsigned long long start, end, size;
  41.119 +      if (!fgets(buf, sizeof(buf), file))
  41.120 +	break;
  41.121 +      if (sscanf(buf, "%llx %llx", &start, &end) != 2)
  41.122 +	a->error("Syntax error in %s", namebuf);
  41.123 +      if (start)
  41.124 +	size = end - start + 1;
  41.125 +      else
  41.126 +	size = 0;
  41.127 +      if (i < 6)
  41.128 +	{
  41.129 +	  d->base_addr[i] = start;
  41.130 +	  d->size[i] = size;
  41.131 +	}
  41.132 +      else
  41.133 +	{
  41.134 +	  d->rom_base_addr = start;
  41.135 +	  d->rom_size = size;
  41.136 +	}
  41.137 +    }
  41.138 +  fclose(file);
  41.139 +}
  41.140 +
  41.141 +static void sysfs_scan(struct pci_access *a)
  41.142 +{
  41.143 +  char dirname[1024];
  41.144 +  DIR *dir;
  41.145 +  struct dirent *entry;
  41.146 +  int n;
  41.147 +
  41.148 +  n = snprintf(dirname, sizeof(dirname), "%s/devices", sysfs_name(a));
  41.149 +  if (n < 0 || n >= (int) sizeof(dirname))
  41.150 +    a->error("Directory name too long");
  41.151 +  dir = opendir(dirname);
  41.152 +  if (!dir)
  41.153 +    a->error("Cannot open %s", dirname);
  41.154 +  while ((entry = readdir(dir)))
  41.155 +    {
  41.156 +      struct pci_dev *d;
  41.157 +      unsigned int dom, bus, dev, func;
  41.158 +
  41.159 +      /* ".", ".." or a special non-device perhaps */
  41.160 +      if (entry->d_name[0] == '.')
  41.161 +	continue;
  41.162 +
  41.163 +      d = pci_alloc_dev(a);
  41.164 +      if (sscanf(entry->d_name, "%x:%x:%x.%d", &dom, &bus, &dev, &func) < 4)
  41.165 +	a->error("sysfs_scan: Couldn't parse entry name %s", entry->d_name);
  41.166 +      d->domain = dom;
  41.167 +      d->bus = bus;
  41.168 +      d->dev = dev;
  41.169 +      d->func = func;
  41.170 +      if (!a->buscentric)
  41.171 +	{
  41.172 +	  sysfs_get_resources(d);
  41.173 +	  d->irq = sysfs_get_value(d, "irq");
  41.174 +	  /*
  41.175 +	   *  We could read these faster from the config registers, but we want to give
  41.176 +	   *  the kernel a chance to fix up ID's and especially classes of broken devices.
  41.177 +	   */
  41.178 +	  d->vendor_id = sysfs_get_value(d, "vendor");
  41.179 +	  d->device_id = sysfs_get_value(d, "device");
  41.180 +	  d->device_class = sysfs_get_value(d, "class") >> 8;
  41.181 +	  d->known_fields = PCI_FILL_IDENT | PCI_FILL_CLASS | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES;
  41.182 +	}
  41.183 +      pci_link_dev(a, d);
  41.184 +    }
  41.185 +  closedir(dir);
  41.186 +}
  41.187 +
  41.188 +static int
  41.189 +sysfs_setup(struct pci_dev *d, int rw)
  41.190 +{
  41.191 +  struct pci_access *a = d->access;
  41.192 +
  41.193 +#ifndef PT_LIBPCI
  41.194 +  if (a->cached_dev != d || a->fd_rw < rw)
  41.195 +#else
  41.196 +  if (a->cached_b != d->bus || 
  41.197 +      a->cached_d != d->dev ||
  41.198 +      a->cached_f != d->func || 
  41.199 +      a->fd_rw < rw)
  41.200 +#endif
  41.201 +    {
  41.202 +      char namebuf[OBJNAMELEN];
  41.203 +      if (a->fd >= 0)
  41.204 +	close(a->fd);
  41.205 +      sysfs_obj_name(d, "config", namebuf);
  41.206 +      a->fd_rw = a->writeable || rw;
  41.207 +      a->fd = open(namebuf, a->fd_rw ? O_RDWR : O_RDONLY);
  41.208 +      if (a->fd < 0)
  41.209 +	a->warning("Cannot open %s", namebuf);
  41.210 +#ifndef PT_LIBPCI
  41.211 +      a->cached_dev = d;
  41.212 +#else
  41.213 +      a->cached_b = d->bus;
  41.214 +      a->cached_d = d->dev;
  41.215 +      a->cached_f = d->func;      
  41.216 +#endif
  41.217 +      a->fd_pos = 0;
  41.218 +    }
  41.219 +  return a->fd;
  41.220 +}
  41.221 +
  41.222 +static int sysfs_read(struct pci_dev *d, int pos, byte *buf, int len)
  41.223 +{
  41.224 +  int fd = sysfs_setup(d, 0);
  41.225 +  int res;
  41.226 +
  41.227 +  if (fd < 0)
  41.228 +    return 0;
  41.229 +  res = do_read(d, fd, buf, len, pos);
  41.230 +  if (res < 0)
  41.231 +    {
  41.232 +      d->access->warning("sysfs_read: read failed: %s", strerror(errno));
  41.233 +      return 0;
  41.234 +    }
  41.235 +  else if (res != len)
  41.236 +    return 0;
  41.237 +  return 1;
  41.238 +}
  41.239 +
  41.240 +static int sysfs_write(struct pci_dev *d, int pos, byte *buf, int len)
  41.241 +{
  41.242 +  int fd = sysfs_setup(d, 1);
  41.243 +  int res;
  41.244 +
  41.245 +  if (fd < 0)
  41.246 +    return 0;
  41.247 +  res = do_write(d, fd, buf, len, pos);
  41.248 +  if (res < 0)
  41.249 +    {
  41.250 +      d->access->warning("sysfs_write: write failed: %s", strerror(errno));
  41.251 +      return 0;
  41.252 +    }
  41.253 +  else if (res != len)
  41.254 +    {
  41.255 +      d->access->warning("sysfs_write: tried to write %d bytes at %d, but only %d succeeded", len, pos, res);
  41.256 +      return 0;
  41.257 +    }
  41.258 +  return 1;
  41.259 +}
  41.260 +
  41.261 +static void sysfs_cleanup_dev(struct pci_dev *d)
  41.262 +{
  41.263 +  struct pci_access *a = d->access;
  41.264 +
  41.265 +  if (a->cached_dev == d)
  41.266 +    {
  41.267 +      a->cached_dev = NULL;
  41.268 +      close(a->fd);
  41.269 +      a->fd = -1;
  41.270 +    }
  41.271 +}
  41.272 +
  41.273 +struct pci_methods pm_linux_sysfs = {
  41.274 +  "Linux-sysfs",
  41.275 +  sysfs_config,
  41.276 +  sysfs_detect,
  41.277 +  sysfs_init,
  41.278 +  sysfs_cleanup,
  41.279 +  sysfs_scan,
  41.280 +#ifndef PT_LIBPCI
  41.281 +  pci_generic_fill_info,
  41.282 +#else
  41.283 +  NULL,
  41.284 +#endif
  41.285 +  sysfs_read,
  41.286 +  sysfs_write,
  41.287 +  NULL,					/* init_dev */
  41.288 +  sysfs_cleanup_dev
  41.289 +#ifdef PT_LIBPCI
  41.290 +  , sysfs_get_value
  41.291 +#endif
  41.292 +};
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/tools/ioemu/pt-libpci/lib2.2.6/types.h	Mon Aug 13 17:49:00 2007 -0400
    42.3 @@ -0,0 +1,62 @@
    42.4 +/*
    42.5 + *	The PCI Library -- Types and Format Strings
    42.6 + *
    42.7 + *	Copyright (c) 1997--2007 Martin Mares <mj@ucw.cz>
    42.8 + *
    42.9 + *	Can be freely distributed and used under the terms of the GNU GPL.
   42.10 + */
   42.11 +#ifndef __TYPES_H__
   42.12 +#define __TYPES_H__
   42.13 +
   42.14 +#include <sys/types.h>
   42.15 +
   42.16 +#ifndef PCI_HAVE_Uxx_TYPES
   42.17 +
   42.18 +#ifdef PCI_OS_WINDOWS
   42.19 +typedef unsigned __int8 u8;
   42.20 +typedef unsigned __int16 u16;
   42.21 +typedef unsigned __int32 u32;
   42.22 +#elif defined(PCI_HAVE_STDINT_H)
   42.23 +#include <stdint.h>
   42.24 +typedef uint8_t u8;
   42.25 +typedef uint16_t u16;
   42.26 +typedef uint32_t u32;
   42.27 +#else
   42.28 +typedef u_int8_t u8;
   42.29 +typedef u_int16_t u16;
   42.30 +typedef u_int32_t u32;
   42.31 +#endif
   42.32 +
   42.33 +#ifdef PCI_HAVE_64BIT_ADDRESS
   42.34 +#include <limits.h>
   42.35 +#if ULONG_MAX > 0xffffffff
   42.36 +typedef unsigned long u64;
   42.37 +#define PCI_U64_FMT "l"
   42.38 +#else
   42.39 +typedef unsigned long long u64;
   42.40 +#define PCI_U64_FMT "ll"
   42.41 +#endif
   42.42 +#endif
   42.43 +
   42.44 +#endif	/* PCI_HAVE_Uxx_TYPES */
   42.45 +
   42.46 +#ifdef PCI_HAVE_64BIT_ADDRESS
   42.47 +typedef u64 pciaddr_t;
   42.48 +#define PCIADDR_T_FMT "%08" PCI_U64_FMT "x"
   42.49 +#define PCIADDR_PORT_FMT "%04" PCI_U64_FMT "x"
   42.50 +#else
   42.51 +typedef u32 pciaddr_t;
   42.52 +#define PCIADDR_T_FMT "%08x"
   42.53 +#define PCIADDR_PORT_FMT "%04x"
   42.54 +#endif
   42.55 +
   42.56 +#ifdef PCI_ARCH_SPARC64
   42.57 +/* On sparc64 Linux the kernel reports remapped port addresses and IRQ numbers */
   42.58 +#undef PCIADDR_PORT_FMT
   42.59 +#define PCIADDR_PORT_FMT PCIADDR_T_FMT
   42.60 +#define PCIIRQ_FMT "%08x"
   42.61 +#else
   42.62 +#define PCIIRQ_FMT "%d"
   42.63 +#endif
   42.64 +
   42.65 +#endif /* __TYPES_H__ */
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/tools/ioemu/pt-libpci/lspci.c	Mon Aug 13 17:49:00 2007 -0400
    43.3 @@ -0,0 +1,22 @@
    43.4 +/*****************************************************************************
    43.5 +
    43.6 +    Copyright (c) 2007, Neocleus: Alex Novik, Guy Zana
    43.7 +
    43.8 +******************************************************************************/
    43.9 +#include <stdio.h>
   43.10 +#include <string.h>
   43.11 +#include <stdlib.h>
   43.12 +#include <stdarg.h>
   43.13 +#include <unistd.h>
   43.14 +
   43.15 +#include "pt_libpci.h"
   43.16 +#include "pt_pci_probe.h"
   43.17 +#include "pt_pci_tree.h"
   43.18 +
   43.19 +int main()
   43.20 +{
   43.21 +    pt_libpci_init(stdout);
   43.22 +    pt_bus_probe(0, 1);
   43.23 +    pt_print_device_map();
   43.24 +    pt_libpci_clean();
   43.25 +}
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/tools/ioemu/pt-libpci/pt_libpci.c	Mon Aug 13 17:49:00 2007 -0400
    44.3 @@ -0,0 +1,52 @@
    44.4 +/*****************************************************************************
    44.5 +
    44.6 +    Copyright (c) 2007, Neocleus: Alex Novik, Guy Zana
    44.7 +
    44.8 +******************************************************************************/
    44.9 +#include <stdio.h>
   44.10 +#include <stdlib.h>
   44.11 +#include <stdarg.h>
   44.12 +#include <string.h>
   44.13 +#include <errno.h>
   44.14 +
   44.15 +#include "pt_libpci.h"
   44.16 +#include "pt_pci_access.h"
   44.17 +
   44.18 +FILE * logfile;
   44.19 +
   44.20 +void pt_libpci_log(char *msg, ...)
   44.21 +{
   44.22 +#ifdef PT_LIBPCI_LOG
   44.23 +  va_list args;
   44.24 +
   44.25 +  va_start(args, msg);
   44.26 +  fputs("pt-pcilib: ", logfile);
   44.27 +  vfprintf(logfile, msg, args);
   44.28 +  fputc('\n', logfile);
   44.29 +#endif
   44.30 +}
   44.31 +
   44.32 +pt_libpci_rc_t pt_libpci_clean(void)
   44.33 +{
   44.34 +    pt_clean_tree();
   44.35 +    pt_pci_access_clean();
   44.36 +}
   44.37 +
   44.38 +pt_libpci_rc_t pt_libpci_init(FILE * fileout)
   44.39 +{  
   44.40 +    pt_libpci_rc_t rc;
   44.41 +    
   44.42 +    logfile = fileout;
   44.43 +    
   44.44 +    /* Initialize our place holder */
   44.45 +    rc = pt_device_tree_init();
   44.46 +    if ( PT_RC_FAILURE == rc )
   44.47 +        return rc;
   44.48 +
   44.49 +    rc = pt_pci_access_init();
   44.50 +    if ( PT_RC_FAILURE == rc )
   44.51 +        return rc;
   44.52 +
   44.53 +    return PT_RC_SUCCESS;
   44.54 +} 
   44.55 +
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/tools/ioemu/pt-libpci/pt_libpci.h	Mon Aug 13 17:49:00 2007 -0400
    45.3 @@ -0,0 +1,100 @@
    45.4 +/*****************************************************************************
    45.5 +
    45.6 +    Copyright (c) 2007, Neocleus: Alex Novik, Guy Zana
    45.7 +
    45.8 +******************************************************************************/
    45.9 +#ifndef __PT_LIBPCI_H__
   45.10 +#define __PT_LIBPCI_H__
   45.11 +
   45.12 +#include <stdio.h>
   45.13 +
   45.14 +#include "lib2.2.6/pci.h"
   45.15 +#include "lib2.2.6/internal.h"
   45.16 +
   45.17 +/* Enable libpci debug log */
   45.18 +//#define PT_LIBPCI_LOG
   45.19 +
   45.20 +/* Return types for functions */
   45.21 +typedef enum pt_rc_e {
   45.22 +    PT_RC_SUCCESS = 0,
   45.23 +    PT_RC_FAILURE	
   45.24 +} pt_libpci_rc_t;
   45.25 +
   45.26 +typedef enum pt_pci_address_width_e {
   45.27 +    PT_PCI_ADDRESS_WIDTH_8         = 8,
   45.28 +    PT_PCI_ADDRESS_WIDTH_16        = 16,
   45.29 +    PT_PCI_ADDRESS_WIDTH_24        = 24,
   45.30 +    PT_PCI_ADDRESS_WIDTH_32        = 32,
   45.31 +    PT_PCI_ADDRESS_WIDTH_64        = 64,
   45.32 +    PT_PCI_ADDRESS_WIDTH_UNKNOWN   = -1
   45.33 +} pci_address_width_t;
   45.34 +
   45.35 +typedef enum pt_pci_address_e {
   45.36 +    PT_PCI_ADDRESS_SPACE_MEM           = 0x00,
   45.37 +    PT_PCI_ADDRESS_SPACE_IO            = 0x01,
   45.38 +    PT_PCI_ADDRESS_SPACE_MEM_PREFETCH  = 0x08
   45.39 +} pt_pci_address_t;
   45.40 +
   45.41 +#define PT_GET_TYPE_STR(type) \
   45.42 +    (type == PT_PCI_ADDRESS_SPACE_MEM) ? \
   45.43 +        "PT_PCI_ADDRESS_SPACE_MEM" : ((type == PT_PCI_ADDRESS_SPACE_IO) ? \
   45.44 +                "PT_PCI_ADDRESS_SPACE_IO": "PT_PCI_ADDRESS_SPACE_MEM_PREFETCH")
   45.45 +
   45.46 +#define PT_GET64(high, low) (u64)(((u64)(high)<<32) | (u64)low)
   45.47 +
   45.48 +typedef enum pt_pci_memory_region_e {
   45.49 +    /* Values for the flag field */
   45.50 +    PT_PCI_REGION_UNASSIGNED   = 0x0001,
   45.51 +    PT_PCI_REGION_DISABLED     = 0x0002,
   45.52 +    PT_PCI_REGION_IGNORED      = 0x0004,
   45.53 +    PT_PCI_REGION_INVALID      = 0x0008,
   45.54 +    PT_PCI_REGION_VALID        = 0x0010
   45.55 +} pt_pci_memory_region_t;
   45.56 +
   45.57 +#define PCI_REGION_IS_VALID(pcidev, region)     (pcidev->regions[region].flags == PT_PCI_REGION_VALID)
   45.58 +#define IS_VALID_REGION(region)                 (region->flags == PT_PCI_REGION_VALID)
   45.59 +
   45.60 +#define MAX_IO_REGIONS			(6) 
   45.61 +typedef struct pci_region_s {
   45.62 +    /* Memory or port I/O */
   45.63 +    pt_pci_address_t type;
   45.64 +    /* Region flags */
   45.65 +    u16 flags;
   45.66 +    /* Granularity of the size (used for PCI bridges) */
   45.67 +    pciaddr_t size_granularity;
   45.68 +    pciaddr_t base_addr;
   45.69 +    /* Size of the region */
   45.70 +    pciaddr_t size;
   45.71 +    /* 16, 32, 64 bits */
   45.72 +    pci_address_width_t addr_width;
   45.73 +} pci_region_t;
   45.74 +
   45.75 +typedef struct pci_phys_dev_s {
   45.76 +    /* Bus inside domain, device and function */
   45.77 +    u8 bus, dev, func;
   45.78 +    /* Identity of the device */
   45.79 +    u16 vendor_id, device_id;
   45.80 +    u32 device_class;
   45.81 +    u8 header_type;
   45.82 +    u8 irq;
   45.83 +    /* secondary bus number (used for PCI bridges) */
   45.84 +    u8 secondary_bus;	
   45.85 +    int is_pcie;    /* not implemented yet */
   45.86 +    /* Number of active regions */
   45.87 +    u16 region_number;
   45.88 +    /* PIO / MMIO Regions */
   45.89 +    pci_region_t regions[MAX_IO_REGIONS];
   45.90 +    /* Is ROM enabled */
   45.91 +    u8 rom_enabled;
   45.92 +    /* Expansion ROM base address */
   45.93 +    pciaddr_t rom_base_addr;
   45.94 +    /* Expansion ROM size */
   45.95 +    pciaddr_t rom_size;
   45.96 +} pci_phys_dev_t;
   45.97 +
   45.98 +void pt_libpci_log(char *msg, ...);
   45.99 +pt_libpci_rc_t pt_libpci_clean(void);
  45.100 +pt_libpci_rc_t pt_libpci_init(FILE * fileout);
  45.101 +
  45.102 +#endif /* __PT_LIBPCI_H__ */
  45.103 +
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/tools/ioemu/pt-libpci/pt_pci_access.c	Mon Aug 13 17:49:00 2007 -0400
    46.3 @@ -0,0 +1,246 @@
    46.4 +/*****************************************************************************
    46.5 +
    46.6 +    Copyright (c) 2007, Neocleus: Alex Novik, Guy Zana
    46.7 +
    46.8 +    Based on code that were taken from the PCI library (pciutils)
    46.9 +    Copyright (c) 1997--2000 Martin Mares <mj@ucw.cz>
   46.10 +
   46.11 +******************************************************************************/
   46.12 +#include <stdio.h>
   46.13 +#include <stdlib.h>
   46.14 +#include <stdarg.h>
   46.15 +#include <string.h>
   46.16 +#include <unistd.h>
   46.17 +#include <sys/io.h>
   46.18 +
   46.19 +#include "pt_libpci.h"
   46.20 +#include "pt_pci_probe.h"
   46.21 +#include "pt_pci_access.h"
   46.22 +#include "pt_pci_tree.h"
   46.23 +
   46.24 +struct pci_access * sysfs_access;
   46.25 +
   46.26 +extern void pt_libpci_log(char *msg, ...);
   46.27 +
   46.28 +int pci_set_access_permissions(void)
   46.29 +{
   46.30 +    static int intel_iopl_set=-1;
   46.31 +    
   46.32 +    if (intel_iopl_set < 0)
   46.33 +        intel_iopl_set = (iopl(3) < 0) ? 0 : 1;
   46.34 +        
   46.35 +    return (intel_iopl_set);
   46.36 +}
   46.37 +
   46.38 +u32 pt_pio_read(u32 addr, u32 size)
   46.39 +{
   46.40 +    u32 val = 0;	
   46.41 +
   46.42 +    switch (size) {
   46.43 +    case 1:
   46.44 +        val = (u32) inb(addr);
   46.45 +        break;
   46.46 +        
   46.47 +    case 2:
   46.48 +        val = (u32) inw(addr);
   46.49 +        break;
   46.50 +        
   46.51 +    case 4:
   46.52 +        val = (u32) inl(addr);
   46.53 +        break;
   46.54 +        
   46.55 +    default:
   46.56 +        val = PCI_INAVLID;
   46.57 +        break;
   46.58 +    }
   46.59 +
   46.60 +    return (val);
   46.61 +}
   46.62 +
   46.63 +int pt_pio_write(u32 addr, u32 val, u32 size)
   46.64 +{
   46.65 +
   46.66 +    switch (size) {
   46.67 +    case 1:
   46.68 +        outb(val, addr);
   46.69 +        break;
   46.70 +        
   46.71 +    case 2:
   46.72 +        outw(val, addr);
   46.73 +        break;
   46.74 +        
   46.75 +    case 4:
   46.76 +        outl(val, addr);
   46.77 +        break;
   46.78 +        
   46.79 +    default:
   46.80 +        return (PCI_INAVLID);
   46.81 +    }
   46.82 +
   46.83 +    /* success */
   46.84 +    return (0);
   46.85 +
   46.86 +} /* end of neo_pio_write */
   46.87 +
   46.88 +u32 pt_mmio_read( u32 addr, u32 size)
   46.89 +{
   46.90 +    u32 val = 0;
   46.91 +
   46.92 +    switch (size) {
   46.93 +        case 1:		
   46.94 +            val = (u32)(*(u8 *)addr);
   46.95 +            break;
   46.96 +            
   46.97 +        case 2:
   46.98 +            val = (u32)(*(u16 *)addr);
   46.99 +            break;
  46.100 +            
  46.101 +        case 4:
  46.102 +            val = (u32)(*(u32 *)addr);
  46.103 +            break;
  46.104 +            
  46.105 +        default:
  46.106 +            return (PCI_INAVLID);
  46.107 +    }
  46.108 +
  46.109 +    return (val);
  46.110 +} 
  46.111 +
  46.112 +u32 pt_mmio_write(u32 addr, u32 value, u32 size)
  46.113 +{
  46.114 +
  46.115 +    switch (size) {
  46.116 +    case 1:
  46.117 +        *((u8 *) addr) = (u8) value;
  46.118 +        break;
  46.119 +        
  46.120 +    case 2:
  46.121 +        *((u16 *) addr) = (u16) value;
  46.122 +        break;
  46.123 +        
  46.124 +    case 4:
  46.125 +        *((u32 *) addr) = (u32) value;
  46.126 +        break;
  46.127 +        
  46.128 +    default:
  46.129 +        return (PCI_INAVLID);
  46.130 +    }
  46.131 +
  46.132 +    /* success */
  46.133 +    return (0);
  46.134 +
  46.135 +}
  46.136 +
  46.137 +void pci_read_data(u8 bus, u8 device, u8 func, void *buf, int pos, int len)
  46.138 +{
  46.139 +    struct pci_dev tmp;
  46.140 +    memset(&tmp, 0, sizeof(struct pci_dev ));
  46.141 +    
  46.142 +    tmp.bus = bus;
  46.143 +    tmp.dev = device;
  46.144 +    tmp.func = func;
  46.145 +    tmp.access = sysfs_access;
  46.146 +    sysfs_access->methods->read(&tmp, pos, buf, len);
  46.147 +}
  46.148 +
  46.149 +u8 pci_read_byte(u8 bus, u8 device, u8 func, int pos)
  46.150 +{
  46.151 +    u8 buf;
  46.152 +
  46.153 +    pci_read_data(bus,device,func, &buf, pos, 1);
  46.154 +    return buf;
  46.155 +}
  46.156 +
  46.157 +u16 pci_read_word(u8 bus, u8 device, u8 func, int pos)
  46.158 +{
  46.159 +    u16 buf;
  46.160 +
  46.161 +    pci_read_data(bus,device,func, &buf, pos, 2);
  46.162 +    return buf;
  46.163 +}
  46.164 +
  46.165 +u32 pci_read_long(u8 bus, u8 device, u8 func, int pos)
  46.166 +{
  46.167 +    u32 buf;
  46.168 +
  46.169 +    pci_read_data(bus,device,func, &buf, pos, 4);
  46.170 +    return buf;
  46.171 +}
  46.172 +
  46.173 +int pci_write_data(u8 bus, u8 device, u8 func, void *buf, int pos, int len)
  46.174 +{
  46.175 +    struct pci_dev tmp;
  46.176 +    int res;
  46.177 +    memset(&tmp, 0, sizeof(struct pci_dev ));
  46.178 +    
  46.179 +    tmp.bus = bus;
  46.180 +    tmp.dev = device;
  46.181 +    tmp.func = func;
  46.182 +    tmp.access = sysfs_access;
  46.183 +    res = sysfs_access->methods->write(&tmp, pos, buf, len);
  46.184 +
  46.185 +    return res;
  46.186 +}
  46.187 +
  46.188 +int pci_write_byte(u8 bus, u8 device, u8 func, int pos, u8 data)
  46.189 +{
  46.190 +    return pci_write_data(bus, device, func, &data, pos, 1);
  46.191 +}
  46.192 +
  46.193 +int pci_write_word(u8 bus, u8 device, u8 func, int pos, u16 data)
  46.194 +{
  46.195 +    u16 buf = data;
  46.196 +    return pci_write_data(bus, device, func, &buf, pos, 2);
  46.197 +}
  46.198 +
  46.199 +int pci_write_long(u8 bus, u8 device, u8 func, int pos, u32 data)
  46.200 +{
  46.201 +    u32 buf = data;
  46.202 +    return pci_write_data(bus, device, func, &buf, pos, 4);
  46.203 +}
  46.204 +
  46.205 +u8 pci_get_irq(u8 bus, u8 device, u8 func)
  46.206 +{
  46.207 +    u8 res;
  46.208 +    struct pci_dev tmp;
  46.209 +    memset(&tmp, 0, sizeof(struct pci_dev ));
  46.210 +    
  46.211 +    tmp.bus = bus;
  46.212 +    tmp.dev = device;
  46.213 +    tmp.func = func;
  46.214 +    tmp.access = sysfs_access;
  46.215 +
  46.216 +    res = sysfs_access->methods->get_object(&tmp, "irq");
  46.217 +    return (res);
  46.218 +}
  46.219 +
  46.220 +pt_libpci_rc_t pt_pci_access_clean(void)
  46.221 +{
  46.222 +    pci_cleanup(sysfs_access);
  46.223 +    return PT_RC_SUCCESS;
  46.224 +}
  46.225 +
  46.226 +pt_libpci_rc_t pt_pci_access_init(void)
  46.227 +{
  46.228 +
  46.229 +    /* Initialize access for PIO access */
  46.230 +    if ( pci_set_access_permissions() < 0 )
  46.231 +        return PT_RC_FAILURE;
  46.232 +
  46.233 +    /* Initialize access methods */
  46.234 +    sysfs_access = pci_alloc();
  46.235 +    
  46.236 +    sysfs_access->error = pt_libpci_log;
  46.237 +    sysfs_access->warning = pt_libpci_log;
  46.238 +    sysfs_access->debug = pt_libpci_log;
  46.239 +
  46.240 +    /* Init sysfs */
  46.241 +    sysfs_access->methods = &pm_linux_sysfs;
  46.242 +    sysfs_access->methods->config(sysfs_access);
  46.243 +    if ( !sysfs_access->methods->detect(sysfs_access) )
  46.244 +        return PT_RC_FAILURE;
  46.245 +
  46.246 +    sysfs_access->methods->init(sysfs_access);
  46.247 +    
  46.248 +    return PT_RC_SUCCESS;
  46.249 +}
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/tools/ioemu/pt-libpci/pt_pci_access.h	Mon Aug 13 17:49:00 2007 -0400
    47.3 @@ -0,0 +1,40 @@
    47.4 +/*****************************************************************************
    47.5 +
    47.6 +    Low-level PCI access routines.
    47.7 +    Copyright (c) 2007, Neocleus: Alex Novik, Guy Zana
    47.8 +
    47.9 +******************************************************************************/
   47.10 +#ifndef __PT_PCI_ACCESS_H__
   47.11 +#define __PT_PCI_ACCESS_H__
   47.12 +
   47.13 +#include "pt_libpci.h"
   47.14 +
   47.15 +#define PCI_CONFIG_SIZE     (256)
   47.16 +#define PCI_INAVLID         (0xFFFFFFFF)
   47.17 +
   47.18 +/* Permissions to access the ports enable */ 
   47.19 +int pci_set_access_permissions(void);
   47.20 +
   47.21 +/* Access to io memory */
   47.22 +u32 pt_mmio_write(u32 addr, u32 value, u32 size);
   47.23 +u32 pt_mmio_read(u32 addr, u32 size);
   47.24 +
   47.25 +/* Access to io ports */
   47.26 +u32 pt_pio_read(u32 addr, u32 size);
   47.27 +int pt_pio_write(u32 addr, u32 val, u32 size);
   47.28 +
   47.29 +/* Access to config space */
   47.30 +void pci_read_data(u8 bus, u8 device, u8 func, void *buf, int pos, int len);
   47.31 +u8 pci_read_byte(u8 bus, u8 device, u8 func, int pos);
   47.32 +u16 pci_read_word(u8 bus, u8 device, u8 func, int pos);
   47.33 +u32 pci_read_long(u8 bus, u8 device, u8 func, int pos);
   47.34 +int pci_write_data(u8 bus, u8 device, u8 func, void *buf, int pos, int len);
   47.35 +int pci_write_byte(u8 bus, u8 device, u8 func, int pos, u8 data);
   47.36 +int pci_write_word(u8 bus, u8 device, u8 func, int pos, u16 data);
   47.37 +int pci_write_long(u8 bus, u8 device, u8 func, int pos, u32 data);
   47.38 +u8 pci_get_irq(u8 bus, u8 device, u8 func);
   47.39 +
   47.40 +pt_libpci_rc_t pt_pci_access_clean(void);
   47.41 +pt_libpci_rc_t pt_pci_access_init(void);
   47.42 +
   47.43 +#endif /* __PT_PCI_ACCESS_H__ */
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/tools/ioemu/pt-libpci/pt_pci_probe.c	Mon Aug 13 17:49:00 2007 -0400
    48.3 @@ -0,0 +1,439 @@
    48.4 +/*****************************************************************************
    48.5 +
    48.6 +    Copyright (c) 2007, Neocleus: Alex Novik, Guy Zana
    48.7 +
    48.8 +    Based on code that were taken from the pciutils (lspci)
    48.9 +    Copyright (c) 1997--2000 Martin Mares <mj@ucw.cz>
   48.10 +
   48.11 +******************************************************************************/
   48.12 +#include <string.h>
   48.13 +
   48.14 +#include "pt_libpci.h"
   48.15 +#include "pt_pci_probe.h"
   48.16 +#include "pt_pci_access.h"
   48.17 +#include "pt_pci_tree.h"
   48.18 +/* 
   48.19 +    PCI test of BAR size. Proceed with caution, 
   48.20 +    since this call writes to hardware PCI configuration for a while. 
   48.21 +*/
   48.22 +static u32 size_test(u8 bus, u8 dev, u8 func, int test_position, int test_size)
   48.23 +{
   48.24 +    u16 command;
   48.25 +    u32 bar_data;
   48.26 +    u32 test_result;
   48.27 +
   48.28 +    if (test_size > 4)
   48.29 +        return 0;
   48.30 +
   48.31 +    test_result = 0xffffffff;
   48.32 +
   48.33 +    /* disable the io of the device and the bus mastering
   48.34 +       to be on the safe side, save the command register content as well */
   48.35 +    command =  pci_read_word(bus, dev, func, PCI_COMMAND);
   48.36 +    pci_write_word(bus, dev, func, PCI_COMMAND, command & (~0x7));
   48.37 +
   48.38 +    /* do size test */
   48.39 +    pci_read_data(bus , dev, func, &bar_data, test_position, test_size);
   48.40 +    pci_write_data(bus, dev, func, &test_result, test_position, test_size);
   48.41 +    pci_read_data(bus, dev, func, &test_result, test_position, test_size);
   48.42 +
   48.43 +    /* restore previous state */
   48.44 +    pci_write_data(bus, dev, func, &bar_data, test_position, test_size);
   48.45 +    pci_write_word(bus, dev, func, PCI_COMMAND, command);	
   48.46 +
   48.47 +    return (test_result);
   48.48 +}
   48.49 +
   48.50 +static void get_bases0(pci_phys_dev_t * pt_dev, pt_pci_scan_t do_safe_probe, 
   48.51 +                        u32 regions_nr, u32 romaddress)
   48.52 +{
   48.53 +    u32 i;
   48.54 +    u32 bar_data;
   48.55 +    u32 mem_modifier = 0;
   48.56 +    u32 bar_size = 0;
   48.57 +    u8 b = pt_dev->bus;
   48.58 +    u8 d = pt_dev->dev;
   48.59 +    u8 f = pt_dev->func;
   48.60 +	
   48.61 +    for (i=0; i < regions_nr; i++) {
   48.62 +    
   48.63 +        bar_data = pci_read_long(b, d, f, PCI_BASE_ADDRESS_0 + 4*i);
   48.64 +
   48.65 +        if (do_safe_probe == PT_PCI_SCAN_FORCE_UNSAFE) {
   48.66 +            mem_modifier = size_test(b, d, f, PCI_BASE_ADDRESS_0 +4*i, 4);	
   48.67 +        }
   48.68 +
   48.69 +        if (bar_data & PCI_BASE_ADDRESS_SPACE_IO) {
   48.70 +            pt_dev->regions[i].base_addr = bar_data & PCI_BASE_ADDRESS_IO_MASK;
   48.71 +            pt_dev->regions[i].type = PT_PCI_ADDRESS_SPACE_IO;
   48.72 +            pt_dev->regions[i].addr_width = PT_PCI_ADDRESS_WIDTH_32;	
   48.73 +            mem_modifier &= PCI_BASE_ADDRESS_IO_MASK;
   48.74 +            pt_dev->regions[i].flags = PT_PCI_REGION_VALID;						
   48.75 +        } else {
   48.76 +            pt_dev->regions[i].type = PT_PCI_ADDRESS_SPACE_MEM;
   48.77 +            mem_modifier &= PCI_BASE_ADDRESS_MEM_MASK;
   48.78 +            pt_dev->regions[i].flags = PT_PCI_REGION_VALID;			
   48.79 +            pt_dev->regions[i].base_addr = bar_data &  PCI_BASE_ADDRESS_MEM_MASK;			
   48.80 +        }
   48.81 +
   48.82 +        /* Read size */
   48.83 +        bar_size = FIND_1(mem_modifier);
   48.84 +        if (bar_size == 0) {
   48.85 +            pt_dev->regions[i].flags = PT_PCI_REGION_UNASSIGNED;
   48.86 +            continue;
   48.87 +        }
   48.88 +
   48.89 +        if (do_safe_probe == PT_PCI_SCAN_FORCE_UNSAFE) {
   48.90 +            pt_dev->regions[i].size_granularity = pt_dev->regions[i].size = bar_size;
   48.91 +        }
   48.92 +        else if ((do_safe_probe == PT_PCI_SCAN_FORCE_SAFE) && (pt_dev->regions[i].size == 0))
   48.93 +            continue;
   48.94 +
   48.95 +        if (pt_dev->regions[i].type == PT_PCI_ADDRESS_SPACE_MEM) {
   48.96 +            if ((bar_data & PCI_BASE_ADDRESS_MEM_PREFETCH) == PCI_BASE_ADDRESS_MEM_PREFETCH)				
   48.97 +                pt_dev->regions[i].type = PT_PCI_ADDRESS_SPACE_MEM_PREFETCH;
   48.98 +
   48.99 +            if ((bar_data & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_32) {
  48.100 +                pt_dev->regions[i].addr_width = PT_PCI_ADDRESS_WIDTH_32;
  48.101 +            } else if((bar_data & PCI_BASE_ADDRESS_MEM_TYPE_MASK)  == PCI_BASE_ADDRESS_MEM_TYPE_64) {
  48.102 +                pt_dev->regions[i].addr_width = PT_PCI_ADDRESS_WIDTH_64;
  48.103 +                /* fatal on this one */
  48.104 +                if ((++i) == regions_nr) {
  48.105 +                    pt_dev->regions[i].flags = PT_PCI_REGION_INVALID;
  48.106 +                } else {
  48.107 +                    pt_dev->regions[i].base_addr = pci_read_long(b, d, f, PCI_BASE_ADDRESS_0 + 4*i);
  48.108 +                    pt_dev->regions[i].size = 0;					
  48.109 +                }				
  48.110 +            }
  48.111 +        else
  48.112 +            pt_dev->regions[i].flags = PT_PCI_REGION_INVALID;	
  48.113 +        
  48.114 +        }
  48.115 +    }
  48.116 +	
  48.117 +    pt_dev->region_number = regions_nr;	
  48.118 +
  48.119 +    /* Handle ROM Address */
  48.120 +    if (0 != romaddress) {
  48.121 +        /* Get expansion ROM address */
  48.122 +        bar_data = pci_read_long(b, d, f, romaddress);
  48.123 +        pt_dev->rom_base_addr = bar_data & PCI_ROM_ADDRESS_MASK;
  48.124 +        /* Get expansion ROM size */
  48.125 +        mem_modifier = size_test(b, d, f, romaddress, 4);	
  48.126 +        pt_dev->rom_size = FIND_1(mem_modifier & PCI_ROM_ADDRESS_MASK);
  48.127 +        pt_dev->rom_enabled = bar_data & PCI_ROM_ADDRESS_ENABLE;
  48.128 +    }
  48.129 +	
  48.130 +}
  48.131 +
  48.132 +static void get_bases1(pci_phys_dev_t * pt_dev, pt_pci_scan_t do_safe_probe)
  48.133 +{
  48.134 +    u32 io_base =  pci_read_byte(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_IO_BASE);
  48.135 +    u32 io_limit = pci_read_byte(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_IO_LIMIT);
  48.136 +    u32 io_type = io_base & PCI_IO_RANGE_TYPE_MASK;
  48.137 +    u32 mem_base = pci_read_word(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_MEMORY_BASE);
  48.138 +    u32 mem_limit = pci_read_word(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_MEMORY_LIMIT);
  48.139 +    u32 mem_type = mem_base & PCI_MEMORY_RANGE_TYPE_MASK;
  48.140 +    u32 pref_base = pci_read_word(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_PREF_MEMORY_BASE);
  48.141 +    u32 pref_limit = pci_read_word(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_PREF_MEMORY_LIMIT);
  48.142 +    u32 pref_type = pref_base & PCI_PREF_RANGE_TYPE_MASK;
  48.143 +    u8 io_modifier;
  48.144 +    u16 mem_modifier;
  48.145 +  
  48.146 +    if ( io_type == PCI_IO_RANGE_TYPE_32 ) 
  48.147 +    {
  48.148 +        pt_dev->regions[pt_dev->region_number].flags = PT_PCI_REGION_VALID;
  48.149 +        pt_dev->regions[pt_dev->region_number].type = PT_PCI_ADDRESS_SPACE_IO;
  48.150 +        pt_dev->regions[pt_dev->region_number].addr_width = PT_PCI_ADDRESS_WIDTH_32;
  48.151 +    }
  48.152 +    else if ( io_type == PCI_IO_RANGE_TYPE_16 )
  48.153 +    {
  48.154 +        pt_dev->regions[pt_dev->region_number].flags = PT_PCI_REGION_VALID;
  48.155 +        pt_dev->regions[pt_dev->region_number].type = PT_PCI_ADDRESS_SPACE_IO;
  48.156 +        pt_dev->regions[pt_dev->region_number].addr_width = PT_PCI_ADDRESS_WIDTH_16;
  48.157 +    }
  48.158 +    else
  48.159 +    {
  48.160 +        pt_dev->regions[pt_dev->region_number].flags = PT_PCI_REGION_INVALID;
  48.161 +        pt_dev->regions[pt_dev->region_number].type = PT_PCI_ADDRESS_SPACE_IO;
  48.162 +        pt_dev->regions[pt_dev->region_number].addr_width = PT_PCI_ADDRESS_WIDTH_UNKNOWN;
  48.163 +    }
  48.164 +
  48.165 +    io_base = (io_base & PCI_IO_RANGE_MASK) << 8;
  48.166 +    io_limit = (io_limit & PCI_IO_RANGE_MASK) << 8;
  48.167 +
  48.168 +    if ( io_type == PCI_IO_RANGE_TYPE_32 )
  48.169 +    {
  48.170 +        io_base |= (pci_read_word(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_IO_BASE_UPPER16) << 16);
  48.171 +        io_limit |= (pci_read_word(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_IO_LIMIT_UPPER16) << 16);
  48.172 +    }
  48.173 +    
  48.174 +    pt_dev->regions[pt_dev->region_number].base_addr= io_base;
  48.175 +
  48.176 +    if ( io_base <= io_limit )
  48.177 +    {
  48.178 +        if ( PT_PCI_SCAN_FORCE_UNSAFE == do_safe_probe )
  48.179 +        {
  48.180 +            io_modifier = (u16)size_test(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_IO_BASE, 1) &(~1);
  48.181 +            io_modifier = FIND_1(io_modifier);
  48.182 +            pt_dev->regions[pt_dev->region_number].size_granularity = MAX(io_modifier<< 8,0x1000);
  48.183 +        }
  48.184 +
  48.185 +        pt_dev->regions[pt_dev->region_number].size = io_limit - io_base + 
  48.186 +            pt_dev->regions[pt_dev->region_number].size_granularity;
  48.187 +    }
  48.188 +    else
  48.189 +    {
  48.190 +        pt_dev->regions[pt_dev->region_number].size = 0;  
  48.191 +        pt_dev->regions[pt_dev->region_number].flags |= PT_PCI_REGION_UNASSIGNED;
  48.192 +    }
  48.193 +    
  48.194 +    pt_dev->region_number++;
  48.195 +
  48.196 +    if ( mem_type )
  48.197 +    {
  48.198 +        pt_dev->regions[pt_dev->region_number].flags = PT_PCI_REGION_INVALID;
  48.199 +        pt_dev->regions[pt_dev->region_number].type = PT_PCI_ADDRESS_SPACE_MEM;
  48.200 +        pt_dev->regions[pt_dev->region_number].addr_width = PT_PCI_ADDRESS_WIDTH_UNKNOWN;
  48.201 +    }
  48.202 +    else
  48.203 +    {
  48.204 +        pt_dev->regions[pt_dev->region_number].flags = PT_PCI_REGION_VALID;
  48.205 +        pt_dev->regions[pt_dev->region_number].type = PT_PCI_ADDRESS_SPACE_MEM;
  48.206 +        pt_dev->regions[pt_dev->region_number].addr_width = PT_PCI_ADDRESS_WIDTH_32;
  48.207 +    }
  48.208 +
  48.209 +    mem_base = (mem_base & PCI_MEMORY_RANGE_MASK) << 16;
  48.210 +    mem_limit = (mem_limit & PCI_MEMORY_RANGE_MASK) << 16;
  48.211 +    pt_dev->regions[pt_dev->region_number].base_addr = mem_base;
  48.212 +    
  48.213 +    if ( mem_base <= mem_limit )
  48.214 +    {
  48.215 +        if ( PT_PCI_SCAN_FORCE_UNSAFE == do_safe_probe )
  48.216 +        {
  48.217 +            mem_modifier = (u16)size_test(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_MEMORY_BASE, 2);
  48.218 +            mem_modifier = FIND_1(mem_modifier);
  48.219 +            pt_dev->regions[pt_dev->region_number].size_granularity = MAX(mem_modifier << 16, 0x100000);
  48.220 +        }
  48.221 +
  48.222 +        pt_dev->regions[pt_dev->region_number].size = mem_limit - mem_base + 
  48.223 +            pt_dev->regions[pt_dev->region_number].size_granularity;
  48.224 +    }
  48.225 +    else
  48.226 +    {
  48.227 +        pt_dev->regions[pt_dev->region_number].size = 0;
  48.228 +        pt_dev->regions[pt_dev->region_number].flags |= PT_PCI_REGION_UNASSIGNED;
  48.229 +    }
  48.230 +    pt_dev->region_number ++;
  48.231 +
  48.232 +    if ( pref_type != (pref_limit & PCI_PREF_RANGE_TYPE_MASK) ||
  48.233 +         (pref_type != PCI_PREF_RANGE_TYPE_32 && pref_type != PCI_PREF_RANGE_TYPE_64) )
  48.234 +    {
  48.235 +        pt_dev->regions[pt_dev->region_number].flags = PT_PCI_REGION_INVALID;
  48.236 +        pt_dev->regions[pt_dev->region_number].type = PT_PCI_ADDRESS_SPACE_MEM_PREFETCH;
  48.237 +        pt_dev->regions[pt_dev->region_number].addr_width = PT_PCI_ADDRESS_WIDTH_UNKNOWN;
  48.238 +    }
  48.239 +    else
  48.240 +    {
  48.241 +        pt_dev->regions[pt_dev->region_number].flags = PT_PCI_REGION_VALID;
  48.242 +        pt_dev->regions[pt_dev->region_number].type = PT_PCI_ADDRESS_SPACE_MEM_PREFETCH;
  48.243 +        pt_dev->regions[pt_dev->region_number].addr_width = PT_PCI_ADDRESS_WIDTH_32;
  48.244 +    }
  48.245 +    
  48.246 +    pref_base = (pref_base & PCI_PREF_RANGE_MASK) << 16;
  48.247 +    pref_limit = (pref_limit & PCI_PREF_RANGE_MASK) << 16;
  48.248 +    pt_dev->regions[pt_dev->region_number].base_addr = pref_base;
  48.249 +
  48.250 +    if ( pref_base <= pref_limit )
  48.251 +    {
  48.252 +
  48.253 +        /* we're not dealing with devices that maps more then 4G memory, hopefully*/ 
  48.254 +        if ( PT_PCI_SCAN_FORCE_UNSAFE == do_safe_probe )
  48.255 +        {
  48.256 +            mem_modifier = (u16)size_test(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_PREF_MEMORY_BASE, 2);
  48.257 +            mem_modifier = FIND_1(mem_modifier);
  48.258 +            pt_dev->regions[pt_dev->region_number].size_granularity = MAX(mem_modifier<< 16,0x100000);
  48.259 +        }
  48.260 +
  48.261 +        pt_dev->regions[pt_dev->region_number].size = pref_limit - pref_base + 
  48.262 +            pt_dev->regions[pt_dev->region_number].size_granularity;
  48.263 +            
  48.264 +        if ( pref_type == PCI_PREF_RANGE_TYPE_64 )
  48.265 +        {
  48.266 +            pt_dev->regions[pt_dev->region_number].addr_width = PT_PCI_ADDRESS_WIDTH_64;    				
  48.267 +            pt_dev->regions[++pt_dev->region_number].base_addr = pci_read_long(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_PREF_BASE_UPPER32);
  48.268 +            pt_dev->regions[pt_dev->region_number].size = pci_read_long(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_PREF_LIMIT_UPPER32) - pt_dev->regions[pt_dev->region_number].base_addr;
  48.269 +        }
  48.270 +
  48.271 +    }
  48.272 +    else
  48.273 +    {
  48.274 +        pt_dev->regions[pt_dev->region_number].size = 0;
  48.275 +        pt_dev->regions[pt_dev->region_number].flags |= PT_PCI_REGION_UNASSIGNED;
  48.276 +    }
  48.277 +
  48.278 +    pt_dev->region_number++;
  48.279 +}
  48.280 +
  48.281 +static void get_bases2(pci_phys_dev_t * pt_dev,pt_pci_scan_t do_safe_probe  )
  48.282 +{
  48.283 +    int i;
  48.284 +    u32 mem_modifier;
  48.285 +    u16 cmd = pci_read_word(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_COMMAND);
  48.286 +    u16 brc = pci_read_word(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_CB_BRIDGE_CONTROL);
  48.287 +    u16 exca = pci_read_word(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_CB_LEGACY_MODE_BASE);
  48.288 +
  48.289 +    for (i=0; i<2; i++)
  48.290 +    {
  48.291 +        int p = 8*i;
  48.292 +        u32 base = pci_read_long(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_CB_MEMORY_BASE_0 + p);
  48.293 +        u32 limit = pci_read_long(pt_dev->bus, pt_dev->dev, pt_dev->func, PCI_CB_MEMORY_LIMIT_0 + p);
  48.294 +
  48.295 +        if ( (limit >= base) && (limit > 0) )
  48.296 +        {
  48.297 +            if ( PT_PCI_SCAN_FORCE_UNSAFE == do_safe_probe )
  48.298 +            {
  48.299 +                mem_modifier = (u32)size_test(pt_dev->bus, pt_dev->dev, pt_dev->func, (PCI_CB_MEMORY_BASE_0+p) ,4);
  48.300 +                mem_modifier = FIND_1(mem_modifier);
  48.301 +                pt_dev->regions[pt_dev->region_number].size_granularity = MAX(mem_modifier,0x1000);
  48.302 +            }
  48.303 +
  48.304 +            pt_dev->regions[pt_dev->region_number].flags = PT_PCI_REGION_VALID;
  48.305 +            pt_dev->regions[pt_dev->region_number].addr_width = PT_PCI_ADDRESS_WIDTH_32;
  48.306 +            pt_dev->regions[pt_dev->region_number].base_addr = base;
  48.307 +            pt_dev->regions[pt_dev->region_number].size = limit - base + pt_dev->regions[pt_dev->region_number].size_granularity;
  48.308 +            
  48.309 +            if ( brc & (PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 << i) )
  48.310 +                pt_dev->regions[pt_dev->region_number].type = PT_PCI_ADDRESS_SPACE_MEM_PREFETCH;
  48.311 +            else
  48.312 +                pt_dev->regions[pt_dev->region_number].type = PT_PCI_ADDRESS_SPACE_MEM;
  48.313 +
  48.314 +            pt_dev->region_number++;
  48.315 +        }
  48.316 +    }
  48.317 +    
  48.318 +    for (i=0; i<2; i++)
  48.319 +    {
  48.320 +        int p = 8*i;
  48.321 +        u32 base = pci_read_long(pt_dev->bus,pt_dev->dev,pt_dev->func,PCI_CB_IO_BASE_0 + p);
  48.322 +        u32 limit = pci_read_long(pt_dev->bus,pt_dev->dev,pt_dev->func,PCI_CB_IO_LIMIT_0 + p);
  48.323 +        
  48.324 +        /* spec claims that this is the only choice */ 
  48.325 +        pt_dev->regions[pt_dev->region_number].size_granularity = 4;
  48.326 +        pt_dev->regions[pt_dev->region_number].addr_width = PT_PCI_ADDRESS_WIDTH_32;
  48.327 +        pt_dev->regions[pt_dev->region_number].type = PT_PCI_ADDRESS_SPACE_IO;
  48.328 +        
  48.329 +        if ( !(base & PCI_IO_RANGE_TYPE_32) )
  48.330 +        {
  48.331 +            base &= 0xffff;
  48.332 +            limit &= 0xffff;
  48.333 +            pt_dev->regions[pt_dev->region_number].addr_width = PT_PCI_ADDRESS_WIDTH_16;
  48.334 +        }
  48.335 +
  48.336 +        base &= PCI_CB_IO_RANGE_MASK;
  48.337 +
  48.338 +        if ( base <= limit )
  48.339 +        {
  48.340 +            pt_dev->regions[pt_dev->region_number].base_addr = base;
  48.341 +            pt_dev->regions[pt_dev->region_number].size = limit - base + 
  48.342 +                pt_dev->regions[pt_dev->region_number].size_granularity;
  48.343 +            pt_dev->regions[pt_dev->region_number].flags = PT_PCI_REGION_VALID;
  48.344 +            pt_dev->region_number++;
  48.345 +        }
  48.346 +    }
  48.347 +
  48.348 +#warning "TBD: The exca handling should be added here"	
  48.349 +}
  48.350 +
  48.351 +static pt_libpci_rc_t  pt_pci_read_regions(pci_phys_dev_t * a_dev, pt_pci_scan_t do_safe_probe)
  48.352 +{
  48.353 +    switch (a_dev->header_type & 0x7f) 
  48.354 +    {
  48.355 +    case PCI_HEADER_TYPE_NORMAL:
  48.356 +        get_bases0(a_dev, do_safe_probe, 6, PCI_ROM_ADDRESS);
  48.357 +        break;
  48.358 +    case PCI_HEADER_TYPE_BRIDGE:
  48.359 +        /*  the part that coincide with the PCI device is 0x10 and 0x14*/
  48.360 +        get_bases0(a_dev, do_safe_probe, 2, PCI_ROM_ADDRESS1);
  48.361 +        get_bases1(a_dev, do_safe_probe);
  48.362 +        break;
  48.363 +    case PCI_HEADER_TYPE_CARDBUS:
  48.364 +        /*  the part that coincide with the PCI device is 0x10*/
  48.365 +        get_bases0(a_dev, do_safe_probe, 1, 0);
  48.366 +        get_bases2(a_dev, do_safe_probe);
  48.367 +        break;
  48.368 +    }
  48.369 +}
  48.370 +
  48.371 +pt_libpci_rc_t pt_bus_probe(u8 bus, pt_pci_scan_t do_safe_probe)
  48.372 +{
  48.373 +    u8 dev, multi, func, ht;
  48.374 +    pci_phys_dev_t * current;
  48.375 +    
  48.376 +    for (dev=0; dev<32; dev++)
  48.377 +    {
  48.378 +        for (func=0, multi=1; ((multi != 0) && (func < 8)); func++)
  48.379 +        {
  48.380 +            if ( (current = pt_devfn_probe(bus, dev, func, do_safe_probe)) == NULL )
  48.381 +            {
  48.382 +                /* it could be anything, we can not recognize the device or it simply is not present -
  48.383 +                anyway just skip the given device and all its functions */
  48.384 +                continue;
  48.385 +            }
  48.386 +
  48.387 +            if ( func == 0 )
  48.388 +                multi = current->header_type & 0x80;
  48.389 +            
  48.390 +            switch (current->header_type & 0x7f) {
  48.391 +            case PCI_HEADER_TYPE_NORMAL:
  48.392 +                break;
  48.393 +            case PCI_HEADER_TYPE_BRIDGE:
  48.394 +            case PCI_HEADER_TYPE_CARDBUS:
  48.395 +                current->secondary_bus = pci_read_byte(bus, dev, func, PCI_SECONDARY_BUS);
  48.396 +                pt_bus_probe(current->secondary_bus, do_safe_probe);
  48.397 +                break;
  48.398 +            }
  48.399 +        }
  48.400 +    }
  48.401 +    
  48.402 +    return PT_RC_SUCCESS;
  48.403 +}
  48.404 +
  48.405 +pci_phys_dev_t * pt_devfn_probe(u8 bus, u8 dev, u8 func, pt_pci_scan_t do_safe_probe)
  48.406 +{
  48.407 +    u32 vd;
  48.408 +    u16 tmp;
  48.409 +    pci_phys_dev_t * current;  
  48.410 +
  48.411 +    /* Check the vital signs of the device */    
  48.412 +    tmp =  pci_read_word(bus, dev, func, PCI_VENDOR_ID);
  48.413 +    if ( !tmp || tmp == 0xffff )
  48.414 +        return NULL;
  48.415 +
  48.416 +    /* do we have this guy already? */
  48.417 +    if ( (current = pt_lookup_device_in_tree(bus, dev, func)) == NULL )
  48.418 +    {
  48.419 +        current = pt_alloc_pci_device();
  48.420 +        current->bus = bus;
  48.421 +        current->dev = dev;
  48.422 +        current->func = func;
  48.423 +        pt_add_device_to_tree(current);
  48.424 +        if (do_safe_probe == PT_PCI_SCAN_FORCE_AUTO) 
  48.425 +            do_safe_probe = PT_PCI_SCAN_FORCE_UNSAFE;
  48.426 +    } 
  48.427 +    else
  48.428 +        /* we have already handled this device, no need to take risks */
  48.429 +        do_safe_probe = PT_PCI_SCAN_FORCE_SAFE;
  48.430 +    
  48.431 +    /* Start rescan */
  48.432 +    current->region_number = 0;
  48.433 +    current->vendor_id = tmp;
  48.434 +    current->device_id =  pci_read_word(bus, dev, func, PCI_DEVICE_ID);
  48.435 +    current->device_class = pci_read_long(bus, dev, func, PCI_CLASS_REVISION);
  48.436 +    current->irq = pci_get_irq(bus, dev, func);
  48.437 +    current->header_type = pci_read_byte(bus, dev, func, PCI_HEADER_TYPE);
  48.438 +    pt_pci_read_regions(current, do_safe_probe);
  48.439 +    
  48.440 +    return current;
  48.441 +}
  48.442 +
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/tools/ioemu/pt-libpci/pt_pci_probe.h	Mon Aug 13 17:49:00 2007 -0400
    49.3 @@ -0,0 +1,28 @@
    49.4 +/*****************************************************************************
    49.5 +
    49.6 +    Copyright (c) 2007, Neocleus: Guy Zana, Alex Novik
    49.7 +
    49.8 +******************************************************************************/
    49.9 +#ifndef __PT_PCI_PROBE_H__
   49.10 +#define __PT_PCI_PROBE_H__
   49.11 +
   49.12 +#include "pt_libpci.h"
   49.13 +
   49.14 +#ifndef MAX
   49.15 +#define MAX(x,y) (((x)>(y))?(x) : (y))
   49.16 +#endif
   49.17 +
   49.18 +#define FIND_1(input) (((((input)-1)^(input))+1)>>1)
   49.19 +
   49.20 +typedef enum pt_pci_scan_e {
   49.21 +    PT_PCI_SCAN_FORCE_SAFE     = 0,
   49.22 +    PT_PCI_SCAN_FORCE_UNSAFE   = 1,	
   49.23 +    PT_PCI_SCAN_FORCE_AUTO     = 2
   49.24 +} pt_pci_scan_t;
   49.25 +
   49.26 +pci_phys_dev_t * pt_devfn_probe(u8 bus, u8 dev, u8 func, 
   49.27 +                                pt_pci_scan_t do_safe_probe);
   49.28 +pt_libpci_rc_t pt_bus_probe(u8 bus, pt_pci_scan_t do_safe_probe);
   49.29 +
   49.30 +#endif /* __PT_PCI_PROBE_H__ */
   49.31 +
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/tools/ioemu/pt-libpci/pt_pci_tree.c	Mon Aug 13 17:49:00 2007 -0400
    50.3 @@ -0,0 +1,202 @@
    50.4 +/*****************************************************************************
    50.5 +
    50.6 +    Copyright (c) 2007, Neocleus: Alex Novik, Guy Zana
    50.7 +
    50.8 +******************************************************************************/
    50.9 +#include <stdio.h>
   50.10 +#include <stdlib.h>
   50.11 +#include <string.h>
   50.12 +
   50.13 +#include "pt_libpci.h"
   50.14 +#include "pt_pci_probe.h"
   50.15 +#include "pt_pci_access.h"
   50.16 +#include "pt_pci_tree.h"
   50.17 +
   50.18 +extern FILE * logfile;
   50.19 +
   50.20 +/* 
   50.21 +    pci_tree is our hash array for the pci devices in the system.
   50.22 +
   50.23 +    Each device is placed in its position which is computed by this function:
   50.24 +    ((bus << 8) | (device << 5) | (function)) % MAX_PCI_HASH_ARRAY
   50.25 +
   50.26 +*/
   50.27 +pci_phys_dev_t * pci_tree[MAX_PCI_HASH_ARRAY];
   50.28 +
   50.29 +
   50.30 +pt_libpci_rc_t pt_device_tree_init(void)
   50.31 +{
   50.32 +    unsigned long i;
   50.33 +
   50.34 +    for (i=0; i < MAX_PCI_HASH_ARRAY; i++) {
   50.35 +        pci_tree[i] = NULL;
   50.36 +    }
   50.37 +
   50.38 +    return (PT_RC_SUCCESS);
   50.39 +}
   50.40 +
   50.41 +pci_phys_dev_t * pt_alloc_pci_device(void)
   50.42 +{
   50.43 +    pci_phys_dev_t * dev;
   50.44 +
   50.45 +    dev = (pci_phys_dev_t *) malloc(sizeof(pci_phys_dev_t));
   50.46 +
   50.47 +    /* Initialize data */
   50.48 +    memset(dev, 0, sizeof(pci_phys_dev_t));
   50.49 +    dev->device_id = dev->vendor_id = 0xffff;
   50.50 +    dev->device_class = 0xffffffff;
   50.51 +    
   50.52 +    return (dev);
   50.53 +}
   50.54 +
   50.55 +pt_libpci_rc_t pt_free_pci_device(pci_phys_dev_t * a_dev)
   50.56 +{
   50.57 +    if (a_dev)
   50.58 +        free(a_dev);
   50.59 +
   50.60 +    a_dev = NULL;
   50.61 +    
   50.62 +    return PT_RC_SUCCESS;
   50.63 +}
   50.64 +
   50.65 +pt_libpci_rc_t pt_add_device_to_tree(pci_phys_dev_t * a_dev)
   50.66 +{
   50.67 +
   50.68 +    unsigned long dev_key;
   50.69 +    unsigned long i;
   50.70 +
   50.71 +    if (NULL == a_dev) {
   50.72 +        return (PT_RC_FAILURE);
   50.73 +    }
   50.74 +
   50.75 +    dev_key = PCI_DEV_GET_INDEX(a_dev);
   50.76 +
   50.77 +    /* find an empty slot */
   50.78 +    for (i=0; i < MAX_PCI_HASH_ARRAY; i++) {
   50.79 +        if (NULL == pci_tree[(dev_key+i) % MAX_PCI_HASH_ARRAY]) {
   50.80 +            break;
   50.81 +        }
   50.82 +    }
   50.83 +
   50.84 +    /* check errors */
   50.85 +    if (i == MAX_PCI_HASH_ARRAY) {
   50.86 +        return (PT_RC_FAILURE);
   50.87 +    }
   50.88 +
   50.89 +    pci_tree[(dev_key+i) % MAX_PCI_HASH_ARRAY] = a_dev;
   50.90 +    return (PT_RC_SUCCESS);	
   50.91 +
   50.92 +}
   50.93 +
   50.94 +pci_phys_dev_t * pt_lookup_device_in_tree(u8 bus, u8 dev, u8 func)
   50.95 +{
   50.96 +
   50.97 +    unsigned long dev_key;
   50.98 +    pci_phys_dev_t * cur_dev;
   50.99 +    unsigned long i;
  50.100 +
  50.101 +    dev_key = PCI_GET_INDEX(bus, dev, func);
  50.102 +
  50.103 +    for (i=0; i < MAX_PCI_HASH_ARRAY; i++) {
  50.104 +        cur_dev = pci_tree[(dev_key+i) % MAX_PCI_HASH_ARRAY];
  50.105 +        if ((NULL != cur_dev) && ((bus == cur_dev->bus) && (dev == cur_dev->dev) && (func == cur_dev->func))) {
  50.106 +            break;
  50.107 +        }
  50.108 +    }
  50.109 +
  50.110 +    /* check errors */
  50.111 +    if (i == MAX_PCI_HASH_ARRAY) {
  50.112 +        return (NULL);
  50.113 +    }
  50.114 +
  50.115 +    return (cur_dev);
  50.116 +
  50.117 +}
  50.118 +
  50.119 +pci_phys_dev_t * pt_remove_device_from_tree(u8 bus, u8 dev, u8 func)
  50.120 +{
  50.121 +    unsigned long dev_key;
  50.122 +    pci_phys_dev_t * cur_dev;
  50.123 +    unsigned long i;
  50.124 +
  50.125 +    dev_key = PCI_GET_INDEX(bus, dev, func);
  50.126 +
  50.127 +    for (i=0; i < MAX_PCI_HASH_ARRAY; i++) {
  50.128 +        cur_dev = pci_tree[(dev_key+i) % MAX_PCI_HASH_ARRAY];
  50.129 +        if ((NULL != cur_dev) && ((bus == cur_dev->bus) && (dev == cur_dev->dev) && (func == cur_dev->func))) {
  50.130 +            pci_tree[(dev_key+i) % MAX_PCI_HASH_ARRAY] = NULL;
  50.131 +            break;
  50.132 +        }
  50.133 +    }
  50.134 +
  50.135 +    /* check errors */
  50.136 +    if (i == MAX_PCI_HASH_ARRAY) {
  50.137 +        return (NULL);
  50.138 +    }
  50.139 +
  50.140 +    return (cur_dev);	
  50.141 +}
  50.142 +
  50.143 +pt_libpci_rc_t pt_clean_tree(void)
  50.144 +{
  50.145 +    unsigned long i;
  50.146 +
  50.147 +    for (i=0; i < MAX_PCI_HASH_ARRAY; i++)
  50.148 +        pt_free_pci_device(pci_tree[i]);
  50.149 +
  50.150 +    return PT_RC_SUCCESS;
  50.151 +}
  50.152 +
  50.153 +void pt_print_device(FILE * fout, pci_phys_dev_t * dev)
  50.154 +{
  50.155 +    unsigned long i;
  50.156 +
  50.157 +    fprintf(fout, "-----=[ %02x:%02x.%x ]=-----\n", dev->bus, dev->dev, dev->func);
  50.158 +    fprintf(fout, "Regions:\n");
  50.159 +    
  50.160 +    for (i=0; i < dev->region_number; i++) {
  50.161 +
  50.162 +        if (!PCI_REGION_IS_VALID(dev, i)) {
  50.163 +            continue;
  50.164 +        }
  50.165 +        
  50.166 +        fprintf(fout, "[%d] \t%dBits: %s (flags=0x%04x)\n", i, dev->regions[i].addr_width,
  50.167 +            PT_GET_TYPE_STR(dev->regions[i].type), (u32)dev->regions[i].flags);
  50.168 +            
  50.169 +        if (dev->regions[i].addr_width == PT_PCI_ADDRESS_WIDTH_64) {
  50.170 +            fprintf(fout, "\t\tBase: 0x%016Lx Size: 0x%016Lx\n", 
  50.171 +                PT_GET64(dev->regions[i+1].base_addr, dev->regions[i].base_addr),
  50.172 +                PT_GET64(dev->regions[i+1].size, dev->regions[i].size));
  50.173 +                
  50.174 +            i++;
  50.175 +        } else {
  50.176 +            fprintf(fout, "\t\tBase: 0x%08x Size: 0x%08x\n",
  50.177 +                (u32) dev->regions[i].base_addr, (u32) dev->regions[i].size);
  50.178 +        }
  50.179 +    }
  50.180 +
  50.181 +    /* Expansion ROM */
  50.182 +    if ((dev->rom_size != 0) && (dev->rom_base_addr != 0)) {
  50.183 +        fprintf(fout, "[6] ROM:\n");
  50.184 +        fprintf(fout, "\t\tBase: 0x%08x Size: 0x%08x\n", dev->rom_base_addr, dev->rom_size);
  50.185 +    }
  50.186 +
  50.187 +    fprintf(fout, "IRQ: %d\n", dev->irq);
  50.188 +    fprintf(fout, "[END: %02x:%02x.%x ]\n\n", dev->bus, dev->dev, dev->func);
  50.189 +
  50.190 +}
  50.191 +
  50.192 +void pt_print_device_map(void)
  50.193 +{
  50.194 +    pci_phys_dev_t * cur_dev;
  50.195 +    unsigned long i,devnum=0;
  50.196 +
  50.197 +    for (i=0; i < MAX_PCI_HASH_ARRAY; i++) {
  50.198 +        if (NULL != pci_tree[i]) { 
  50.199 +            devnum++;
  50.200 +            pt_print_device(logfile, pci_tree[i]);
  50.201 +        }
  50.202 +    }
  50.203 +    
  50.204 +    fprintf(logfile, "Number of devices = %d\n", devnum);
  50.205 +}
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/tools/ioemu/pt-libpci/pt_pci_tree.h	Mon Aug 13 17:49:00 2007 -0400
    51.3 @@ -0,0 +1,31 @@
    51.4 +/*****************************************************************************
    51.5 +
    51.6 +    Copyright (c) 2007, Neocleus: Alex Novik, Guy Zana
    51.7 +
    51.8 +******************************************************************************/
    51.9 +#ifndef __PT_PCI_TREE_H__
   51.10 +#define __PT_PCI_TREE_H__
   51.11 +
   51.12 +#include <stdio.h>
   51.13 +
   51.14 +#include "pt_libpci.h"
   51.15 +
   51.16 +/* Our PCI device tree is hashed into an array of 1021 pointers */
   51.17 +#define MAX_PCI_HASH_ARRAY      (1021)
   51.18 +#define PCI_GET_INDEX(b,d,f)    ((unsigned long)((((((b)&0xFF)<<8) | (((d)&0x1F)<<5) | ((f)&0x7))) % MAX_PCI_HASH_ARRAY))
   51.19 +#define PCI_DEV_GET_INDEX(a)    PCI_GET_INDEX(a->bus, a->dev, a->func)
   51.20 +
   51.21 +
   51.22 +/* PCI tree data structures */
   51.23 +pt_libpci_rc_t pt_device_tree_init(void);
   51.24 +pci_phys_dev_t * pt_alloc_pci_device(void);
   51.25 +pt_libpci_rc_t pt_free_pci_device(pci_phys_dev_t * a_dev);
   51.26 +pt_libpci_rc_t pt_add_device_to_tree(pci_phys_dev_t * a_dev);
   51.27 +pci_phys_dev_t * pt_lookup_device_in_tree(u8 bus, u8 dev, u8 func);
   51.28 +pci_phys_dev_t * pt_remove_device_in_tree(u8 bus, u8 dev, u8 func);
   51.29 +pt_libpci_rc_t pt_clean_tree(void);
   51.30 +
   51.31 +void pt_print_device(FILE * fout, pci_phys_dev_t * dev);
   51.32 +void pt_print_device_map(void);
   51.33 +
   51.34 +#endif /* __PT_PCI_TREE_H__ */
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/tools/ioemu/pt-libpci/pt_util.c	Mon Aug 13 17:49:00 2007 -0400
    52.3 @@ -0,0 +1,62 @@
    52.4 +#include <stdio.h>
    52.5 +#include <stdlib.h>
    52.6 +#include <string.h>
    52.7 +
    52.8 +#include "pt_libpci.h"
    52.9 +#include "pt_pci_probe.h"
   52.10 +#include "pt_pci_access.h"
   52.11 +#include "pt_pci_tree.h"
   52.12 +
   52.13 +u8 find_cap_offset(u8 bus, u8 device, u8 func, u8 cap)
   52.14 +{
   52.15 +    int id;
   52.16 +    int max_cap = 48;
   52.17 +    int pos = PCI_CAPABILITY_LIST;
   52.18 +    int status;
   52.19 +
   52.20 +    status = pci_read_byte(bus, device, func, PCI_STATUS);
   52.21 +    if ( (status & PCI_STATUS_CAP_LIST) == 0 )
   52.22 +        return 0;
   52.23 +
   52.24 +    while ( max_cap-- )
   52.25 +    {
   52.26 +        pos = pci_read_byte(bus, device, func, pos);
   52.27 +        if ( pos < 0x40 )
   52.28 +            break;
   52.29 +
   52.30 +        pos &= ~3;
   52.31 +        id = pci_read_byte(bus, device, func, pos + PCI_CAP_LIST_ID);
   52.32 +
   52.33 +        if ( id == 0xff )
   52.34 +            break;
   52.35 +        if ( id == cap )
   52.36 +            return pos;
   52.37 +
   52.38 +        pos += PCI_CAP_LIST_NEXT;
   52.39 +    }
   52.40 +    return 0;
   52.41 +}
   52.42 +
   52.43 +#define PCI_EXP_DEVCAP_FLR    (1 << 28)
   52.44 +#define PCI_EXP_DEVCTL_FLR     0x1b
   52.45 +
   52.46 +void pdev_flr(u8 bus, u8 device, u8 func)
   52.47 +{
   52.48 +    int pos;
   52.49 +    int dev_cap;
   52.50 +    int dev_status;
   52.51 +
   52.52 +    pos = find_cap_offset(bus, device, func, PCI_CAP_ID_EXP);
   52.53 +    if ( pos )
   52.54 +    {
   52.55 +        dev_cap = pci_read_long(bus, device, func, pos + PCI_EXP_DEVCAP);
   52.56 +        if ( dev_cap & PCI_EXP_DEVCAP_FLR )
   52.57 +        {
   52.58 +            pci_write_word(bus, device, func, pos + PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_FLR);
   52.59 +            do {
   52.60 +                dev_status = pci_read_long(bus, device, func, pos + PCI_EXP_DEVSTA);
   52.61 +            } while (dev_status & PCI_EXP_DEVSTA_TRPND);
   52.62 +        }
   52.63 +    }
   52.64 +}
   52.65 +
    53.1 --- a/tools/ioemu/target-i386-dm/exec-dm.c	Tue Jul 31 12:36:34 2007 -0700
    53.2 +++ b/tools/ioemu/target-i386-dm/exec-dm.c	Mon Aug 13 17:49:00 2007 -0400
    53.3 @@ -568,6 +568,8 @@ void cpu_physical_memory_rw(target_phys_
    53.4                  memcpy_words(buf, ptr, l);
    53.5              } else {
    53.6                  /* Neither RAM nor known MMIO space */
    53.7 +                fprintf(logfile,"cpu_physical_memory_rw error: Neither RAM nor known MMIO space.\n"
    53.8 +                    "\taddr=" TARGET_FMT_lx " len=%08x is_write=%d\n", addr, len, is_write);                
    53.9                  memset(buf, 0xff, len); 
   53.10              }
   53.11          }
    54.1 --- a/tools/ioemu/target-i386-dm/helper2.c	Tue Jul 31 12:36:34 2007 -0700
    54.2 +++ b/tools/ioemu/target-i386-dm/helper2.c	Mon Aug 13 17:49:00 2007 -0400
    54.3 @@ -92,6 +92,36 @@ int send_vcpu = 0;
    54.4  #define NR_CPUS 32
    54.5  evtchn_port_t ioreq_local_port[NR_CPUS];
    54.6  
    54.7 +void dump_ioreq(ioreq_t * ioreq)
    54.8 +{
    54.9 +    char csize;
   54.10 +
   54.11 +    switch (ioreq->size) {
   54.12 +    case 1:
   54.13 +        csize = 'B';
   54.14 +        break;
   54.15 +    case 2:
   54.16 +        csize = 'W';
   54.17 +        break;
   54.18 +    case 4:
   54.19 +        csize = 'L';
   54.20 +        break;
   54.21 +    default:
   54.22 +        csize = '?';
   54.23 +    }
   54.24 +
   54.25 +    fprintf(logfile, TARGET_FMT_lx ": [%c%c] addr: 0x" TARGET_FMT_lx " [count: %u] data: 0x" TARGET_FMT_lx " data_is_ptr=%u\n",
   54.26 +        ioreq->io_count,
   54.27 +        (ioreq->dir==IOREQ_READ)?'R':'W',
   54.28 +        csize,
   54.29 +        ioreq->addr,
   54.30 +        (uint32_t)ioreq->count,
   54.31 +        ioreq->data,
   54.32 +        ioreq->data_is_ptr); 
   54.33 +        
   54.34 +} 
   54.35 +
   54.36 +
   54.37  CPUX86State *cpu_x86_init(void)
   54.38  {
   54.39      CPUX86State *env;
   54.40 @@ -531,6 +561,7 @@ void __handle_ioreq(CPUState *env, ioreq
   54.41          qemu_invalidate_map_cache();
   54.42          break;
   54.43      default:
   54.44 +        dump_ioreq(req);
   54.45          hw_error("Invalid ioreq type 0x%x\n", req->type);
   54.46      }
   54.47  }
    55.1 --- a/tools/ioemu/target-i386-dm/piix_pci-dm.c	Tue Jul 31 12:36:34 2007 -0700
    55.2 +++ b/tools/ioemu/target-i386-dm/piix_pci-dm.c	Mon Aug 13 17:49:00 2007 -0400
    55.3 @@ -40,6 +40,46 @@ static uint32_t i440fx_addr_readl(void* 
    55.4      return s->config_reg;
    55.5  }
    55.6  
    55.7 +static void i440fx_addr_writew(void* opaque, uint32_t addr, uint32_t val)
    55.8 +{
    55.9 +    I440FXState *s = opaque;
   55.10 +    uint32_t offset_bits = (addr - 0xcf8) * 8;
   55.11 +
   55.12 +    s->config_reg &= ~(0x0000FFFF << offset_bits);
   55.13 +    s->config_reg |= ((uint16_t)val << offset_bits);
   55.14 +}
   55.15 +
   55.16 +static uint32_t i440fx_addr_readw(void* opaque, uint32_t addr)
   55.17 +{
   55.18 +    I440FXState *s = opaque;
   55.19 +    uint32_t offset_bits = (addr - 0xcf8) * 8;
   55.20 +    uint32_t val;
   55.21 +
   55.22 +    val = (s->config_reg >> offset_bits) & 0xFFFF;
   55.23 +    
   55.24 +    return val;
   55.25 +}
   55.26 +
   55.27 +static void i440fx_addr_writeb(void* opaque, uint32_t addr, uint32_t val)
   55.28 +{
   55.29 +    I440FXState *s = opaque;
   55.30 +    uint32_t offset_bits = (addr - 0xcf8) * 8;
   55.31 +
   55.32 +    s->config_reg &= ~(0x000000FF << offset_bits);
   55.33 +    s->config_reg |= ((val & 0xFF) << offset_bits);
   55.34 +}
   55.35 +
   55.36 +static uint32_t i440fx_addr_readb(void* opaque, uint32_t addr)
   55.37 +{
   55.38 +    I440FXState *s = opaque;
   55.39 +    uint32_t offset_bits = (addr - 0xcf8) * 8;
   55.40 +    uint32_t val;
   55.41 +
   55.42 +    val = (s->config_reg >> offset_bits) & 0xFF;
   55.43 +    
   55.44 +    return val;
   55.45 +}
   55.46 +
   55.47  /* return the global irq number corresponding to a given device irq
   55.48     pin. We could also use the bus number to have a more precise
   55.49     mapping. */
   55.50 @@ -96,7 +136,11 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_
   55.51      b = pci_register_bus(i440fx_set_irq, pci_slot_get_pirq, NULL, 0, 128);
   55.52      s->bus = b;
   55.53  
   55.54 +    register_ioport_write(0xcf8, 4, 1, i440fx_addr_writeb, s);
   55.55 +    register_ioport_write(0xcf8, 4, 2, i440fx_addr_writew, s);
   55.56      register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s);
   55.57 +    register_ioport_read(0xcf8, 4, 1, i440fx_addr_readb, s);
   55.58 +    register_ioport_read(0xcf8, 4, 2, i440fx_addr_readw, s);
   55.59      register_ioport_read(0xcf8, 4, 4, i440fx_addr_readl, s);
   55.60  
   55.61      register_ioport_write(0xcfc, 4, 1, pci_host_data_writeb, s);
    56.1 --- a/tools/ioemu/vl.c	Tue Jul 31 12:36:34 2007 -0700
    56.2 +++ b/tools/ioemu/vl.c	Mon Aug 13 17:49:00 2007 -0400
    56.3 @@ -195,10 +195,13 @@ unsigned char challenge[AUTHCHALLENGESIZ
    56.4  target_phys_addr_t isa_mem_base = 0;
    56.5  PicState2 *isa_pic;
    56.6  
    56.7 +/* Tells whether this is a NativeDom instance of qemu (1:1 mapping is enabled) */
    56.8 +uint8_t is_nativedom = 0;
    56.9 +
   56.10  uint32_t default_ioport_readb(void *opaque, uint32_t address)
   56.11  {
   56.12  #ifdef DEBUG_UNUSED_IOPORT
   56.13 -    fprintf(stderr, "inb: port=0x%04x\n", address);
   56.14 +    fprintf(logfile, "inb: port=0x%04x\n", address);
   56.15  #endif
   56.16      return 0xff;
   56.17  }
   56.18 @@ -206,7 +209,8 @@ uint32_t default_ioport_readb(void *opaq
   56.19  void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
   56.20  {
   56.21  #ifdef DEBUG_UNUSED_IOPORT
   56.22 -    fprintf(stderr, "outb: port=0x%04x data=0x%02x\n", address, data);
   56.23 +    fprintf(logfile, "outb: port=0x%04x data=0x%02x %c\n", 
   56.24 +        address, data, (address==0xe9)?(char)data:' ');
   56.25  #endif
   56.26  }
   56.27  
   56.28 @@ -214,6 +218,11 @@ void default_ioport_writeb(void *opaque,
   56.29  uint32_t default_ioport_readw(void *opaque, uint32_t address)
   56.30  {
   56.31      uint32_t data;
   56.32 +
   56.33 +#ifdef DEBUG_UNUSED_IOPORT
   56.34 +    fprintf(logfile, "inw port=0x%04x (breaking to two reads)\n", address);
   56.35 +#endif
   56.36 +    
   56.37      data = ioport_read_table[0][address](ioport_opaque[address], address);
   56.38      address = (address + 1) & (MAX_IOPORTS - 1);
   56.39      data |= ioport_read_table[0][address](ioport_opaque[address], address) << 8;
   56.40 @@ -222,6 +231,11 @@ uint32_t default_ioport_readw(void *opaq
   56.41  
   56.42  void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
   56.43  {
   56.44 +
   56.45 +#ifdef DEBUG_UNUSED_IOPORT
   56.46 +    fprintf(logfile, "outw port=0x%04x data=0x%04x (breaking to two reads)\n", address, data);
   56.47 +#endif
   56.48 +
   56.49      ioport_write_table[0][address](ioport_opaque[address], address, data & 0xff);
   56.50      address = (address + 1) & (MAX_IOPORTS - 1);
   56.51      ioport_write_table[0][address](ioport_opaque[address], address, (data >> 8) & 0xff);
   56.52 @@ -230,7 +244,7 @@ void default_ioport_writew(void *opaque,
   56.53  uint32_t default_ioport_readl(void *opaque, uint32_t address)
   56.54  {
   56.55  #ifdef DEBUG_UNUSED_IOPORT
   56.56 -    fprintf(stderr, "inl: port=0x%04x\n", address);
   56.57 +    fprintf(logfile, "inl: port=0x%04x\n", address);
   56.58  #endif
   56.59      return 0xffffffff;
   56.60  }
   56.61 @@ -238,7 +252,8 @@ uint32_t default_ioport_readl(void *opaq
   56.62  void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
   56.63  {
   56.64  #ifdef DEBUG_UNUSED_IOPORT
   56.65 -    fprintf(stderr, "outl: port=0x%04x data=0x%02x\n", address, data);
   56.66 +    fprintf(logfile, "outl: port=0x%04x data=0x%02x (cs=%04x eip=%08x)\n", 
   56.67 +        address, data);
   56.68  #endif
   56.69  }
   56.70  
   56.71 @@ -6496,8 +6511,10 @@ enum {
   56.72      QEMU_OPTION_vcpus,
   56.73      QEMU_OPTION_acpi,
   56.74      QEMU_OPTION_vncviewer,
   56.75 +    QEMU_OPTION_vncunused,
   56.76 +
   56.77 +    QEMU_OPTION_nativedom,
   56.78      QEMU_OPTION_pci,
   56.79 -    QEMU_OPTION_vncunused,
   56.80  };
   56.81  
   56.82  typedef struct QEMUOption {
   56.83 @@ -6595,7 +6612,10 @@ const QEMUOption qemu_options[] = {
   56.84      { "d", HAS_ARG, QEMU_OPTION_d },
   56.85      { "vcpus", 1, QEMU_OPTION_vcpus },
   56.86      { "acpi", 0, QEMU_OPTION_acpi },
   56.87 -    { "pci", HAS_ARG, QEMU_OPTION_pci },
   56.88 +
   56.89 +    { "nativedom", HAS_ARG, QEMU_OPTION_nativedom },
   56.90 +    { "pci", HAS_ARG, QEMU_OPTION_pci},
   56.91 +    
   56.92      { NULL },
   56.93  };
   56.94  
   56.95 @@ -7062,7 +7082,7 @@ int main(int argc, char **argv)
   56.96  
   56.97      char qemu_dm_logfilename[128];
   56.98      const char *direct_pci = NULL;
   56.99 -    
  56.100 +
  56.101      /* Ensure that SIGUSR2 is blocked by default when a new thread is created,
  56.102         then only the threads that use the signal unblock it -- this fixes a
  56.103         race condition in Qcow support where the AIO signal is misdelivered.  */
  56.104 @@ -7560,6 +7580,9 @@ int main(int argc, char **argv)
  56.105              case QEMU_OPTION_vncunused:
  56.106                  vncunused++;
  56.107                  break;
  56.108 +            case QEMU_OPTION_nativedom:
  56.109 +                is_nativedom=1;
  56.110 +                break;
  56.111              case QEMU_OPTION_pci:
  56.112                  direct_pci = optarg;
  56.113                  break;
  56.114 @@ -7620,6 +7643,21 @@ int main(int argc, char **argv)
  56.115  #endif
  56.116  
  56.117  #ifdef CONFIG_DM
  56.118 +    xc_handle = xc_interface_open();
  56.119 +
  56.120 +    /* Compute the RAM size of nativedom */    
  56.121 +    if ( is_nativedom )
  56.122 +    {
  56.123 +        if ( !xc_is_nativedom_enabled(xc_handle) )
  56.124 +        {
  56.125 +            fprintf(logfile, "Error: NativeDom is not enabled. Use the enable_nativedom=1 boot parameter\n");
  56.126 +            exit(1);
  56.127 +        }
  56.128 +
  56.129 +        /* Recompute the size of RAM */
  56.130 +        ram_size = xc_get_nativedom_last_mfn(xc_handle) << 12;
  56.131 +    }
  56.132 +
  56.133      bdrv_init();
  56.134      xenstore_parse_domain_config(domid);
  56.135  #endif /* CONFIG_DM */
  56.136 @@ -7718,8 +7756,6 @@ int main(int argc, char **argv)
  56.137  
  56.138  #ifdef CONFIG_DM
  56.139  
  56.140 -    xc_handle = xc_interface_open();
  56.141 -
  56.142  #if defined(__i386__) || defined(__x86_64__)
  56.143  
  56.144      if (qemu_map_cache_init()) {
    57.1 --- a/tools/ioemu/vl.h	Tue Jul 31 12:36:34 2007 -0700
    57.2 +++ b/tools/ioemu/vl.h	Mon Aug 13 17:49:00 2007 -0400
    57.3 @@ -818,10 +818,6 @@ struct PCIDevice {
    57.4  
    57.5      /* Current IRQ levels.  Used internally by the generic PCI code.  */
    57.6      int irq_state[4];
    57.7 -
    57.8 -    /* fields used for direct pci device access */
    57.9 -    uint32_t old_bars[PCI_NUM_REGIONS];
   57.10 -    struct pci_dev *pci_dev;
   57.11  };
   57.12  
   57.13  PCIDevice *pci_register_device(PCIBus *bus, const char *name,
   57.14 @@ -1502,11 +1498,4 @@ void destroy_hvm_domain(void);
   57.15  /* VNC Authentication */
   57.16  #define AUTHCHALLENGESIZE 16
   57.17  
   57.18 -/* HVM guest pci pass through support */
   57.19 -void dpci_init(PCIBus *pci_bus, char *direct_pci);
   57.20 -void dpci_ioport_map(PCIDevice *pci_dev, int region_num, 
   57.21 -                     uint32_t addr, uint32_t size, int type);
   57.22 -void dpci_mmio_map(PCIDevice *pci_dev, int region_num, 
   57.23 -                   uint32_t addr, uint32_t size, int type);
   57.24 -
   57.25  #endif /* VL_H */
    58.1 --- a/tools/libxc/xc_domain.c	Tue Jul 31 12:36:34 2007 -0700
    58.2 +++ b/tools/libxc/xc_domain.c	Mon Aug 13 17:49:00 2007 -0400
    58.3 @@ -501,6 +501,38 @@ int xc_domain_memory_decrease_reservatio
    58.4      return err;
    58.5  }
    58.6  
    58.7 +int xc_domain_1to1_memory_populate_physmap(int xc_handle,
    58.8 +                                          uint32_t domid,
    58.9 +                                          unsigned long nr_extents,
   58.10 +                                          unsigned int extent_order,
   58.11 +                                          unsigned int address_bits,
   58.12 +                                          xen_pfn_t *extent_start)
   58.13 +{
   58.14 +    int err;
   58.15 +    struct xen_memory_reservation reservation = {
   58.16 +        .nr_extents   = nr_extents,
   58.17 +        .extent_order = extent_order,
   58.18 +        .address_bits = address_bits,
   58.19 +        .domid        = domid
   58.20 +    };
   58.21 +    set_xen_guest_handle(reservation.extent_start, extent_start);
   58.22 +
   58.23 +    err = xc_memory_op(xc_handle, XENMEM_populate_1to1_physmap, &reservation);
   58.24 +
   58.25 +    if ( err == nr_extents )
   58.26 +        return 0;
   58.27 +
   58.28 +    if ( err >= 0 )
   58.29 +    {
   58.30 +        DPRINTF("Failed allocation for dom %d: %ld extents of order %d\n",
   58.31 +                domid, nr_extents, extent_order);
   58.32 +        errno = EBUSY;
   58.33 +        err = -1;
   58.34 +    }
   58.35 +
   58.36 +    return err;
   58.37 +}
   58.38 +
   58.39  int xc_domain_memory_populate_physmap(int xc_handle,
   58.40                                            uint32_t domid,
   58.41                                            unsigned long nr_extents,
   58.42 @@ -672,28 +704,65 @@ int xc_assign_device(int xc_handle,
   58.43      return do_domctl(xc_handle, &domctl);
   58.44  }
   58.45  
   58.46 -int xc_irq_mapping(int xc_handle,
   58.47 -                  uint32_t domid,
   58.48 -                  uint32_t machine_irq,
   58.49 -                  uint32_t device,
   58.50 -                  uint32_t intx)
   58.51 +/* Pass-through: binds machine irq to guests irq */
   58.52 +int xc_domain_bind_pt_irq(  int xc_handle,
   58.53 +                                                 uint32_t domid,
   58.54 +                                                 uint8_t machine_irq,
   58.55 +                                                 uint8_t irq_type,
   58.56 +                                                 uint8_t bus,
   58.57 +                                                 uint8_t device,
   58.58 +                                                 uint8_t intx,
   58.59 +                                                 uint8_t isa_irq)
   58.60  {
   58.61 +    int rc;
   58.62 +    xen_domctl_bind_pt_irq_t * bind;
   58.63      DECLARE_DOMCTL;
   58.64  
   58.65 -    domctl.cmd = XEN_DOMCTL_irq_mapping;
   58.66 -    domctl.domain = domid;
   58.67 -    domctl.u.irq_mapping.machine_irq = machine_irq;
   58.68 -    domctl.u.irq_mapping.device = device;
   58.69 -    domctl.u.irq_mapping.intx = intx;
   58.70 - 
   58.71 -    return do_domctl(xc_handle, &domctl);
   58.72 +    domctl.cmd = XEN_DOMCTL_bind_pt_irq;
   58.73 +    domctl.domain = (domid_t)domid;
   58.74 +
   58.75 +    bind = &(domctl.u.bind_pt_irq);
   58.76 +    bind->hvm_domid = domid;
   58.77 +    bind->irq_type = irq_type;
   58.78 +    bind->machine_irq = machine_irq;
   58.79 +    bind->u.pci.bus = bus;
   58.80 +    bind->u.pci.device = device;    
   58.81 +    bind->u.pci.intx = intx;
   58.82 +    bind->u.isa.isa_irq = isa_irq;
   58.83 +    
   58.84 +    rc = do_domctl(xc_handle, &domctl);
   58.85 +    return rc;
   58.86 +}
   58.87 +
   58.88 +int xc_domain_bind_pt_pci_irq(  int xc_handle,
   58.89 +                                                 uint32_t domid,
   58.90 +                                                 uint8_t machine_irq,
   58.91 +                                                 uint8_t bus,
   58.92 +                                                 uint8_t device,
   58.93 +                                                 uint8_t intx)
   58.94 +{
   58.95 +
   58.96 +    return (    xc_domain_bind_pt_irq(xc_handle, domid, machine_irq, PT_IRQ_TYPE_PCI, 
   58.97 +                                                            bus, device, intx, 0)   );
   58.98 +
   58.99 +}
  58.100 +
  58.101 +int xc_domain_bind_pt_isa_irq(  int xc_handle,
  58.102 +                                                 uint32_t domid,
  58.103 +                                                 uint8_t machine_irq)
  58.104 +{
  58.105 +
  58.106 +    return (    xc_domain_bind_pt_irq(xc_handle, domid, machine_irq, PT_IRQ_TYPE_ISA, 
  58.107 +                                                            0, 0, 0, machine_irq)   );
  58.108 +
  58.109  }
  58.110  
  58.111  int xc_domain_memory_mapping(int xc_handle,
  58.112                               uint32_t domid,
  58.113                               unsigned long first_gfn,
  58.114                               unsigned long first_mfn,
  58.115 -                             unsigned long nr_mfns)
  58.116 +                             unsigned long nr_mfns,
  58.117 +                             uint32_t add_mapping)
  58.118  {
  58.119      DECLARE_DOMCTL;
  58.120  
  58.121 @@ -702,6 +771,7 @@ int xc_domain_memory_mapping(int xc_hand
  58.122      domctl.u.memory_mapping.first_gfn = first_gfn;
  58.123      domctl.u.memory_mapping.first_mfn = first_mfn;
  58.124      domctl.u.memory_mapping.nr_mfns = nr_mfns;
  58.125 +    domctl.u.memory_mapping.add_mapping = add_mapping;
  58.126  
  58.127      return do_domctl(xc_handle, &domctl);
  58.128  }
  58.129 @@ -710,7 +780,8 @@ int xc_domain_ioport_mapping(int xc_hand
  58.130                               uint32_t domid,
  58.131                               uint32_t first_gport,
  58.132                               uint32_t first_mport,
  58.133 -                             uint32_t nr_ports)
  58.134 +                             uint32_t nr_ports,
  58.135 +                             uint32_t add_mapping)
  58.136  {
  58.137      DECLARE_DOMCTL;
  58.138  
  58.139 @@ -719,6 +790,7 @@ int xc_domain_ioport_mapping(int xc_hand
  58.140      domctl.u.ioport_mapping.first_gport = first_gport;
  58.141      domctl.u.ioport_mapping.first_mport = first_mport;
  58.142      domctl.u.ioport_mapping.nr_ports = nr_ports;
  58.143 +    domctl.u.ioport_mapping.add_mapping = add_mapping;
  58.144  
  58.145      return do_domctl(xc_handle, &domctl);
  58.146  }
    59.1 --- a/tools/libxc/xc_hvm_build.c	Tue Jul 31 12:36:34 2007 -0700
    59.2 +++ b/tools/libxc/xc_hvm_build.c	Mon Aug 13 17:49:00 2007 -0400
    59.3 @@ -10,6 +10,7 @@
    59.4  
    59.5  #include "xg_private.h"
    59.6  #include "xc_private.h"
    59.7 +#include "xg_save_restore.h" /* PFN_TO_KB */
    59.8  
    59.9  #include <xen/foreign/x86_32.h>
   59.10  #include <xen/foreign/x86_64.h>
   59.11 @@ -108,6 +109,45 @@ static void build_e820map(void *e820_pag
   59.12      *(((unsigned char *)e820_page) + HVM_E820_NR_OFFSET) = nr_map;
   59.13  }
   59.14  
   59.15 +int xc_is_nativedom_enabled(int xc_handle)
   59.16 +{
   59.17 +    DECLARE_HYPERCALL;
   59.18 +    int rc;
   59.19 +
   59.20 +    hypercall.op = __HYPERVISOR_hvm_op;
   59.21 +    hypercall.arg[0] = HVMOP_is_nativedom_enabled;
   59.22 +
   59.23 +    rc = do_xen_hypercall(xc_handle, &hypercall);
   59.24 +
   59.25 +    return rc;
   59.26 +}
   59.27 +
   59.28 +int xc_get_nativedom_last_mfn(int xc_handle)
   59.29 +{
   59.30 +    return (xc_memory_op(xc_handle, XENMEM_maximum_ram_page_nativedom, NULL));
   59.31 +}
   59.32 +
   59.33 +int xc_build_nativedom_e820map(int handle, uint32_t dom)
   59.34 +{
   59.35 +    DECLARE_HYPERCALL;
   59.36 +    xen_hvm_copy_nativedom_e820_map_t arg;
   59.37 +    int rc;
   59.38 +
   59.39 +    hypercall.op = __HYPERVISOR_hvm_op;
   59.40 +    hypercall.arg[0] = HVMOP_copy_nativedom_e820_map;
   59.41 +    hypercall.arg[1] = (unsigned long)&arg;
   59.42 +
   59.43 +    arg.domid = dom;
   59.44 +
   59.45 +    if ( lock_pages(&arg, sizeof(arg)) != 0 )
   59.46 +        return -1;
   59.47 +
   59.48 +    rc = do_xen_hypercall(handle, &hypercall);
   59.49 +    unlock_pages(&arg, sizeof(arg));
   59.50 +
   59.51 +    return rc;
   59.52 +}
   59.53 +
   59.54  static int loadelfimage(
   59.55      struct elf_binary *elf, int xch, uint32_t dom, unsigned long *parray)
   59.56  {
   59.57 @@ -155,14 +195,14 @@ static int loadelfimage(
   59.58  static int setup_guest(int xc_handle,
   59.59                         uint32_t dom, int memsize,
   59.60                         char *image, unsigned long image_size,
   59.61 -                       vcpu_guest_context_either_t *ctxt)
   59.62 +                       vcpu_guest_context_either_t *ctxt, int is_nativedom)
   59.63  {
   59.64      xen_pfn_t *page_array = NULL;
   59.65 +    void *e820_page = NULL;
   59.66      unsigned long i, nr_pages = (unsigned long)memsize << (20 - PAGE_SHIFT);
   59.67      unsigned long shared_page_nr;
   59.68      struct xen_add_to_physmap xatp;
   59.69      struct shared_info *shared_info;
   59.70 -    void *e820_page;
   59.71      struct elf_binary elf;
   59.72      uint64_t v_start, v_end;
   59.73      int rc;
   59.74 @@ -175,8 +215,28 @@ static int setup_guest(int xc_handle,
   59.75      if ( elf_init(&elf, image, image_size) != 0 )
   59.76          goto error_out;
   59.77      elf_parse_binary(&elf);
   59.78 -    v_start = 0;
   59.79 -    v_end = (unsigned long long)memsize << 20;
   59.80 +
   59.81 +    if ( !is_nativedom ) 
   59.82 +    {
   59.83 +        v_start = 0;
   59.84 +        v_end = (unsigned long long)memsize << 20;
   59.85 +    }
   59.86 +    else
   59.87 +    {
   59.88 +        nr_pages = xc_get_nativedom_last_mfn(xc_handle);
   59.89 +        v_start = 0;
   59.90 +        v_end = nr_pages << PAGE_SHIFT;
   59.91 +
   59.92 +        DPRINTF("NativeDom: last page = %lu\n", nr_pages-1);
   59.93 +
   59.94 +        /* set the max memory in KB */
   59.95 +        rc = xc_domain_setmaxmem(xc_handle, dom, PFN_TO_KB(nr_pages));
   59.96 +        if ( 0 != rc ) 
   59.97 +        {
   59.98 +            PERROR("NativeDom: Couldn't set domain's maxmem\n");
   59.99 +            goto error_out;
  59.100 +        }    
  59.101 +    }
  59.102  
  59.103      if ( xc_version(xc_handle, XENVER_capabilities, &caps) != 0 )
  59.104      {
  59.105 @@ -209,28 +269,53 @@ static int setup_guest(int xc_handle,
  59.106      for ( i = HVM_BELOW_4G_RAM_END >> PAGE_SHIFT; i < nr_pages; i++ )
  59.107          page_array[i] += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT;
  59.108  
  59.109 -    /* Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000. */
  59.110 -    rc = xc_domain_memory_populate_physmap(
  59.111 -        xc_handle, dom, 0xa0, 0, 0, &page_array[0x00]);
  59.112 -    if ( rc == 0 )
  59.113 +    if ( !is_nativedom )
  59.114 +    {
  59.115 +        /* Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000. */
  59.116          rc = xc_domain_memory_populate_physmap(
  59.117 -            xc_handle, dom, nr_pages - 0xc0, 0, 0, &page_array[0xc0]);
  59.118 -    if ( rc != 0 )
  59.119 +            xc_handle, dom, 0xa0, 0, 0, &page_array[0x00]);
  59.120 +        if ( rc == 0 )
  59.121 +            rc = xc_domain_memory_populate_physmap(
  59.122 +                xc_handle, dom, nr_pages - 0xc0, 0, 0, &page_array[0xc0]);
  59.123 +        if ( rc != 0 )
  59.124 +        {
  59.125 +            PERROR("Could not allocate memory for HVM guest.\n");
  59.126 +            goto error_out;
  59.127 +        }
  59.128 +    }
  59.129 +    else
  59.130      {
  59.131 -        PERROR("Could not allocate memory for HVM guest.\n");
  59.132 -        goto error_out;
  59.133 +        rc = xc_domain_1to1_memory_populate_physmap(xc_handle, dom, nr_pages, 0, 0, &page_array[0x00]);
  59.134 +        if ( rc != 0 )
  59.135 +        {
  59.136 +            PERROR("NativeDom: Couldn't populate 1:1 mapping.\n");
  59.137 +            goto error_out;
  59.138 +        }    
  59.139      }
  59.140 -
  59.141 +    
  59.142      if ( loadelfimage(&elf, xc_handle, dom, page_array) != 0 )
  59.143          goto error_out;
  59.144  
  59.145 -    if ( (e820_page = xc_map_foreign_range(
  59.146 -              xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
  59.147 -              HVM_E820_PAGE >> PAGE_SHIFT)) == NULL )
  59.148 -        goto error_out;
  59.149 -    memset(e820_page, 0, PAGE_SIZE);
  59.150 -    build_e820map(e820_page, v_end);
  59.151 -    munmap(e820_page, PAGE_SIZE);
  59.152 +    if ( !is_nativedom ) 
  59.153 +    {
  59.154 +        if ( (e820_page = xc_map_foreign_range(
  59.155 +                  xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
  59.156 +                  HVM_E820_PAGE >> PAGE_SHIFT)) == NULL )
  59.157 +            goto error_out;
  59.158 +        memset(e820_page, 0, PAGE_SIZE);
  59.159 +        build_e820map(e820_page, v_end);
  59.160 +        munmap(e820_page, PAGE_SIZE);
  59.161 +    }
  59.162 +    else
  59.163 +    {
  59.164 +        /* Use a hypercall to build the guest e820 table */
  59.165 +        rc = xc_build_nativedom_e820map(xc_handle, dom);
  59.166 +        if ( rc != 0 )
  59.167 +        {
  59.168 +            PERROR("NativeDom: Couldn't build e820 memory map\n");
  59.169 +            goto error_out;
  59.170 +        }            
  59.171 +    }
  59.172  
  59.173      /* Map and initialise shared_info page. */
  59.174      xatp.domid = dom;
  59.175 @@ -288,7 +373,8 @@ static int xc_hvm_build_internal(int xc_
  59.176                                   uint32_t domid,
  59.177                                   int memsize,
  59.178                                   char *image,
  59.179 -                                 unsigned long image_size)
  59.180 +                                 unsigned long image_size,
  59.181 +                                 int is_nativedom)
  59.182  {
  59.183      struct xen_domctl launch_domctl;
  59.184      vcpu_guest_context_either_t ctxt;
  59.185 @@ -302,7 +388,8 @@ static int xc_hvm_build_internal(int xc_
  59.186  
  59.187      memset(&ctxt, 0, sizeof(ctxt));
  59.188  
  59.189 -    if ( setup_guest(xc_handle, domid, memsize, image, image_size, &ctxt) < 0 )
  59.190 +    if ( setup_guest(xc_handle, domid, memsize, image, image_size, &ctxt, 
  59.191 +                     is_nativedom) < 0 )
  59.192      {
  59.193          goto error_out;
  59.194      }
  59.195 @@ -340,7 +427,8 @@ static inline int is_loadable_phdr(Elf32
  59.196  int xc_hvm_build(int xc_handle,
  59.197                   uint32_t domid,
  59.198                   int memsize,
  59.199 -                 const char *image_name)
  59.200 +                 const char *image_name,
  59.201 +                 int is_nativedom)
  59.202  {
  59.203      char *image;
  59.204      int  sts;
  59.205 @@ -350,7 +438,13 @@ int xc_hvm_build(int xc_handle,
  59.206           ((image = xc_read_image(image_name, &image_size)) == NULL) )
  59.207          return -1;
  59.208  
  59.209 -    sts = xc_hvm_build_internal(xc_handle, domid, memsize, image, image_size);
  59.210 +    if ( (is_nativedom)  && (!xc_is_nativedom_enabled(xc_handle)) )
  59.211 +    {
  59.212 +        ERROR("Couldn't start NativeDom since it's not enabled. Add enable_nativedom=1 as a boot parameter");
  59.213 +        return -1;
  59.214 +    }
  59.215 +    
  59.216 +    sts = xc_hvm_build_internal(xc_handle, domid, memsize, image, image_size, is_nativedom);
  59.217  
  59.218      free(image);
  59.219  
  59.220 @@ -364,7 +458,8 @@ int xc_hvm_build_mem(int xc_handle,
  59.221                       uint32_t domid,
  59.222                       int memsize,
  59.223                       const char *image_buffer,
  59.224 -                     unsigned long image_size)
  59.225 +                     unsigned long image_size,
  59.226 +                     int is_nativedom)
  59.227  {
  59.228      int           sts;
  59.229      unsigned long img_len;
  59.230 @@ -386,7 +481,7 @@ int xc_hvm_build_mem(int xc_handle,
  59.231      }
  59.232  
  59.233      sts = xc_hvm_build_internal(xc_handle, domid, memsize,
  59.234 -                                img, img_len);
  59.235 +                                img, img_len, is_nativedom);
  59.236  
  59.237      /* xc_inflate_buffer may return the original buffer pointer (for
  59.238         for already inflated buffers), so exercise some care in freeing */
    60.1 --- a/tools/libxc/xc_private.c	Tue Jul 31 12:36:34 2007 -0700
    60.2 +++ b/tools/libxc/xc_private.c	Mon Aug 13 17:49:00 2007 -0400
    60.3 @@ -225,6 +225,7 @@ int xc_memory_op(int xc_handle,
    60.4      {
    60.5      case XENMEM_increase_reservation:
    60.6      case XENMEM_decrease_reservation:
    60.7 +    case XENMEM_populate_1to1_physmap:
    60.8      case XENMEM_populate_physmap:
    60.9          if ( lock_pages(reservation, sizeof(*reservation)) != 0 )
   60.10          {
   60.11 @@ -280,6 +281,7 @@ int xc_memory_op(int xc_handle,
   60.12      {
   60.13      case XENMEM_increase_reservation:
   60.14      case XENMEM_decrease_reservation:
   60.15 +    case XENMEM_populate_1to1_physmap:
   60.16      case XENMEM_populate_physmap:
   60.17          unlock_pages(reservation, sizeof(*reservation));
   60.18          get_xen_guest_handle(extent_start, reservation->extent_start);
    61.1 --- a/tools/libxc/xc_private.h	Tue Jul 31 12:36:34 2007 -0700
    61.2 +++ b/tools/libxc/xc_private.h	Mon Aug 13 17:49:00 2007 -0400
    61.3 @@ -49,21 +49,21 @@
    61.4  #define MAX_PAGECACHE_USAGE (4*1024)
    61.5  
    61.6  #if INFO
    61.7 -#define IPRINTF(_f, _a...) printf(_f , ## _a)
    61.8 +#define IPRINTF(_f, _a...) fprintf(stderr, "[INFO] " _f , ## _a)
    61.9  #else
   61.10  #define IPRINTF(_f, _a...) ((void)0)
   61.11  #endif
   61.12  
   61.13  #if DEBUG
   61.14 -#define DPRINTF(_f, _a...) fprintf(stderr, _f , ## _a)
   61.15 +#define DPRINTF(_f, _a...) fprintf(stderr, "[DEBUG] " _f , ## _a)
   61.16  #else
   61.17  #define DPRINTF(_f, _a...) ((void)0)
   61.18  #endif
   61.19  
   61.20  #if PROGRESS
   61.21 -#define PPRINTF(_f, _a...) fprintf(stderr, _f , ## _a)
   61.22 +#define PPRINTF(_f, _a...) fprintf(stderr, "[PROGRESS] " _f , ## _a)
   61.23  #else
   61.24 -#define PPRINTF(_f, _a...)
   61.25 +#define PPRINTF(_f, _a...) ((void)0)
   61.26  #endif
   61.27  
   61.28  char *safe_strerror(int errcode);
    62.1 --- a/tools/libxc/xenctrl.h	Tue Jul 31 12:36:34 2007 -0700
    62.2 +++ b/tools/libxc/xenctrl.h	Mon Aug 13 17:49:00 2007 -0400
    62.3 @@ -516,6 +516,13 @@ int xc_domain_memory_populate_physmap(in
    62.4                                        unsigned int address_bits,
    62.5                                        xen_pfn_t *extent_start);
    62.6  
    62.7 +int xc_domain_1to1_memory_populate_physmap(int xc_handle,
    62.8 +                                           uint32_t domid,
    62.9 +                                           unsigned long nr_extents,
   62.10 +                                           unsigned int extent_order,
   62.11 +                                           unsigned int address_bits,
   62.12 +                                           xen_pfn_t *extent_start);
   62.13 +
   62.14  int xc_domain_ioport_permission(int xc_handle,
   62.15                                  uint32_t domid,
   62.16                                  uint32_t first_port,
   62.17 @@ -859,24 +866,43 @@ int xc_ia64_save_to_nvram(int xc_handle,
   62.18  /* IA64 specific, nvram init */
   62.19  int xc_ia64_nvram_init(int xc_handle, char *dom_name, uint32_t dom);
   62.20  
   62.21 -/* HVM guest PCI pass through */
   62.22 +/* HVM guest pass-through */
   62.23  int xc_assign_device(int xc_handle,
   62.24                       uint32_t domid,
   62.25                       uint32_t machine_bdf);
   62.26 -int xc_irq_mapping(int xc_handle,
   62.27 -                   uint32_t domid,
   62.28 -                   uint32_t machine_irq,
   62.29 -                   uint32_t device,
   62.30 -                   uint32_t intx);
   62.31 +
   62.32  int xc_domain_memory_mapping(int xc_handle,
   62.33                               uint32_t domid,
   62.34                               unsigned long first_gfn,
   62.35                               unsigned long first_mfn,
   62.36 -                             unsigned long nr_mfns);
   62.37 +                             unsigned long nr_mfns,
   62.38 +                             uint32_t add_mapping);
   62.39 +
   62.40  int xc_domain_ioport_mapping(int xc_handle,
   62.41                               uint32_t domid,
   62.42                               uint32_t first_gport,
   62.43                               uint32_t first_mport,
   62.44 -                             uint32_t nr_ports);
   62.45 +                             uint32_t nr_ports,
   62.46 +                             uint32_t add_mapping);
   62.47 +
   62.48 +int xc_domain_bind_pt_irq(int xc_handle,
   62.49 +                          uint32_t domid,
   62.50 +                          uint8_t machine_irq,
   62.51 +                          uint8_t irq_type,
   62.52 +                          uint8_t bus,
   62.53 +                          uint8_t device,
   62.54 +                          uint8_t intx,
   62.55 +                          uint8_t isa_irq);
   62.56 +
   62.57 +int xc_domain_bind_pt_pci_irq(int xc_handle,
   62.58 +                              uint32_t domid,
   62.59 +                              uint8_t machine_irq,
   62.60 +                              uint8_t bus,
   62.61 +                              uint8_t device,
   62.62 +                              uint8_t intx);
   62.63 +
   62.64 +int xc_domain_bind_pt_isa_irq(int xc_handle,
   62.65 +                              uint32_t domid,
   62.66 +                              uint8_t machine_irq);
   62.67  
   62.68  #endif /* XENCTRL_H */
    63.1 --- a/tools/libxc/xenguest.h	Tue Jul 31 12:36:34 2007 -0700
    63.2 +++ b/tools/libxc/xenguest.h	Mon Aug 13 17:49:00 2007 -0400
    63.3 @@ -128,13 +128,20 @@ int xc_linux_build_mem(int xc_handle,
    63.4  int xc_hvm_build(int xc_handle,
    63.5                   uint32_t domid,
    63.6                   int memsize,
    63.7 -                 const char *image_name);
    63.8 +                 const char *image_name,
    63.9 +                 int is_nativedom);
   63.10  
   63.11  int xc_hvm_build_mem(int xc_handle,
   63.12                       uint32_t domid,
   63.13                       int memsize,
   63.14                       const char *image_buffer,
   63.15 -                     unsigned long image_size);
   63.16 +                     unsigned long image_size,
   63.17 +                     int is_nativedom);
   63.18 +
   63.19 +/* NativeDom support */
   63.20 +int xc_is_nativedom_enabled(int xc_handle);
   63.21 +int xc_get_nativedom_last_mfn(int xc_handle);
   63.22 +int xc_build_nativedom_e820map(int handle, uint32_t dom);
   63.23  
   63.24  /* PowerPC specific. */
   63.25  int xc_prose_build(int xc_handle,
    64.1 --- a/tools/libxc/xg_private.c	Tue Jul 31 12:36:34 2007 -0700
    64.2 +++ b/tools/libxc/xg_private.c	Mon Aug 13 17:49:00 2007 -0400
    64.3 @@ -192,7 +192,8 @@ unsigned long csum_page(void *page)
    64.4      int xc_hvm_build(int xc_handle,
    64.5                       uint32_t domid,
    64.6                       int memsize,
    64.7 -                     const char *image_name)
    64.8 +                     const char *image_name,
    64.9 +                     int is_nativedom)
   64.10  {
   64.11      errno = ENOSYS;
   64.12      return -1;
    65.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Tue Jul 31 12:36:34 2007 -0700
    65.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Mon Aug 13 17:49:00 2007 -0400
    65.3 @@ -536,18 +536,18 @@ static PyObject *pyxc_hvm_build(XcObject
    65.4      int i;
    65.5  #endif
    65.6      char *image;
    65.7 -    int store_evtchn, memsize, vcpus = 1, pae = 0, acpi = 0, apic = 1;
    65.8 +    int store_evtchn, memsize, vcpus = 1, pae = 0, acpi = 0, apic = 1, is_nativedom = 0;
    65.9      unsigned long store_mfn;
   65.10  
   65.11      static char *kwd_list[] = { "domid", "store_evtchn",
   65.12  				"memsize", "image", "vcpus", "pae", "acpi",
   65.13 -				"apic", NULL };
   65.14 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|iiii", kwd_list,
   65.15 +				"apic", "nativedom", NULL };
   65.16 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|iiiii", kwd_list,
   65.17                                        &dom, &store_evtchn, &memsize,
   65.18 -                                      &image, &vcpus, &pae, &acpi, &apic) )
   65.19 +                                      &image, &vcpus, &pae, &acpi, &apic, &is_nativedom) )
   65.20          return NULL;
   65.21  
   65.22 -    if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
   65.23 +    if ( xc_hvm_build(self->xc_handle, dom, memsize, image, is_nativedom) != 0 )
   65.24          return pyxc_error_to_exception();
   65.25  
   65.26  #if !defined(__ia64__)
   65.27 @@ -577,6 +577,8 @@ static PyObject *pyxc_hvm_build(XcObject
   65.28      xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_EVTCHN,
   65.29                       store_evtchn);
   65.30  
   65.31 +    xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_IS_NATIVEDOM, is_nativedom);
   65.32 +
   65.33      return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
   65.34  }
   65.35  
    66.1 --- a/tools/python/xen/xend/XendConfig.py	Tue Jul 31 12:36:34 2007 -0700
    66.2 +++ b/tools/python/xen/xend/XendConfig.py	Mon Aug 13 17:49:00 2007 -0400
    66.3 @@ -33,8 +33,8 @@ from xen.util.blkif import blkdev_name_t
    66.4  from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
    66.5  from xen.util import xsconstants
    66.6  
    66.7 -log = logging.getLogger("xend.XendConfig")
    66.8 -log.setLevel(logging.WARN)
    66.9 +log = logging.getLogger("xend.XendDomainInfo")
   66.10 +#log.setLevel(logging.WARN)
   66.11  
   66.12  
   66.13  """
   66.14 @@ -127,7 +127,8 @@ XENAPI_PLATFORM_CFG = [ 'acpi', 'apic', 
   66.15                          'nographic', 'pae', 'rtc_timeoffset', 'serial', 'sdl',
   66.16                          'soundhw','stdvga', 'usb', 'usbdevice', 'vnc',
   66.17                          'vncconsole', 'vncdisplay', 'vnclisten',
   66.18 -                        'vncpasswd', 'vncunused', 'xauthority', 'pci']
   66.19 +                        'vncpasswd', 'vncunused', 'xauthority', 'nativedom',
   66.20 +                        'pci']
   66.21  
   66.22  # List of XendConfig configuration keys that have no direct equivalent
   66.23  # in the old world.
   66.24 @@ -164,6 +165,7 @@ XENAPI_CFG_TYPES = {
   66.25      'other_config': dict,
   66.26      'security_label': str,
   66.27      'pci': str,
   66.28 +    'nativedom': int,
   66.29  }
   66.30  
   66.31  # List of legacy configuration keys that have no equivalent in the
    67.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Tue Jul 31 12:36:34 2007 -0700
    67.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Mon Aug 13 17:49:00 2007 -0400
    67.3 @@ -343,7 +343,15 @@ class XendDomainInfo:
    67.4              self.domid =  self.info.get('domid')
    67.5          else:
    67.6              self.domid = domid
    67.7 -        
    67.8 +
    67.9 +        try:
   67.10 +            hvm_platform = self.info.get('platform', {})
   67.11 +            self.is_nativedom = bool(hvm_platform['nativedom'])
   67.12 +        except:
   67.13 +            self.is_nativedom = False
   67.14 +
   67.15 +        log.debug("NativeDom: %s" % self.is_nativedom)
   67.16 +
   67.17          #REMOVE: uuid is now generated in XendConfig
   67.18          #if not self._infoIsSet('uuid'):
   67.19          #    self.info['uuid'] = uuid.toString(uuid.create())
   67.20 @@ -1486,6 +1494,8 @@ class XendDomainInfo:
   67.21          except RuntimeError, exn:
   67.22              raise XendError(str(exn))
   67.23  
   67.24 +    def _isNativeDom(self):
   67.25 +        return self.is_nativedom
   67.26  
   67.27      def _initDomain(self):
   67.28          log.debug('XendDomainInfo.initDomain: %s %s',
   67.29 @@ -1526,11 +1536,14 @@ class XendDomainInfo:
   67.30              # takes MiB and we must not round down and end up under-providing.
   67.31              shadow = ((shadow + 1023) / 1024) * 1024
   67.32  
   67.33 -            # set memory limit
   67.34 -            xc.domain_setmaxmem(self.domid, maxmem)
   67.35 -
   67.36 -            # Make sure there's enough RAM available for the domain
   67.37 -            balloon.free(memory + shadow)
   67.38 +            if (not self._isNativeDom()):
   67.39 +                # set memory limit
   67.40 +                xc.domain_setmaxmem(self.domid, maxmem)
   67.41 +                
   67.42 +                # Make sure there's enough RAM available for the domain
   67.43 +                balloon.free(memory + shadow)
   67.44 +            else:
   67.45 +                balloon.free(shadow)
   67.46  
   67.47              # Set up the shadow memory
   67.48              shadow_cur = xc.shadow_mem_control(self.domid, shadow / 1024)
    68.1 --- a/tools/python/xen/xend/image.py	Tue Jul 31 12:36:34 2007 -0700
    68.2 +++ b/tools/python/xen/xend/image.py	Mon Aug 13 17:49:00 2007 -0400
    68.3 @@ -267,6 +267,7 @@ class HVMImageHandler(ImageHandler):
    68.4          self.pae  = int(vmConfig['platform'].get('pae',  0))
    68.5          self.apic = int(vmConfig['platform'].get('apic', 0))
    68.6          self.acpi = int(vmConfig['platform'].get('acpi', 0))
    68.7 +        self.nativedom = int(vmConfig['platform'].get('nativedom', 0))
    68.8          
    68.9  
   68.10      def buildDomain(self):
   68.11 @@ -282,6 +283,8 @@ class HVMImageHandler(ImageHandler):
   68.12          log.debug("pae            = %d", self.pae)
   68.13          log.debug("acpi           = %d", self.acpi)
   68.14          log.debug("apic           = %d", self.apic)
   68.15 +        log.debug("nativedom      = %d", self.nativedom)
   68.16 +
   68.17  
   68.18          rc = xc.hvm_build(domid          = self.vm.getDomid(),
   68.19                            image          = self.kernel,
   68.20 @@ -290,7 +293,8 @@ class HVMImageHandler(ImageHandler):
   68.21                            vcpus          = self.vm.getVCpuCount(),
   68.22                            pae            = self.pae,
   68.23                            acpi           = self.acpi,
   68.24 -                          apic           = self.apic)
   68.25 +                          apic           = self.apic,
   68.26 +                          nativedom      = self.nativedom)
   68.27          rc['notes'] = { 'SUSPEND_CANCEL': 1 }
   68.28          return rc
   68.29  
   68.30 @@ -299,7 +303,7 @@ class HVMImageHandler(ImageHandler):
   68.31      def parseDeviceModelArgs(self, vmConfig):
   68.32          dmargs = [ 'boot', 'fda', 'fdb', 'soundhw',
   68.33                     'localtime', 'serial', 'stdvga', 'isa',
   68.34 -                   'acpi', 'usb', 'usbdevice', 'keymap', 'pci' ]
   68.35 +                   'acpi', 'usb', 'usbdevice', 'keymap', 'pci', 'nativedom' ]
   68.36          
   68.37          ret = ['-vcpus', str(self.vm.getVCpuCount())]
   68.38  
    69.1 --- a/tools/python/xen/xm/create.py	Tue Jul 31 12:36:34 2007 -0700
    69.2 +++ b/tools/python/xen/xm/create.py	Mon Aug 13 17:49:00 2007 -0400
    69.3 @@ -282,6 +282,10 @@ gopts.var('disk', val='phy:DEV,VDEV,MODE
    69.4            backend driver domain to use for the disk.
    69.5            The option may be repeated to add more than one disk.""")
    69.6  
    69.7 +gopts.var('nativedom', val='no|yes',
    69.8 +          fn=set_bool, default=0,
    69.9 +          use="Tells whether the domain is NativeDom")
   69.10 +
   69.11  gopts.var('pci', val='BUS:DEV.FUNC',
   69.12            fn=append_value, default=[],
   69.13            use="""Add a PCI device to a domain, using given params (in hex).
   69.14 @@ -730,7 +734,7 @@ def configure_hvm(config_image, vals):
   69.15               'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw',
   69.16               'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten',
   69.17               'sdl', 'display', 'xauthority', 'rtc_timeoffset', 'monitor',
   69.18 -             'acpi', 'apic', 'usb', 'usbdevice', 'keymap', 'pci' ]
   69.19 +             'acpi', 'apic', 'usb', 'usbdevice', 'keymap', 'nativedom', 'pci' ]
   69.20      for a in args:
   69.21          if a in vals.__dict__ and vals.__dict__[a] is not None:
   69.22              config_image.append([a, vals.__dict__[a]])
    70.1 --- a/xen/arch/x86/Makefile	Tue Jul 31 12:36:34 2007 -0700
    70.2 +++ b/xen/arch/x86/Makefile	Mon Aug 13 17:49:00 2007 -0400
    70.3 @@ -2,6 +2,7 @@ subdir-y += acpi
    70.4  subdir-y += cpu
    70.5  subdir-y += genapic
    70.6  subdir-y += hvm
    70.7 +subdir-y += pt
    70.8  subdir-y += mm
    70.9  subdir-y += oprofile
   70.10  
    71.1 --- a/xen/arch/x86/domain.c	Tue Jul 31 12:36:34 2007 -0700
    71.2 +++ b/xen/arch/x86/domain.c	Mon Aug 13 17:49:00 2007 -0400
    71.3 @@ -43,11 +43,14 @@
    71.4  #include <asm/hvm/hvm.h>
    71.5  #include <asm/hvm/support.h>
    71.6  #include <asm/msr.h>
    71.7 +#include <asm/pass-through.h>
    71.8  #include <asm/iommu.h>
    71.9  #ifdef CONFIG_COMPAT
   71.10  #include <compat/vcpu.h>
   71.11  #endif
   71.12  
   71.13 +extern int opt_nativedom;
   71.14 +
   71.15  DEFINE_PER_CPU(struct vcpu *, curr_vcpu);
   71.16  DEFINE_PER_CPU(__u64, efer);
   71.17  
   71.18 @@ -483,8 +486,14 @@ int arch_domain_create(struct domain *d)
   71.19              virt_to_page(d->shared_info), d, XENSHARE_writable);
   71.20      }
   71.21  
   71.22 -    if (iommu_found())
   71.23 -        iommu_domain_init(d);
   71.24 +    if ( is_hvm_domain(d) )
   71.25 +    {
   71.26 +        /* Init common pass-through structures */
   71.27 +        passthrough_domain_init(d);
   71.28 +        
   71.29 +        if ( iommu_found() )
   71.30 +            iommu_domain_init(d);
   71.31 +    }
   71.32  
   71.33      if ( is_hvm_domain(d) )
   71.34      {
    72.1 --- a/xen/arch/x86/domctl.c	Tue Jul 31 12:36:34 2007 -0700
    72.2 +++ b/xen/arch/x86/domctl.c	Mon Aug 13 17:49:00 2007 -0400
    72.3 @@ -25,7 +25,9 @@
    72.4  #include <asm/hvm/support.h>
    72.5  #include <asm/processor.h>
    72.6  #include <xen/list.h>
    72.7 +#include <asm/pass-through.h>
    72.8  #include <asm/iommu.h>
    72.9 +#include <xen/irq_bind.h>
   72.10  
   72.11  long arch_do_domctl(
   72.12      struct xen_domctl *domctl,
   72.13 @@ -461,43 +463,26 @@ long arch_do_domctl(
   72.14      }
   72.15      break;
   72.16  
   72.17 -    case XEN_DOMCTL_irq_mapping:
   72.18 +    case XEN_DOMCTL_bind_pt_irq:
   72.19      {
   72.20 -        struct domain *d;
   72.21 -        uint32_t machine_gsi, guest_gsi;
   72.22 -        uint32_t device, intx;
   72.23 -
   72.24 -        ret = -EINVAL;
   72.25 -        if ( unlikely((d = get_domain_by_id(domctl->domain)) == NULL) ) {
   72.26 -            gdprintk(XENLOG_ERR,
   72.27 -                "XEN_DOMCTL_irq_mapping: get_domain_by_id() failed\n"); 
   72.28 -            break;
   72.29 -        }
   72.30 -        machine_gsi = domctl->u.irq_mapping.machine_irq;
   72.31 -        device = domctl->u.irq_mapping.device;
   72.32 -        intx = domctl->u.irq_mapping.intx;
   72.33 -        guest_gsi = hvm_pci_intx_gsi(device, intx);
   72.34 +        struct domain * d;
   72.35 +        xen_domctl_bind_pt_irq_t * bind;
   72.36  
   72.37 -        d->arch.hvm_domain.irq.mirq[machine_gsi].valid = 1;
   72.38 -        d->arch.hvm_domain.irq.mirq[machine_gsi].device = device;
   72.39 -        d->arch.hvm_domain.irq.mirq[machine_gsi].intx = intx;
   72.40 -        d->arch.hvm_domain.irq.mirq[machine_gsi].guest_gsi = guest_gsi;
   72.41 -
   72.42 -        d->arch.hvm_domain.irq.girq[guest_gsi].valid = 1;
   72.43 -        d->arch.hvm_domain.irq.girq[guest_gsi].device = device;
   72.44 -        d->arch.hvm_domain.irq.girq[guest_gsi].intx = intx;
   72.45 -        d->arch.hvm_domain.irq.girq[guest_gsi].machine_gsi = machine_gsi;
   72.46 +        ret = -ESRCH;
   72.47 +        if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL )
   72.48 +            break;
   72.49  
   72.50 -        /* Deal with gsi for legacy devices */
   72.51 -        pirq_guest_bind(d->vcpu[0], machine_gsi, BIND_PIRQ__WILL_SHARE);
   72.52 -        gdprintk(XENLOG_INFO,
   72.53 -            "XEN_DOMCTL_irq_mapping: m_irq = %x device = %x intx = %x\n",
   72.54 -            machine_gsi, domctl->u.irq_mapping.device,
   72.55 -            domctl->u.irq_mapping.intx);
   72.56 -        ret = 0;
   72.57 -        put_domain(d);
   72.58 +        bind = &(domctl->u.bind_pt_irq);
   72.59 +        
   72.60 +        ret = pt_irq_create_bind(bind);
   72.61 +        if (ret < 0) {
   72.62 +            printk("Error: pt_irq_create_bind failed!\n");
   72.63 +        }
   72.64 +
   72.65 +        rcu_unlock_domain(d);
   72.66 +        
   72.67      }
   72.68 -    break;
   72.69 +    break;    
   72.70  
   72.71      case XEN_DOMCTL_memory_mapping:
   72.72      {
   72.73 @@ -510,25 +495,36 @@ long arch_do_domctl(
   72.74          ret = -EINVAL;
   72.75          if ( (mfn + nr_mfns - 1) < mfn ) /* wrap? */
   72.76              break;
   72.77 +            
   72.78          ret = -ESRCH;
   72.79 -        if ( unlikely((d = get_domain_by_id(domctl->domain)) == NULL) ) {
   72.80 -            gdprintk(XENLOG_ERR,
   72.81 -                "XEN_DOMCTL_memory_mapping: get_domain_by_id() failed\n"); 
   72.82 +        if ( unlikely((d = rcu_lock_domain_by_id(domctl->domain)) == NULL) )
   72.83              break;
   72.84 +
   72.85 +        ret=0;        
   72.86 +        if ( domctl->u.memory_mapping.add_mapping ) 
   72.87 +        {
   72.88 +            gdprintk(XENLOG_INFO,
   72.89 +                "memory_map:add: gfn=%lx mfn=%lx nr_mfns=%lx\n",
   72.90 +                gfn, mfn, nr_mfns);   
   72.91 +            
   72.92 +            ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
   72.93 +            
   72.94 +            for ( i = 0; i < nr_mfns; i++ )      
   72.95 +                set_mmio_p2m_entry(d, gfn+i, _mfn(mfn+i)); 
   72.96          }
   72.97 -        if ( !is_hvm_domain(d) )
   72.98 -            goto memory_mapping_out;
   72.99 -        if ( !iomem_access_permitted(d, mfn, mfn + nr_mfns - 1) )
  72.100 -            goto memory_mapping_out;
  72.101 -        gdprintk(XENLOG_INFO,
  72.102 -            "DOMCTL_memory_map:add: gfn= %lx mfn= %lx nr_mfns = %lx\n",
  72.103 -            gfn, mfn, nr_mfns);
  72.104 -        for ( i = 0; i < nr_mfns ; i++ )
  72.105 -            set_p2m_entry(d, gfn+i, _mfn(mfn+i),
  72.106 -                __PAGE_HYPERVISOR|_PAGE_USER|_PAGE_PCD|_PAGE_PWT);
  72.107 -        ret = iomem_permit_access(d, gfn, gfn + nr_mfns - 1);
  72.108 -memory_mapping_out:
  72.109 -        put_domain(d);
  72.110 +        else 
  72.111 +        {
  72.112 +            gdprintk(XENLOG_INFO,
  72.113 +                "memory_map:remove: gfn=%lx mfn=%lx nr_mfns=%lx\n",
  72.114 +                 gfn, mfn, nr_mfns);
  72.115 +            
  72.116 +            for ( i = 0; i < nr_mfns; i++ )
  72.117 +                clear_mmio_p2m_entry(d, gfn+i); 
  72.118 +
  72.119 +            ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
  72.120 +        }
  72.121 +
  72.122 +        rcu_unlock_domain(d);
  72.123      }
  72.124      break;
  72.125  
  72.126 @@ -536,7 +532,7 @@ memory_mapping_out:
  72.127      {
  72.128  #define MAX_IOPORTS    0x10000
  72.129          struct domain *d;
  72.130 -        struct hvm_iommu *hd;
  72.131 +        struct hvm_domain *hd;
  72.132          unsigned int fgp = domctl->u.ioport_mapping.first_gport;
  72.133          unsigned int fmp = domctl->u.ioport_mapping.first_mport;
  72.134          unsigned int np = domctl->u.ioport_mapping.nr_ports;
  72.135 @@ -544,40 +540,61 @@ memory_mapping_out:
  72.136          int found = 0;
  72.137  
  72.138          ret = -EINVAL;
  72.139 -        if ((fgp > MAX_IOPORTS) || (fmp > MAX_IOPORTS) ||
  72.140 -            ((fgp + np) > MAX_IOPORTS) || ((fmp + np) > MAX_IOPORTS))
  72.141 +        if ( (np == 0) || (fgp > MAX_IOPORTS) || (fmp > MAX_IOPORTS) ||
  72.142 +            ((fgp + np) > MAX_IOPORTS) || ((fmp + np) > MAX_IOPORTS) )
  72.143          {
  72.144              gdprintk(XENLOG_ERR,
  72.145 -                "XEN_DOMCTL_ioport_map:invalid:gport=%x mport=%x nr_ports=%x\n",
  72.146 +                "ioport_map:invalid:gport=%x mport=%x nr_ports=%x\n",
  72.147                  fgp, fmp, np);
  72.148              break;
  72.149          }
  72.150 -        if ( np == 0 )
  72.151 -            ret = 0;
  72.152 -        ret = -ESRCH;
  72.153  
  72.154 -        if ( unlikely((d = get_domain_by_id(domctl->domain)) == NULL) ) {
  72.155 -            gdprintk(XENLOG_ERR,
  72.156 -                "XEN_DOMCTL_ioport_mapping: get_domain_by_id() failed\n"); 
  72.157 +        ret = -ESRCH;
  72.158 +        if ( unlikely((d = rcu_lock_domain_by_id(domctl->domain)) == NULL) )
  72.159              break;
  72.160 -        }
  72.161 -        hd = domain_hvm_iommu(d);
  72.162 -        list_for_each_entry(g2m_ioport, &hd->g2m_ioport_list, list)
  72.163 -            if (g2m_ioport->gport == fgp ) {
  72.164 +
  72.165 +        hd = &d->arch.hvm_domain;
  72.166 +        if ( domctl->u.ioport_mapping.add_mapping )
  72.167 +        {
  72.168 +            gdprintk(XENLOG_INFO,
  72.169 +                "ioport_map:add f_gport=%x f_mport=%x np=%x\n",
  72.170 +                fgp, fmp, np);
  72.171 +                
  72.172 +            list_for_each_entry(g2m_ioport, &hd->g2m_ioport_list, list)
  72.173 +                if (g2m_ioport->mport == fmp ) {
  72.174 +                    g2m_ioport->gport = fgp;
  72.175 +                    g2m_ioport->np = np;                    
  72.176 +                    found = 1;
  72.177 +                    break;
  72.178 +                }
  72.179 +                
  72.180 +            if ( !found ) 
  72.181 +            {                 
  72.182 +                g2m_ioport = xmalloc(struct g2m_ioport);
  72.183 +                g2m_ioport->gport = fgp;
  72.184                  g2m_ioport->mport = fmp;
  72.185 -                found = 1;
  72.186 -                break;
  72.187 +                g2m_ioport->np = np;
  72.188 +                list_add_tail(&g2m_ioport->list, &hd->g2m_ioport_list);
  72.189 +            } 
  72.190 +
  72.191 +            ret = ioports_permit_access(d, fmp, fmp + np - 1);
  72.192 +            
  72.193          }
  72.194 -        if ( !found ) {
  72.195 -            g2m_ioport = xmalloc(struct g2m_ioport);
  72.196 -            g2m_ioport->gport = fgp;
  72.197 -            g2m_ioport->mport = fmp;
  72.198 -            list_add_tail(&g2m_ioport->list, &hd->g2m_ioport_list);
  72.199 +        else {
  72.200 +            gdprintk(XENLOG_INFO,
  72.201 +                "ioport_map:remove f_gport=%x f_mport=%x np=%x\n",
  72.202 +                fgp, fmp, np);
  72.203 +                
  72.204 +            list_for_each_entry(g2m_ioport, &hd->g2m_ioport_list, list)
  72.205 +                if ( g2m_ioport->mport == fmp ) {
  72.206 +                    list_del(&g2m_ioport->list);
  72.207 +                    break;
  72.208 +                }
  72.209 +            ret = ioports_deny_access(d, fmp, fmp + np - 1);
  72.210          }
  72.211 -        ret = ioports_permit_access(d, fgp, fgp + np - 1);
  72.212 -        put_domain(d);
  72.213 +        rcu_unlock_domain(d);
  72.214      }
  72.215 -    break;
  72.216 +    break;    
  72.217  
  72.218      default:
  72.219          ret = -ENOSYS;
    73.1 --- a/xen/arch/x86/e820.c	Tue Jul 31 12:36:34 2007 -0700
    73.2 +++ b/xen/arch/x86/e820.c	Mon Aug 13 17:49:00 2007 -0400
    73.3 @@ -32,7 +32,7 @@ static void __init add_memory_region(uns
    73.4      }
    73.5  } /* add_memory_region */
    73.6  
    73.7 -static void __init print_e820_memory_map(struct e820entry *map, int entries)
    73.8 +void __init print_e820_memory_map(struct e820entry *map, int entries)
    73.9  {
   73.10      int i;
   73.11  
   73.12 @@ -52,6 +52,9 @@ static void __init print_e820_memory_map
   73.13          case E820_NVS:
   73.14              printk("(ACPI NVS)\n");
   73.15              break;
   73.16 +        case E820_1TO1:
   73.17 +            printk("(1:1)\n");
   73.18 +            break;
   73.19          default:	printk("type %u\n", map[i].type);
   73.20              break;
   73.21          }
    74.1 --- a/xen/arch/x86/hvm/Makefile	Tue Jul 31 12:36:34 2007 -0700
    74.2 +++ b/xen/arch/x86/hvm/Makefile	Mon Aug 13 17:49:00 2007 -0400
    74.3 @@ -16,3 +16,4 @@ obj-y += vioapic.o
    74.4  obj-y += vlapic.o
    74.5  obj-y += vpic.o
    74.6  obj-y += save.o
    74.7 +obj-y += nativedom_access.o 
    75.1 --- a/xen/arch/x86/hvm/hvm.c	Tue Jul 31 12:36:34 2007 -0700
    75.2 +++ b/xen/arch/x86/hvm/hvm.c	Mon Aug 13 17:49:00 2007 -0400
    75.3 @@ -45,10 +45,13 @@
    75.4  #include <asm/hvm/vpt.h>
    75.5  #include <asm/hvm/support.h>
    75.6  #include <public/sched.h>
    75.7 +#include <public/hvm/e820.h>
    75.8  #include <public/hvm/ioreq.h>
    75.9  #include <public/version.h>
   75.10  #include <public/memory.h>
   75.11  
   75.12 +extern int opt_nativedom;
   75.13 +extern struct e820map e820_nativedom;
   75.14  int hvm_enabled __read_mostly;
   75.15  
   75.16  unsigned int opt_hvm_debug_level __read_mostly;
   75.17 @@ -1108,6 +1111,60 @@ long do_hvm_op(unsigned long op, XEN_GUE
   75.18              guest_handle_cast(arg, xen_hvm_set_pci_link_route_t));
   75.19          break;
   75.20  
   75.21 +    case HVMOP_is_nativedom_enabled:
   75.22 +        rc = opt_nativedom;
   75.23 +        break;
   75.24 +        
   75.25 +    case HVMOP_copy_nativedom_e820_map:
   75.26 +    {
   75.27 +        struct xen_hvm_copy_nativedom_e820_map a;
   75.28 +        struct domain *d;
   75.29 +        unsigned long mfn;
   75.30 +        void *p;
   75.31 +
   75.32 +        if ( !opt_nativedom ) 
   75.33 +            return -EFAULT;
   75.34 +
   75.35 +        if ( copy_from_guest(&a, arg, 1) )
   75.36 +            return -EFAULT;
   75.37 +            
   75.38 +        if ( IS_PRIV(current->domain) ) 
   75.39 +        {
   75.40 +            d = get_domain_by_id(a.domid);
   75.41 +            if ( NULL == d )
   75.42 +                return -ESRCH;
   75.43 +        } 
   75.44 +        else
   75.45 +            return -EPERM;
   75.46 +
   75.47 +        mfn = gmfn_to_mfn(d, HVM_E820_PAGE >> 12);
   75.48 +        if ( INVALID_MFN == mfn )
   75.49 +        {
   75.50 +            rc = -EINVAL;
   75.51 +            goto copy_nativedom_e820_end;
   75.52 +        }
   75.53 +
   75.54 +        p = map_domain_page_global(mfn);
   75.55 +        if ( NULL == p )
   75.56 +        {
   75.57 +            rc = -ENOMEM;
   75.58 +            goto copy_nativedom_e820_end;
   75.59 +        }
   75.60 +
   75.61 +        /* Copy e820 map */
   75.62 +        gdprintk(XENLOG_INFO, "Writing NativeDom E820...\n");
   75.63 +        *(unsigned char *)(p + HVM_E820_NR_OFFSET) = (unsigned char) e820_nativedom.nr_map;
   75.64 +        memcpy(p + HVM_E820_OFFSET,  (void*)&e820_nativedom.map[0],  
   75.65 +            sizeof(struct e820entry) * e820_nativedom.nr_map);
   75.66 +
   75.67 +        unmap_domain_page_global(p);
   75.68 +        rc = 0;
   75.69 +
   75.70 +copy_nativedom_e820_end:
   75.71 +        rcu_unlock_domain(d);
   75.72 +        break;
   75.73 +    }        
   75.74 +
   75.75      default:
   75.76      {
   75.77          gdprintk(XENLOG_WARNING, "Bad HVM op %ld.\n", op);
    76.1 --- a/xen/arch/x86/hvm/intercept.c	Tue Jul 31 12:36:34 2007 -0700
    76.2 +++ b/xen/arch/x86/hvm/intercept.c	Mon Aug 13 17:49:00 2007 -0400
    76.3 @@ -29,19 +29,21 @@
    76.4  #include <asm/current.h>
    76.5  #include <io_ports.h>
    76.6  #include <xen/event.h>
    76.7 -
    76.8 +#include <asm/pass-through.h>
    76.9  
   76.10  extern struct hvm_mmio_handler hpet_mmio_handler;
   76.11  extern struct hvm_mmio_handler vlapic_mmio_handler;
   76.12  extern struct hvm_mmio_handler vioapic_mmio_handler;
   76.13 +extern struct hvm_mmio_handler nd_access_mmio_handler;
   76.14  
   76.15 -#define HVM_MMIO_HANDLER_NR 3
   76.16 +#define HVM_MMIO_HANDLER_NR 4
   76.17  
   76.18  static struct hvm_mmio_handler *hvm_mmio_handlers[HVM_MMIO_HANDLER_NR] =
   76.19  {
   76.20      &hpet_mmio_handler,
   76.21      &vlapic_mmio_handler,
   76.22 -    &vioapic_mmio_handler
   76.23 +    &vioapic_mmio_handler,
   76.24 +    &nd_access_mmio_handler
   76.25  };
   76.26  
   76.27  struct hvm_buffered_io_range {
   76.28 @@ -243,7 +245,7 @@ int hvm_io_intercept(ioreq_t *p, int typ
   76.29      int i;
   76.30      unsigned long addr, size;
   76.31  
   76.32 -    if (dpci_ioport_intercept(p, type))
   76.33 +    if ( (type == HVM_PORTIO) && (dpci_ioport_intercept(p)) )
   76.34          return 1;
   76.35  
   76.36      for (i = 0; i < handler->num_slot; i++) {
    77.1 --- a/xen/arch/x86/hvm/io.c	Tue Jul 31 12:36:34 2007 -0700
    77.2 +++ b/xen/arch/x86/hvm/io.c	Mon Aug 13 17:49:00 2007 -0400
    77.3 @@ -40,6 +40,7 @@
    77.4  #include <asm/hvm/vpt.h>
    77.5  #include <asm/hvm/vpic.h>
    77.6  #include <asm/hvm/vlapic.h>
    77.7 +#include <asm/pass-through.h> 
    77.8  
    77.9  #include <public/sched.h>
   77.10  #include <xen/iocap.h>
   77.11 @@ -874,106 +875,131 @@ void hvm_io_assist(void)
   77.12      vcpu_end_shutdown_deferral(v);
   77.13  }
   77.14  
   77.15 -int hvm_do_IRQ_dpci(struct domain *d, unsigned int mirq)
   77.16 +void dpci_ioport_read(uint32_t mport, ioreq_t *p)
   77.17  {
   77.18 -    uint32_t device, intx;
   77.19 -    uint32_t link, isa_irq;
   77.20 -    struct hvm_irq *hvm_irq;
   77.21 +    uint64_t i;
   77.22 +    uint64_t z_data;
   77.23 +    uint64_t length = (p->count * p->size);
   77.24  
   77.25 -    if ((d == dom0) || !dev_assigned(d))
   77.26 -        return 0;
   77.27 -
   77.28 -    if (d->arch.hvm_domain.irq.mirq[mirq].valid)
   77.29 +    for (i=0; i<length; i+=p->size)
   77.30      {
   77.31 -        device = d->arch.hvm_domain.irq.mirq[mirq].device;
   77.32 -        intx = d->arch.hvm_domain.irq.mirq[mirq].intx;
   77.33 -        link = hvm_pci_intx_link(device, intx);
   77.34 -        hvm_irq = &d->arch.hvm_domain.irq;
   77.35 -        isa_irq = hvm_irq->pci_link.route[link];
   77.36 -
   77.37 -        if ( !d->arch.hvm_domain.irq.girq[isa_irq].valid )
   77.38 +        z_data = ~0ULL;
   77.39 +        
   77.40 +        switch (p->size) {
   77.41 +        case BYTE:
   77.42 +            z_data = (uint64_t)inb(mport);
   77.43 +            break;
   77.44 +        case WORD:
   77.45 +            z_data = (uint64_t)inw(mport);
   77.46 +            break;
   77.47 +        case LONG:
   77.48 +            z_data = (uint64_t)inl(mport);
   77.49 +            break;
   77.50 +        default:
   77.51 +            gdprintk(XENLOG_ERR, "Error: unable to handle size: %Lu", p->size);
   77.52 +            goto out;
   77.53 +        }
   77.54 +        
   77.55 +        if ( p->data_is_ptr )
   77.56          {
   77.57 -            d->arch.hvm_domain.irq.girq[isa_irq].valid = 1;
   77.58 -            d->arch.hvm_domain.irq.girq[isa_irq].device = device;
   77.59 -            d->arch.hvm_domain.irq.girq[isa_irq].intx = intx;
   77.60 -            d->arch.hvm_domain.irq.girq[isa_irq].machine_gsi = mirq;
   77.61 -        }
   77.62 +            if ( 0 != hvm_copy_to_guest_phys(p->data + i, (void *)&z_data, (int)p->size) ) 
   77.63 +            {
   77.64 +                gdprintk(XENLOG_ERR, "Error: couldn't copy to hvm phys\n");
   77.65 +                goto out;
   77.66 +            }
   77.67 +        } 
   77.68 +        else
   77.69 +            p->data = z_data;
   77.70  
   77.71 -        if ( !test_and_set_bit(mirq, d->arch.hvm_domain.irq.dirq_mask) )
   77.72 +    }
   77.73 +
   77.74 +out:
   77.75 +    return;    
   77.76 +}
   77.77 +
   77.78 +void dpci_ioport_write(uint32_t mport, ioreq_t *p)
   77.79 +{
   77.80 +    uint64_t i;
   77.81 +    uint64_t z_data = 0;
   77.82 +    uint64_t length = (p->count * p->size);
   77.83 +
   77.84 +    for (i=0; i<length; i+=p->size)
   77.85 +    {
   77.86 +        if ( p->data_is_ptr )
   77.87          {
   77.88 -            vcpu_kick(d->vcpu[0]);
   77.89 -            return 1;
   77.90 +            if (0 != hvm_copy_from_guest_phys((void *)&z_data, p->data + i, (int)p->size))
   77.91 +            {
   77.92 +                gdprintk(XENLOG_ERR, "Error: couldn't copy from hvm phys\n");
   77.93 +                goto out;
   77.94 +            }
   77.95          }
   77.96          else
   77.97 -            dprintk(XENLOG_INFO, "Want to pending mirq, but failed\n");
   77.98 +            z_data = p->data;
   77.99 +
  77.100 +        switch (p->size) {
  77.101 +        case BYTE:
  77.102 +            outb((uint8_t) z_data, mport);
  77.103 +            break;
  77.104 +        case WORD:
  77.105 +            outw((uint16_t) z_data, mport);
  77.106 +            break;
  77.107 +        case LONG:
  77.108 +            outl((uint32_t) z_data, mport);
  77.109 +            break;
  77.110 +        default:
  77.111 +            gdprintk(XENLOG_ERR, "Error: unable to handle size: %Lu\n", p->size);
  77.112 +            goto out;
  77.113 +        }
  77.114      }
  77.115 -    return 0;
  77.116 +
  77.117 +out:
  77.118 +    return;
  77.119  }
  77.120  
  77.121 -void hvm_dpci_eoi(unsigned int guest_gsi)
  77.122 +int dpci_ioport_intercept(ioreq_t *p)
  77.123  {
  77.124      struct domain *d = current->domain;
  77.125 -    uint32_t device, intx, machine_gsi;
  77.126 -    irq_desc_t *desc;
  77.127 -
  77.128 -    if (d->arch.hvm_domain.irq.girq[guest_gsi].valid)
  77.129 -    {
  77.130 -        device = d->arch.hvm_domain.irq.girq[guest_gsi].device;
  77.131 -        intx = d->arch.hvm_domain.irq.girq[guest_gsi].intx;
  77.132 -        machine_gsi = d->arch.hvm_domain.irq.girq[guest_gsi].machine_gsi;
  77.133 -        gdprintk(XENLOG_INFO, "hvm_dpci_eoi:: device %x intx %x\n", device, intx);
  77.134 -        hvm_pci_intx_deassert(d, device, intx);
  77.135 -        desc = &irq_desc[irq_to_vector(machine_gsi)];
  77.136 -        desc->handler->end(irq_to_vector(machine_gsi));
  77.137 -    }
  77.138 -}
  77.139 -
  77.140 -int dpci_ioport_intercept(ioreq_t *p, int type)
  77.141 -{
  77.142 -    struct domain *d = current->domain;
  77.143 -    struct hvm_iommu *hd = domain_hvm_iommu(d);
  77.144 +    struct hvm_domain *hd = &d->arch.hvm_domain;
  77.145      struct g2m_ioport *g2m_ioport;
  77.146      unsigned int mport;
  77.147 +    unsigned int found = 0;
  77.148 +    unsigned int gport = p->addr;
  77.149 +    unsigned int s,e = 0;
  77.150      int ret = 0;
  77.151  
  77.152 -    if (!dev_assigned(d))
  77.153 +    list_for_each_entry(g2m_ioport, &hd->g2m_ioport_list, list) {
  77.154 +        s = g2m_ioport->gport;
  77.155 +        e = s + g2m_ioport->np;
  77.156 +        if ( (gport >= s) && (gport < e) )
  77.157 +        {
  77.158 +            found = 1;
  77.159 +            break;
  77.160 +        }
  77.161 +    }
  77.162 +
  77.163 +    if ( !found )
  77.164          return 0;
  77.165  
  77.166 -    if (ioports_access_permitted(d, p->addr, p->addr + p->size - 1)) {
  77.167 -        list_for_each_entry(g2m_ioport, &hd->g2m_ioport_list, list)
  77.168 -            if ( g2m_ioport->gport == p->addr )
  77.169 -                break;
  77.170 -
  77.171 -        gdprintk(XENLOG_INFO, "dpci_ioport_intercept: gport = %x mport = %x\n",
  77.172 -                 g2m_ioport->gport, g2m_ioport->mport);
  77.173 +    mport = (gport - s) + g2m_ioport->mport;
  77.174  
  77.175 -        mport = g2m_ioport->mport;
  77.176 -        if (p->dir == 1) {
  77.177 -            for (int i = 0; i < p->count; i++)
  77.178 -            {
  77.179 -                switch (p->size)
  77.180 -                {
  77.181 -                case 1: p->data = inb(mport); break;
  77.182 -                case 2: p->data = inw(mport); break;
  77.183 -                case 4: p->data = inl(mport); break;
  77.184 -                default: gdprintk(XENLOG_ERR, "invalid IO port read size\n"); 
  77.185 -                }
  77.186 -            }
  77.187 +    if ( ioports_access_permitted(d, mport, mport + p->size - 1) ) 
  77.188 +    {
  77.189 +        switch (p->dir) {
  77.190 +        case IOREQ_READ:
  77.191 +            dpci_ioport_read(mport, p);
  77.192 +            break;
  77.193 +        case IOREQ_WRITE:
  77.194 +            dpci_ioport_write(mport, p);
  77.195 +            break;
  77.196 +        default:
  77.197 +            gdprintk(XENLOG_ERR, "Error: couldn't handle p->dir = %d", p->dir);
  77.198          }
  77.199 -        else {
  77.200 -            for (int i = 0; i < p->count; i++)
  77.201 -            { 
  77.202 -                switch (p->size)
  77.203 -                {
  77.204 -                case 1: outb(mport, p->data); break;
  77.205 -                case 2: outw(mport, p->data); break;
  77.206 -                case 4: outl(mport, p->data); break;
  77.207 -                default: gdprintk(XENLOG_ERR, "invalid io port write size\n"); 
  77.208 -                }
  77.209 -            }
  77.210 -        }
  77.211 +                
  77.212          ret = 1;
  77.213 -    }
  77.214 +    } 
  77.215 +    else
  77.216 +        gdprintk(XENLOG_ERR, "Error: access to gport=0x%x denied!\n", (uint32_t)p->addr);
  77.217 +    
  77.218      return ret;
  77.219  }
  77.220  
  77.221 @@ -981,17 +1007,10 @@ int release_devices(struct vcpu *v)
  77.222  {
  77.223      int ret = 0;
  77.224      struct domain *d = v->domain;
  77.225 -    struct hvm_domain *hd = &d->arch.hvm_domain;
  77.226 -    uint32_t i;
  77.227 -
  77.228 +    
  77.229      if (! dev_assigned(d))
  77.230          return ret;
  77.231  
  77.232 -    /* unbind irq */
  77.233 -    for (i = 0; i < NR_IRQS; i++) {
  77.234 -        if (hd->irq.mirq[i].valid)
  77.235 -            ret = pirq_guest_unbind(d, i);
  77.236 -    }
  77.237      if (iommu_found())
  77.238          iommu_domain_teardown(d);
  77.239      else {
    78.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.2 +++ b/xen/arch/x86/hvm/nativedom_access.c	Mon Aug 13 17:49:00 2007 -0400
    78.3 @@ -0,0 +1,45 @@
    78.4 +/* Copyright (c) 2007, Neocleus, Guy Zana (guy@neocleus.com) */
    78.5 +#include <xen/mm_early.h>
    78.6 +#include <xen/sched.h>
    78.7 +#include <xen/types.h>
    78.8 +#include <xen/config.h>
    78.9 +#include <asm/hvm/io.h>
   78.10 +#include <asm/current.h>
   78.11 +
   78.12 +extern nd_areas_t nd_areas;
   78.13 +
   78.14 +static unsigned long nd_access_read(struct vcpu *v, unsigned long addr, unsigned long length)
   78.15 +{
   78.16 +    gdprintk(XENLOG_WARNING, "NativeDom: read access to protected region (addr:%08lx)\n", addr);
   78.17 +    return ~0UL;
   78.18 +}
   78.19 +
   78.20 +static void nd_access_write(struct vcpu *v, unsigned long addr, unsigned long length, unsigned long val)
   78.21 +{
   78.22 +    gdprintk(XENLOG_WARNING, "NativeDom: write access to protected region (addr:%08lx)\n", addr);
   78.23 +}
   78.24 +
   78.25 +static int nd_access_range(struct vcpu *v, unsigned long addr)
   78.26 +{
   78.27 +    unsigned long i;
   78.28 +
   78.29 +    if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_IS_NATIVEDOM] )
   78.30 +        return 0;
   78.31 +
   78.32 +    /* check for protected pseudo pfns */
   78.33 +    for ( i=0; i < nd_areas.protected.nr; i++ ) 
   78.34 +    {
   78.35 +        if ( (addr >= nd_areas.protected.areas[i].addr) && 
   78.36 +             (addr < nd_areas.protected.areas[i].addr + nd_areas.protected.areas[i].size))
   78.37 +            return 1;
   78.38 +    }	
   78.39 +
   78.40 +    return 0;
   78.41 +}
   78.42 +
   78.43 +struct hvm_mmio_handler nd_access_mmio_handler = {
   78.44 +    .check_handler = nd_access_range,
   78.45 +    .read_handler  = nd_access_read,
   78.46 +    .write_handler = nd_access_write
   78.47 +};
   78.48 +
    79.1 --- a/xen/arch/x86/hvm/vioapic.c	Tue Jul 31 12:36:34 2007 -0700
    79.2 +++ b/xen/arch/x86/hvm/vioapic.c	Mon Aug 13 17:49:00 2007 -0400
    79.3 @@ -462,13 +462,6 @@ void vioapic_update_EOI(struct domain *d
    79.4      ent = &vioapic->redirtbl[gsi];
    79.5  
    79.6      ent->fields.remote_irr = 0;
    79.7 -
    79.8 -    if (dev_assigned(d)) {
    79.9 -        spin_unlock(&d->arch.hvm_domain.irq_lock);
   79.10 -        hvm_dpci_eoi(gsi);
   79.11 -        return;
   79.12 -    }
   79.13 -
   79.14      if ( (ent->fields.trig_mode == VIOAPIC_LEVEL_TRIG) &&
   79.15           !ent->fields.mask &&
   79.16           hvm_irq->gsi_assert_count[gsi] )
    80.1 --- a/xen/arch/x86/hvm/vmx/intr.c	Tue Jul 31 12:36:34 2007 -0700
    80.2 +++ b/xen/arch/x86/hvm/vmx/intr.c	Mon Aug 13 17:49:00 2007 -0400
    80.3 @@ -24,6 +24,7 @@
    80.4  #include <xen/errno.h>
    80.5  #include <xen/trace.h>
    80.6  #include <xen/event.h>
    80.7 +#include <xen/pt_irq.h>
    80.8  #include <asm/current.h>
    80.9  #include <asm/cpufeature.h>
   80.10  #include <asm/processor.h>
   80.11 @@ -126,27 +127,6 @@ static void update_tpr_threshold(struct 
   80.12      __vmwrite(TPR_THRESHOLD, (max_irr > tpr) ? (tpr >> 4) : (max_irr >> 4));
   80.13  }
   80.14  
   80.15 -static void vmx_dirq_assist(struct domain *d)
   80.16 -{
   80.17 -    unsigned int irq;
   80.18 -    uint32_t device;
   80.19 -    uint32_t intx;
   80.20 -    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
   80.21 -
   80.22 -    for (irq = find_first_bit(hvm_irq->dirq_mask, NR_IRQS);
   80.23 -         irq < NR_IRQS;
   80.24 -         irq = find_next_bit(hvm_irq->dirq_mask, NR_IRQS, irq + 1))
   80.25 -    {
   80.26 -        test_and_clear_bit(irq, &hvm_irq->dirq_mask);
   80.27 -
   80.28 -        device = hvm_irq->mirq[irq].device;
   80.29 -        intx = hvm_irq->mirq[irq].intx;
   80.30 -        gdprintk(XENLOG_INFO VTDPREFIX, "hvm_do_IRQ_dpci:injecting intr: device %x intx %x, irq= %x\n",
   80.31 -                 device, intx, irq);
   80.32 -        hvm_pci_intx_assert(d, device, intx);
   80.33 -    }
   80.34 -}
   80.35 -
   80.36  asmlinkage void vmx_intr_assist(void)
   80.37  {
   80.38      int intr_vector;
   80.39 @@ -155,10 +135,10 @@ asmlinkage void vmx_intr_assist(void)
   80.40      unsigned int idtv_info_field;
   80.41      unsigned long inst_len;
   80.42  
   80.43 -    pt_update_irq(v);
   80.44 +    /* Pass-through interrupts handling */
   80.45 +    pt_intr_assist(v->domain);
   80.46  
   80.47 -    if ( v->vcpu_id == 0 )
   80.48 -        vmx_dirq_assist(v->domain);
   80.49 +    pt_update_irq(v);
   80.50  
   80.51      hvm_set_callback_irq_level();
   80.52  
    81.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Tue Jul 31 12:36:34 2007 -0700
    81.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Mon Aug 13 17:49:00 2007 -0400
    81.3 @@ -27,7 +27,6 @@
    81.4  #include <xen/domain_page.h>
    81.5  #include <xen/hypercall.h>
    81.6  #include <xen/perfc.h>
    81.7 -#include <xen/iocap.h>
    81.8  #include <asm/current.h>
    81.9  #include <asm/io.h>
   81.10  #include <asm/regs.h>
   81.11 @@ -100,7 +99,9 @@ static int vmx_vcpu_initialise(struct vc
   81.12  static void vmx_vcpu_destroy(struct vcpu *v)
   81.13  {
   81.14      vmx_destroy_vmcs(v);
   81.15 +#if 0
   81.16      release_devices(v);
   81.17 +#endif
   81.18  }
   81.19  
   81.20  static int vmx_paging_enabled(struct vcpu *v)
    82.1 --- a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c	Tue Jul 31 12:36:34 2007 -0700
    82.2 +++ b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c	Mon Aug 13 17:49:00 2007 -0400
    82.3 @@ -37,6 +37,7 @@
    82.4  extern void print_iommu_regs(struct acpi_drhd_unit *drhd);
    82.5  extern void print_vtd_entries(struct domain *d, int bus, int devfn,
    82.6                         unsigned long gmfn);
    82.7 +extern void (*interrupt[])(void);
    82.8  
    82.9  #define DMAR_OPERATION_TIMEOUT (HZ*60) /* 1m */
   82.10  
   82.11 @@ -931,7 +932,6 @@ int iommu_domain_init(struct domain *dom
   82.12      spin_lock_init(&hd->mapping_lock);
   82.13      spin_lock_init(&hd->iommu_list_lock);
   82.14      INIT_LIST_HEAD(&hd->pdev_list);
   82.15 -    INIT_LIST_HEAD(&hd->g2m_ioport_list);
   82.16  
   82.17      for_each_drhd_unit(drhd) {
   82.18          if (drhd->iommu)
   82.19 @@ -1679,7 +1679,6 @@ int iommu_setup(void)
   82.20          return 0;
   82.21  
   82.22      INIT_LIST_HEAD(&hd->pdev_list);
   82.23 -    INIT_LIST_HEAD(&hd->g2m_ioport_list);
   82.24  
   82.25      /* start from scratch */
   82.26      flush_all();
    83.1 --- a/xen/arch/x86/hvm/vpic.c	Tue Jul 31 12:36:34 2007 -0700
    83.2 +++ b/xen/arch/x86/hvm/vpic.c	Mon Aug 13 17:49:00 2007 -0400
    83.3 @@ -177,9 +177,8 @@ static int