qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] Re: pci_default_config_write() clean up.


From: Isaku Yamahata
Subject: [Qemu-devel] Re: pci_default_config_write() clean up.
Date: Thu, 7 May 2009 18:06:39 +0900
User-agent: Mutt/1.5.6i

On Thu, May 07, 2009 at 11:50:10AM +0300, Michael S. Tsirkin wrote:
> Hmm, this adds more code that it removes.
> Did you take a look at my attempt at the rewrite of the same function?

Yes, so I added you on Cc.
The most of code is trivial tables,
so I don't think it complicates the logic.
If we want more precise emulation, your pci_init_mask()
will bigger anyway.

With callback, codes which define its own config write
functions can be rewritten into table driven code, I suppose.

thanks,

> This had this diffstat:
> 
>  hw/pci.c |  146
> ++++++++++++++------------------------------------------------
>  hw/pci.h |   16 +++++++
>  2 files changed, 49 insertions(+), 113 deletions(-)
> 
> Better, no?
> 
> On Thu, May 07, 2009 at 05:40:19PM +0900, Isaku Yamahata wrote:
> > 
> > >From 9b87d45e497785cb615eef8a96debea805276392 Mon Sep 17 00:00:00 2001
> > From: Isaku Yamahata <address@hidden>
> > Date: Thu, 7 May 2009 16:14:04 +0900
> > Subject: [PATCH] pci: pci_default_config_write() clean up.
> > 
> > clean up of pci_default_config_write() by table driven code.
> > 
> > Cc: Michael S. Tsirkin <address@hidden>
> > Signed-off-by: Isaku Yamahata <address@hidden>
> > ---
> >  hw/cirrus_vga.c |    2 +-
> >  hw/pci.c        |  403 
> > ++++++++++++++++++++++++++++++++++++++-----------------
> >  hw/pci.h        |   98 +++++++++++++-
> >  3 files changed, 377 insertions(+), 126 deletions(-)
> > 
> > diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
> > index e4728a4..3c68884 100644
> > --- a/hw/cirrus_vga.c
> > +++ b/hw/cirrus_vga.c
> > @@ -180,7 +180,7 @@
> >  #define PCI_COMMAND_PALETTESNOOPING         0x0020
> >  #define PCI_COMMAND_PARITYDETECTION         0x0040
> >  #define PCI_COMMAND_ADDRESSDATASTEPPING     0x0080
> > -#define PCI_COMMAND_SERR                    0x0100
> > +//#define PCI_COMMAND_SERR                    0x0100       /* duplicated */
> >  #define PCI_COMMAND_BACKTOBACKTRANS         0x0200
> >  // PCI 0x08, 0xff000000 (0x09-0x0b:class,0x08:rev)
> >  #define PCI_CLASS_BASE_DISPLAY        0x03
> > diff --git a/hw/pci.c b/hw/pci.c
> > index ee7d403..3406e46 100644
> > --- a/hw/pci.c
> > +++ b/hw/pci.c
> > @@ -21,6 +21,9 @@
> >   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
> > IN
> >   * THE SOFTWARE.
> >   */
> > +
> > +#include <assert.h>
> > +
> >  #include "hw.h"
> >  #include "pci.h"
> >  #include "monitor.h"
> > @@ -236,6 +239,89 @@ int pci_assign_devaddr(const char *addr, int *domp, 
> > int *busp, unsigned *slotp)
> >      return pci_parse_devaddr(devaddr, domp, busp, slotp);
> >  }
> >  
> > +static const struct PCIConfigReg
> > +pci_default_config_regs_type_00[PCI_CONFIG_SPACE_SIZE] =
> > +{
> > +    /* Vendor ID, Device ID: read only */
> > +    [PCI_COMMAND] = {
> > +        .wmask =
> > +        (PCI_COMMAND_IO |
> > +         PCI_COMMAND_MEMORY |
> > +         PCI_COMMAND_MASTER |
> > +         PCI_COMMAND_SPECIAL |
> > +         PCI_COMMAND_INVALIDATE |
> > +         PCI_COMMAND_VGA_PALETTE |
> > +         PCI_COMMAND_PARITY |
> > +         PCI_COMMAND_WAIT),
> > +        .changed = pci_update_mappings,
> > +    },
> > +    [PCI_COMMAND + 1] = {
> > +        .wmask =
> > +        (PCI_COMMAND_SERR |
> > +         PCI_COMMAND_FAST_BACK |
> > +         PCI_COMMAND_INTX_DISABLE) >> 8,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_STATUS ... (PCI_STATUS + 1)] = {
> > +        /* nothing is emulated at this moment */
> > +        .wmask = 0,
> > +        .changed = NULL,
> > +    },
> > +    /* revision id, class code: read only */
> > +    [PCI_CACHE_LINE_SIZE] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_LATENCY_TIMER] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +    /* header type: read only */
> > +    [PCI_BIST] = {
> > +        .wmask = 0,     /* BIST emulation isn't implemented */
> > +        .changed = NULL,
> > +    },
> > +    [PCI_BASE_ADDRESS_0 ... (PCI_BASE_ADDRESS_5 + 3)] = {
> > +        .wmask = 0,     /* this will be updated by 
> > pci_register_io_region() */
> > +        .changed = pci_update_mappings,
> > +    },
> > +    [PCI_CARDBUS_CIS ... (PCI_CARDBUS_CIS + 3)] = {
> > +        .wmask = 0,     /* not card bus */
> > +        .changed = NULL,
> > +    },
> > +    [PCI_ROM_ADDRESS ... (PCI_ROM_ADDRESS + 3)] = {
> > +        .wmask = 0,     /* this will be updated by 
> > pci_register_io_region() */
> > +        .changed = pci_update_mappings,
> > +    },
> > +    [PCI_CAPABILITY_LIST] = {
> > +        .wmask = 0,
> > +        .changed = NULL,
> > +    },
> > +    /* offset 0x35 ... 0x3d are reserved so is read only */
> > +    [PCI_INTERRUPT_LINE] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_INTERRUPT_PIN] = {
> > +        .wmask = 0,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_MIN_GNT] = {
> > +        .wmask = 0,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_MAX_LAT] = {
> > +        .wmask = 0,
> > +        .changed = NULL,
> > +    },
> > +
> > +    /* device dependent part */
> > +    [PCI_CONFIG_HEADER_SIZE ... (PCI_CONFIG_SPACE_SIZE - 1)] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +};
> > +
> >  /* -1 for devfn means auto assign */
> >  PCIDevice *pci_register_device(PCIBus *bus, const char *name,
> >                                 int instance_size, int devfn,
> > @@ -261,6 +347,8 @@ PCIDevice *pci_register_device(PCIBus *bus, const char 
> > *name,
> >      pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
> >      memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state));
> >      pci_set_default_subsystem_id(pci_dev);
> > +    memcpy(pci_dev->config_regs, pci_default_config_regs_type_00,
> > +           sizeof(pci_dev->config_regs));
> >  
> >      if (!config_read)
> >          config_read = pci_default_read_config;
> > @@ -322,6 +410,7 @@ void pci_register_io_region(PCIDevice *pci_dev, int 
> > region_num,
> >  {
> >      PCIIORegion *r;
> >      uint32_t addr;
> > +    uint32_t mask;
> >  
> >      if ((unsigned int)region_num >= PCI_NUM_REGIONS)
> >          return;
> > @@ -337,12 +426,20 @@ void pci_register_io_region(PCIDevice *pci_dev, int 
> > region_num,
> >      r->size = size;
> >      r->type = type;
> >      r->map_func = map_func;
> > +    mask = ~(size - 1);
> >      if (region_num == PCI_ROM_SLOT) {
> >          addr = 0x30;
> > +        /* ROM enable bit is writeable */
> > +        mask |= PCI_ROM_ADDRESS_ENABLE;
> >      } else {
> >          addr = 0x10 + region_num * 4;
> >      }
> >      *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
> > +
> > +    pci_dev->config_regs[addr    ].wmask =  mask        && 0xff;
> > +    pci_dev->config_regs[addr + 1].wmask = (mask >>  8) && 0xff;
> > +    pci_dev->config_regs[addr + 2].wmask = (mask >> 16) && 0xff;
> > +    pci_dev->config_regs[addr + 3].wmask = (mask >> 24) && 0xff;
> >  }
> >  
> >  static void pci_update_mappings(PCIDevice *d)
> > @@ -452,117 +549,33 @@ uint32_t pci_default_read_config(PCIDevice *d,
> >  }
> >  
> >  void pci_default_write_config(PCIDevice *d,
> > -                              uint32_t address, uint32_t val, int len)
> > +                              uint32_t addr, uint32_t val, int len)
> >  {
> > -    int can_write, i;
> > -    uint32_t end, addr;
> > -
> > -    if (len == 4 && ((address >= 0x10 && address < 0x10 + 4 * 6) ||
> > -                     (address >= 0x30 && address < 0x34))) {
> > -        PCIIORegion *r;
> > -        int reg;
> > -
> > -        if ( address >= 0x30 ) {
> > -            reg = PCI_ROM_SLOT;
> > -        }else{
> > -            reg = (address - 0x10) >> 2;
> > -        }
> > -        r = &d->io_regions[reg];
> > -        if (r->size == 0)
> > -            goto default_config;
> > -        /* compute the stored value */
> > -        if (reg == PCI_ROM_SLOT) {
> > -            /* keep ROM enable bit */
> > -            val &= (~(r->size - 1)) | 1;
> > -        } else {
> > -            val &= ~(r->size - 1);
> > -            val |= r->type;
> > -        }
> > -        *(uint32_t *)(d->config + address) = cpu_to_le32(val);
> > -        pci_update_mappings(d);
> > -        return;
> > -    }
> > - default_config:
> > -    /* not efficient, but simple */
> > -    addr = address;
> > -    for(i = 0; i < len; i++) {
> > -        /* default read/write accesses */
> > -        switch(d->config[0x0e]) {
> > -        case 0x00:
> > -        case 0x80:
> > -            switch(addr) {
> > -            case 0x00:
> > -            case 0x01:
> > -            case 0x02:
> > -            case 0x03:
> > -            case 0x06:
> > -            case 0x07:
> > -            case 0x08:
> > -            case 0x09:
> > -            case 0x0a:
> > -            case 0x0b:
> > -            case 0x0e:
> > -            case 0x10 ... 0x27: /* base */
> > -            case 0x2c ... 0x2f: /* read-only subsystem ID & vendor ID */
> > -            case 0x30 ... 0x33: /* rom */
> > -            case 0x3d:
> > -                can_write = 0;
> > -                break;
> > -            default:
> > -                can_write = 1;
> > -                break;
> > -            }
> > -            break;
> > -        default:
> > -        case 0x01:
> > -            switch(addr) {
> > -            case 0x00:
> > -            case 0x01:
> > -            case 0x02:
> > -            case 0x03:
> > -            case 0x06:
> > -            case 0x07:
> > -            case 0x08:
> > -            case 0x09:
> > -            case 0x0a:
> > -            case 0x0b:
> > -            case 0x0e:
> > -            case 0x2c ... 0x2f: /* read-only subsystem ID & vendor ID */
> > -            case 0x38 ... 0x3b: /* rom */
> > -            case 0x3d:
> > -                can_write = 0;
> > -                break;
> > -            default:
> > -                can_write = 1;
> > -                break;
> > -            }
> > -            break;
> > -        }
> > -        if (can_write) {
> > -            /* Mask out writes to reserved bits in registers */
> > -            switch (addr) {
> > -       case 0x05:
> > -                val &= ~PCI_COMMAND_RESERVED_MASK_HI;
> > -                break;
> > -            case 0x06:
> > -                val &= ~PCI_STATUS_RESERVED_MASK_LO;
> > -                break;
> > -            case 0x07:
> > -                val &= ~PCI_STATUS_RESERVED_MASK_HI;
> > -                break;
> > +    int i;
> > +    pci_config_changed_t callback[4] = {NULL, NULL, NULL, NULL};
> > +    int changed = 0;
> > +
> > +    assert(len == 1 || len == 2 || len == 4);
> > +    for (i = 0; i < len; val >>= 8, ++i) {
> > +        uint8_t mask = d->config_regs[addr].wmask;
> > +        uint8_t old_val = d->config[addr];
> > +        uint8_t new_val = (old_val & ~mask) | (val & mask);
> > +
> > +        d->config[addr] = new_val;
> > +        if (old_val != new_val && d->config_regs[addr].changed != NULL) {
> > +            if (changed == 0 ||
> > +                callback[changed] != d->config_regs[addr].changed) {
> > +                callback[changed] = d->config_regs[addr].changed;
> > +                changed++;
> >              }
> > -            d->config[addr] = val;
> >          }
> > -        if (++addr > 0xff)
> > -           break;
> > -        val >>= 8;
> > -    }
> >  
> > -    end = address + len;
> > -    if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) {
> > -        /* if the command register is modified, we must modify the 
> > mappings */
> > -        pci_update_mappings(d);
> > +        if (++addr >= PCI_CONFIG_SPACE_SIZE)
> > +             break;
> >      }
> > +
> > +    for (i = 0; i < changed; i++)
> > +        (callback[i])(d);
> >  }
> >  
> >  void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
> > @@ -829,23 +842,6 @@ typedef struct {
> >      PCIBus *bus;
> >  } PCIBridge;
> >  
> > -static void pci_bridge_write_config(PCIDevice *d,
> > -                             uint32_t address, uint32_t val, int len)
> > -{
> > -    PCIBridge *s = (PCIBridge *)d;
> > -
> > -    if (address == 0x19 || (address == 0x18 && len > 1)) {
> > -        if (address == 0x19)
> > -            s->bus->bus_num = val & 0xff;
> > -        else
> > -            s->bus->bus_num = (val >> 8) & 0xff;
> > -#if defined(DEBUG_PCI)
> > -        printf ("pci-bridge: %s: Assigned bus %d\n", d->name, 
> > s->bus->bus_num);
> > -#endif
> > -    }
> > -    pci_default_write_config(d, address, val, len);
> > -}
> > -
> >  PCIBus *pci_find_bus(int bus_num)
> >  {
> >      PCIBus *bus = first_bus;
> > @@ -866,15 +862,174 @@ PCIDevice *pci_find_device(int bus_num, int slot, 
> > int function)
> >      return bus->devices[PCI_DEVFN(slot, function)];
> >  }
> >  
> > +static void pci_conf_secondary_bus_changed(PCIDevice *d)
> > +{
> > +    PCIBridge *s = (PCIBridge*) d;
> > +    s->bus->bus_num = s->dev.config[PCI_SECONDARY_BUS];
> > +}
> > +
> > +static const struct PCIConfigReg
> > +pci_default_config_regs_type_01[PCI_CONFIG_SPACE_SIZE] =
> > +{
> > +    /* Vendor ID, Device ID: read only */
> > +    [PCI_COMMAND] = {
> > +        .wmask =
> > +        (PCI_COMMAND_IO |
> > +         PCI_COMMAND_MEMORY |
> > +         PCI_COMMAND_MASTER |
> > +         PCI_COMMAND_SPECIAL |
> > +         PCI_COMMAND_INVALIDATE |
> > +         PCI_COMMAND_VGA_PALETTE |
> > +         PCI_COMMAND_PARITY |
> > +         PCI_COMMAND_WAIT),
> > +        .changed = pci_update_mappings,
> > +    },
> > +    [PCI_COMMAND + 1] = {
> > +        .wmask =
> > +        (PCI_COMMAND_SERR |
> > +         PCI_COMMAND_FAST_BACK |
> > +         PCI_COMMAND_INTX_DISABLE) >> 8,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_STATUS ... (PCI_STATUS + 1)] = {
> > +        /* nothing is emulated at this moment */
> > +        .wmask = 0,
> > +        .changed = NULL,
> > +    },
> > +    /* revision id, class code: read only */
> > +    [PCI_CACHE_LINE_SIZE] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_LATENCY_TIMER] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +    /* header type: read only */
> > +    [PCI_BIST] = {
> > +        .wmask = 0,     /* BIST emulation isn't implemented */
> > +        .changed = NULL,
> > +    },
> > +    [PCI_BASE_ADDRESS_0 ... (PCI_BASE_ADDRESS_1 + 3)] = {
> > +        .wmask = 0,     /* this will be updated by 
> > pci_register_io_region() */
> > +        .changed = pci_update_mappings,
> > +    },
> > +    [PCI_PRIMARY_BUS] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_SECONDARY_BUS] = {
> > +        .wmask = 0xff,
> > +        .changed = pci_conf_secondary_bus_changed,
> > +    },
> > +    [PCI_SUBORDINATE_BUS] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_SEC_LATENCY_TIMER] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_IO_BASE] = {
> > +        .wmask = PCI_IO_RANGE_MASK & 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_IO_LIMIT] = {
> > +        .wmask = PCI_IO_RANGE_MASK & 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_SEC_STATUS ... (PCI_SEC_STATUS + 1)] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_MEMORY_BASE] = {
> > +        .wmask = PCI_MEMORY_RANGE_MASK & 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_MEMORY_BASE + 1] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_MEMORY_LIMIT] = {
> > +        .wmask = PCI_MEMORY_RANGE_MASK & 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_MEMORY_LIMIT + 1] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_PREF_MEMORY_BASE] = {
> > +        .wmask = PCI_PREF_RANGE_MASK & 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_PREF_MEMORY_BASE + 1] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_PREF_MEMORY_LIMIT] = {
> > +        .wmask = PCI_PREF_RANGE_MASK & 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_PREF_MEMORY_LIMIT + 1] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_PREF_BASE_UPPER32 ... (PCI_PREF_BASE_UPPER32 + 3)] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_PREF_LIMIT_UPPER32 ... (PCI_PREF_LIMIT_UPPER32 + 3)] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_IO_BASE_UPPER16] = {
> > +        .wmask = 0,     /* only support 64K io port */
> > +        .changed = NULL,
> > +    },
> > +    [PCI_IO_LIMIT_UPPER16] = {
> > +        .wmask = 0,     /* only support 64K io port */
> > +        .changed = NULL,
> > +    },
> > +    [PCI_CAPABILITY_LIST] = {
> > +        .wmask = 0,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_ROM_ADDRESS1 ... (PCI_ROM_ADDRESS1 + 3)] = {
> > +        .wmask = 0,     /* this will be updated by 
> > pci_register_io_region() */
> > +        .changed = pci_update_mappings,
> > +    },
> > +    /* 0x35 - 0x37 reserved */
> > +    [PCI_INTERRUPT_LINE] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_INTERRUPT_PIN] = {
> > +        .wmask = 0,
> > +        .changed = NULL,
> > +    },
> > +    [PCI_BRIDGE_CONTROL] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +
> > +    /* device dependent part */
> > +    [PCI_CONFIG_HEADER_SIZE ... (PCI_CONFIG_SPACE_SIZE - 1)] = {
> > +        .wmask = 0xff,
> > +        .changed = NULL,
> > +    },
> > +};
> > +
> >  PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
> >                          pci_map_irq_fn map_irq, const char *name)
> >  {
> >      PCIBridge *s;
> >      s = (PCIBridge *)pci_register_device(bus, name, sizeof(PCIBridge),
> > -                                         devfn, NULL, 
> > pci_bridge_write_config);
> > +                                         devfn, NULL, NULL);
> >  
> >      pci_config_set_vendor_id(s->dev.config, vid);
> >      pci_config_set_device_id(s->dev.config, did);
> > +    memcpy(s->dev.config_regs, pci_default_config_regs_type_01,
> > +           sizeof(s->dev.config_regs));
> >  
> >      s->dev.config[0x04] = 0x06; // command = bus master, pci mem
> >      s->dev.config[0x05] = 0x00;
> > diff --git a/hw/pci.h b/hw/pci.h
> > index ff858a1..c220a19 100644
> > --- a/hw/pci.h
> > +++ b/hw/pci.h
> > @@ -98,16 +98,52 @@ typedef struct PCIIORegion {
> >  #define PCI_COMMAND                0x04    /* 16 bits */
> >  #define  PCI_COMMAND_IO            0x1     /* Enable response in I/O space 
> > */
> >  #define  PCI_COMMAND_MEMORY        0x2     /* Enable response in Memory 
> > space */
> > +#define  PCI_COMMAND_MASTER        0x4     /* Enable bus master */
> > +#define  PCI_COMMAND_SPECIAL       0x8     /* Enable response to special 
> > cycles */
> > +#define  PCI_COMMAND_INVALIDATE 0x10       /* Use memory write and 
> > invalidate */
> > +#define  PCI_COMMAND_VGA_PALETTE 0x20      /* Enable palette snooping */
> > +#define  PCI_COMMAND_PARITY        0x40    /* Enable parity checking */
> > +#define  PCI_COMMAND_WAIT  0x80    /* Enable address/data stepping */
> > +#define  PCI_COMMAND_SERR  0x100   /* Enable SERR */
> > +#define  PCI_COMMAND_FAST_BACK     0x200   /* Enable back-to-back writes */
> > +#define  PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
> >  #define PCI_STATUS              0x06    /* 16 bits */
> >  #define PCI_REVISION_ID         0x08    /* 8 bits  */
> >  #define PCI_CLASS_DEVICE        0x0a    /* Device class */
> > +#define PCI_CACHE_LINE_SIZE        0x0c    /* 8 bits */
> > +#define PCI_LATENCY_TIMER  0x0d    /* 8 bits */
> >  #define PCI_HEADER_TYPE         0x0e    /* 8 bits */
> >  #define  PCI_HEADER_TYPE_NORMAL            0
> >  #define  PCI_HEADER_TYPE_BRIDGE            1
> >  #define  PCI_HEADER_TYPE_CARDBUS   2
> >  #define  PCI_HEADER_TYPE_MULTI_FUNCTION 0x80
> > +#define PCI_BIST           0x0f    /* 8 bits */
> > +#define  PCI_BIST_CODE_MASK        0x0f    /* Return result */
> > +#define  PCI_BIST_START            0x40    /* 1 to start BIST, 2 secs or 
> > less */
> > +#define  PCI_BIST_CAPABLE  0x80    /* 1 if BIST capable */
> > +#define PCI_BASE_ADDRESS_0 0x10    /* 32 bits */
> > +#define PCI_BASE_ADDRESS_1 0x14    /* 32 bits [htype 0,1 only] */
> > +#define PCI_BASE_ADDRESS_2 0x18    /* 32 bits [htype 0 only] */
> > +#define PCI_BASE_ADDRESS_3 0x1c    /* 32 bits */
> > +#define PCI_BASE_ADDRESS_4 0x20    /* 32 bits */
> > +#define PCI_BASE_ADDRESS_5 0x24    /* 32 bits */
> > +#define  PCI_BASE_ADDRESS_SPACE            0x01    /* 0 = memory, 1 = I/O 
> > */
> > +#define  PCI_BASE_ADDRESS_SPACE_IO 0x01
> > +#define  PCI_BASE_ADDRESS_SPACE_MEMORY     0x00
> > +#define  PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
> > +#define  PCI_BASE_ADDRESS_MEM_TYPE_32      0x00    /* 32 bit address */
> > +#define  PCI_BASE_ADDRESS_MEM_TYPE_1M      0x02    /* Below 1M [obsolete] 
> > */
> > +#define  PCI_BASE_ADDRESS_MEM_TYPE_64      0x04    /* 64 bit address */
> > +#define  PCI_BASE_ADDRESS_MEM_PREFETCH     0x08    /* prefetchable? */
> > +#define  PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
> > +#define  PCI_BASE_ADDRESS_IO_MASK  (~0x03UL)
> > +#define PCI_PRIMARY_BUS            0x18    /* Primary bus number */
> > +#define PCI_SECONDARY_BUS  0x19    /* Secondary bus number */
> > +#define PCI_SEC_STATUS             0x1e    /* Secondary status register, 
> > only bit 14 used */
> > +#define PCI_CARDBUS_CIS         0x28
> >  #define PCI_SUBSYSTEM_VENDOR_ID 0x2c    /* 16 bits */
> >  #define PCI_SUBSYSTEM_ID        0x2e    /* 16 bits */
> > +#define PCI_CAPABILITY_LIST        0x34    /* Offset of first capability 
> > list entry */
> >  #define PCI_INTERRUPT_LINE 0x3c    /* 8 bits */
> >  #define PCI_INTERRUPT_PIN  0x3d    /* 8 bits */
> >  #define PCI_MIN_GNT                0x3e    /* 8 bits */
> > @@ -117,6 +153,10 @@ typedef struct PCIIORegion {
> >  #define PCI_SUBVENDOR_ID        0x2c    /* obsolete, use 
> > PCI_SUBSYSTEM_VENDOR_ID */
> >  #define PCI_SUBDEVICE_ID        0x2e    /* obsolete, use PCI_SUBSYSTEM_ID 
> > */
> >  
> > +#define PCI_ROM_ADDRESS         0x30    /* Bits 31..11 are address, 10..1 
> > reserved */
> > +#define  PCI_ROM_ADDRESS_ENABLE 0x01
> > +#define PCI_ROM_ADDRESS_MASK    (~0x7ffUL)
> > +
> >  /* Bits in the PCI Status Register (PCI 2.3 spec) */
> >  #define PCI_STATUS_RESERVED1       0x007
> >  #define PCI_STATUS_INT_STATUS      0x008
> > @@ -137,9 +177,65 @@ typedef struct PCIIORegion {
> >  
> >  #define PCI_COMMAND_RESERVED_MASK_HI (PCI_COMMAND_RESERVED >> 8)
> >  
> > +/* Header type 1 (PCI-to-PCI bridges) */
> > +#define PCI_PRIMARY_BUS            0x18    /* Primary bus number */
> > +#define PCI_SECONDARY_BUS  0x19    /* Secondary bus number */
> > +#define PCI_SUBORDINATE_BUS        0x1a    /* Highest bus number behind 
> > the bridge */
> > +#define PCI_SEC_LATENCY_TIMER      0x1b    /* Latency timer for secondary 
> > interface */
> > +#define PCI_IO_BASE                0x1c    /* I/O range behind the bridge 
> > */
> > +#define PCI_IO_LIMIT               0x1d
> > +#define  PCI_IO_RANGE_TYPE_MASK    0x0fUL  /* I/O bridging type */
> > +#define  PCI_IO_RANGE_TYPE_16      0x00
> > +#define  PCI_IO_RANGE_TYPE_32      0x01
> > +#define  PCI_IO_RANGE_MASK (~0x0fUL)
> > +#define PCI_SEC_STATUS             0x1e    /* Secondary status register, 
> > only bit 14 used */
> > +#define PCI_MEMORY_BASE            0x20    /* Memory range behind */
> > +#define PCI_MEMORY_LIMIT   0x22
> > +#define  PCI_MEMORY_RANGE_TYPE_MASK 0x0fUL
> > +#define  PCI_MEMORY_RANGE_MASK     (~0x0fUL)
> > +#define PCI_PREF_MEMORY_BASE       0x24    /* Prefetchable memory range 
> > behind */
> > +#define PCI_PREF_MEMORY_LIMIT      0x26
> > +#define  PCI_PREF_RANGE_TYPE_MASK 0x0fUL
> > +#define  PCI_PREF_RANGE_TYPE_32    0x00
> > +#define  PCI_PREF_RANGE_TYPE_64    0x01
> > +#define  PCI_PREF_RANGE_MASK       (~0x0fUL)
> > +#define PCI_PREF_BASE_UPPER32      0x28    /* Upper half of prefetchable 
> > memory range */
> > +#define PCI_PREF_LIMIT_UPPER32     0x2c
> > +#define PCI_IO_BASE_UPPER16        0x30    /* Upper half of I/O addresses 
> > */
> > +#define PCI_IO_LIMIT_UPPER16       0x32
> > +/* 0x34 same as for htype 0 */
> > +/* 0x35-0x3b is reserved */
> > +#define PCI_ROM_ADDRESS1   0x38    /* Same as PCI_ROM_ADDRESS, but for 
> > htype 1 */
> > +/* 0x3c-0x3d are same as for htype 0 */
> > +#define PCI_BRIDGE_CONTROL 0x3e
> > +#define  PCI_BRIDGE_CTL_PARITY     0x01    /* Enable parity detection on 
> > secondary interface */
> > +#define  PCI_BRIDGE_CTL_SERR       0x02    /* The same for SERR forwarding 
> > */
> > +#define  PCI_BRIDGE_CTL_ISA        0x04    /* Enable ISA mode */
> > +#define  PCI_BRIDGE_CTL_VGA        0x08    /* Forward VGA addresses */
> > +#define  PCI_BRIDGE_CTL_MASTER_ABORT       0x20  /* Report master aborts */
> > +#define  PCI_BRIDGE_CTL_BUS_RESET  0x40    /* Secondary bus reset */
> > +#define  PCI_BRIDGE_CTL_FAST_BACK  0x80    /* Fast Back2Back enabled on 
> > secondary interface */
> > +
> > +/* Bits in the PCI Command Register (PCI 2.3 spec) */
> > +#define PCI_COMMAND_RESERVED_BRIDGE        0xf880
> > +
> > +#define PCI_COMMAND_RESERVED_MASK_HI_BRIDGE (PCI_COMMAND_RESERVED >> 8)
> > +
> > +/* Size of the standard PCI config header */
> > +#define PCI_CONFIG_HEADER_SIZE  0x40
> > +/* Size of the standard PCI config space */
> > +#define PCI_CONFIG_SPACE_SIZE   0x100
> > +
> > +typedef void (*pci_config_changed_t)(struct PCIDevice *d);
> > +struct PCIConfigReg {
> > +    uint8_t wmask;
> > +    pci_config_changed_t changed;
> > +};
> > +
> >  struct PCIDevice {
> >      /* PCI config space */
> > -    uint8_t config[256];
> > +    uint8_t config[PCI_CONFIG_SPACE_SIZE];
> > +    struct PCIConfigReg config_regs[PCI_CONFIG_SPACE_SIZE];
> >  
> >      /* the following fields are read only */
> >      PCIBus *bus;
> 

-- 
yamahata




reply via email to

[Prev in Thread] Current Thread [Next in Thread]