Diff for /qemu/hw/pci.c between versions 1.1.1.14 and 1.1.1.15

version 1.1.1.14, 2018/04/24 18:39:57 version 1.1.1.15, 2018/04/24 19:01:56
Line 126  static void pci_change_irq_level(PCIDevi Line 126  static void pci_change_irq_level(PCIDevi
     bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);      bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
 }  }
   
   int pci_bus_get_irq_level(PCIBus *bus, int irq_num)
   {
       assert(irq_num >= 0);
       assert(irq_num < bus->nirq);
       return !!bus->irq_count[irq_num];
   }
   
 /* Update interrupt status bit in config space on interrupt  /* Update interrupt status bit in config space on interrupt
  * state change. */   * state change. */
 static void pci_update_irq_status(PCIDevice *dev)  static void pci_update_irq_status(PCIDevice *dev)
Line 161  void pci_device_reset(PCIDevice *dev) Line 168  void pci_device_reset(PCIDevice *dev)
     dev->irq_state = 0;      dev->irq_state = 0;
     pci_update_irq_status(dev);      pci_update_irq_status(dev);
     pci_device_deassert_intx(dev);      pci_device_deassert_intx(dev);
     /* Clear all writeable bits */      /* Clear all writable bits */
     pci_word_test_and_clear_mask(dev->config + PCI_COMMAND,      pci_word_test_and_clear_mask(dev->config + PCI_COMMAND,
                                  pci_get_word(dev->wmask + PCI_COMMAND) |                                   pci_get_word(dev->wmask + PCI_COMMAND) |
                                  pci_get_word(dev->w1cmask + PCI_COMMAND));                                   pci_get_word(dev->w1cmask + PCI_COMMAND));
Line 256  int pci_find_domain(const PCIBus *bus) Line 263  int pci_find_domain(const PCIBus *bus)
 }  }
   
 void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,  void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
                          const char *name, int devfn_min)                           const char *name, uint8_t devfn_min)
 {  {
     qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);      qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);
     assert(PCI_FUNC(devfn_min) == 0);      assert(PCI_FUNC(devfn_min) == 0);
