Commit 1431b6a17e6546569e09bcf8fb7773c925658d8f

Authored by Paul Brook
1 parent fd93a799

Record device property types

Record device property types, and provide a list of properties at device
registration time.

Add a "device" property type that holds a reference to annother device.

Signed-off-by: Paul Brook <paul@codesourcery.com>
hw/qdev.c
... ... @@ -32,6 +32,7 @@
32 32  
33 33 struct DeviceProperty {
34 34 const char *name;
  35 + DevicePropType type;
35 36 union {
36 37 uint64_t i;
37 38 void *ptr;
... ... @@ -119,13 +120,15 @@ void qdev_free(DeviceState *dev)
119 120 free(dev);
120 121 }
121 122  
122   -static DeviceProperty *create_prop(DeviceState *dev, const char *name)
  123 +static DeviceProperty *create_prop(DeviceState *dev, const char *name,
  124 + DevicePropType type)
123 125 {
124 126 DeviceProperty *prop;
125 127  
126 128 /* TODO: Check for duplicate properties. */
127 129 prop = qemu_mallocz(sizeof(*prop));
128 130 prop->name = qemu_strdup(name);
  131 + prop->type = type;
129 132 prop->next = dev->props;
130 133 dev->props = prop;
131 134  
... ... @@ -136,15 +139,23 @@ void qdev_set_prop_int(DeviceState *dev, const char *name, uint64_t value)
136 139 {
137 140 DeviceProperty *prop;
138 141  
139   - prop = create_prop(dev, name);
  142 + prop = create_prop(dev, name, PROP_TYPE_INT);
140 143 prop->value.i = value;
141 144 }
142 145  
  146 +void qdev_set_prop_dev(DeviceState *dev, const char *name, DeviceState *value)
  147 +{
  148 + DeviceProperty *prop;
  149 +
  150 + prop = create_prop(dev, name, PROP_TYPE_DEV);
  151 + prop->value.ptr = value;
  152 +}
  153 +
143 154 void qdev_set_prop_ptr(DeviceState *dev, const char *name, void *value)
144 155 {
145 156 DeviceProperty *prop;
146 157  
147   - prop = create_prop(dev, name);
  158 + prop = create_prop(dev, name, PROP_TYPE_INT);
148 159 prop->value.ptr = value;
149 160 }
150 161  
... ... @@ -173,12 +184,14 @@ BusState *qdev_get_parent_bus(DeviceState *dev)
173 184 return dev->parent_bus;
174 185 }
175 186  
176   -static DeviceProperty *find_prop(DeviceState *dev, const char *name)
  187 +static DeviceProperty *find_prop(DeviceState *dev, const char *name,
  188 + DevicePropType type)
177 189 {
178 190 DeviceProperty *prop;
179 191  
180 192 for (prop = dev->props; prop; prop = prop->next) {
181 193 if (strcmp(prop->name, name) == 0) {
  194 + assert (prop->type == type);
182 195 return prop;
183 196 }
184 197 }
... ... @@ -189,9 +202,10 @@ uint64_t qdev_get_prop_int(DeviceState *dev, const char *name, uint64_t def)
189 202 {
190 203 DeviceProperty *prop;
191 204  
192   - prop = find_prop(dev, name);
193   - if (!prop)
  205 + prop = find_prop(dev, name, PROP_TYPE_INT);
  206 + if (!prop) {
194 207 return def;
  208 + }
195 209  
196 210 return prop->value.i;
197 211 }
... ... @@ -200,11 +214,22 @@ void *qdev_get_prop_ptr(DeviceState *dev, const char *name)
200 214 {
201 215 DeviceProperty *prop;
202 216  
203   - prop = find_prop(dev, name);
  217 + prop = find_prop(dev, name, PROP_TYPE_PTR);
204 218 assert(prop);
205 219 return prop->value.ptr;
206 220 }
207 221  
  222 +DeviceState *qdev_get_prop_dev(DeviceState *dev, const char *name)
  223 +{
  224 + DeviceProperty *prop;
  225 +
  226 + prop = find_prop(dev, name, PROP_TYPE_DEV);
  227 + if (!prop) {
  228 + return NULL;
  229 + }
  230 + return prop->value.ptr;
  231 +}
  232 +
208 233 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
209 234 {
210 235 assert(dev->num_gpio_in == 0);
... ...
hw/qdev.h
... ... @@ -49,6 +49,7 @@ void qdev_free(DeviceState *dev);
49 49  
50 50 /* Set properties between creation and init. */
51 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);
52 53 void qdev_set_prop_ptr(DeviceState *dev, const char *name, void *value);
53 54 void qdev_set_netdev(DeviceState *dev, NICInfo *nd);
54 55  
... ... @@ -59,6 +60,17 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
59 60  
60 61 /*** Device API. ***/
61 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 +
62 74 typedef struct DeviceInfo DeviceInfo;
63 75  
64 76 typedef void (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
... ... @@ -68,6 +80,7 @@ typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv,
68 80 struct DeviceInfo {
69 81 qdev_initfn init;
70 82 BusType bus_type;
  83 + DevicePropList *props;
71 84 };
72 85  
73 86 void qdev_register(const char *name, int size, DeviceInfo *info);
... ... @@ -83,6 +96,8 @@ CharDriverState *qdev_init_chardev(DeviceState *dev);
83 96  
84 97 BusState *qdev_get_parent_bus(DeviceState *dev);
85 98 uint64_t qdev_get_prop_int(DeviceState *dev, const char *name, uint64_t def);
  99 +DeviceState *qdev_get_prop_dev(DeviceState *dev, const char *name);
  100 +/* FIXME: Remove opaque pointer properties. */
86 101 void *qdev_get_prop_ptr(DeviceState *dev, const char *name);
87 102  
88 103 /* Convery from a base type to a parent type, with compile time checking. */
... ...
hw/syborg_timer.c
... ... @@ -226,10 +226,20 @@ static void syborg_timer_init(SysBusDevice *dev)
226 226 syborg_timer_save, syborg_timer_load, s);
227 227 }
228 228  
  229 +static SysBusDeviceInfo syborg_timer_info = {
  230 + .init = syborg_timer_init,
  231 + .qdev = {
  232 + .props = (DevicePropList[]) {
  233 + {.name = "frequency", .type = PROP_TYPE_INT},
  234 + {.name = NULL}
  235 + }
  236 + }
  237 +};
  238 +
229 239 static void syborg_timer_register_devices(void)
230 240 {
231   - sysbus_register_dev("syborg,timer", sizeof(SyborgTimerState),
232   - syborg_timer_init);
  241 + sysbus_register_withprop("syborg,timer", sizeof(SyborgTimerState),
  242 + &syborg_timer_info);
233 243 }
234 244  
235 245 device_init(syborg_timer_register_devices)
... ...
hw/sysbus.c
... ... @@ -21,11 +21,6 @@
21 21 #include "sysbus.h"
22 22 #include "sysemu.h"
23 23  
24   -typedef struct {
25   - DeviceInfo qdev;
26   - sysbus_initfn init;
27   -} SysBusDeviceInfo;
28   -
29 24 void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq)
30 25 {
31 26 assert(n >= 0 && n < dev->num_irq);
... ... @@ -109,12 +104,9 @@ static void sysbus_device_init(DeviceState *dev, DeviceInfo *base)
109 104 info->init(sysbus_from_qdev(dev));
110 105 }
111 106  
112   -void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init)
  107 +void sysbus_register_withprop(const char *name, size_t size,
  108 + SysBusDeviceInfo *info)
