root / hw / core / qdev-properties.c @ ec4936e1
History | View | Annotate | Download (28.6 kB)
1 | 1422e32d | Paolo Bonzini | #include "net/net.h" |
---|---|---|---|
2 | 83c9f4ca | Paolo Bonzini | #include "hw/qdev.h" |
3 | 7b1b5d19 | Paolo Bonzini | #include "qapi/qmp/qerror.h" |
4 | 9c17d615 | Paolo Bonzini | #include "sysemu/blockdev.h" |
5 | 0d09e41a | Paolo Bonzini | #include "hw/block/block.h" |
6 | 606c10e2 | Zhi Yong Wu | #include "net/hub.h" |
7 | 7b1b5d19 | Paolo Bonzini | #include "qapi/visitor.h" |
8 | dccfcd0e | Paolo Bonzini | #include "sysemu/char.h" |
9 | ee6847d1 | Gerd Hoffmann | |
10 | b000dfbd | Peter Maydell | void qdev_prop_set_after_realize(DeviceState *dev, const char *name, |
11 | b000dfbd | Peter Maydell | Error **errp) |
12 | b000dfbd | Peter Maydell | { |
13 | b000dfbd | Peter Maydell | if (dev->id) {
|
14 | b000dfbd | Peter Maydell | error_setg(errp, "Attempt to set property '%s' on device '%s' "
|
15 | b000dfbd | Peter Maydell | "(type '%s') after it was realized", name, dev->id,
|
16 | b000dfbd | Peter Maydell | object_get_typename(OBJECT(dev))); |
17 | b000dfbd | Peter Maydell | } else {
|
18 | b000dfbd | Peter Maydell | error_setg(errp, "Attempt to set property '%s' on anonymous device "
|
19 | b000dfbd | Peter Maydell | "(type '%s') after it was realized", name,
|
20 | b000dfbd | Peter Maydell | object_get_typename(OBJECT(dev))); |
21 | b000dfbd | Peter Maydell | } |
22 | b000dfbd | Peter Maydell | } |
23 | b000dfbd | Peter Maydell | |
24 | ee6847d1 | Gerd Hoffmann | void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
|
25 | ee6847d1 | Gerd Hoffmann | { |
26 | ee6847d1 | Gerd Hoffmann | void *ptr = dev;
|
27 | ee6847d1 | Gerd Hoffmann | ptr += prop->offset; |
28 | ee6847d1 | Gerd Hoffmann | return ptr;
|
29 | ee6847d1 | Gerd Hoffmann | } |
30 | ee6847d1 | Gerd Hoffmann | |
31 | d4d34b0d | Markus Armbruster | static void get_enum(Object *obj, Visitor *v, void *opaque, |
32 | d4d34b0d | Markus Armbruster | const char *name, Error **errp) |
33 | d4d34b0d | Markus Armbruster | { |
34 | d4d34b0d | Markus Armbruster | DeviceState *dev = DEVICE(obj); |
35 | d4d34b0d | Markus Armbruster | Property *prop = opaque; |
36 | d4d34b0d | Markus Armbruster | int *ptr = qdev_get_prop_ptr(dev, prop);
|
37 | d4d34b0d | Markus Armbruster | |
38 | d4d34b0d | Markus Armbruster | visit_type_enum(v, ptr, prop->info->enum_table, |
39 | d4d34b0d | Markus Armbruster | prop->info->name, prop->name, errp); |
40 | d4d34b0d | Markus Armbruster | } |
41 | d4d34b0d | Markus Armbruster | |
42 | d4d34b0d | Markus Armbruster | static void set_enum(Object *obj, Visitor *v, void *opaque, |
43 | d4d34b0d | Markus Armbruster | const char *name, Error **errp) |
44 | d4d34b0d | Markus Armbruster | { |
45 | d4d34b0d | Markus Armbruster | DeviceState *dev = DEVICE(obj); |
46 | d4d34b0d | Markus Armbruster | Property *prop = opaque; |
47 | d4d34b0d | Markus Armbruster | int *ptr = qdev_get_prop_ptr(dev, prop);
|
48 | d4d34b0d | Markus Armbruster | |
49 | 7983c8a3 | Andreas Färber | if (dev->realized) {
|
50 | b000dfbd | Peter Maydell | qdev_prop_set_after_realize(dev, name, errp); |
51 | d4d34b0d | Markus Armbruster | return;
|
52 | d4d34b0d | Markus Armbruster | } |
53 | d4d34b0d | Markus Armbruster | |
54 | d4d34b0d | Markus Armbruster | visit_type_enum(v, ptr, prop->info->enum_table, |
55 | d4d34b0d | Markus Armbruster | prop->info->name, prop->name, errp); |
56 | d4d34b0d | Markus Armbruster | } |
57 | d4d34b0d | Markus Armbruster | |
58 | d4d34b0d | Markus Armbruster | /* Bit */
|
59 | d4d34b0d | Markus Armbruster | |
60 | d2364ee4 | Michael S. Tsirkin | static uint32_t qdev_get_prop_mask(Property *prop)
|
61 | d2364ee4 | Michael S. Tsirkin | { |
62 | a3d4a1b0 | Paolo Bonzini | assert(prop->info == &qdev_prop_bit); |
63 | d2364ee4 | Michael S. Tsirkin | return 0x1 << prop->bitnr; |
64 | d2364ee4 | Michael S. Tsirkin | } |
65 | d2364ee4 | Michael S. Tsirkin | |
66 | d2364ee4 | Michael S. Tsirkin | static void bit_prop_set(DeviceState *dev, Property *props, bool val) |
67 | d2364ee4 | Michael S. Tsirkin | { |
68 | d2364ee4 | Michael S. Tsirkin | uint32_t *p = qdev_get_prop_ptr(dev, props); |
69 | d2364ee4 | Michael S. Tsirkin | uint32_t mask = qdev_get_prop_mask(props); |
70 | 04a2d61e | Eduardo Habkost | if (val) {
|
71 | dbd48324 | Michael S. Tsirkin | *p |= mask; |
72 | 04a2d61e | Eduardo Habkost | } else {
|
73 | d2364ee4 | Michael S. Tsirkin | *p &= ~mask; |
74 | 04a2d61e | Eduardo Habkost | } |
75 | d2364ee4 | Michael S. Tsirkin | } |
76 | d2364ee4 | Michael S. Tsirkin | |
77 | d2364ee4 | Michael S. Tsirkin | static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len) |
78 | d2364ee4 | Michael S. Tsirkin | { |
79 | 5a5e3d55 | David 'Digit' Turner | uint32_t *p = qdev_get_prop_ptr(dev, prop); |
80 | d2364ee4 | Michael S. Tsirkin | return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off"); |
81 | d2364ee4 | Michael S. Tsirkin | } |
82 | d2364ee4 | Michael S. Tsirkin | |
83 | 57c9fafe | Anthony Liguori | static void get_bit(Object *obj, Visitor *v, void *opaque, |
84 | 80e555c2 | Paolo Bonzini | const char *name, Error **errp) |
85 | 80e555c2 | Paolo Bonzini | { |
86 | 57c9fafe | Anthony Liguori | DeviceState *dev = DEVICE(obj); |
87 | 80e555c2 | Paolo Bonzini | Property *prop = opaque; |
88 | 80e555c2 | Paolo Bonzini | uint32_t *p = qdev_get_prop_ptr(dev, prop); |
89 | 80e555c2 | Paolo Bonzini | bool value = (*p & qdev_get_prop_mask(prop)) != 0; |
90 | 80e555c2 | Paolo Bonzini | |
91 | 80e555c2 | Paolo Bonzini | visit_type_bool(v, &value, name, errp); |
92 | 80e555c2 | Paolo Bonzini | } |
93 | 80e555c2 | Paolo Bonzini | |
94 | 57c9fafe | Anthony Liguori | static void set_bit(Object *obj, Visitor *v, void *opaque, |
95 | 80e555c2 | Paolo Bonzini | const char *name, Error **errp) |
96 | 80e555c2 | Paolo Bonzini | { |
97 | 57c9fafe | Anthony Liguori | DeviceState *dev = DEVICE(obj); |
98 | 80e555c2 | Paolo Bonzini | Property *prop = opaque; |
99 | 80e555c2 | Paolo Bonzini | Error *local_err = NULL;
|
100 | 80e555c2 | Paolo Bonzini | bool value;
|
101 | 80e555c2 | Paolo Bonzini | |
102 | 7983c8a3 | Andreas Färber | if (dev->realized) {
|
103 | b000dfbd | Peter Maydell | qdev_prop_set_after_realize(dev, name, errp); |
104 | 80e555c2 | Paolo Bonzini | return;
|
105 | 80e555c2 | Paolo Bonzini | } |
106 | 80e555c2 | Paolo Bonzini | |
107 | 80e555c2 | Paolo Bonzini | visit_type_bool(v, &value, name, &local_err); |
108 | 80e555c2 | Paolo Bonzini | if (local_err) {
|
109 | 80e555c2 | Paolo Bonzini | error_propagate(errp, local_err); |
110 | 80e555c2 | Paolo Bonzini | return;
|
111 | 80e555c2 | Paolo Bonzini | } |
112 | 80e555c2 | Paolo Bonzini | bit_prop_set(dev, prop, value); |
113 | 80e555c2 | Paolo Bonzini | } |
114 | 80e555c2 | Paolo Bonzini | |
115 | d2364ee4 | Michael S. Tsirkin | PropertyInfo qdev_prop_bit = { |
116 | cafe5bdb | Paolo Bonzini | .name = "boolean",
|
117 | cafe5bdb | Paolo Bonzini | .legacy_name = "on/off",
|
118 | d2364ee4 | Michael S. Tsirkin | .print = print_bit, |
119 | 80e555c2 | Paolo Bonzini | .get = get_bit, |
120 | 80e555c2 | Paolo Bonzini | .set = set_bit, |
121 | d2364ee4 | Michael S. Tsirkin | }; |
122 | d2364ee4 | Michael S. Tsirkin | |
123 | 72cc5137 | Igor Mammedov | /* --- bool --- */
|
124 | 72cc5137 | Igor Mammedov | |
125 | 72cc5137 | Igor Mammedov | static void get_bool(Object *obj, Visitor *v, void *opaque, |
126 | 72cc5137 | Igor Mammedov | const char *name, Error **errp) |
127 | 72cc5137 | Igor Mammedov | { |
128 | 72cc5137 | Igor Mammedov | DeviceState *dev = DEVICE(obj); |
129 | 72cc5137 | Igor Mammedov | Property *prop = opaque; |
130 | 72cc5137 | Igor Mammedov | bool *ptr = qdev_get_prop_ptr(dev, prop);
|
131 | 72cc5137 | Igor Mammedov | |
132 | 72cc5137 | Igor Mammedov | visit_type_bool(v, ptr, name, errp); |
133 | 72cc5137 | Igor Mammedov | } |
134 | 72cc5137 | Igor Mammedov | |
135 | 72cc5137 | Igor Mammedov | static void set_bool(Object *obj, Visitor *v, void *opaque, |
136 | 72cc5137 | Igor Mammedov | const char *name, Error **errp) |
137 | 72cc5137 | Igor Mammedov | { |
138 | 72cc5137 | Igor Mammedov | DeviceState *dev = DEVICE(obj); |
139 | 72cc5137 | Igor Mammedov | Property *prop = opaque; |
140 | 72cc5137 | Igor Mammedov | bool *ptr = qdev_get_prop_ptr(dev, prop);
|
141 | 72cc5137 | Igor Mammedov | |
142 | 72cc5137 | Igor Mammedov | if (dev->realized) {
|
143 | 72cc5137 | Igor Mammedov | qdev_prop_set_after_realize(dev, name, errp); |
144 | 72cc5137 | Igor Mammedov | return;
|
145 | 72cc5137 | Igor Mammedov | } |
146 | 72cc5137 | Igor Mammedov | |
147 | 72cc5137 | Igor Mammedov | visit_type_bool(v, ptr, name, errp); |
148 | 72cc5137 | Igor Mammedov | } |
149 | 72cc5137 | Igor Mammedov | |
150 | 72cc5137 | Igor Mammedov | PropertyInfo qdev_prop_bool = { |
151 | 72cc5137 | Igor Mammedov | .name = "boolean",
|
152 | 72cc5137 | Igor Mammedov | .get = get_bool, |
153 | 72cc5137 | Igor Mammedov | .set = set_bool, |
154 | 72cc5137 | Igor Mammedov | }; |
155 | 72cc5137 | Igor Mammedov | |
156 | c7cc172d | Juan Quintela | /* --- 8bit integer --- */
|
157 | c7cc172d | Juan Quintela | |
158 | c08fb2ac | Michael Roth | static void get_uint8(Object *obj, Visitor *v, void *opaque, |
159 | c08fb2ac | Michael Roth | const char *name, Error **errp) |
160 | 80e555c2 | Paolo Bonzini | { |
161 | 57c9fafe | Anthony Liguori | DeviceState *dev = DEVICE(obj); |
162 | 80e555c2 | Paolo Bonzini | Property *prop = opaque; |
163 | c08fb2ac | Michael Roth | uint8_t *ptr = qdev_get_prop_ptr(dev, prop); |
164 | 80e555c2 | Paolo Bonzini | |
165 | c08fb2ac | Michael Roth | visit_type_uint8(v, ptr, name, errp); |
166 | 80e555c2 | Paolo Bonzini | } |
167 | 80e555c2 | Paolo Bonzini | |
168 | c08fb2ac | Michael Roth | static void set_uint8(Object *obj, Visitor *v, void *opaque, |
169 | c08fb2ac | Michael Roth | const char *name, Error **errp) |
170 | 80e555c2 | Paolo Bonzini | { |
171 | 57c9fafe | Anthony Liguori | DeviceState *dev = DEVICE(obj); |
172 | 80e555c2 | Paolo Bonzini | Property *prop = opaque; |
173 | 27712df9 | Paolo Bonzini | uint8_t *ptr = qdev_get_prop_ptr(dev, prop); |
174 | 80e555c2 | Paolo Bonzini | |
175 | 7983c8a3 | Andreas Färber | if (dev->realized) {
|
176 | b000dfbd | Peter Maydell | qdev_prop_set_after_realize(dev, name, errp); |
177 | 80e555c2 | Paolo Bonzini | return;
|
178 | 80e555c2 | Paolo Bonzini | } |
179 | 80e555c2 | Paolo Bonzini | |
180 | 27712df9 | Paolo Bonzini | visit_type_uint8(v, ptr, name, errp); |
181 | 80e555c2 | Paolo Bonzini | } |
182 | 80e555c2 | Paolo Bonzini | |
183 | c7cc172d | Juan Quintela | PropertyInfo qdev_prop_uint8 = { |
184 | c7cc172d | Juan Quintela | .name = "uint8",
|
185 | c08fb2ac | Michael Roth | .get = get_uint8, |
186 | c08fb2ac | Michael Roth | .set = set_uint8, |
187 | c7cc172d | Juan Quintela | }; |
188 | c7cc172d | Juan Quintela | |
189 | 6835678c | Jan Kiszka | /* --- 8bit hex value --- */
|
190 | 6835678c | Jan Kiszka | |
191 | 6835678c | Jan Kiszka | static int parse_hex8(DeviceState *dev, Property *prop, const char *str) |
192 | 6835678c | Jan Kiszka | { |
193 | 6835678c | Jan Kiszka | uint8_t *ptr = qdev_get_prop_ptr(dev, prop); |
194 | 6835678c | Jan Kiszka | char *end;
|
195 | 6835678c | Jan Kiszka | |
196 | 97aa6e9b | Paolo Bonzini | if (str[0] != '0' || str[1] != 'x') { |
197 | 97aa6e9b | Paolo Bonzini | return -EINVAL;
|
198 | 97aa6e9b | Paolo Bonzini | } |
199 | 97aa6e9b | Paolo Bonzini | |
200 | 6835678c | Jan Kiszka | *ptr = strtoul(str, &end, 16);
|
201 | 6835678c | Jan Kiszka | if ((*end != '\0') || (end == str)) { |
202 | 6835678c | Jan Kiszka | return -EINVAL;
|
203 | 6835678c | Jan Kiszka | } |
204 | 6835678c | Jan Kiszka | |
205 | 6835678c | Jan Kiszka | return 0; |
206 | 6835678c | Jan Kiszka | } |
207 | 6835678c | Jan Kiszka | |
208 | 6835678c | Jan Kiszka | static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len) |
209 | 6835678c | Jan Kiszka | { |
210 | 6835678c | Jan Kiszka | uint8_t *ptr = qdev_get_prop_ptr(dev, prop); |
211 | 6835678c | Jan Kiszka | return snprintf(dest, len, "0x%" PRIx8, *ptr); |
212 | 6835678c | Jan Kiszka | } |
213 | 6835678c | Jan Kiszka | |
214 | 6835678c | Jan Kiszka | PropertyInfo qdev_prop_hex8 = { |
215 | cafe5bdb | Paolo Bonzini | .name = "uint8",
|
216 | cafe5bdb | Paolo Bonzini | .legacy_name = "hex8",
|
217 | 6835678c | Jan Kiszka | .parse = parse_hex8, |
218 | 6835678c | Jan Kiszka | .print = print_hex8, |
219 | c08fb2ac | Michael Roth | .get = get_uint8, |
220 | c08fb2ac | Michael Roth | .set = set_uint8, |
221 | 6835678c | Jan Kiszka | }; |
222 | 6835678c | Jan Kiszka | |
223 | ee6847d1 | Gerd Hoffmann | /* --- 16bit integer --- */
|
224 | ee6847d1 | Gerd Hoffmann | |
225 | c08fb2ac | Michael Roth | static void get_uint16(Object *obj, Visitor *v, void *opaque, |
226 | c08fb2ac | Michael Roth | const char *name, Error **errp) |
227 | 80e555c2 | Paolo Bonzini | { |
228 | 57c9fafe | Anthony Liguori | DeviceState *dev = DEVICE(obj); |
229 | 80e555c2 | Paolo Bonzini | Property *prop = opaque; |
230 | c08fb2ac | Michael Roth | uint16_t *ptr = qdev_get_prop_ptr(dev, prop); |
231 | 80e555c2 | Paolo Bonzini | |
232 | c08fb2ac | Michael Roth | visit_type_uint16(v, ptr, name, errp); |
233 | 80e555c2 | Paolo Bonzini | } |
234 | 80e555c2 | Paolo Bonzini | |
235 | c08fb2ac | Michael Roth | static void set_uint16(Object *obj, Visitor *v, void *opaque, |
236 | c08fb2ac | Michael Roth | const char *name, Error **errp) |
237 | 80e555c2 | Paolo Bonzini | { |
238 | 57c9fafe | Anthony Liguori | DeviceState *dev = DEVICE(obj); |
239 | 80e555c2 | Paolo Bonzini | Property *prop = opaque; |
240 | 27712df9 | Paolo Bonzini | uint16_t *ptr = qdev_get_prop_ptr(dev, prop); |
241 | 80e555c2 | Paolo Bonzini | |
242 | 7983c8a3 | Andreas Färber | if (dev->realized) {
|
243 | b000dfbd | Peter Maydell | qdev_prop_set_after_realize(dev, name, errp); |
244 | 80e555c2 | Paolo Bonzini | return;
|
245 | 80e555c2 | Paolo Bonzini | } |
246 | 80e555c2 | Paolo Bonzini | |
247 | 27712df9 | Paolo Bonzini | visit_type_uint16(v, ptr, name, errp); |
248 | 80e555c2 | Paolo Bonzini | } |
249 | 80e555c2 | Paolo Bonzini | |
250 | ee6847d1 | Gerd Hoffmann | PropertyInfo qdev_prop_uint16 = { |
251 | ee6847d1 | Gerd Hoffmann | .name = "uint16",
|
252 | c08fb2ac | Michael Roth | .get = get_uint16, |
253 | c08fb2ac | Michael Roth | .set = set_uint16, |
254 | ee6847d1 | Gerd Hoffmann | }; |
255 | ee6847d1 | Gerd Hoffmann | |
256 | ee6847d1 | Gerd Hoffmann | /* --- 32bit integer --- */
|
257 | ee6847d1 | Gerd Hoffmann | |
258 | c08fb2ac | Michael Roth | static void get_uint32(Object *obj, Visitor *v, void *opaque, |
259 | c08fb2ac | Michael Roth | const char *name, Error **errp) |
260 | c08fb2ac | Michael Roth | { |
261 | c08fb2ac | Michael Roth | DeviceState *dev = DEVICE(obj); |
262 | c08fb2ac | Michael Roth | Property *prop = opaque; |
263 | 27712df9 | Paolo Bonzini | uint32_t *ptr = qdev_get_prop_ptr(dev, prop); |
264 | c08fb2ac | Michael Roth | |
265 | 27712df9 | Paolo Bonzini | visit_type_uint32(v, ptr, name, errp); |
266 | c08fb2ac | Michael Roth | } |
267 | c08fb2ac | Michael Roth | |
268 | c08fb2ac | Michael Roth | static void set_uint32(Object *obj, Visitor *v, void *opaque, |
269 | c08fb2ac | Michael Roth | const char *name, Error **errp) |
270 | c08fb2ac | Michael Roth | { |
271 | c08fb2ac | Michael Roth | DeviceState *dev = DEVICE(obj); |
272 | c08fb2ac | Michael Roth | Property *prop = opaque; |
273 | 27712df9 | Paolo Bonzini | uint32_t *ptr = qdev_get_prop_ptr(dev, prop); |
274 | c08fb2ac | Michael Roth | |
275 | 7983c8a3 | Andreas Färber | if (dev->realized) {
|
276 | b000dfbd | Peter Maydell | qdev_prop_set_after_realize(dev, name, errp); |
277 | c08fb2ac | Michael Roth | return;
|
278 | c08fb2ac | Michael Roth | } |
279 | c08fb2ac | Michael Roth | |
280 | 27712df9 | Paolo Bonzini | visit_type_uint32(v, ptr, name, errp); |
281 | c08fb2ac | Michael Roth | } |
282 | c08fb2ac | Michael Roth | |
283 | 57c9fafe | Anthony Liguori | static void get_int32(Object *obj, Visitor *v, void *opaque, |
284 | 80e555c2 | Paolo Bonzini | const char *name, Error **errp) |
285 | 80e555c2 | Paolo Bonzini | { |
286 | 57c9fafe | Anthony Liguori | DeviceState *dev = DEVICE(obj); |
287 | 80e555c2 | Paolo Bonzini | Property *prop = opaque; |
288 | 80e555c2 | Paolo Bonzini | int32_t *ptr = qdev_get_prop_ptr(dev, prop); |
289 | 80e555c2 | Paolo Bonzini | |
290 | c08fb2ac | Michael Roth | visit_type_int32(v, ptr, name, errp); |
291 | 80e555c2 | Paolo Bonzini | } |
292 | 80e555c2 | Paolo Bonzini | |
293 | 57c9fafe | Anthony Liguori | static void set_int32(Object *obj, Visitor *v, void *opaque, |
294 | 80e555c2 | Paolo Bonzini | const char *name, Error **errp) |
295 | 80e555c2 | Paolo Bonzini | { |
296 | 57c9fafe | Anthony Liguori | DeviceState *dev = DEVICE(obj); |
297 | 80e555c2 | Paolo Bonzini | Property *prop = opaque; |
298 | 27712df9 | Paolo Bonzini | int32_t *ptr = qdev_get_prop_ptr(dev, prop); |
299 | 80e555c2 | Paolo Bonzini | |
300 | 7983c8a3 | Andreas Färber | if (dev->realized) {
|
301 | b000dfbd | Peter Maydell | qdev_prop_set_after_realize(dev, name, errp); |
302 | 80e555c2 | Paolo Bonzini | return;
|
303 | 80e555c2 | Paolo Bonzini | } |
304 | 80e555c2 | Paolo Bonzini | |
305 | 27712df9 | Paolo Bonzini | visit_type_int32(v, ptr, name, errp); |
306 | 80e555c2 | Paolo Bonzini | } |
307 | 80e555c2 | Paolo Bonzini | |
308 | ee6847d1 | Gerd Hoffmann | PropertyInfo qdev_prop_uint32 = { |
309 | ee6847d1 | Gerd Hoffmann | .name = "uint32",
|
310 | c08fb2ac | Michael Roth | .get = get_uint32, |
311 | c08fb2ac | Michael Roth | .set = set_uint32, |
312 | ee6847d1 | Gerd Hoffmann | }; |
313 | ee6847d1 | Gerd Hoffmann | |
314 | 316940b0 | Gerd Hoffmann | PropertyInfo qdev_prop_int32 = { |
315 | 316940b0 | Gerd Hoffmann | .name = "int32",
|
316 | 80e555c2 | Paolo Bonzini | .get = get_int32, |
317 | 80e555c2 | Paolo Bonzini | .set = set_int32, |
318 | 316940b0 | Gerd Hoffmann | }; |
319 | 316940b0 | Gerd Hoffmann | |
320 | ee6847d1 | Gerd Hoffmann | /* --- 32bit hex value --- */
|
321 | ee6847d1 | Gerd Hoffmann | |
322 | ee6847d1 | Gerd Hoffmann | static int parse_hex32(DeviceState *dev, Property *prop, const char *str) |
323 | ee6847d1 | Gerd Hoffmann | { |
324 | ee6847d1 | Gerd Hoffmann | uint32_t *ptr = qdev_get_prop_ptr(dev, prop); |
325 | 449041d4 | Kevin Wolf | char *end;
|
326 | ee6847d1 | Gerd Hoffmann | |
327 | 97aa6e9b | Paolo Bonzini | if (str[0] != '0' || str[1] != 'x') { |
328 | 97aa6e9b | Paolo Bonzini | return -EINVAL;
|
329 | 97aa6e9b | Paolo Bonzini | } |
330 | 97aa6e9b | Paolo Bonzini | |
331 | 449041d4 | Kevin Wolf | *ptr = strtoul(str, &end, 16);
|
332 | 449041d4 | Kevin Wolf | if ((*end != '\0') || (end == str)) { |
333 | 6bf38816 | Markus Armbruster | return -EINVAL;
|
334 | 449041d4 | Kevin Wolf | } |
335 | 449041d4 | Kevin Wolf | |
336 | ee6847d1 | Gerd Hoffmann | return 0; |
337 | ee6847d1 | Gerd Hoffmann | } |
338 | ee6847d1 | Gerd Hoffmann | |
339 | ee6847d1 | Gerd Hoffmann | static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len) |
340 | ee6847d1 | Gerd Hoffmann | { |
341 | ee6847d1 | Gerd Hoffmann | uint32_t *ptr = qdev_get_prop_ptr(dev, prop); |
342 | ee6847d1 | Gerd Hoffmann | return snprintf(dest, len, "0x%" PRIx32, *ptr); |
343 | ee6847d1 | Gerd Hoffmann | } |
344 | ee6847d1 | Gerd Hoffmann | |
345 | ee6847d1 | Gerd Hoffmann | PropertyInfo qdev_prop_hex32 = { |
346 | cafe5bdb | Paolo Bonzini | .name = "uint32",
|
347 | cafe5bdb | Paolo Bonzini | .legacy_name = "hex32",
|
348 | ee6847d1 | Gerd Hoffmann | .parse = parse_hex32, |
349 | ee6847d1 | Gerd Hoffmann | .print = print_hex32, |
350 | c08fb2ac | Michael Roth | .get = get_uint32, |
351 | c08fb2ac | Michael Roth | .set = set_uint32, |
352 | ee6847d1 | Gerd Hoffmann | }; |
353 | ee6847d1 | Gerd Hoffmann | |
354 | 5a053d1f | Blue Swirl | /* --- 64bit integer --- */
|
355 | 5a053d1f | Blue Swirl | |
356 | c08fb2ac | Michael Roth | static void get_uint64(Object *obj, Visitor *v, void *opaque, |
357 | c08fb2ac | Michael Roth | const char *name, Error **errp) |
358 | 80e555c2 | Paolo Bonzini | { |
359 | 57c9fafe | Anthony Liguori | DeviceState *dev = DEVICE(obj); |
360 | 80e555c2 | Paolo Bonzini | Property *prop = opaque; |
361 | c08fb2ac | Michael Roth | uint64_t *ptr = qdev_get_prop_ptr(dev, prop); |
362 | 80e555c2 | Paolo Bonzini | |
363 | c08fb2ac | Michael Roth | visit_type_uint64(v, ptr, name, errp); |
364 | 80e555c2 | Paolo Bonzini | } |
365 | 80e555c2 | Paolo Bonzini | |
366 | c08fb2ac | Michael Roth | static void set_uint64(Object *obj, Visitor *v, void *opaque, |
367 | c08fb2ac | Michael Roth | const char *name, Error **errp) |
368 | 80e555c2 | Paolo Bonzini | { |
369 | 57c9fafe | Anthony Liguori | DeviceState *dev = DEVICE(obj); |
370 | 80e555c2 | Paolo Bonzini | Property *prop = opaque; |
371 | c08fb2ac | Michael Roth | uint64_t *ptr = qdev_get_prop_ptr(dev, prop); |
372 | 80e555c2 | Paolo Bonzini | |
373 | 7983c8a3 | Andreas Färber | if (dev->realized) {
|
374 | b000dfbd | Peter Maydell | qdev_prop_set_after_realize(dev, name, errp); |
375 | 80e555c2 | Paolo Bonzini | return;
|
376 | 80e555c2 | Paolo Bonzini | } |
377 | 80e555c2 | Paolo Bonzini | |
378 | c08fb2ac | Michael Roth | visit_type_uint64(v, ptr, name, errp); |
379 | 80e555c2 | Paolo Bonzini | } |
380 | 80e555c2 | Paolo Bonzini | |
381 | 5a053d1f | Blue Swirl | PropertyInfo qdev_prop_uint64 = { |
382 | 5a053d1f | Blue Swirl | .name = "uint64",
|
383 | c08fb2ac | Michael Roth | .get = get_uint64, |
384 | c08fb2ac | Michael Roth | .set = set_uint64, |
385 | 5a053d1f | Blue Swirl | }; |
386 | 5a053d1f | Blue Swirl | |
387 | 5a053d1f | Blue Swirl | /* --- 64bit hex value --- */
|
388 | 5a053d1f | Blue Swirl | |
389 | 5a053d1f | Blue Swirl | static int parse_hex64(DeviceState *dev, Property *prop, const char *str) |
390 | 5a053d1f | Blue Swirl | { |
391 | 5a053d1f | Blue Swirl | uint64_t *ptr = qdev_get_prop_ptr(dev, prop); |
392 | 449041d4 | Kevin Wolf | char *end;
|
393 | 5a053d1f | Blue Swirl | |
394 | 97aa6e9b | Paolo Bonzini | if (str[0] != '0' || str[1] != 'x') { |
395 | 97aa6e9b | Paolo Bonzini | return -EINVAL;
|
396 | 97aa6e9b | Paolo Bonzini | } |
397 | 97aa6e9b | Paolo Bonzini | |
398 | 449041d4 | Kevin Wolf | *ptr = strtoull(str, &end, 16);
|
399 | 449041d4 | Kevin Wolf | if ((*end != '\0') || (end == str)) { |
400 | 6bf38816 | Markus Armbruster | return -EINVAL;
|
401 | 449041d4 | Kevin Wolf | } |
402 | 449041d4 | Kevin Wolf | |
403 | 5a053d1f | Blue Swirl | return 0; |
404 | 5a053d1f | Blue Swirl | } |
405 | 5a053d1f | Blue Swirl | |
406 | 5a053d1f | Blue Swirl | static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len) |
407 | 5a053d1f | Blue Swirl | { |
408 | 5a053d1f | Blue Swirl | uint64_t *ptr = qdev_get_prop_ptr(dev, prop); |
409 | 5a053d1f | Blue Swirl | return snprintf(dest, len, "0x%" PRIx64, *ptr); |
410 | 5a053d1f | Blue Swirl | } |
411 | 5a053d1f | Blue Swirl | |
412 | 5a053d1f | Blue Swirl | PropertyInfo qdev_prop_hex64 = { |
413 | cafe5bdb | Paolo Bonzini | .name = "uint64",
|
414 | cafe5bdb | Paolo Bonzini | .legacy_name = "hex64",
|
415 | 5a053d1f | Blue Swirl | .parse = parse_hex64, |
416 | 5a053d1f | Blue Swirl | .print = print_hex64, |
417 | c08fb2ac | Michael Roth | .get = get_uint64, |
418 | c08fb2ac | Michael Roth | .set = set_uint64, |
419 | 5a053d1f | Blue Swirl | }; |
420 | 5a053d1f | Blue Swirl | |
421 | 59419663 | Gerd Hoffmann | /* --- string --- */
|
422 | 59419663 | Gerd Hoffmann | |
423 | dd0ba250 | Paolo Bonzini | static void release_string(Object *obj, const char *name, void *opaque) |
424 | d21357df | Markus Armbruster | { |
425 | dd0ba250 | Paolo Bonzini | Property *prop = opaque; |
426 | dd0ba250 | Paolo Bonzini | g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
|
427 | d21357df | Markus Armbruster | } |
428 | d21357df | Markus Armbruster | |
429 | 04a2d61e | Eduardo Habkost | static int print_string(DeviceState *dev, Property *prop, char *dest, |
430 | 04a2d61e | Eduardo Habkost | size_t len) |
431 | 59419663 | Gerd Hoffmann | { |
432 | 59419663 | Gerd Hoffmann | char **ptr = qdev_get_prop_ptr(dev, prop);
|
433 | 04a2d61e | Eduardo Habkost | if (!*ptr) {
|
434 | 59419663 | Gerd Hoffmann | return snprintf(dest, len, "<null>"); |
435 | 04a2d61e | Eduardo Habkost | } |
436 | 59419663 | Gerd Hoffmann | return snprintf(dest, len, "\"%s\"", *ptr); |
437 | 59419663 | Gerd Hoffmann | } |
438 | 59419663 | Gerd Hoffmann | |
439 | 57c9fafe | Anthony Liguori | static void get_string(Object *obj, Visitor *v, void *opaque, |
440 | 80e555c2 | Paolo Bonzini | const char *name, Error **errp) |
441 | 80e555c2 | Paolo Bonzini | { |
442 | 57c9fafe | Anthony Liguori | DeviceState *dev = DEVICE(obj); |
443 | 80e555c2 | Paolo Bonzini | Property *prop = opaque; |
444 | 80e555c2 | Paolo Bonzini | char **ptr = qdev_get_prop_ptr(dev, prop);
|
445 | 80e555c2 | Paolo Bonzini | |
446 | 80e555c2 | Paolo Bonzini | if (!*ptr) {
|
447 | 80e555c2 | Paolo Bonzini | char *str = (char *)""; |
448 | 80e555c2 | Paolo Bonzini | visit_type_str(v, &str, name, errp); |
449 | 80e555c2 | Paolo Bonzini | } else {
|
450 | 80e555c2 | Paolo Bonzini | visit_type_str(v, ptr, name, errp); |
451 | 80e555c2 | Paolo Bonzini | } |
452 | 80e555c2 | Paolo Bonzini | } |
453 | 80e555c2 | Paolo Bonzini | |
454 | 57c9fafe | Anthony Liguori | static void set_string(Object *obj, Visitor *v, void *opaque, |
455 | 80e555c2 | Paolo Bonzini | const char *name, Error **errp) |
456 | 80e555c2 | Paolo Bonzini | { |
457 | 57c9fafe | Anthony Liguori | DeviceState *dev = DEVICE(obj); |
458 | 80e555c2 | Paolo Bonzini | Property *prop = opaque; |
459 | 80e555c2 | Paolo Bonzini | char **ptr = qdev_get_prop_ptr(dev, prop);
|
460 | 80e555c2 | Paolo Bonzini | Error *local_err = NULL;
|
461 | 80e555c2 | Paolo Bonzini | char *str;
|
462 | 80e555c2 | Paolo Bonzini | |
463 | 7983c8a3 | Andreas Färber | if (dev->realized) {
|
464 | b000dfbd | Peter Maydell | qdev_prop_set_after_realize(dev, name, errp); |
465 | 80e555c2 | Paolo Bonzini | return;
|
466 | 80e555c2 | Paolo Bonzini | } |
467 | 80e555c2 | Paolo Bonzini | |
468 | 80e555c2 | Paolo Bonzini | visit_type_str(v, &str, name, &local_err); |
469 | 80e555c2 | Paolo Bonzini | if (local_err) {
|
470 | 80e555c2 | Paolo Bonzini | error_propagate(errp, local_err); |
471 | 80e555c2 | Paolo Bonzini | return;
|
472 | 80e555c2 | Paolo Bonzini | } |
473 | 80e555c2 | Paolo Bonzini | if (*ptr) {
|
474 | 80e555c2 | Paolo Bonzini | g_free(*ptr); |
475 | 80e555c2 | Paolo Bonzini | } |
476 | 80e555c2 | Paolo Bonzini | *ptr = str; |
477 | 80e555c2 | Paolo Bonzini | } |
478 | 80e555c2 | Paolo Bonzini | |
479 | 59419663 | Gerd Hoffmann | PropertyInfo qdev_prop_string = { |
480 | 59419663 | Gerd Hoffmann | .name = "string",
|
481 | 59419663 | Gerd Hoffmann | .print = print_string, |
482 | dd0ba250 | Paolo Bonzini | .release = release_string, |
483 | 80e555c2 | Paolo Bonzini | .get = get_string, |
484 | 80e555c2 | Paolo Bonzini | .set = set_string, |
485 | 59419663 | Gerd Hoffmann | }; |
486 | 59419663 | Gerd Hoffmann | |
487 | ee6847d1 | Gerd Hoffmann | /* --- pointer --- */
|
488 | ee6847d1 | Gerd Hoffmann | |
489 | 036f7166 | Markus Armbruster | /* Not a proper property, just for dirty hacks. TODO Remove it! */
|
490 | ee6847d1 | Gerd Hoffmann | PropertyInfo qdev_prop_ptr = { |
491 | ee6847d1 | Gerd Hoffmann | .name = "ptr",
|
492 | ee6847d1 | Gerd Hoffmann | }; |
493 | ee6847d1 | Gerd Hoffmann | |
494 | ee6847d1 | Gerd Hoffmann | /* --- mac address --- */
|
495 | ee6847d1 | Gerd Hoffmann | |
496 | ee6847d1 | Gerd Hoffmann | /*
|
497 | ee6847d1 | Gerd Hoffmann | * accepted syntax versions:
|
498 | ee6847d1 | Gerd Hoffmann | * 01:02:03:04:05:06
|
499 | ee6847d1 | Gerd Hoffmann | * 01-02-03-04-05-06
|
500 | ee6847d1 | Gerd Hoffmann | */
|
501 | e39e5d60 | Paolo Bonzini | static void get_mac(Object *obj, Visitor *v, void *opaque, |
502 | e39e5d60 | Paolo Bonzini | const char *name, Error **errp) |
503 | ee6847d1 | Gerd Hoffmann | { |
504 | e39e5d60 | Paolo Bonzini | DeviceState *dev = DEVICE(obj); |
505 | e39e5d60 | Paolo Bonzini | Property *prop = opaque; |
506 | 1503fff3 | Gerd Hoffmann | MACAddr *mac = qdev_get_prop_ptr(dev, prop); |
507 | e39e5d60 | Paolo Bonzini | char buffer[2 * 6 + 5 + 1]; |
508 | e39e5d60 | Paolo Bonzini | char *p = buffer;
|
509 | e39e5d60 | Paolo Bonzini | |
510 | e39e5d60 | Paolo Bonzini | snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x", |
511 | e39e5d60 | Paolo Bonzini | mac->a[0], mac->a[1], mac->a[2], |
512 | e39e5d60 | Paolo Bonzini | mac->a[3], mac->a[4], mac->a[5]); |
513 | e39e5d60 | Paolo Bonzini | |
514 | e39e5d60 | Paolo Bonzini | visit_type_str(v, &p, name, errp); |
515 | e39e5d60 | Paolo Bonzini | } |
516 | e39e5d60 | Paolo Bonzini | |
517 | e39e5d60 | Paolo Bonzini | static void set_mac(Object *obj, Visitor *v, void *opaque, |
518 | e39e5d60 | Paolo Bonzini | const char *name, Error **errp) |
519 | e39e5d60 | Paolo Bonzini | { |
520 | e39e5d60 | Paolo Bonzini | DeviceState *dev = DEVICE(obj); |
521 | e39e5d60 | Paolo Bonzini | Property *prop = opaque; |
522 | e39e5d60 | Paolo Bonzini | MACAddr *mac = qdev_get_prop_ptr(dev, prop); |
523 | e39e5d60 | Paolo Bonzini | Error *local_err = NULL;
|
524 | ee6847d1 | Gerd Hoffmann | int i, pos;
|
525 | e39e5d60 | Paolo Bonzini | char *str, *p;
|
526 | e39e5d60 | Paolo Bonzini | |
527 | 7983c8a3 | Andreas Färber | if (dev->realized) {
|
528 | b000dfbd | Peter Maydell | qdev_prop_set_after_realize(dev, name, errp); |
529 | e39e5d60 | Paolo Bonzini | return;
|
530 | e39e5d60 | Paolo Bonzini | } |
531 | e39e5d60 | Paolo Bonzini | |
532 | e39e5d60 | Paolo Bonzini | visit_type_str(v, &str, name, &local_err); |
533 | e39e5d60 | Paolo Bonzini | if (local_err) {
|
534 | e39e5d60 | Paolo Bonzini | error_propagate(errp, local_err); |
535 | e39e5d60 | Paolo Bonzini | return;
|
536 | e39e5d60 | Paolo Bonzini | } |
537 | ee6847d1 | Gerd Hoffmann | |
538 | ee6847d1 | Gerd Hoffmann | for (i = 0, pos = 0; i < 6; i++, pos += 3) { |
539 | 04a2d61e | Eduardo Habkost | if (!qemu_isxdigit(str[pos])) {
|
540 | e39e5d60 | Paolo Bonzini | goto inval;
|
541 | 04a2d61e | Eduardo Habkost | } |
542 | 04a2d61e | Eduardo Habkost | if (!qemu_isxdigit(str[pos+1])) { |
543 | e39e5d60 | Paolo Bonzini | goto inval;
|
544 | 04a2d61e | Eduardo Habkost | } |
545 | 1503fff3 | Gerd Hoffmann | if (i == 5) { |
546 | 04a2d61e | Eduardo Habkost | if (str[pos+2] != '\0') { |
547 | e39e5d60 | Paolo Bonzini | goto inval;
|
548 | 04a2d61e | Eduardo Habkost | } |
549 | 1503fff3 | Gerd Hoffmann | } else {
|
550 | 04a2d61e | Eduardo Habkost | if (str[pos+2] != ':' && str[pos+2] != '-') { |
551 | e39e5d60 | Paolo Bonzini | goto inval;
|
552 | 04a2d61e | Eduardo Habkost | } |
553 | 1503fff3 | Gerd Hoffmann | } |
554 | 1503fff3 | Gerd Hoffmann | mac->a[i] = strtol(str+pos, &p, 16);
|
555 | ee6847d1 | Gerd Hoffmann | } |
556 | a3400466 | dunrong huang | g_free(str); |
557 | e39e5d60 | Paolo Bonzini | return;
|
558 | 1503fff3 | Gerd Hoffmann | |
559 | e39e5d60 | Paolo Bonzini | inval:
|
560 | e39e5d60 | Paolo Bonzini | error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); |
561 | a3400466 | dunrong huang | g_free(str); |
562 | ee6847d1 | Gerd Hoffmann | } |
563 | ee6847d1 | Gerd Hoffmann | |
564 | ee6847d1 | Gerd Hoffmann | PropertyInfo qdev_prop_macaddr = { |
565 | 1503fff3 | Gerd Hoffmann | .name = "macaddr",
|
566 | e39e5d60 | Paolo Bonzini | .get = get_mac, |
567 | e39e5d60 | Paolo Bonzini | .set = set_mac, |
568 | ee6847d1 | Gerd Hoffmann | }; |
569 | ee6847d1 | Gerd Hoffmann | |
570 | 4e4fa398 | Jan Kiszka | /* --- lost tick policy --- */
|
571 | 4e4fa398 | Jan Kiszka | |
572 | 1ce05125 | Paolo Bonzini | static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = { |
573 | 1ce05125 | Paolo Bonzini | [LOST_TICK_DISCARD] = "discard",
|
574 | 1ce05125 | Paolo Bonzini | [LOST_TICK_DELAY] = "delay",
|
575 | 1ce05125 | Paolo Bonzini | [LOST_TICK_MERGE] = "merge",
|
576 | 1ce05125 | Paolo Bonzini | [LOST_TICK_SLEW] = "slew",
|
577 | 1ce05125 | Paolo Bonzini | [LOST_TICK_MAX] = NULL,
|
578 | 4e4fa398 | Jan Kiszka | }; |
579 | 4e4fa398 | Jan Kiszka | |
580 | 1ce05125 | Paolo Bonzini | QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int)); |
581 | 1ce05125 | Paolo Bonzini | |
582 | 4e4fa398 | Jan Kiszka | PropertyInfo qdev_prop_losttickpolicy = { |
583 | 1ce05125 | Paolo Bonzini | .name = "LostTickPolicy",
|
584 | 1ce05125 | Paolo Bonzini | .enum_table = lost_tick_policy_table, |
585 | 1ce05125 | Paolo Bonzini | .get = get_enum, |
586 | 1ce05125 | Paolo Bonzini | .set = set_enum, |
587 | 4e4fa398 | Jan Kiszka | }; |
588 | 4e4fa398 | Jan Kiszka | |
589 | 8cd41745 | Markus Armbruster | /* --- BIOS CHS translation */
|
590 | 8cd41745 | Markus Armbruster | |
591 | 8cd41745 | Markus Armbruster | static const char *bios_chs_trans_table[] = { |
592 | 8cd41745 | Markus Armbruster | [BIOS_ATA_TRANSLATION_AUTO] = "auto",
|
593 | 8cd41745 | Markus Armbruster | [BIOS_ATA_TRANSLATION_NONE] = "none",
|
594 | 8cd41745 | Markus Armbruster | [BIOS_ATA_TRANSLATION_LBA] = "lba",
|
595 | 8cd41745 | Markus Armbruster | }; |
596 | 8cd41745 | Markus Armbruster | |
597 | 8cd41745 | Markus Armbruster | PropertyInfo qdev_prop_bios_chs_trans = { |
598 | 8cd41745 | Markus Armbruster | .name = "bios-chs-trans",
|
599 | 8cd41745 | Markus Armbruster | .enum_table = bios_chs_trans_table, |
600 | 8cd41745 | Markus Armbruster | .get = get_enum, |
601 | 8cd41745 | Markus Armbruster | .set = set_enum, |
602 | 8cd41745 | Markus Armbruster | }; |
603 | 8cd41745 | Markus Armbruster | |
604 | 05cb5fe4 | Gerd Hoffmann | /* --- pci address --- */
|
605 | 05cb5fe4 | Gerd Hoffmann | |
606 | 05cb5fe4 | Gerd Hoffmann | /*
|
607 | 05cb5fe4 | Gerd Hoffmann | * bus-local address, i.e. "$slot" or "$slot.$fn"
|
608 | 05cb5fe4 | Gerd Hoffmann | */
|
609 | 768a9ebe | Paolo Bonzini | static void set_pci_devfn(Object *obj, Visitor *v, void *opaque, |
610 | 768a9ebe | Paolo Bonzini | const char *name, Error **errp) |
611 | 05cb5fe4 | Gerd Hoffmann | { |
612 | 768a9ebe | Paolo Bonzini | DeviceState *dev = DEVICE(obj); |
613 | 768a9ebe | Paolo Bonzini | Property *prop = opaque; |
614 | 27712df9 | Paolo Bonzini | int32_t value, *ptr = qdev_get_prop_ptr(dev, prop); |
615 | 05cb5fe4 | Gerd Hoffmann | unsigned int slot, fn, n; |
616 | 768a9ebe | Paolo Bonzini | Error *local_err = NULL;
|
617 | a3400466 | dunrong huang | char *str;
|
618 | 768a9ebe | Paolo Bonzini | |
619 | 7983c8a3 | Andreas Färber | if (dev->realized) {
|
620 | b000dfbd | Peter Maydell | qdev_prop_set_after_realize(dev, name, errp); |
621 | 768a9ebe | Paolo Bonzini | return;
|
622 | 768a9ebe | Paolo Bonzini | } |
623 | 768a9ebe | Paolo Bonzini | |
624 | 768a9ebe | Paolo Bonzini | visit_type_str(v, &str, name, &local_err); |
625 | 768a9ebe | Paolo Bonzini | if (local_err) {
|
626 | 5c878008 | Stefan Weil | error_free(local_err); |
627 | 27712df9 | Paolo Bonzini | local_err = NULL;
|
628 | 27712df9 | Paolo Bonzini | visit_type_int32(v, &value, name, &local_err); |
629 | 27712df9 | Paolo Bonzini | if (local_err) {
|
630 | 27712df9 | Paolo Bonzini | error_propagate(errp, local_err); |
631 | 27712df9 | Paolo Bonzini | } else if (value < -1 || value > 255) { |
632 | 27712df9 | Paolo Bonzini | error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
|
633 | 27712df9 | Paolo Bonzini | "pci_devfn");
|
634 | 27712df9 | Paolo Bonzini | } else {
|
635 | 27712df9 | Paolo Bonzini | *ptr = value; |
636 | 27712df9 | Paolo Bonzini | } |
637 | 27712df9 | Paolo Bonzini | return;
|
638 | 768a9ebe | Paolo Bonzini | } |
639 | 05cb5fe4 | Gerd Hoffmann | |
640 | 05cb5fe4 | Gerd Hoffmann | if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) { |
641 | 05cb5fe4 | Gerd Hoffmann | fn = 0;
|
642 | 05cb5fe4 | Gerd Hoffmann | if (sscanf(str, "%x%n", &slot, &n) != 1) { |
643 | 768a9ebe | Paolo Bonzini | goto invalid;
|
644 | 05cb5fe4 | Gerd Hoffmann | } |
645 | 05cb5fe4 | Gerd Hoffmann | } |
646 | 768a9ebe | Paolo Bonzini | if (str[n] != '\0' || fn > 7 || slot > 31) { |
647 | 768a9ebe | Paolo Bonzini | goto invalid;
|
648 | 768a9ebe | Paolo Bonzini | } |
649 | 05cb5fe4 | Gerd Hoffmann | *ptr = slot << 3 | fn;
|
650 | a3400466 | dunrong huang | g_free(str); |
651 | 768a9ebe | Paolo Bonzini | return;
|
652 | 768a9ebe | Paolo Bonzini | |
653 | 768a9ebe | Paolo Bonzini | invalid:
|
654 | 768a9ebe | Paolo Bonzini | error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); |
655 | a3400466 | dunrong huang | g_free(str); |
656 | 05cb5fe4 | Gerd Hoffmann | } |
657 | 05cb5fe4 | Gerd Hoffmann | |
658 | 04a2d61e | Eduardo Habkost | static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, |
659 | 04a2d61e | Eduardo Habkost | size_t len) |
660 | 05cb5fe4 | Gerd Hoffmann | { |
661 | 09f1bbcd | Michael Roth | int32_t *ptr = qdev_get_prop_ptr(dev, prop); |
662 | 05cb5fe4 | Gerd Hoffmann | |
663 | 73538c31 | Blue Swirl | if (*ptr == -1) { |
664 | 05cb5fe4 | Gerd Hoffmann | return snprintf(dest, len, "<unset>"); |
665 | 05cb5fe4 | Gerd Hoffmann | } else {
|
666 | 05cb5fe4 | Gerd Hoffmann | return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7); |
667 | 05cb5fe4 | Gerd Hoffmann | } |
668 | 05cb5fe4 | Gerd Hoffmann | } |
669 | 05cb5fe4 | Gerd Hoffmann | |
670 | 05cb5fe4 | Gerd Hoffmann | PropertyInfo qdev_prop_pci_devfn = { |
671 | b403298a | Paolo Bonzini | .name = "int32",
|
672 | b403298a | Paolo Bonzini | .legacy_name = "pci-devfn",
|
673 | 05cb5fe4 | Gerd Hoffmann | .print = print_pci_devfn, |
674 | b403298a | Paolo Bonzini | .get = get_int32, |
675 | 768a9ebe | Paolo Bonzini | .set = set_pci_devfn, |
676 | 05cb5fe4 | Gerd Hoffmann | }; |
677 | 05cb5fe4 | Gerd Hoffmann | |
678 | 02fda01c | Stefan Hajnoczi | /* --- blocksize --- */
|
679 | 02fda01c | Stefan Hajnoczi | |
680 | 02fda01c | Stefan Hajnoczi | static void set_blocksize(Object *obj, Visitor *v, void *opaque, |
681 | 02fda01c | Stefan Hajnoczi | const char *name, Error **errp) |
682 | 02fda01c | Stefan Hajnoczi | { |
683 | 02fda01c | Stefan Hajnoczi | DeviceState *dev = DEVICE(obj); |
684 | 02fda01c | Stefan Hajnoczi | Property *prop = opaque; |
685 | c08fb2ac | Michael Roth | uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop); |
686 | 02fda01c | Stefan Hajnoczi | Error *local_err = NULL;
|
687 | 27712df9 | Paolo Bonzini | const int64_t min = 512; |
688 | 27712df9 | Paolo Bonzini | const int64_t max = 32768; |
689 | 02fda01c | Stefan Hajnoczi | |
690 | 7983c8a3 | Andreas Färber | if (dev->realized) {
|
691 | b000dfbd | Peter Maydell | qdev_prop_set_after_realize(dev, name, errp); |
692 | 02fda01c | Stefan Hajnoczi | return;
|
693 | 02fda01c | Stefan Hajnoczi | } |
694 | 02fda01c | Stefan Hajnoczi | |
695 | c08fb2ac | Michael Roth | visit_type_uint16(v, &value, name, &local_err); |
696 | 02fda01c | Stefan Hajnoczi | if (local_err) {
|
697 | 02fda01c | Stefan Hajnoczi | error_propagate(errp, local_err); |
698 | 02fda01c | Stefan Hajnoczi | return;
|
699 | 02fda01c | Stefan Hajnoczi | } |
700 | 27712df9 | Paolo Bonzini | if (value < min || value > max) {
|
701 | 02fda01c | Stefan Hajnoczi | error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, |
702 | 27712df9 | Paolo Bonzini | dev->id?:"", name, (int64_t)value, min, max);
|
703 | 02fda01c | Stefan Hajnoczi | return;
|
704 | 02fda01c | Stefan Hajnoczi | } |
705 | 02fda01c | Stefan Hajnoczi | |
706 | 02fda01c | Stefan Hajnoczi | /* We rely on power-of-2 blocksizes for bitmasks */
|
707 | 02fda01c | Stefan Hajnoczi | if ((value & (value - 1)) != 0) { |
708 | 02fda01c | Stefan Hajnoczi | error_set(errp, QERR_PROPERTY_VALUE_NOT_POWER_OF_2, |
709 | c08fb2ac | Michael Roth | dev->id?:"", name, (int64_t)value);
|
710 | 02fda01c | Stefan Hajnoczi | return;
|
711 | 02fda01c | Stefan Hajnoczi | } |
712 | 02fda01c | Stefan Hajnoczi | |
713 | 02fda01c | Stefan Hajnoczi | *ptr = value; |
714 | 02fda01c | Stefan Hajnoczi | } |
715 | 02fda01c | Stefan Hajnoczi | |
716 | 02fda01c | Stefan Hajnoczi | PropertyInfo qdev_prop_blocksize = { |
717 | 02fda01c | Stefan Hajnoczi | .name = "blocksize",
|
718 | c08fb2ac | Michael Roth | .get = get_uint16, |
719 | 02fda01c | Stefan Hajnoczi | .set = set_blocksize, |
720 | 02fda01c | Stefan Hajnoczi | }; |
721 | 02fda01c | Stefan Hajnoczi | |
722 | 679042f0 | Anthony PERARD | /* --- pci host address --- */
|
723 | 679042f0 | Anthony PERARD | |
724 | 679042f0 | Anthony PERARD | static void get_pci_host_devaddr(Object *obj, Visitor *v, void *opaque, |
725 | 679042f0 | Anthony PERARD | const char *name, Error **errp) |
726 | 679042f0 | Anthony PERARD | { |
727 | 679042f0 | Anthony PERARD | DeviceState *dev = DEVICE(obj); |
728 | 679042f0 | Anthony PERARD | Property *prop = opaque; |
729 | 679042f0 | Anthony PERARD | PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop); |
730 | 679042f0 | Anthony PERARD | char buffer[] = "xxxx:xx:xx.x"; |
731 | 679042f0 | Anthony PERARD | char *p = buffer;
|
732 | 679042f0 | Anthony PERARD | int rc = 0; |
733 | 679042f0 | Anthony PERARD | |
734 | 679042f0 | Anthony PERARD | rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d", |
735 | 679042f0 | Anthony PERARD | addr->domain, addr->bus, addr->slot, addr->function); |
736 | 679042f0 | Anthony PERARD | assert(rc == sizeof(buffer) - 1); |
737 | 679042f0 | Anthony PERARD | |
738 | 679042f0 | Anthony PERARD | visit_type_str(v, &p, name, errp); |
739 | 679042f0 | Anthony PERARD | } |
740 | 679042f0 | Anthony PERARD | |
741 | 679042f0 | Anthony PERARD | /*
|
742 | 679042f0 | Anthony PERARD | * Parse [<domain>:]<bus>:<slot>.<func>
|
743 | 679042f0 | Anthony PERARD | * if <domain> is not supplied, it's assumed to be 0.
|
744 | 679042f0 | Anthony PERARD | */
|
745 | 679042f0 | Anthony PERARD | static void set_pci_host_devaddr(Object *obj, Visitor *v, void *opaque, |
746 | 679042f0 | Anthony PERARD | const char *name, Error **errp) |
747 | 679042f0 | Anthony PERARD | { |
748 | 679042f0 | Anthony PERARD | DeviceState *dev = DEVICE(obj); |
749 | 679042f0 | Anthony PERARD | Property *prop = opaque; |
750 | 679042f0 | Anthony PERARD | PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop); |
751 | 679042f0 | Anthony PERARD | Error *local_err = NULL;
|
752 | 679042f0 | Anthony PERARD | char *str, *p;
|
753 | 679042f0 | Anthony PERARD | char *e;
|
754 | 679042f0 | Anthony PERARD | unsigned long val; |
755 | 679042f0 | Anthony PERARD | unsigned long dom = 0, bus = 0; |
756 | 679042f0 | Anthony PERARD | unsigned int slot = 0, func = 0; |
757 | 679042f0 | Anthony PERARD | |
758 | 7983c8a3 | Andreas Färber | if (dev->realized) {
|
759 | b000dfbd | Peter Maydell | qdev_prop_set_after_realize(dev, name, errp); |
760 | 679042f0 | Anthony PERARD | return;
|
761 | 679042f0 | Anthony PERARD | } |
762 | 679042f0 | Anthony PERARD | |
763 | 679042f0 | Anthony PERARD | visit_type_str(v, &str, name, &local_err); |
764 | 679042f0 | Anthony PERARD | if (local_err) {
|
765 | 679042f0 | Anthony PERARD | error_propagate(errp, local_err); |
766 | 679042f0 | Anthony PERARD | return;
|
767 | 679042f0 | Anthony PERARD | } |
768 | 679042f0 | Anthony PERARD | |
769 | 679042f0 | Anthony PERARD | p = str; |
770 | 679042f0 | Anthony PERARD | val = strtoul(p, &e, 16);
|
771 | 679042f0 | Anthony PERARD | if (e == p || *e != ':') { |
772 | 679042f0 | Anthony PERARD | goto inval;
|
773 | 679042f0 | Anthony PERARD | } |
774 | 679042f0 | Anthony PERARD | bus = val; |
775 | 679042f0 | Anthony PERARD | |
776 | 679042f0 | Anthony PERARD | p = e + 1;
|
777 | 679042f0 | Anthony PERARD | val = strtoul(p, &e, 16);
|
778 | 679042f0 | Anthony PERARD | if (e == p) {
|
779 | 679042f0 | Anthony PERARD | goto inval;
|
780 | 679042f0 | Anthony PERARD | } |
781 | 679042f0 | Anthony PERARD | if (*e == ':') { |
782 | 679042f0 | Anthony PERARD | dom = bus; |
783 | 679042f0 | Anthony PERARD | bus = val; |
784 | 679042f0 | Anthony PERARD | p = e + 1;
|
785 | 679042f0 | Anthony PERARD | val = strtoul(p, &e, 16);
|
786 | 679042f0 | Anthony PERARD | if (e == p) {
|
787 | 679042f0 | Anthony PERARD | goto inval;
|
788 | 679042f0 | Anthony PERARD | } |
789 | 679042f0 | Anthony PERARD | } |
790 | 679042f0 | Anthony PERARD | slot = val; |
791 | 679042f0 | Anthony PERARD | |
792 | 679042f0 | Anthony PERARD | if (*e != '.') { |
793 | 679042f0 | Anthony PERARD | goto inval;
|
794 | 679042f0 | Anthony PERARD | } |
795 | 679042f0 | Anthony PERARD | p = e + 1;
|
796 | 679042f0 | Anthony PERARD | val = strtoul(p, &e, 10);
|
797 | 679042f0 | Anthony PERARD | if (e == p) {
|
798 | 679042f0 | Anthony PERARD | goto inval;
|
799 | 679042f0 | Anthony PERARD | } |
800 | 679042f0 | Anthony PERARD | func = val; |
801 | 679042f0 | Anthony PERARD | |
802 | 679042f0 | Anthony PERARD | if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) { |
803 | 679042f0 | Anthony PERARD | goto inval;
|
804 | 679042f0 | Anthony PERARD | } |
805 | 679042f0 | Anthony PERARD | |
806 | 679042f0 | Anthony PERARD | if (*e) {
|
807 | 679042f0 | Anthony PERARD | goto inval;
|
808 | 679042f0 | Anthony PERARD | } |
809 | 679042f0 | Anthony PERARD | |
810 | 679042f0 | Anthony PERARD | addr->domain = dom; |
811 | 679042f0 | Anthony PERARD | addr->bus = bus; |
812 | 679042f0 | Anthony PERARD | addr->slot = slot; |
813 | 679042f0 | Anthony PERARD | addr->function = func; |
814 | 679042f0 | Anthony PERARD | |
815 | 679042f0 | Anthony PERARD | g_free(str); |
816 | 679042f0 | Anthony PERARD | return;
|
817 | 679042f0 | Anthony PERARD | |
818 | 679042f0 | Anthony PERARD | inval:
|
819 | 679042f0 | Anthony PERARD | error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); |
820 | 679042f0 | Anthony PERARD | g_free(str); |
821 | 679042f0 | Anthony PERARD | } |
822 | 679042f0 | Anthony PERARD | |
823 | 679042f0 | Anthony PERARD | PropertyInfo qdev_prop_pci_host_devaddr = { |
824 | 679042f0 | Anthony PERARD | .name = "pci-host-devaddr",
|
825 | 679042f0 | Anthony PERARD | .get = get_pci_host_devaddr, |
826 | 679042f0 | Anthony PERARD | .set = set_pci_host_devaddr, |
827 | 679042f0 | Anthony PERARD | }; |
828 | 679042f0 | Anthony PERARD | |
829 | 0be6bfac | Peter Maydell | /* --- support for array properties --- */
|
830 | 0be6bfac | Peter Maydell | |
831 | 0be6bfac | Peter Maydell | /* Used as an opaque for the object properties we add for each
|
832 | 0be6bfac | Peter Maydell | * array element. Note that the struct Property must be first
|
833 | 0be6bfac | Peter Maydell | * in the struct so that a pointer to this works as the opaque
|
834 | 0be6bfac | Peter Maydell | * for the underlying element's property hooks as well as for
|
835 | 0be6bfac | Peter Maydell | * our own release callback.
|
836 | 0be6bfac | Peter Maydell | */
|
837 | 0be6bfac | Peter Maydell | typedef struct { |
838 | 0be6bfac | Peter Maydell | struct Property prop;
|
839 | 0be6bfac | Peter Maydell | char *propname;
|
840 | 0be6bfac | Peter Maydell | ObjectPropertyRelease *release; |
841 | 0be6bfac | Peter Maydell | } ArrayElementProperty; |
842 | 0be6bfac | Peter Maydell | |
843 | 0be6bfac | Peter Maydell | /* object property release callback for array element properties:
|
844 | 0be6bfac | Peter Maydell | * we call the underlying element's property release hook, and
|
845 | 0be6bfac | Peter Maydell | * then free the memory we allocated when we added the property.
|
846 | 0be6bfac | Peter Maydell | */
|
847 | 0be6bfac | Peter Maydell | static void array_element_release(Object *obj, const char *name, void *opaque) |
848 | 0be6bfac | Peter Maydell | { |
849 | 0be6bfac | Peter Maydell | ArrayElementProperty *p = opaque; |
850 | 0be6bfac | Peter Maydell | if (p->release) {
|
851 | 0be6bfac | Peter Maydell | p->release(obj, name, opaque); |
852 | 0be6bfac | Peter Maydell | } |
853 | 0be6bfac | Peter Maydell | g_free(p->propname); |
854 | 0be6bfac | Peter Maydell | g_free(p); |
855 | 0be6bfac | Peter Maydell | } |
856 | 0be6bfac | Peter Maydell | |
857 | 0be6bfac | Peter Maydell | static void set_prop_arraylen(Object *obj, Visitor *v, void *opaque, |
858 | 0be6bfac | Peter Maydell | const char *name, Error **errp) |
859 | 0be6bfac | Peter Maydell | { |
860 | 0be6bfac | Peter Maydell | /* Setter for the property which defines the length of a
|
861 | 0be6bfac | Peter Maydell | * variable-sized property array. As well as actually setting the
|
862 | 0be6bfac | Peter Maydell | * array-length field in the device struct, we have to create the
|
863 | 0be6bfac | Peter Maydell | * array itself and dynamically add the corresponding properties.
|
864 | 0be6bfac | Peter Maydell | */
|
865 | 0be6bfac | Peter Maydell | DeviceState *dev = DEVICE(obj); |
866 | 0be6bfac | Peter Maydell | Property *prop = opaque; |
867 | 0be6bfac | Peter Maydell | uint32_t *alenptr = qdev_get_prop_ptr(dev, prop); |
868 | 0be6bfac | Peter Maydell | void **arrayptr = (void *)dev + prop->arrayoffset; |
869 | 0be6bfac | Peter Maydell | void *eltptr;
|
870 | 0be6bfac | Peter Maydell | const char *arrayname; |
871 | 0be6bfac | Peter Maydell | int i;
|
872 | 0be6bfac | Peter Maydell | |
873 | 0be6bfac | Peter Maydell | if (dev->realized) {
|
874 | b000dfbd | Peter Maydell | qdev_prop_set_after_realize(dev, name, errp); |
875 | 0be6bfac | Peter Maydell | return;
|
876 | 0be6bfac | Peter Maydell | } |
877 | 0be6bfac | Peter Maydell | if (*alenptr) {
|
878 | 0be6bfac | Peter Maydell | error_setg(errp, "array size property %s may not be set more than once",
|
879 | 0be6bfac | Peter Maydell | name); |
880 | 0be6bfac | Peter Maydell | return;
|
881 | 0be6bfac | Peter Maydell | } |
882 | 0be6bfac | Peter Maydell | visit_type_uint32(v, alenptr, name, errp); |
883 | 0be6bfac | Peter Maydell | if (error_is_set(errp)) {
|
884 | 0be6bfac | Peter Maydell | return;
|
885 | 0be6bfac | Peter Maydell | } |
886 | 0be6bfac | Peter Maydell | if (!*alenptr) {
|
887 | 0be6bfac | Peter Maydell | return;
|
888 | 0be6bfac | Peter Maydell | } |
889 | 0be6bfac | Peter Maydell | |
890 | 0be6bfac | Peter Maydell | /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
|
891 | 0be6bfac | Peter Maydell | * strip it off so we can get the name of the array itself.
|
892 | 0be6bfac | Peter Maydell | */
|
893 | 0be6bfac | Peter Maydell | assert(strncmp(name, PROP_ARRAY_LEN_PREFIX, |
894 | 0be6bfac | Peter Maydell | strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
|
895 | 0be6bfac | Peter Maydell | arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX); |
896 | 0be6bfac | Peter Maydell | |
897 | 0be6bfac | Peter Maydell | /* Note that it is the responsibility of the individual device's deinit
|
898 | 0be6bfac | Peter Maydell | * to free the array proper.
|
899 | 0be6bfac | Peter Maydell | */
|
900 | 0be6bfac | Peter Maydell | *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize); |
901 | 0be6bfac | Peter Maydell | for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) { |
902 | 0be6bfac | Peter Maydell | char *propname = g_strdup_printf("%s[%d]", arrayname, i); |
903 | 0be6bfac | Peter Maydell | ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1);
|
904 | 0be6bfac | Peter Maydell | arrayprop->release = prop->arrayinfo->release; |
905 | 0be6bfac | Peter Maydell | arrayprop->propname = propname; |
906 | 0be6bfac | Peter Maydell | arrayprop->prop.info = prop->arrayinfo; |
907 | 0be6bfac | Peter Maydell | arrayprop->prop.name = propname; |
908 | 0be6bfac | Peter Maydell | /* This ugly piece of pointer arithmetic sets up the offset so
|
909 | 0be6bfac | Peter Maydell | * that when the underlying get/set hooks call qdev_get_prop_ptr
|
910 | 0be6bfac | Peter Maydell | * they get the right answer despite the array element not actually
|
911 | 0be6bfac | Peter Maydell | * being inside the device struct.
|
912 | 0be6bfac | Peter Maydell | */
|
913 | 0be6bfac | Peter Maydell | arrayprop->prop.offset = eltptr - (void *)dev;
|
914 | 0be6bfac | Peter Maydell | assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr); |
915 | 0be6bfac | Peter Maydell | object_property_add(obj, propname, |
916 | 0be6bfac | Peter Maydell | arrayprop->prop.info->name, |
917 | 0be6bfac | Peter Maydell | arrayprop->prop.info->get, |
918 | 0be6bfac | Peter Maydell | arrayprop->prop.info->set, |
919 | 0be6bfac | Peter Maydell | array_element_release, |
920 | 0be6bfac | Peter Maydell | arrayprop, errp); |
921 | 0be6bfac | Peter Maydell | if (error_is_set(errp)) {
|
922 | 0be6bfac | Peter Maydell | return;
|
923 | 0be6bfac | Peter Maydell | } |
924 | 0be6bfac | Peter Maydell | } |
925 | 0be6bfac | Peter Maydell | } |
926 | 0be6bfac | Peter Maydell | |
927 | 0be6bfac | Peter Maydell | PropertyInfo qdev_prop_arraylen = { |
928 | 0be6bfac | Peter Maydell | .name = "uint32",
|
929 | 0be6bfac | Peter Maydell | .get = get_uint32, |
930 | 0be6bfac | Peter Maydell | .set = set_prop_arraylen, |
931 | 0be6bfac | Peter Maydell | }; |
932 | 0be6bfac | Peter Maydell | |
933 | ee6847d1 | Gerd Hoffmann | /* --- public helpers --- */
|
934 | ee6847d1 | Gerd Hoffmann | |
935 | ee6847d1 | Gerd Hoffmann | static Property *qdev_prop_walk(Property *props, const char *name) |
936 | ee6847d1 | Gerd Hoffmann | { |
937 | 04a2d61e | Eduardo Habkost | if (!props) {
|
938 | ee6847d1 | Gerd Hoffmann | return NULL; |
939 | 04a2d61e | Eduardo Habkost | } |
940 | ee6847d1 | Gerd Hoffmann | while (props->name) {
|
941 | 04a2d61e | Eduardo Habkost | if (strcmp(props->name, name) == 0) { |
942 | ee6847d1 | Gerd Hoffmann | return props;
|
943 | 04a2d61e | Eduardo Habkost | } |
944 | ee6847d1 | Gerd Hoffmann | props++; |
945 | ee6847d1 | Gerd Hoffmann | } |
946 | ee6847d1 | Gerd Hoffmann | return NULL; |
947 | ee6847d1 | Gerd Hoffmann | } |
948 | ee6847d1 | Gerd Hoffmann | |
949 | ee6847d1 | Gerd Hoffmann | static Property *qdev_prop_find(DeviceState *dev, const char *name) |
950 | ee6847d1 | Gerd Hoffmann | { |
951 | bce54474 | Paolo Bonzini | ObjectClass *class; |
952 | ee6847d1 | Gerd Hoffmann | Property *prop; |
953 | ee6847d1 | Gerd Hoffmann | |
954 | ee6847d1 | Gerd Hoffmann | /* device properties */
|
955 | bce54474 | Paolo Bonzini | class = object_get_class(OBJECT(dev)); |
956 | bce54474 | Paolo Bonzini | do {
|
957 | bce54474 | Paolo Bonzini | prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name); |
958 | bce54474 | Paolo Bonzini | if (prop) {
|
959 | bce54474 | Paolo Bonzini | return prop;
|
960 | bce54474 | Paolo Bonzini | } |
961 | bce54474 | Paolo Bonzini | class = object_class_get_parent(class); |
962 | bce54474 | Paolo Bonzini | } while (class != object_class_by_name(TYPE_DEVICE));
|
963 | ee6847d1 | Gerd Hoffmann | |
964 | ee6847d1 | Gerd Hoffmann | return NULL; |
965 | ee6847d1 | Gerd Hoffmann | } |
966 | ee6847d1 | Gerd Hoffmann | |
967 | 7db4c4e8 | Paolo Bonzini | void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, |
968 | 7db4c4e8 | Paolo Bonzini | Property *prop, const char *value) |
969 | 7db4c4e8 | Paolo Bonzini | { |
970 | 7db4c4e8 | Paolo Bonzini | switch (ret) {
|
971 | 7db4c4e8 | Paolo Bonzini | case -EEXIST:
|
972 | 7db4c4e8 | Paolo Bonzini | error_set(errp, QERR_PROPERTY_VALUE_IN_USE, |
973 | f79f2bfc | Anthony Liguori | object_get_typename(OBJECT(dev)), prop->name, value); |
974 | 7db4c4e8 | Paolo Bonzini | break;
|
975 | 7db4c4e8 | Paolo Bonzini | default:
|
976 | 7db4c4e8 | Paolo Bonzini | case -EINVAL:
|
977 | 7db4c4e8 | Paolo Bonzini | error_set(errp, QERR_PROPERTY_VALUE_BAD, |
978 | f79f2bfc | Anthony Liguori | object_get_typename(OBJECT(dev)), prop->name, value); |
979 | 7db4c4e8 | Paolo Bonzini | break;
|
980 | 7db4c4e8 | Paolo Bonzini | case -ENOENT:
|
981 | 7db4c4e8 | Paolo Bonzini | error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND, |
982 | f79f2bfc | Anthony Liguori | object_get_typename(OBJECT(dev)), prop->name, value); |
983 | 7db4c4e8 | Paolo Bonzini | break;
|
984 | 7db4c4e8 | Paolo Bonzini | case 0: |
985 | 7db4c4e8 | Paolo Bonzini | break;
|
986 | 7db4c4e8 | Paolo Bonzini | } |
987 | 7db4c4e8 | Paolo Bonzini | } |
988 | 7db4c4e8 | Paolo Bonzini | |
989 | b1fe9bcb | Andreas Färber | void qdev_prop_parse(DeviceState *dev, const char *name, const char *value, |
990 | b1fe9bcb | Andreas Färber | Error **errp) |
991 | ee6847d1 | Gerd Hoffmann | { |
992 | d822979b | Paolo Bonzini | char *legacy_name;
|
993 | ee6847d1 | Gerd Hoffmann | |
994 | d822979b | Paolo Bonzini | legacy_name = g_strdup_printf("legacy-%s", name);
|
995 | d822979b | Paolo Bonzini | if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) { |
996 | b1fe9bcb | Andreas Färber | object_property_parse(OBJECT(dev), value, legacy_name, errp); |
997 | d822979b | Paolo Bonzini | } else {
|
998 | b1fe9bcb | Andreas Färber | object_property_parse(OBJECT(dev), value, name, errp); |
999 | ee6847d1 | Gerd Hoffmann | } |
1000 | d822979b | Paolo Bonzini | g_free(legacy_name); |
1001 | ee6847d1 | Gerd Hoffmann | } |
1002 | ee6847d1 | Gerd Hoffmann | |
1003 | f4594a3b | Isaku Yamahata | void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value) |
1004 | f4594a3b | Isaku Yamahata | { |
1005 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1006 | 9b170e60 | Paolo Bonzini | object_property_set_bool(OBJECT(dev), value, name, &errp); |
1007 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1008 | f4594a3b | Isaku Yamahata | } |
1009 | f4594a3b | Isaku Yamahata | |
1010 | c7cc172d | Juan Quintela | void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value) |
1011 | c7cc172d | Juan Quintela | { |
1012 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1013 | 9b170e60 | Paolo Bonzini | object_property_set_int(OBJECT(dev), value, name, &errp); |
1014 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1015 | c7cc172d | Juan Quintela | } |
1016 | c7cc172d | Juan Quintela | |
1017 | ee6847d1 | Gerd Hoffmann | void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value) |
1018 | ee6847d1 | Gerd Hoffmann | { |
1019 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1020 | 9b170e60 | Paolo Bonzini | object_property_set_int(OBJECT(dev), value, name, &errp); |
1021 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1022 | ee6847d1 | Gerd Hoffmann | } |
1023 | ee6847d1 | Gerd Hoffmann | |
1024 | ee6847d1 | Gerd Hoffmann | void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value) |
1025 | ee6847d1 | Gerd Hoffmann | { |
1026 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1027 | 9b170e60 | Paolo Bonzini | object_property_set_int(OBJECT(dev), value, name, &errp); |
1028 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1029 | ee6847d1 | Gerd Hoffmann | } |
1030 | ee6847d1 | Gerd Hoffmann | |
1031 | 316940b0 | Gerd Hoffmann | void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value) |
1032 | 316940b0 | Gerd Hoffmann | { |
1033 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1034 | 9b170e60 | Paolo Bonzini | object_property_set_int(OBJECT(dev), value, name, &errp); |
1035 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1036 | 316940b0 | Gerd Hoffmann | } |
1037 | 316940b0 | Gerd Hoffmann | |
1038 | 5a053d1f | Blue Swirl | void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value) |
1039 | 5a053d1f | Blue Swirl | { |
1040 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1041 | 9b170e60 | Paolo Bonzini | object_property_set_int(OBJECT(dev), value, name, &errp); |
1042 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1043 | 5a053d1f | Blue Swirl | } |
1044 | 5a053d1f | Blue Swirl | |
1045 | 3b25597b | Christian Borntraeger | void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value) |
1046 | cc984673 | Markus Armbruster | { |
1047 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1048 | 9b170e60 | Paolo Bonzini | object_property_set_str(OBJECT(dev), value, name, &errp); |
1049 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1050 | cc984673 | Markus Armbruster | } |
1051 | cc984673 | Markus Armbruster | |
1052 | 1503fff3 | Gerd Hoffmann | void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value) |
1053 | 1503fff3 | Gerd Hoffmann | { |
1054 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1055 | 9b170e60 | Paolo Bonzini | char str[2 * 6 + 5 + 1]; |
1056 | 9b170e60 | Paolo Bonzini | snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", |
1057 | 9b170e60 | Paolo Bonzini | value[0], value[1], value[2], value[3], value[4], value[5]); |
1058 | 9b170e60 | Paolo Bonzini | |
1059 | 9b170e60 | Paolo Bonzini | object_property_set_str(OBJECT(dev), str, name, &errp); |
1060 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1061 | 1503fff3 | Gerd Hoffmann | } |
1062 | 1503fff3 | Gerd Hoffmann | |
1063 | 9b170e60 | Paolo Bonzini | void qdev_prop_set_enum(DeviceState *dev, const char *name, int value) |
1064 | 4e4fa398 | Jan Kiszka | { |
1065 | 9b170e60 | Paolo Bonzini | Property *prop; |
1066 | 9b170e60 | Paolo Bonzini | Error *errp = NULL;
|
1067 | 9b170e60 | Paolo Bonzini | |
1068 | 9b170e60 | Paolo Bonzini | prop = qdev_prop_find(dev, name); |
1069 | 9b170e60 | Paolo Bonzini | object_property_set_str(OBJECT(dev), prop->info->enum_table[value], |
1070 | 9b170e60 | Paolo Bonzini | name, &errp); |
1071 | 59f971d4 | Paolo Bonzini | assert_no_error(errp); |
1072 | 4e4fa398 | Jan Kiszka | } |
1073 | 4e4fa398 | Jan Kiszka | |
1074 | ee6847d1 | Gerd Hoffmann | void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value) |
1075 | ee6847d1 | Gerd Hoffmann | { |
1076 | 7a7aae21 | Paolo Bonzini | Property *prop; |
1077 | 7a7aae21 | Paolo Bonzini | void **ptr;
|
1078 | 7a7aae21 | Paolo Bonzini | |
1079 | 7a7aae21 | Paolo Bonzini | prop = qdev_prop_find(dev, name); |
1080 | 7a7aae21 | Paolo Bonzini | assert(prop && prop->info == &qdev_prop_ptr); |
1081 | 7a7aae21 | Paolo Bonzini | ptr = qdev_get_prop_ptr(dev, prop); |
1082 | 7a7aae21 | Paolo Bonzini | *ptr = value; |
1083 | ee6847d1 | Gerd Hoffmann | } |
1084 | ee6847d1 | Gerd Hoffmann | |
1085 | 04a2d61e | Eduardo Habkost | static QTAILQ_HEAD(, GlobalProperty) global_props =
|
1086 | 04a2d61e | Eduardo Habkost | QTAILQ_HEAD_INITIALIZER(global_props); |
1087 | b6b61144 | Gerd Hoffmann | |
1088 | a404b612 | Eduardo Habkost | void qdev_prop_register_global(GlobalProperty *prop)
|
1089 | b6b61144 | Gerd Hoffmann | { |
1090 | 458fb679 | Gerd Hoffmann | QTAILQ_INSERT_TAIL(&global_props, prop, next); |
1091 | b6b61144 | Gerd Hoffmann | } |
1092 | b6b61144 | Gerd Hoffmann | |
1093 | 458fb679 | Gerd Hoffmann | void qdev_prop_register_global_list(GlobalProperty *props)
|
1094 | b6b61144 | Gerd Hoffmann | { |
1095 | 458fb679 | Gerd Hoffmann | int i;
|
1096 | b6b61144 | Gerd Hoffmann | |
1097 | 458fb679 | Gerd Hoffmann | for (i = 0; props[i].driver != NULL; i++) { |
1098 | 458fb679 | Gerd Hoffmann | qdev_prop_register_global(props+i); |
1099 | b6b61144 | Gerd Hoffmann | } |
1100 | 458fb679 | Gerd Hoffmann | } |
1101 | 458fb679 | Gerd Hoffmann | |
1102 | 868d378b | Andreas Färber | void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename, |
1103 | 868d378b | Andreas Färber | Error **errp) |
1104 | 868d378b | Andreas Färber | { |
1105 | 868d378b | Andreas Färber | GlobalProperty *prop; |
1106 | 868d378b | Andreas Färber | |
1107 | 868d378b | Andreas Färber | QTAILQ_FOREACH(prop, &global_props, next) { |
1108 | 868d378b | Andreas Färber | Error *err = NULL;
|
1109 | 868d378b | Andreas Färber | |
1110 | 868d378b | Andreas Färber | if (strcmp(typename, prop->driver) != 0) { |
1111 | 868d378b | Andreas Färber | continue;
|
1112 | 868d378b | Andreas Färber | } |
1113 | 868d378b | Andreas Färber | qdev_prop_parse(dev, prop->property, prop->value, &err); |
1114 | 868d378b | Andreas Färber | if (err != NULL) { |
1115 | 868d378b | Andreas Färber | error_propagate(errp, err); |
1116 | 868d378b | Andreas Färber | return;
|
1117 | 868d378b | Andreas Färber | } |
1118 | 868d378b | Andreas Färber | } |
1119 | 868d378b | Andreas Färber | } |
1120 | 868d378b | Andreas Färber | |
1121 | b1fe9bcb | Andreas Färber | void qdev_prop_set_globals(DeviceState *dev, Error **errp)
|
1122 | 458fb679 | Gerd Hoffmann | { |
1123 | bce54474 | Paolo Bonzini | ObjectClass *class = object_get_class(OBJECT(dev)); |
1124 | bce54474 | Paolo Bonzini | |
1125 | bce54474 | Paolo Bonzini | do {
|
1126 | 868d378b | Andreas Färber | Error *err = NULL;
|
1127 | b1fe9bcb | Andreas Färber | |
1128 | 868d378b | Andreas Färber | qdev_prop_set_globals_for_type(dev, object_class_get_name(class), |
1129 | 868d378b | Andreas Färber | &err); |
1130 | 868d378b | Andreas Färber | if (err != NULL) { |
1131 | 868d378b | Andreas Färber | error_propagate(errp, err); |
1132 | 868d378b | Andreas Färber | return;
|
1133 | b6b61144 | Gerd Hoffmann | } |
1134 | bce54474 | Paolo Bonzini | class = object_class_get_parent(class); |
1135 | bce54474 | Paolo Bonzini | } while (class);
|
1136 | b6b61144 | Gerd Hoffmann | } |