Line 269  void pci_bus_new_inplace(PCIBus *bus, De Line 276  void pci_bus_new_inplace(PCIBus *bus, De
     vmstate_register(NULL, -1, &vmstate_pcibus, bus);      vmstate_register(NULL, -1, &vmstate_pcibus, bus);
 }  }
   
 PCIBus *pci_bus_new(DeviceState *parent, const char *name, int devfn_min)  PCIBus *pci_bus_new(DeviceState *parent, const char *name, uint8_t devfn_min)
 {  {
     PCIBus *bus;      PCIBus *bus;
   
Line 303  void pci_bus_set_mem_base(PCIBus *bus, t Line 310  void pci_bus_set_mem_base(PCIBus *bus, t
   
 PCIBus *pci_register_bus(DeviceState *parent, const char *name,  PCIBus *pci_register_bus(DeviceState *parent, const char *name,
                          pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,                           pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                          void *irq_opaque, int devfn_min, int nirq)                           void *irq_opaque, uint8_t devfn_min, int nirq)
 {  {
     PCIBus *bus;      PCIBus *bus;
   
Line 558  PCIBus *pci_get_bus_devfn(int *devfnp, c Line 565  PCIBus *pci_get_bus_devfn(int *devfnp, c
         return NULL;          return NULL;
     }      }
   
     *devfnp = slot << 3;      *devfnp = PCI_DEVFN(slot, 0);
     return pci_find_bus(pci_find_root_bus(dom), bus);      return pci_find_bus(pci_find_root_bus(dom), bus);
 }  }
   
Line 719  static void pci_config_free(PCIDevice *p Line 726  static void pci_config_free(PCIDevice *p
 /* -1 for devfn means auto assign */  /* -1 for devfn means auto assign */
 static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,  static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
                                          const char *name, int devfn,                                           const char *name, int devfn,
                                          PCIConfigReadFunc *config_read,                                           const PCIDeviceInfo *info)
                                          PCIConfigWriteFunc *config_write,  
                                          bool is_bridge)  
 {  {
       PCIConfigReadFunc *config_read = info->config_read;
       PCIConfigWriteFunc *config_write = info->config_write;
   
     if (devfn < 0) {      if (devfn < 0) {
         for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);          for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);
             devfn += PCI_FUNC_MAX) {              devfn += PCI_FUNC_MAX) {
Line 743  static PCIDevice *do_pci_register_device Line 751  static PCIDevice *do_pci_register_device
     pci_dev->irq_state = 0;      pci_dev->irq_state = 0;
     pci_config_alloc(pci_dev);      pci_config_alloc(pci_dev);
   
     if (!is_bridge) {      pci_config_set_vendor_id(pci_dev->config, info->vendor_id);
         pci_set_default_subsystem_id(pci_dev);      pci_config_set_device_id(pci_dev->config, info->device_id);
       pci_config_set_revision(pci_dev->config, info->revision);
       pci_config_set_class(pci_dev->config, info->class_id);
   
       if (!info->is_bridge) {
           if (info->subsystem_vendor_id || info->subsystem_id) {
               pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID,
                            info->subsystem_vendor_id);
               pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID,
                            info->subsystem_id);
           } else {
               pci_set_default_subsystem_id(pci_dev);
           }
       } else {
           /* subsystem_vendor_id/subsystem_id are only for header type 0 */
           assert(!info->subsystem_vendor_id);
           assert(!info->subsystem_id);
     }      }
     pci_init_cmask(pci_dev);      pci_init_cmask(pci_dev);
     pci_init_wmask(pci_dev);      pci_init_wmask(pci_dev);
     pci_init_w1cmask(pci_dev);      pci_init_w1cmask(pci_dev);
     if (is_bridge) {      if (info->is_bridge) {
         pci_init_wmask_bridge(pci_dev);          pci_init_wmask_bridge(pci_dev);
     }      }
     if (pci_init_multifunction(bus, pci_dev)) {      if (pci_init_multifunction(bus, pci_dev)) {
Line 776  static void do_pci_unregister_device(PCI Line 800  static void do_pci_unregister_device(PCI
     pci_config_free(pci_dev);      pci_config_free(pci_dev);
 }  }
   
   /* TODO: obsolete. eliminate this once all pci devices are qdevifed. */
 PCIDevice *pci_register_device(PCIBus *bus, const char *name,  PCIDevice *pci_register_device(PCIBus *bus, const char *name,
                                int instance_size, int devfn,                                 int instance_size, int devfn,
                                PCIConfigReadFunc *config_read,                                 PCIConfigReadFunc *config_read,
                                PCIConfigWriteFunc *config_write)                                 PCIConfigWriteFunc *config_write)
 {  {
     PCIDevice *pci_dev;      PCIDevice *pci_dev;
       PCIDeviceInfo info = {
           .config_read = config_read,
           .config_write = config_write,
       };
   
     pci_dev = qemu_mallocz(instance_size);      pci_dev = qemu_mallocz(instance_size);
     pci_dev = do_pci_register_device(pci_dev, bus, name, devfn,      pci_dev = do_pci_register_device(pci_dev, bus, name, devfn, &info);
                                      config_read, config_write,  
                                      PCI_HEADER_TYPE_NORMAL);  
     if (pci_dev == NULL) {      if (pci_dev == NULL) {
         hw_error("PCI: can't register device\n");          hw_error("PCI: can't register device\n");
     }      }
Line 859  void pci_register_bar(PCIDevice *pci_dev Line 886  void pci_register_bar(PCIDevice *pci_dev
     r->filtered_size = size;      r->filtered_size = size;
     r->type = type;      r->type = type;
     r->map_func = map_func;      r->map_func = map_func;
       r->ram_addr = IO_MEM_UNASSIGNED;
   
     wmask = ~(size - 1);      wmask = ~(size - 1);
     addr = pci_bar(pci_dev, region_num);      addr = pci_bar(pci_dev, region_num);
     if (region_num == PCI_ROM_SLOT) {      if (region_num == PCI_ROM_SLOT) {
         /* ROM enable bit is writeable */          /* ROM enable bit is writable */
         wmask |= PCI_ROM_ADDRESS_ENABLE;          wmask |= PCI_ROM_ADDRESS_ENABLE;
     }      }
     pci_set_long(pci_dev->config + addr, type);      pci_set_long(pci_dev->config + addr, type);
Line 877  void pci_register_bar(PCIDevice *pci_dev Line 905  void pci_register_bar(PCIDevice *pci_dev
     }      }
 }  }
   
   static void pci_simple_bar_mapfunc(PCIDevice *pci_dev, int region_num,
                                      pcibus_t addr, pcibus_t size, int type)
   {
       cpu_register_physical_memory(addr, size,
                                    pci_dev->io_regions[region_num].ram_addr);
   }
   
   void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
                                pcibus_t size,  uint8_t attr, ram_addr_t ram_addr)
   {
       pci_register_bar(pci_dev, region_num, size,
                        PCI_BASE_ADDRESS_SPACE_MEMORY | attr,
                        pci_simple_bar_mapfunc);
       pci_dev->io_regions[region_num].ram_addr = ram_addr;
   }
   
 static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size,  static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size,
                               uint8_t type)                                uint8_t type)
 {  {
Line 1145  static const pci_class_desc pci_class_de Line 1189  static const pci_class_desc pci_class_de
     { 0x0400, "Video controller", "video"},      { 0x0400, "Video controller", "video"},
     { 0x0401, "Audio controller", "sound"},      { 0x0401, "Audio controller", "sound"},
     { 0x0402, "Phone"},      { 0x0402, "Phone"},
       { 0x0403, "Audio controller", "sound"},
     { 0x0480, "Multimedia controller"},      { 0x0480, "Multimedia controller"},
     { 0x0500, "RAM controller", "memory"},      { 0x0500, "RAM controller", "memory"},
     { 0x0501, "Flash controller", "flash"},      { 0x0501, "Flash controller", "flash"},
Line 1603  PCIBus *pci_find_bus(PCIBus *bus, int bu Line 1648  PCIBus *pci_find_bus(PCIBus *bus, int bu
     return NULL;      return NULL;
 }  }
   
 PCIDevice *pci_find_device(PCIBus *bus, int bus_num, int slot, int function)  PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn)
 {  {
     bus = pci_find_bus(bus, bus_num);      bus = pci_find_bus(bus, bus_num);
   
     if (!bus)      if (!bus)
         return NULL;          return NULL;
   
     return bus->devices[PCI_DEVFN(slot, function)];      return bus->devices[devfn];
 }  }
   
 static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)  static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
Line 1618  static int pci_qdev_init(DeviceState *qd Line 1663  static int pci_qdev_init(DeviceState *qd
     PCIDevice *pci_dev = (PCIDevice *)qdev;      PCIDevice *pci_dev = (PCIDevice *)qdev;
     PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev);      PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev);
     PCIBus *bus;      PCIBus *bus;
     int devfn, rc;      int rc;
     bool is_default_rom;      bool is_default_rom;
   
     /* initialize cap_present for pci_is_express() and pci_config_size() */      /* initialize cap_present for pci_is_express() and pci_config_size() */
Line 1627  static int pci_qdev_init(DeviceState *qd Line 1672  static int pci_qdev_init(DeviceState *qd
     }      }
   
     bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));      bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
     devfn = pci_dev->devfn;      pci_dev = do_pci_register_device(pci_dev, bus, base->name,
     pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn,                                       pci_dev->devfn, info);
                                      info->config_read, info->config_write,  
                                      info->is_bridge);  
     if (pci_dev == NULL)      if (pci_dev == NULL)
         return -1;          return -1;
     if (qdev->hotplugged && info->no_hotplug) {      if (qdev->hotplugged && info->no_hotplug) {
Line 1638  static int pci_qdev_init(DeviceState *qd Line 1681  static int pci_qdev_init(DeviceState *qd
         do_pci_unregister_device(pci_dev);          do_pci_unregister_device(pci_dev);
         return -1;          return -1;
     }      }
     rc = info->init(pci_dev);      if (info->init) {
     if (rc != 0) {          rc = info->init(pci_dev);
         do_pci_unregister_device(pci_dev);          if (rc != 0) {
         return rc;              do_pci_unregister_device(pci_dev);
               return rc;
           }
     }      }
   
     /* rom loading */      /* rom loading */
Line 1708  PCIDevice *pci_create_multifunction(PCIB Line 1753  PCIDevice *pci_create_multifunction(PCIB
     return DO_UPCAST(PCIDevice, qdev, dev);      return DO_UPCAST(PCIDevice, qdev, dev);
 }  }
   
   PCIDevice *pci_try_create_multifunction(PCIBus *bus, int devfn,
                                           bool multifunction,
                                           const char *name)
   {
       DeviceState *dev;
   
       dev = qdev_try_create(&bus->qbus, name);
       if (!dev) {
           return NULL;
       }
       qdev_prop_set_uint32(dev, "addr", devfn);
       qdev_prop_set_bit(dev, "multifunction", multifunction);
       return DO_UPCAST(PCIDevice, qdev, dev);
   }
   
 PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn,  PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn,
                                            bool multifunction,                                             bool multifunction,
                                            const char *name)                                             const char *name)
Line 1727  PCIDevice *pci_create_simple(PCIBus *bus Line 1787  PCIDevice *pci_create_simple(PCIBus *bus
     return pci_create_simple_multifunction(bus, devfn, false, name);      return pci_create_simple_multifunction(bus, devfn, false, name);
 }  }
   
   PCIDevice *pci_try_create(PCIBus *bus, int devfn, const char *name)
   {
       return pci_try_create_multifunction(bus, devfn, false, name);
   }
   
 static int pci_find_space(PCIDevice *pdev, uint8_t size)  static int pci_find_space(PCIDevice *pdev, uint8_t size)
 {  {
     int config_size = pci_config_size(pdev);      int config_size = pci_config_size(pdev);
Line 1855  static int pci_add_option_rom(PCIDevice  Line 1920  static int pci_add_option_rom(PCIDevice 
     if (size < 0) {      if (size < 0) {
         error_report("%s: failed to find romfile \"%s\"",          error_report("%s: failed to find romfile \"%s\"",
                      __FUNCTION__, pdev->romfile);                       __FUNCTION__, pdev->romfile);
           qemu_free(path);
         return -1;          return -1;
     }      }
     if (size & (size - 1)) {      if (size & (size - 1)) {
Line 1876  static int pci_add_option_rom(PCIDevice  Line 1942  static int pci_add_option_rom(PCIDevice 
         pci_patch_ids(pdev, ptr, size);          pci_patch_ids(pdev, ptr, size);
     }      }
   
       qemu_put_ram_ptr(ptr);
   
     pci_register_bar(pdev, PCI_ROM_SLOT, size,      pci_register_bar(pdev, PCI_ROM_SLOT, size,
                      0, pci_map_option_rom);                       0, pci_map_option_rom);
   
Line 1929  void pci_del_capability(PCIDevice *pdev, Line 1997  void pci_del_capability(PCIDevice *pdev,
     if (!offset)      if (!offset)
         return;          return;
     pdev->config[prev] = pdev->config[offset + PCI_CAP_LIST_NEXT];      pdev->config[prev] = pdev->config[offset + PCI_CAP_LIST_NEXT];
     /* Make capability writeable again */      /* Make capability writable again */
     memset(pdev->wmask + offset, 0xff, size);      memset(pdev->wmask + offset, 0xff, size);
     memset(pdev->w1cmask + offset, 0, size);      memset(pdev->w1cmask + offset, 0, size);
     /* Clear cmask as device-specific registers can't be checked */      /* Clear cmask as device-specific registers can't be checked */

Removed from v.1.1.1.14  
changed lines
  Added in v.1.1.1.15


unix.superglobalmegacorp.com