113 109 {
114   - SysBusDeviceInfo *info;
115   -
116   - info = qemu_mallocz(sizeof(*info));
117   - info->init = init;
118 110 info->qdev.init = sysbus_device_init;
119 111 info->qdev.bus_type = BUS_TYPE_SYSTEM;
120 112  
... ... @@ -122,6 +114,15 @@ void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init)
122 114 qdev_register(name, size, &info->qdev);
123 115 }
124 116  
  117 +void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init)
  118 +{
  119 + SysBusDeviceInfo *info;
  120 +
  121 + info = qemu_mallocz(sizeof(*info));
  122 + info->init = init;
  123 + sysbus_register_withprop(name, size, info);
  124 +}
  125 +
125 126 DeviceState *sysbus_create_varargs(const char *name,
126 127 target_phys_addr_t addr, ...)
127 128 {
... ...
hw/sysbus.h
... ... @@ -31,7 +31,14 @@ typedef void (*sysbus_initfn)(SysBusDevice *dev);
31 31 #define sysbus_from_qdev(dev) ((SysBusDevice *)(dev))
32 32 #define FROM_SYSBUS(type, dev) DO_UPCAST(type, busdev, dev)
33 33  
  34 +typedef struct {
  35 + DeviceInfo qdev;
  36 + sysbus_initfn init;
  37 +} SysBusDeviceInfo;
  38 +
34 39 void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init);
  40 +void sysbus_register_withprop(const char *name, size_t size,
  41 + SysBusDeviceInfo *info);
35 42 void *sysbus_new(void);
36 43 void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size, int iofunc);
37 44 void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,
... ...