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,6 +32,7 @@
32 32
33 struct DeviceProperty { 33 struct DeviceProperty {
34 const char *name; 34 const char *name;
  35 + DevicePropType type;
35 union { 36 union {
36 uint64_t i; 37 uint64_t i;
37 void *ptr; 38 void *ptr;
@@ -119,13 +120,15 @@ void qdev_free(DeviceState *dev) @@ -119,13 +120,15 @@ void qdev_free(DeviceState *dev)
119 free(dev); 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 DeviceProperty *prop; 126 DeviceProperty *prop;
125 127
126 /* TODO: Check for duplicate properties. */ 128 /* TODO: Check for duplicate properties. */
127 prop = qemu_mallocz(sizeof(*prop)); 129 prop = qemu_mallocz(sizeof(*prop));
128 prop->name = qemu_strdup(name); 130 prop->name = qemu_strdup(name);
  131 + prop->type = type;
129 prop->next = dev->props; 132 prop->next = dev->props;
130 dev->props = prop; 133 dev->props = prop;
131 134
@@ -136,15 +139,23 @@ void qdev_set_prop_int(DeviceState *dev, const char *name, uint64_t value) @@ -136,15 +139,23 @@ void qdev_set_prop_int(DeviceState *dev, const char *name, uint64_t value)
136 { 139 {
137 DeviceProperty *prop; 140 DeviceProperty *prop;
138 141
139 - prop = create_prop(dev, name); 142 + prop = create_prop(dev, name, PROP_TYPE_INT);
140 prop->value.i = value; 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 void qdev_set_prop_ptr(DeviceState *dev, const char *name, void *value) 154 void qdev_set_prop_ptr(DeviceState *dev, const char *name, void *value)
144 { 155 {
145 DeviceProperty *prop; 156 DeviceProperty *prop;
146 157
147 - prop = create_prop(dev, name); 158 + prop = create_prop(dev, name, PROP_TYPE_INT);
148 prop->value.ptr = value; 159 prop->value.ptr = value;
149 } 160 }
150 161
@@ -173,12 +184,14 @@ BusState *qdev_get_parent_bus(DeviceState *dev) @@ -173,12 +184,14 @@ BusState *qdev_get_parent_bus(DeviceState *dev)
173 return dev->parent_bus; 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 DeviceProperty *prop; 190 DeviceProperty *prop;
179 191
180 for (prop = dev->props; prop; prop = prop->next) { 192 for (prop = dev->props; prop; prop = prop->next) {
181 if (strcmp(prop->name, name) == 0) { 193 if (strcmp(prop->name, name) == 0) {
  194 + assert (prop->type == type);
182 return prop; 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,9 +202,10 @@ uint64_t qdev_get_prop_int(DeviceState *dev, const char *name, uint64_t def)
189 { 202 {
190 DeviceProperty *prop; 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 return def; 207 return def;
  208 + }
195 209
196 return prop->value.i; 210 return prop->value.i;
197 } 211 }
@@ -200,11 +214,22 @@ void *qdev_get_prop_ptr(DeviceState *dev, const char *name) @@ -200,11 +214,22 @@ void *qdev_get_prop_ptr(DeviceState *dev, const char *name)
200 { 214 {
201 DeviceProperty *prop; 215 DeviceProperty *prop;
202 216
203 - prop = find_prop(dev, name); 217 + prop = find_prop(dev, name, PROP_TYPE_PTR);
204 assert(prop); 218 assert(prop);
205 return prop->value.ptr; 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 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n) 233 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
209 { 234 {
210 assert(dev->num_gpio_in == 0); 235 assert(dev->num_gpio_in == 0);
hw/qdev.h
@@ -49,6 +49,7 @@ void qdev_free(DeviceState *dev); @@ -49,6 +49,7 @@ void qdev_free(DeviceState *dev);
49 49
50 /* Set properties between creation and init. */ 50 /* Set properties between creation and init. */
51 void qdev_set_prop_int(DeviceState *dev, const char *name, uint64_t value); 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 void qdev_set_prop_ptr(DeviceState *dev, const char *name, void *value); 53 void qdev_set_prop_ptr(DeviceState *dev, const char *name, void *value);
53 void qdev_set_netdev(DeviceState *dev, NICInfo *nd); 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,6 +60,17 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
59 60
60 /*** Device API. ***/ 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 typedef struct DeviceInfo DeviceInfo; 74 typedef struct DeviceInfo DeviceInfo;
63 75
64 typedef void (*qdev_initfn)(DeviceState *dev, DeviceInfo *info); 76 typedef void (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
@@ -68,6 +80,7 @@ typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv, @@ -68,6 +80,7 @@ typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv,
68 struct DeviceInfo { 80 struct DeviceInfo {
69 qdev_initfn init; 81 qdev_initfn init;
70 BusType bus_type; 82 BusType bus_type;
  83 + DevicePropList *props;
71 }; 84 };
72 85
73 void qdev_register(const char *name, int size, DeviceInfo *info); 86 void qdev_register(const char *name, int size, DeviceInfo *info);
@@ -83,6 +96,8 @@ CharDriverState *qdev_init_chardev(DeviceState *dev); @@ -83,6 +96,8 @@ CharDriverState *qdev_init_chardev(DeviceState *dev);
83 96
84 BusState *qdev_get_parent_bus(DeviceState *dev); 97 BusState *qdev_get_parent_bus(DeviceState *dev);
85 uint64_t qdev_get_prop_int(DeviceState *dev, const char *name, uint64_t def); 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 void *qdev_get_prop_ptr(DeviceState *dev, const char *name); 101 void *qdev_get_prop_ptr(DeviceState *dev, const char *name);
87 102
88 /* Convery from a base type to a parent type, with compile time checking. */ 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,10 +226,20 @@ static void syborg_timer_init(SysBusDevice *dev)
226 syborg_timer_save, syborg_timer_load, s); 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 static void syborg_timer_register_devices(void) 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 device_init(syborg_timer_register_devices) 245 device_init(syborg_timer_register_devices)
hw/sysbus.c
@@ -21,11 +21,6 @@ @@ -21,11 +21,6 @@
21 #include "sysbus.h" 21 #include "sysbus.h"
22 #include "sysemu.h" 22 #include "sysemu.h"
23 23
24 -typedef struct {  
25 - DeviceInfo qdev;  
26 - sysbus_initfn init;  
27 -} SysBusDeviceInfo;  
28 -  
29 void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq) 24 void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq)
30 { 25 {
31 assert(n >= 0 && n < dev->num_irq); 26 assert(n >= 0 && n < dev->num_irq);
@@ -109,12 +104,9 @@ static void sysbus_device_init(DeviceState *dev, DeviceInfo *base) @@ -109,12 +104,9 @@ static void sysbus_device_init(DeviceState *dev, DeviceInfo *base)
109 info->init(sysbus_from_qdev(dev)); 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 info->qdev.init = sysbus_device_init; 110 info->qdev.init = sysbus_device_init;
119 info->qdev.bus_type = BUS_TYPE_SYSTEM; 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,6 +114,15 @@ void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init)
122 qdev_register(name, size, &info->qdev); 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 DeviceState *sysbus_create_varargs(const char *name, 126 DeviceState *sysbus_create_varargs(const char *name,
126 target_phys_addr_t addr, ...) 127 target_phys_addr_t addr, ...)
127 { 128 {
hw/sysbus.h
@@ -31,7 +31,14 @@ typedef void (*sysbus_initfn)(SysBusDevice *dev); @@ -31,7 +31,14 @@ typedef void (*sysbus_initfn)(SysBusDevice *dev);
31 #define sysbus_from_qdev(dev) ((SysBusDevice *)(dev)) 31 #define sysbus_from_qdev(dev) ((SysBusDevice *)(dev))
32 #define FROM_SYSBUS(type, dev) DO_UPCAST(type, busdev, dev) 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 void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init); 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 void *sysbus_new(void); 42 void *sysbus_new(void);
36 void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size, int iofunc); 43 void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size, int iofunc);
37 void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size, 44 void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,