Commit 6b1b92d35b247188139c3dd022fd9521882ef8a9
1 parent
4d6ae674
PCI qdev support
Signed-off-by: Paul Brook <paul@codesourcery.com>
Showing
2 changed files
with
56 additions
and
7 deletions
hw/pci.c
| @@ -237,13 +237,11 @@ int pci_assign_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp) | @@ -237,13 +237,11 @@ int pci_assign_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp) | ||
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | /* -1 for devfn means auto assign */ | 239 | /* -1 for devfn means auto assign */ |
| 240 | -PCIDevice *pci_register_device(PCIBus *bus, const char *name, | ||
| 241 | - int instance_size, int devfn, | ||
| 242 | - PCIConfigReadFunc *config_read, | ||
| 243 | - PCIConfigWriteFunc *config_write) | 240 | +static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, |
| 241 | + const char *name, int devfn, | ||
| 242 | + PCIConfigReadFunc *config_read, | ||
| 243 | + PCIConfigWriteFunc *config_write) | ||
| 244 | { | 244 | { |
| 245 | - PCIDevice *pci_dev; | ||
| 246 | - | ||
| 247 | if (pci_irq_index >= PCI_DEVICES_MAX) | 245 | if (pci_irq_index >= PCI_DEVICES_MAX) |
| 248 | return NULL; | 246 | return NULL; |
| 249 | 247 | ||
| @@ -255,7 +253,6 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name, | @@ -255,7 +253,6 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name, | ||
| 255 | return NULL; | 253 | return NULL; |
| 256 | found: ; | 254 | found: ; |
| 257 | } | 255 | } |
| 258 | - pci_dev = qemu_mallocz(instance_size); | ||
| 259 | pci_dev->bus = bus; | 256 | pci_dev->bus = bus; |
| 260 | pci_dev->devfn = devfn; | 257 | pci_dev->devfn = devfn; |
| 261 | pstrcpy(pci_dev->name, sizeof(pci_dev->name), name); | 258 | pstrcpy(pci_dev->name, sizeof(pci_dev->name), name); |
| @@ -274,6 +271,18 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name, | @@ -274,6 +271,18 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name, | ||
| 274 | return pci_dev; | 271 | return pci_dev; |
| 275 | } | 272 | } |
| 276 | 273 | ||
| 274 | +PCIDevice *pci_register_device(PCIBus *bus, const char *name, | ||
| 275 | + int instance_size, int devfn, | ||
| 276 | + PCIConfigReadFunc *config_read, | ||
| 277 | + PCIConfigWriteFunc *config_write) | ||
| 278 | +{ | ||
| 279 | + PCIDevice *pci_dev; | ||
| 280 | + | ||
| 281 | + pci_dev = qemu_mallocz(instance_size); | ||
| 282 | + pci_dev = do_pci_register_device(pci_dev, bus, name, devfn, | ||
| 283 | + config_read, config_write); | ||
| 284 | + return pci_dev; | ||
| 285 | +} | ||
| 277 | static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr) | 286 | static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr) |
| 278 | { | 287 | { |
| 279 | return addr + pci_mem_base; | 288 | return addr + pci_mem_base; |
| @@ -891,3 +900,35 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did, | @@ -891,3 +900,35 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did, | ||
| 891 | s->bus = pci_register_secondary_bus(&s->dev, map_irq); | 900 | s->bus = pci_register_secondary_bus(&s->dev, map_irq); |
| 892 | return s->bus; | 901 | return s->bus; |
| 893 | } | 902 | } |
| 903 | + | ||
| 904 | +static void pci_qdev_init(DeviceState *qdev, void *opaque) | ||
| 905 | +{ | ||
| 906 | + PCIDevice *pci_dev = (PCIDevice *)qdev; | ||
| 907 | + pci_qdev_initfn init; | ||
| 908 | + PCIBus *bus; | ||
| 909 | + int devfn; | ||
| 910 | + | ||
| 911 | + init = opaque; | ||
| 912 | + bus = qdev_get_bus(qdev); | ||
| 913 | + devfn = qdev_get_prop_int(qdev, "devfn", -1); | ||
| 914 | + pci_dev = do_pci_register_device(pci_dev, bus, "FIXME", devfn, | ||
| 915 | + NULL, NULL);//FIXME:config_read, config_write); | ||
| 916 | + assert(pci_dev); | ||
| 917 | + init(pci_dev); | ||
| 918 | +} | ||
| 919 | + | ||
| 920 | +void pci_qdev_register(const char *name, int size, pci_qdev_initfn init) | ||
| 921 | +{ | ||
| 922 | + qdev_register(name, size, pci_qdev_init, init); | ||
| 923 | +} | ||
| 924 | + | ||
| 925 | +PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name) | ||
| 926 | +{ | ||
| 927 | + DeviceState *dev; | ||
| 928 | + | ||
| 929 | + dev = qdev_create(bus, name); | ||
| 930 | + qdev_set_prop_int(dev, "devfn", devfn); | ||
| 931 | + qdev_init(dev); | ||
| 932 | + | ||
| 933 | + return (PCIDevice *)dev; | ||
| 934 | +} |
hw/pci.h
| @@ -3,6 +3,8 @@ | @@ -3,6 +3,8 @@ | ||
| 3 | 3 | ||
| 4 | #include "qemu-common.h" | 4 | #include "qemu-common.h" |
| 5 | 5 | ||
| 6 | +#include "qdev.h" | ||
| 7 | + | ||
| 6 | /* PCI includes legacy ISA access. */ | 8 | /* PCI includes legacy ISA access. */ |
| 7 | #include "isa.h" | 9 | #include "isa.h" |
| 8 | 10 | ||
| @@ -138,6 +140,7 @@ typedef struct PCIIORegion { | @@ -138,6 +140,7 @@ typedef struct PCIIORegion { | ||
| 138 | #define PCI_COMMAND_RESERVED_MASK_HI (PCI_COMMAND_RESERVED >> 8) | 140 | #define PCI_COMMAND_RESERVED_MASK_HI (PCI_COMMAND_RESERVED >> 8) |
| 139 | 141 | ||
| 140 | struct PCIDevice { | 142 | struct PCIDevice { |
| 143 | + DeviceState qdev; | ||
| 141 | /* PCI config space */ | 144 | /* PCI config space */ |
| 142 | uint8_t config[256]; | 145 | uint8_t config[256]; |
| 143 | 146 | ||
| @@ -217,6 +220,11 @@ pci_config_set_class(uint8_t *pci_config, uint16_t val) | @@ -217,6 +220,11 @@ pci_config_set_class(uint8_t *pci_config, uint16_t val) | ||
| 217 | cpu_to_le16wu((uint16_t *)&pci_config[PCI_CLASS_DEVICE], val); | 220 | cpu_to_le16wu((uint16_t *)&pci_config[PCI_CLASS_DEVICE], val); |
| 218 | } | 221 | } |
| 219 | 222 | ||
| 223 | +typedef void (*pci_qdev_initfn)(PCIDevice *dev); | ||
| 224 | +void pci_qdev_register(const char *name, int size, pci_qdev_initfn init); | ||
| 225 | + | ||
| 226 | +PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name); | ||
| 227 | + | ||
| 220 | /* lsi53c895a.c */ | 228 | /* lsi53c895a.c */ |
| 221 | #define LSI_MAX_DEVS 7 | 229 | #define LSI_MAX_DEVS 7 |
| 222 | void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id); | 230 | void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id); |