| David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 1 | #ifndef QDEV_H |
| 2 | #define QDEV_H |
| 3 | |
| 4 | #include "hw.h" |
| David 'Digit' Turner | a5d4120 | 2010-05-10 18:37:10 -0700 | [diff] [blame] | 5 | #include "qemu-queue.h" |
| David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 6 | |
| 7 | typedef struct DeviceType DeviceType; |
| 8 | |
| 9 | typedef struct DeviceProperty DeviceProperty; |
| 10 | |
| 11 | typedef struct BusState BusState; |
| 12 | |
| 13 | /* This structure should not be accessed directly. We declare it here |
| 14 | so that it can be embedded in individual device state structures. */ |
| 15 | struct DeviceState { |
| 16 | DeviceType *type; |
| 17 | BusState *parent_bus; |
| 18 | DeviceProperty *props; |
| 19 | int num_gpio_out; |
| 20 | qemu_irq *gpio_out; |
| 21 | int num_gpio_in; |
| 22 | qemu_irq *gpio_in; |
| David 'Digit' Turner | a5d4120 | 2010-05-10 18:37:10 -0700 | [diff] [blame] | 23 | QLIST_HEAD(, BusState) child_bus; |
| David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 24 | NICInfo *nd; |
| David 'Digit' Turner | a5d4120 | 2010-05-10 18:37:10 -0700 | [diff] [blame] | 25 | QLIST_ENTRY(DeviceState) sibling; |
| David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 26 | }; |
| 27 | |
| 28 | typedef enum { |
| 29 | BUS_TYPE_SYSTEM, |
| 30 | BUS_TYPE_PCI, |
| 31 | BUS_TYPE_SCSI, |
| 32 | BUS_TYPE_I2C, |
| 33 | BUS_TYPE_SSI |
| 34 | } BusType; |
| 35 | |
| 36 | struct BusState { |
| 37 | DeviceState *parent; |
| 38 | const char *name; |
| 39 | BusType type; |
| David 'Digit' Turner | a5d4120 | 2010-05-10 18:37:10 -0700 | [diff] [blame] | 40 | QLIST_HEAD(, DeviceState) children; |
| 41 | QLIST_ENTRY(BusState) sibling; |
| David 'Digit' Turner | 5d8f37a | 2009-09-14 14:32:27 -0700 | [diff] [blame] | 42 | }; |
| 43 | |
| 44 | /*** Board API. This should go away once we have a machine config file. ***/ |
| 45 | |
| 46 | DeviceState *qdev_create(BusState *bus, const char *name); |
| 47 | void qdev_init(DeviceState *dev); |
| 48 | void qdev_free(DeviceState *dev); |
| 49 | |
| 50 | /* Set properties between creation and init. */ |
| 51 | void qdev_set_prop_int(DeviceState *dev, const char *name, uint64_t value); |
| 52 | void qdev_set_prop_dev(DeviceState *dev, const char *name, DeviceState *value); |
| 53 | void qdev_set_prop_ptr(DeviceState *dev, const char *name, void *value); |
| 54 | void qdev_set_netdev(DeviceState *dev, NICInfo *nd); |
| 55 | |
| 56 | qemu_irq qdev_get_gpio_in(DeviceState *dev, int n); |
| 57 | void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin); |
| 58 | |
| 59 | BusState *qdev_get_child_bus(DeviceState *dev, const char *name); |
| 60 | |
| 61 | /*** Device API. ***/ |
| 62 | |
| 63 | typedef enum { |
| 64 | PROP_TYPE_INT, |
| 65 | PROP_TYPE_PTR, |
| 66 | PROP_TYPE_DEV |
| 67 | } DevicePropType; |
| 68 | |
| 69 | typedef struct { |
| 70 | const char *name; |
| 71 | DevicePropType type; |
| 72 | } DevicePropList; |
| 73 | |
| 74 | typedef struct DeviceInfo DeviceInfo; |
| 75 | |
| 76 | typedef void (*qdev_initfn)(DeviceState *dev, DeviceInfo *info); |
| 77 | typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv, |
| 78 | int unit); |
| 79 | |
| 80 | struct DeviceInfo { |
| 81 | const char *name; |
| 82 | size_t size; |
| 83 | DevicePropList *props; |
| 84 | |
| 85 | /* Private to qdev / bus. */ |
| 86 | qdev_initfn init; |
| 87 | BusType bus_type; |
| 88 | }; |
| 89 | |
| 90 | void qdev_register(DeviceInfo *info); |
| 91 | |
| 92 | /* Register device properties. */ |
| 93 | /* GPIO inputs also double as IRQ sinks. */ |
| 94 | void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n); |
| 95 | void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n); |
| 96 | |
| 97 | void scsi_bus_new(DeviceState *host, SCSIAttachFn attach); |
| 98 | |
| 99 | CharDriverState *qdev_init_chardev(DeviceState *dev); |
| 100 | |
| 101 | BusState *qdev_get_parent_bus(DeviceState *dev); |
| 102 | uint64_t qdev_get_prop_int(DeviceState *dev, const char *name, uint64_t def); |
| 103 | DeviceState *qdev_get_prop_dev(DeviceState *dev, const char *name); |
| 104 | /* FIXME: Remove opaque pointer properties. */ |
| 105 | void *qdev_get_prop_ptr(DeviceState *dev, const char *name); |
| 106 | |
| 107 | /* Convery from a base type to a parent type, with compile time checking. */ |
| 108 | #ifdef __GNUC__ |
| 109 | #define DO_UPCAST(type, field, dev) ( __extension__ ( { \ |
| 110 | char __attribute__((unused)) offset_must_be_zero[ \ |
| 111 | -offsetof(type, field)]; \ |
| 112 | container_of(dev, type, field);})) |
| 113 | #else |
| 114 | #define DO_UPCAST(type, field, dev) container_of(dev, type, field) |
| 115 | #endif |
| 116 | |
| 117 | /*** BUS API. ***/ |
| 118 | |
| 119 | BusState *qbus_create(BusType type, size_t size, |
| 120 | DeviceState *parent, const char *name); |
| 121 | |
| 122 | #define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev) |
| 123 | |
| 124 | /*** monitor commands ***/ |
| 125 | |
| 126 | void do_info_qtree(Monitor *mon); |
| 127 | void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent); |
| 128 | |
| 129 | #endif |