1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include "qemu/osdep.h"
29#include "hw/fdt_generic_util.h"
30#include "hw/fdt_generic_devices.h"
31#include "net/net.h"
32#include "exec/memory.h"
33#include "exec/address-spaces.h"
34#include "hw/sysbus.h"
35#include "qapi/error.h"
36#include "sysemu/sysemu.h"
37#include "qemu/cutils.h"
38#include "sysemu/blockdev.h"
39#include "chardev/char.h"
40#include "qemu/log.h"
41#include "qemu/config-file.h"
42#include "qom/cpu.h"
43
44#ifndef FDT_GENERIC_UTIL_ERR_DEBUG
45#define FDT_GENERIC_UTIL_ERR_DEBUG 3
46#endif
47#define DB_PRINT(lvl, ...) do { \
48 if (FDT_GENERIC_UTIL_ERR_DEBUG > (lvl)) { \
49 qemu_log_mask(LOG_FDT, ": %s: ", __func__); \
50 qemu_log_mask(LOG_FDT, ## __VA_ARGS__); \
51 } \
52} while (0);
53
54#define DB_PRINT_NP(lvl, ...) do { \
55 if (FDT_GENERIC_UTIL_ERR_DEBUG > (lvl)) { \
56 qemu_log_mask(LOG_FDT, "%s", node_path); \
57 DB_PRINT((lvl), ## __VA_ARGS__); \
58 } \
59} while (0);
60
61#include "hw/remote-port-device.h"
62#include "hw/remote-port.h"
63
64
65
66#include <libfdt.h>
67#include <stdlib.h>
68
69int fdt_serial_ports;
70
71static int simple_bus_fdt_init(char *bus_node_path, FDTMachineInfo *fdti);
72
73static void fdt_get_irq_info_from_intc(FDTMachineInfo *fdti, qemu_irq *ret,
74 char *intc_node_path,
75 uint32_t *cells, uint32_t num_cells,
76 uint32_t max, Error **errp);
77
78
79typedef struct QEMUIRQSharedState {
80 qemu_irq sink;
81 int num;
82 bool (*merge_fn)(bool *, int);
83
84#define MAX_IRQ_SHARED_INPUTS 128
85 bool inputs[MAX_IRQ_SHARED_INPUTS];
86} QEMUIRQSharedState;
87
88static bool qemu_irq_shared_or_handler(bool *inputs, int n)
89{
90 int i;
91
92 assert(n < MAX_IRQ_SHARED_INPUTS);
93
94 for (i = 0; i < n; ++i) {
95 if (inputs[i]) {
96 return true;
97 }
98 }
99 return false;
100}
101
102static bool qemu_irq_shared_and_handler(bool *inputs, int n)
103{
104 int i;
105
106 assert(n < MAX_IRQ_SHARED_INPUTS);
107
108 for (i = 0; i < n; ++i) {
109 if (!inputs[i]) {
110 return false;
111 }
112 }
113 return true;
114}
115
116static void qemu_irq_shared_handler(void *opaque, int n, int level)
117{
118 QEMUIRQSharedState *s = opaque;
119
120 assert(n < MAX_IRQ_SHARED_INPUTS);
121 s->inputs[n] = level;
122 qemu_set_irq(s->sink, s->merge_fn(s->inputs, s->num));
123}
124
125static void fdt_init_all_irqs(FDTMachineInfo *fdti)
126{
127 while (fdti->irqs) {
128 FDTIRQConnection *first = fdti->irqs;
129 qemu_irq sink = first->irq;
130 bool (*merge_fn)(bool *, int) = first->merge_fn;
131 int num_sources = 0;
132 FDTIRQConnection *irq;
133
134 for (irq = first; irq; irq = irq->next) {
135 if (irq->irq == sink) {
136 num_sources++;
137 }
138 }
139 if (num_sources > 1) {
140 QEMUIRQSharedState *s = g_malloc0(sizeof *s);
141 s->sink = sink;
142 s->merge_fn = merge_fn;
143 qemu_irq *sources = qemu_allocate_irqs(qemu_irq_shared_handler, s,
144 num_sources);
145 for (irq = first; irq; irq = irq->next) {
146 if (irq->irq == sink) {
147 char *shared_irq_name = g_strdup_printf("shared-irq-%p",
148 *sources);
149
150 if (irq->merge_fn != merge_fn) {
151 fprintf(stderr, "ERROR: inconsistent IRQ merge fns\n");
152 exit(1);
153 }
154
155 object_property_add_child(OBJECT(irq->dev), shared_irq_name,
156 OBJECT(*sources), &error_abort);
157 g_free(shared_irq_name);
158 irq->irq = *(sources++);
159 s->num++;
160 }
161 }
162 }
163 DB_PRINT(0, "%s: connected to %s irq line %d (%s)\n",
164 first->sink_info ? first->sink_info : "",
165 object_get_canonical_path(OBJECT(first->dev)),
166 first->i, first->name ? first->name : "");
167
168 qdev_connect_gpio_out_named(DEVICE(first->dev), first->name, first->i,
169 first->irq);
170 fdti->irqs = first->next;
171 g_free(first);
172 }
173}
174
175FDTMachineInfo *fdt_generic_create_machine(void *fdt, qemu_irq *cpu_irq)
176{
177 char node_path[DT_PATH_LENGTH];
178 QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL);
179 FDTMachineInfo *fdti = fdt_init_new_fdti(fdt);
180
181 fdti->irq_base = cpu_irq;
182
183 fdt_serial_ports = 0;
184
185
186 if (!qemu_devtree_get_root_node(fdt, node_path)) {
187 memory_region_transaction_begin();
188 fdt_init_set_opaque(fdti, node_path, NULL);
189 simple_bus_fdt_init(node_path, fdti);
190 while (qemu_co_enter_next(fdti->cq));
191 fdt_init_all_irqs(fdti);
192 memory_region_transaction_commit();
193 } else {
194 fprintf(stderr, "FDT: ERROR: cannot get root node from device tree %s\n"
195 , node_path);
196 }
197
198 DB_PRINT(0, "FDT: Device tree scan complete\n");
199
200
201 if (!qemu_opt_get_number(opts, "cpus", 0)) {
202 smp_cpus = fdt_generic_num_cpus;
203 }
204
205 DB_PRINT(0, "The value of smp_cpus is: %d\n", smp_cpus);
206
207 return fdti;
208}
209
210struct FDTInitNodeArgs {
211 char *node_path;
212 char *parent_path;
213 FDTMachineInfo *fdti;
214};
215
216static int fdt_init_qdev(char *node_path, FDTMachineInfo *fdti, char *compat);
217
218static void fdt_init_node(void *args)
219{
220 struct FDTInitNodeArgs *a = args;
221 char *node_path = a->node_path;
222 FDTMachineInfo *fdti = a->fdti;
223 g_free(a);
224
225 simple_bus_fdt_init(node_path, fdti);
226
227 char *all_compats = NULL, *compat, *node_name, *next_compat;
228 char *device_type = NULL;
229 int compat_len;
230
231 DB_PRINT_NP(1, "enter\n");
232
233
234 node_name = qemu_devtree_get_node_name(fdti->fdt, node_path);
235 DB_PRINT_NP(1, "node with name: %s\n", node_name ? node_name : "(none)");
236 if (!node_name) {
237 printf("FDT: ERROR: nameless node: %s\n", node_path);
238 }
239 if (!fdt_init_inst_bind(node_path, fdti, node_name)) {
240 DB_PRINT_NP(0, "instance bind successful\n");
241 goto exit;
242 }
243
244
245 all_compats = qemu_fdt_getprop(fdti->fdt, node_path, "compatible",
246 &compat_len, false, NULL);
247 if (!all_compats) {
248 DB_PRINT_NP(0, "no compatibility found\n");
249 }
250
251 for (compat = all_compats; compat && compat_len; compat = next_compat+1) {
252 char *compat_prefixed = g_strdup_printf("compatible:%s", compat);
253 if (!fdt_init_compat(node_path, fdti, compat_prefixed)) {
254 goto exit;
255 }
256 g_free(compat_prefixed);
257 if (!fdt_init_qdev(node_path, fdti, compat)) {
258 goto exit;
259 }
260 next_compat = memchr(compat, '\0', DT_PATH_LENGTH);
261 compat_len -= (next_compat + 1 - compat);
262 if (compat_len > 0) {
263 *next_compat = ' ';
264 }
265 }
266
267 device_type = qemu_fdt_getprop(fdti->fdt, node_path,
268 "device_type", NULL, false, NULL);
269 device_type = g_strdup_printf("device_type:%s", device_type);
270 if (!fdt_init_compat(node_path, fdti, device_type)) {
271 goto exit;
272 }
273
274
275
276
277
278 if (!fdt_init_qdev(node_path, fdti, device_type)) {
279 goto exit;
280 }
281
282 if (!all_compats) {
283 goto exit;
284 }
285 DB_PRINT_NP(0, "FDT: Unsupported peripheral invalidated - "
286 "compatibilities %s\n", all_compats);
287 qemu_fdt_setprop_string(fdti->fdt, node_path, "compatible", "invalidated");
288exit:
289
290 DB_PRINT_NP(1, "exit\n");
291
292 if (!fdt_init_has_opaque(fdti, node_path)) {
293 fdt_init_set_opaque(fdti, node_path, NULL);
294 }
295 g_free(node_path);
296 g_free(all_compats);
297 g_free(device_type);
298 return;
299}
300
301static int simple_bus_fdt_init(char *node_path, FDTMachineInfo *fdti)
302{
303 int i;
304 int num_children = qemu_devtree_get_num_children(fdti->fdt, node_path,
305 1);
306 char **children = qemu_devtree_get_children(fdti->fdt, node_path, 1);
307
308 DB_PRINT_NP(num_children ? 0 : 1, "num child devices: %d\n", num_children);
309
310 for (i = 0; i < num_children; i++) {
311 struct FDTInitNodeArgs *init_args = g_malloc0(sizeof(*init_args));
312 init_args->node_path = children[i];
313 init_args->fdti = fdti;
314 qemu_coroutine_enter(qemu_coroutine_create(fdt_init_node, init_args));
315 }
316
317 g_free(children);
318 return 0;
319}
320
321static qemu_irq fdt_get_gpio(FDTMachineInfo *fdti, char *node_path,
322 int* cur_cell, qemu_irq input,
323 const FDTGenericGPIOSet *gpio_set,
324 const char *debug_success, bool *end) {
325 void *fdt = fdti->fdt;
326 uint32_t parent_phandle, parent_cells = 0, cells[32];
327 char parent_node_path[DT_PATH_LENGTH];
328 DeviceState *parent;
329 int i;
330 Error *errp = NULL;
331 const char *reason = NULL;
332 bool free_reason = false;
333 const char *propname = gpio_set->names->propname;
334 const char *cells_propname = gpio_set->names->cells_propname;
335
336 cells[0] = 0;
337
338 parent_phandle = qemu_fdt_getprop_cell(fdt, node_path, propname,
339 (*cur_cell)++, false, &errp);
340 if (errp) {
341 reason = g_strdup_printf("Cant get phandle from \"%s\" property\n",
342 propname);
343 *end = true;
344 free_reason = true;
345 goto fail_silent;
346 }
347 if (qemu_devtree_get_node_by_phandle(fdt, parent_node_path,
348 parent_phandle)) {
349 *end = true;
350 reason = "cant get node from phandle\n";
351 goto fail;
352 }
353 parent_cells = qemu_fdt_getprop_cell(fdt, parent_node_path,
354 cells_propname, 0, false, &errp);
355 if (errp) {
356 *end = true;
357 reason = g_strdup_printf("cant get the property \"%s\" from the " \
358 "parent \"%s\"\n",
359 cells_propname, parent_node_path);
360 free_reason = true;
361 goto fail;
362 }
363
364 for (i = 0; i < parent_cells; ++i) {
365 cells[i] = qemu_fdt_getprop_cell(fdt, node_path, propname,
366 (*cur_cell)++, false, &errp);
367 if (errp) {
368 *end = true;
369 reason = "cant get cell value";
370 goto fail;
371 }
372 }
373
374 while (!fdt_init_has_opaque(fdti, parent_node_path)) {
375 fdt_init_yield(fdti);
376 }
377 parent = DEVICE(fdt_init_get_opaque(fdti, parent_node_path));
378
379 if (!parent) {
380 reason = "parent is not a device";
381 goto fail_silent;
382 }
383
384 while (!parent->realized) {
385 fdt_init_yield(fdti);
386 }
387
388 {
389 const FDTGenericGPIOConnection *fgg_con = NULL;
390 uint16_t range, idx;
391 const char *gpio_name = NULL;
392 qemu_irq ret;
393
394 if (object_dynamic_cast(OBJECT(parent), TYPE_FDT_GENERIC_GPIO)) {
395 const FDTGenericGPIOSet *set;
396 FDTGenericGPIOClass *parent_fggc =
397 FDT_GENERIC_GPIO_GET_CLASS(parent);
398
399 for (set = parent_fggc->controller_gpios; set && set->names;
400 set++) {
401 if (!strcmp(gpio_set->names->cells_propname,
402 set->names->cells_propname)) {
403 fgg_con = set->gpios;
404 break;
405 }
406 }
407 }
408
409
410 idx = cells[0] & ~(1ul << 31);
411 if (fgg_con) {
412 range = fgg_con->range ? fgg_con->range : 1;
413 while (!(idx >= fgg_con->fdt_index
414 && idx < (fgg_con->fdt_index + range))
415 && fgg_con->name) {
416 fgg_con++;
417 }
418
419 idx -= fgg_con->fdt_index;
420 gpio_name = fgg_con->name;
421 }
422
423 if (input) {
424 FDTIRQConnection *irq = g_new0(FDTIRQConnection, 1);
425 bool (*merge_fn)(bool *, int) = qemu_irq_shared_or_handler;
426
427
428
429
430
431 if (cells[0] & (1 << 31)) {
432 merge_fn = qemu_irq_shared_and_handler;
433 }
434
435 DB_PRINT_NP(1, "%s GPIO output %s[%d] on %s\n", debug_success,
436 gpio_name ? gpio_name : "unnamed", idx,
437 parent_node_path);
438 *irq = (FDTIRQConnection) {
439 .dev = parent,
440 .name = gpio_name,
441 .merge_fn = merge_fn,
442 .i = idx,
443 .irq = input,
444 .sink_info = NULL,
445 .next = fdti->irqs
446 };
447 fdti->irqs = irq;
448 }
449
450 if (!strcmp(propname, "interrupts-extended") &&
451 object_dynamic_cast(OBJECT(parent), TYPE_FDT_GENERIC_INTC) &&
452 parent_cells > 1) {
453 qemu_irq *irqs = g_new0(qemu_irq, fdt_generic_num_cpus);
454 int i;
455
456 fdt_get_irq_info_from_intc(fdti, irqs, parent_node_path, cells,
457 parent_cells, fdt_generic_num_cpus, &errp);
458 if (errp) {
459 reason = "failed to create gpio connection";
460 goto fail;
461 }
462
463 ret = NULL;
464 for (i = 0; i < fdt_generic_num_cpus; i++) {
465 if (irqs[i]) {
466 ret = irqs[i];
467 break;
468 }
469 }
470 g_free(irqs);
471 } else {
472 ret = qdev_get_gpio_in_named(parent, gpio_name, idx);
473 }
474
475 if (ret) {
476 DB_PRINT_NP(1, "wiring GPIO input %s on %s ...\n",
477 fgg_con ? fgg_con->name : "unnamed", parent_node_path);
478 }
479 return ret;
480 }
481fail:
482 if (reason) {
483 fprintf(stderr, "%s Failed: %s\n", node_path, reason);
484 }
485
486fail_silent:
487 if (free_reason) {
488 g_free((void *)reason);
489 }
490 return NULL;
491}
492
493static void fdt_get_irq_info_from_intc(FDTMachineInfo *fdti, qemu_irq *ret,
494 char *intc_node_path,
495 uint32_t *cells, uint32_t num_cells,
496 uint32_t max, Error **errp)
497{
498 FDTGenericIntcClass *intc_fdt_class;
499 DeviceState *intc;
500
501 while (!fdt_init_has_opaque(fdti, intc_node_path)) {
502 fdt_init_yield(fdti);
503 }
504 intc = DEVICE(fdt_init_get_opaque(fdti, intc_node_path));
505
506 if (!intc) {
507 goto fail;
508 }
509
510 while (!intc->realized) {
511 fdt_init_yield(fdti);
512 }
513
514 intc_fdt_class = FDT_GENERIC_INTC_GET_CLASS(intc);
515 if (!intc_fdt_class) {
516 goto fail;
517 }
518
519 intc_fdt_class->get_irq(FDT_GENERIC_INTC(intc), ret, cells, num_cells,
520 max, errp);
521
522 return;
523fail:
524 error_setg(errp, "%s", __func__);
525}
526
527static uint32_t imap_cache[4096];
528static bool imap_cached = false;
529
530qemu_irq *fdt_get_irq_info(FDTMachineInfo *fdti, char *node_path, int irq_idx,
531 char *info, bool *map_mode) {
532 void *fdt = fdti->fdt;
533 uint32_t intc_phandle, intc_cells, cells[32];
534 char intc_node_path[DT_PATH_LENGTH];
535 qemu_irq *ret = NULL;
536 int i;
537 Error *errp = NULL;
538
539 intc_phandle = qemu_fdt_getprop_cell(fdt, node_path, "interrupt-parent",
540 0, true, &errp);
541 if (errp) {
542 errp = NULL;
543 intc_cells = qemu_fdt_getprop_cell(fdt, node_path,
544 "#interrupt-cells", 0, true, &errp);
545 *map_mode = true;
546 } else {
547 if (qemu_devtree_get_node_by_phandle(fdt, intc_node_path,
548 intc_phandle)) {
549 goto fail;
550 }
551
552
553 qemu_fdt_getprop_cell(fdt, node_path, "interrupt-map-mask", 0,
554 false, &errp);
555 if (!errp) {
556 errp = NULL;
557 intc_cells = qemu_fdt_getprop_cell(fdt, node_path,
558 "#interrupt-cells", 0,
559 true, &errp);
560 *map_mode = true;
561 } else {
562 errp = NULL;
563 intc_cells = qemu_fdt_getprop_cell(fdt, intc_node_path,
564 "#interrupt-cells", 0,
565 true, &errp);
566 *map_mode = false;
567 }
568 }
569
570 if (errp) {
571 goto fail;
572 }
573
574 DB_PRINT_NP(2, "%s intc_phandle: %d\n", node_path, intc_phandle);
575
576 for (i = 0; i < intc_cells; ++i) {
577 cells[i] = qemu_fdt_getprop_cell(fdt, node_path, "interrupts",
578 intc_cells * irq_idx + i, false, &errp);
579 if (errp) {
580 goto fail;
581 }
582 }
583
584 if (*map_mode) {
585 int k;
586 ret = g_new0(qemu_irq, 1);
587 int num_matches = 0;
588 int len;
589 uint32_t imap_mask[intc_cells];
590 uint32_t *imap_p;
591 uint32_t *imap;
592 bool use_parent = false;
593
594 for (k = 0; k < intc_cells; ++k) {
595 imap_mask[k] = qemu_fdt_getprop_cell(fdt, node_path,
596 "interrupt-map-mask", k + 2,
597 true, &errp);
598 if (errp) {
599 goto fail;
600 }
601 }
602
603
604 imap = qemu_fdt_getprop(fdt, node_path, "interrupt-map", &len,
605 use_parent, &errp);
606
607 if (!imap || errp) {
608
609
610
611 use_parent = true;
612 errp = NULL;
613
614 imap_p = qemu_fdt_getprop(fdt, node_path, "interrupt-map",
615 &len, use_parent, &errp);
616 if (!imap_cached) {
617 memcpy(imap_cache, imap_p, len);
618 imap_cached = true;
619 }
620 imap = imap_cache;
621
622 if (errp) {
623 goto fail;
624 }
625 }
626
627 len /= sizeof(uint32_t);
628
629 i = 0;
630 assert(imap);
631 while (i < len) {
632 if (!use_parent) {
633
634
635
636 imap = qemu_fdt_getprop(fdt, node_path, "interrupt-map", &len,
637 use_parent, &errp);
638
639 if (errp) {
640 goto fail;
641 }
642
643 len /= sizeof(uint32_t);
644 }
645
646 bool match = true;
647 uint32_t new_intc_cells, new_cells[32];
648 i++; i++;
649 for (k = 0; k < intc_cells; ++k) {
650 uint32_t map_val = be32_to_cpu(imap[i++]);
651 if ((cells[k] ^ map_val) & imap_mask[k]) {
652 match = false;
653 }
654 }
655
656
657
658
659 intc_phandle = be32_to_cpu(imap[i++]);
660 if (intc_phandle & (0xffu << 24)) {
661 new_intc_cells = (intc_phandle >> 24) - 1;
662 } else {
663 if (qemu_devtree_get_node_by_phandle(fdt, intc_node_path,
664 intc_phandle)) {
665 goto fail;
666 }
667 new_intc_cells = qemu_fdt_getprop_cell(fdt, intc_node_path,
668 "#interrupt-cells", 0,
669 false, &errp);
670 imap[i - 1] = cpu_to_be32(intc_phandle |
671 (new_intc_cells + 1) << 24);
672 if (errp) {
673 goto fail;
674 }
675 }
676 for (k = 0; k < new_intc_cells; ++k) {
677 new_cells[k] = be32_to_cpu(imap[i++]);
678 }
679 if (match) {
680 num_matches++;
681 ret = g_renew(qemu_irq, ret, num_matches + 1);
682 if (intc_phandle & (0xffu << 24)) {
683 if (qemu_devtree_get_node_by_phandle(fdt, intc_node_path,
684 intc_phandle &
685 ((1 << 24) - 1))) {
686 goto fail;
687 }
688 }
689
690 DB_PRINT_NP(2, "Getting IRQ information: %s -> 0x%x (%s)\n",
691 node_path, intc_phandle, intc_node_path);
692
693 memset(&ret[num_matches], 0, sizeof(*ret));
694 fdt_get_irq_info_from_intc(fdti, &ret[num_matches-1], intc_node_path,
695 new_cells, new_intc_cells, 1, &errp);
696 if (info) {
697 sprintf(info, "%s", intc_node_path);
698 info += strlen(info) + 1;
699 }
700 if (errp) {
701 goto fail;
702 }
703 }
704 }
705 return ret;
706 }
707
708 DB_PRINT_NP(2, "Getting IRQ information: %s -> %s\n",
709 node_path, intc_node_path);
710
711 ret = g_new0(qemu_irq, fdt_generic_num_cpus + 2);
712 fdt_get_irq_info_from_intc(fdti, ret, intc_node_path, cells, intc_cells,
713 fdt_generic_num_cpus, &errp);
714
715 if (errp) {
716 goto fail;
717 }
718
719
720 if (info) {
721 sprintf(info, "%s", intc_node_path);
722 }
723
724 return ret;
725
726fail:
727 if (errp) {
728 sprintf(info, "%s", error_get_pretty(errp));
729 } else {
730 sprintf(info, "(none)");
731 }
732 return NULL;
733}
734
735qemu_irq *fdt_get_irq(FDTMachineInfo *fdti, char *node_path, int irq_idx,
736 bool *map_mode)
737{
738 return fdt_get_irq_info(fdti, node_path, irq_idx, NULL, map_mode);
739}
740
741
742
743#define DIGIT(a) ((a) >= '0' && (a) <= '9')
744#define LOWER_CASE(a) ((a) >= 'a' && (a) <= 'z')
745
746static void trim_version(char *x)
747{
748 long result;
749
750 for (;;) {
751 x = strchr(x, '-');
752 if (!x) {
753 return;
754 }
755 if (DIGIT(x[1])) {
756
757 const char *p;
758
759 qemu_strtol(x + 1, &p, 0, &result);
760
761 if ( *p == '.') {
762 *x = 0;
763 return;
764 } else if ( *p == 0) {
765 return;
766 }
767 } else if (x[1] == 'r' && x[3] == 'p') {
768
769 if (DIGIT(x[2]) && DIGIT(x[4])) {
770 *x = 0;
771 return;
772 }
773 }
774 x++;
775 }
776}
777
778static void substitute_char(char *s, char a, char b)
779{
780 for (;;) {
781 s = strchr(s, a);
782 if (!s) {
783 return;
784 }
785 *s = b;
786 s++;
787 }
788}
789
790static inline const char *trim_vendor(const char *s)
791{
792
793 const char *ret = memchr(s, ',', strlen(s));
794 return ret ? ret + 1 : s;
795}
796
797static Object *fdt_create_from_compat(const char *compat, char **dev_type)
798{
799 Object *ret = NULL;
800 char *c = g_strdup(compat);
801
802
803 ret = object_new(c);
804
805 if (!ret) {
806
807 trim_version(c);
808 ret = object_new(c);
809
810 if (!ret) {
811
812 substitute_char(c, ',', '.');
813 ret = object_new(c);
814 }
815 }
816
817 if (!ret) {
818
819
820
821 g_free(c);
822 c = g_strdup(compat);
823 substitute_char(c, ',', '.');
824 ret = object_new(c);
825 }
826
827 if (dev_type) {
828 *dev_type = c;
829 } else {
830 g_free(c);
831 }
832
833 if (!ret) {
834 const char *no_vendor = trim_vendor(compat);
835
836 if (no_vendor != compat) {
837 return fdt_create_from_compat(no_vendor, dev_type);
838 }
839 }
840 return ret;
841}
842
843
844
845static inline uint64_t get_int_be(const void *p, int len)
846{
847 switch (len) {
848 case 1:
849 return *((uint8_t *)p);
850 case 2:
851 return be16_to_cpu(*((uint16_t *)p));
852 case 4:
853 return be32_to_cpu(*((uint32_t *)p));
854 case 8:
855 return be32_to_cpu(*((uint64_t *)p));
856 default:
857 fprintf(stderr, "unsupported integer length\n");
858 abort();
859 }
860}
861
862
863
864static const char *fdt_generic_reg_size_prop_names[] = {
865 "#address-cells",
866 "#size-cells",
867 "#bus-cells",
868 "#priority-cells",
869};
870
871static const int fdt_generic_reg_cells_defaults[] = {
872 1,
873 1,
874 0,
875 0,
876};
877
878static int fdt_init_qdev(char *node_path, FDTMachineInfo *fdti, char *compat)
879{
880 Object *dev, *parent;
881 char *dev_type = NULL;
882 int is_intc;
883 Error *errp = NULL;
884 int i, j;
885 QEMUDevtreeProp *prop, *props;
886 char parent_node_path[DT_PATH_LENGTH];
887 const FDTGenericGPIOSet *gpio_set = NULL;
888 FDTGenericGPIOClass *fggc = NULL;
889
890 if (!compat) {
891 return 1;
892 }
893 dev = fdt_create_from_compat(compat, &dev_type);
894 if (!dev) {
895 DB_PRINT_NP(1, "no match found for %s\n", compat);
896 return 1;
897 }
898 DB_PRINT_NP(1, "matched compat %s\n", compat);
899
900
901 if (object_dynamic_cast(dev, TYPE_CPU)) {
902 fdt_generic_num_cpus++;
903 DB_PRINT_NP(0, "is a CPU - total so far %d\n", fdt_generic_num_cpus);
904 }
905
906 if (qemu_devtree_getparent(fdti->fdt, parent_node_path, node_path)) {
907 abort();
908 }
909 while (!fdt_init_has_opaque(fdti, parent_node_path)) {
910 fdt_init_yield(fdti);
911 }
912 parent = fdt_init_get_opaque(fdti, parent_node_path);
913 if (dev->parent) {
914 DB_PRINT_NP(0, "Node already parented - skipping node\n");
915 } else if (parent) {
916 DB_PRINT_NP(1, "parenting node\n");
917 object_property_add_child(OBJECT(parent),
918 qemu_devtree_get_node_name(fdti->fdt, node_path),
919 OBJECT(dev), NULL);
920 if (object_dynamic_cast(dev, TYPE_DEVICE)) {
921 Object *parent_bus = parent;
922 unsigned int depth = 0;
923
924 DB_PRINT_NP(1, "bus parenting node\n");
925
926 while (parent_bus && !object_dynamic_cast(parent_bus, TYPE_BUS)) {
927
928
929
930
931 assert(depth < 4096);
932
933 parent_bus = parent_bus->parent;
934 depth++;
935 }
936
937 if (!parent_bus
938 && object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE)) {
939
940
941
942
943
944 parent_bus = OBJECT(sysbus_get_default());
945 }
946
947 if (parent_bus) {
948 qdev_set_parent_bus(DEVICE(dev), BUS(parent_bus));
949 }
950 }
951 } else {
952 DB_PRINT_NP(1, "orphaning node\n");
953
954 object_property_add_child(
955 object_get_root(),
956 qemu_devtree_get_node_name(fdti->fdt, node_path),
957 OBJECT(dev), NULL);
958 }
959 fdt_init_set_opaque(fdti, node_path, dev);
960
961
962
963 if (global_sync_quantum) {
964 ObjectProperty *p;
965
966 p = object_property_find(OBJECT(dev), "sync-quantum", NULL);
967 if (p) {
968 object_property_set_int(OBJECT(dev), global_sync_quantum,
969 "sync-quantum", &errp);
970 }
971 }
972
973 props = qemu_devtree_get_props(fdti->fdt, node_path);
974 for (prop = props; prop->name; prop++) {
975 const char *propname = trim_vendor(prop->name);
976 int len = prop->len;
977 void *val = prop->value;
978
979 ObjectProperty *p = object_property_find(OBJECT(dev), propname, NULL);
980 if (p) {
981 DB_PRINT_NP(1, "matched property: %s of type %s, len %d\n",
982 propname, p->type, prop->len);
983 }
984 if (!p) {
985 continue;
986 }
987
988 if (!strcmp(propname, "type")) {
989 continue;
990 }
991
992
993 if (!strcmp(p->type, "uint8") || !strcmp(p->type, "uint16") ||
994 !strcmp(p->type, "uint32") || !strcmp(p->type, "uint64")) {
995 object_property_set_int(OBJECT(dev), get_int_be(val, len), propname,
996 &error_abort);
997 DB_PRINT_NP(0, "set property %s to %#llx\n", propname,
998 (unsigned long long)get_int_be(val, len));
999 } else if (!strcmp(p->type, "boolean") || !strcmp(p->type, "bool")) {
1000 object_property_set_bool(OBJECT(dev), !!get_int_be(val, len),
1001 propname, &error_abort);
1002 DB_PRINT_NP(0, "set property %s to %s\n", propname,
1003 get_int_be(val, len) ? "true" : "false");
1004 } else if (!strcmp(p->type, "string") || !strcmp(p->type, "str")) {
1005 object_property_set_str(OBJECT(dev), (const char *)val, propname,
1006 &error_abort);
1007 DB_PRINT_NP(0, "set property %s to %s\n", propname,
1008 (const char *)val);
1009 } else if (!strncmp(p->type, "link", 4)) {
1010 char target_node_path[DT_PATH_LENGTH];
1011 char propname_target[1024];
1012 strcpy(propname_target, propname);
1013 strcat(propname_target, "-target");
1014
1015 Object *linked_dev, *proxy;
1016
1017 if (qemu_devtree_get_node_by_phandle(fdti->fdt, target_node_path,
1018 get_int_be(val, len))) {
1019 abort();
1020 }
1021 while (!fdt_init_has_opaque(fdti, target_node_path)) {
1022 fdt_init_yield(fdti);
1023 }
1024 linked_dev = fdt_init_get_opaque(fdti, target_node_path);
1025
1026 proxy = linked_dev ? object_property_get_link(linked_dev,
1027 propname_target,
1028 &errp) : NULL;
1029 if (!errp && proxy) {
1030 DB_PRINT_NP(0, "detected proxy object for %s connection\n",
1031 propname);
1032 linked_dev = proxy;
1033 }
1034 errp = NULL;
1035 if (linked_dev) {
1036 object_property_set_link(OBJECT(dev), linked_dev, propname,
1037 &errp);
1038 if (errp) {
1039
1040
1041
1042 MemoryRegion *alias_mr;
1043 int offset = len / 2;
1044 alias_mr =
1045 sysbus_mmio_get_region(SYS_BUS_DEVICE(linked_dev),
1046 get_int_be(val + offset,
1047 len - offset));
1048
1049 object_property_set_link(OBJECT(dev), OBJECT(alias_mr),
1050 propname, &error_abort);
1051
1052 errp = NULL;
1053 }
1054 DB_PRINT_NP(0, "set link %s\n", propname);
1055 }
1056 } else {
1057 DB_PRINT_NP(0, "WARNING: property is of unknown type\n");
1058 }
1059 }
1060
1061
1062 if (object_dynamic_cast(dev, TYPE_REMOTE_PORT_DEVICE)) {
1063 int i;
1064
1065 for (i = 0;;++i) {
1066 char adaptor_node_path[DT_PATH_LENGTH];
1067 uint32_t adaptor_phandle, chan;
1068 DeviceState *adaptor;
1069 char *name;
1070
1071 adaptor_phandle = qemu_fdt_getprop_cell(fdti->fdt, node_path,
1072 "remote-ports",
1073 2 * i, false, &errp);
1074 if (errp) {
1075 DB_PRINT_NP(1, "cant get phandle from \"remote-ports\" "
1076 "property\n");
1077 break;
1078 }
1079 if (qemu_devtree_get_node_by_phandle(fdti->fdt, adaptor_node_path,
1080 adaptor_phandle)) {
1081 DB_PRINT_NP(1, "cant get node from phandle\n");
1082 break;
1083 }
1084 adaptor = DEVICE(fdt_init_get_opaque(fdti, adaptor_node_path));
1085 name = g_strdup_printf("rp-adaptor%" PRId32, i);
1086 object_property_set_link(OBJECT(dev), OBJECT(adaptor), name, &errp);
1087 DB_PRINT_NP(0, "connecting RP to adaptor %s channel %d",
1088 object_get_canonical_path(OBJECT(adaptor)), i);
1089 g_free(name);
1090 if (errp) {
1091 DB_PRINT_NP(1, "cant set adaptor link for device property\n");
1092 break;
1093 }
1094
1095 chan = qemu_fdt_getprop_cell(fdti->fdt, node_path, "remote-ports",
1096 2 * i + 1, false, &errp);
1097 if (errp) {
1098 DB_PRINT_NP(1, "cant get channel from \"remote-ports\" "
1099 "property\n");
1100 break;
1101 }
1102
1103 name = g_strdup_printf("rp-chan%" PRId32, i);
1104 object_property_set_int(OBJECT(dev), chan, name, &errp);
1105
1106
1107
1108 if (errp) {
1109 DB_PRINT_NP(1, "cant set %s property %s\n", name, error_get_pretty(errp));
1110 errp = NULL;
1111 }
1112 g_free(name);
1113
1114 name = g_strdup_printf("remote-port-dev%d", chan);
1115 object_property_set_link(OBJECT(adaptor), OBJECT(dev), name,
1116 &errp);
1117 g_free(name);
1118 if (errp) {
1119 DB_PRINT_NP(1, "cant set device link for adaptor\n");
1120 break;
1121 }
1122 }
1123 errp = NULL;
1124 }
1125
1126 if (object_dynamic_cast(dev, TYPE_DEVICE)) {
1127 DeviceClass *dc = DEVICE_GET_CLASS(dev);
1128
1129 static int nics;
1130 const char *short_name = qemu_devtree_get_node_name(fdti->fdt, node_path);
1131
1132 if (object_property_find(OBJECT(dev), "mac", NULL) &&
1133 object_property_find(OBJECT(dev), "netdev", NULL)) {
1134 qdev_set_nic_properties(DEVICE(dev), &nd_table[nics]);
1135 }
1136 if (nd_table[nics].instantiated) {
1137 DB_PRINT_NP(0, "NIC instantiated: %s\n", dev_type);
1138 nics++;
1139 }
1140
1141
1142
1143
1144 if (!object_dynamic_cast(dev, TYPE_REMOTE_PORT)) {
1145
1146 if (fdt_serial_ports < MAX_SERIAL_PORTS && serial_hds[fdt_serial_ports]) {
1147 Chardev *value = (Chardev*) serial_hds[fdt_serial_ports];
1148
1149 object_property_set_str(dev, value->label, "chardev", &errp);
1150 if (!errp) {
1151
1152 fdt_serial_ports++;
1153 }
1154
1155 errp = NULL;
1156 }
1157 }
1158
1159
1160
1161
1162
1163 object_property_find(OBJECT(dev), "drive", &errp);
1164 if (errp == NULL) {
1165 DriveInfo *dinfo = drive_get_next(IF_MTD);
1166 if (dinfo) {
1167 qdev_prop_set_drive(DEVICE(dev), "drive",
1168 blk_by_legacy_dinfo(dinfo), &error_abort);
1169 }
1170 }
1171 errp = NULL;
1172
1173
1174 DB_PRINT_NP(0, "Short naming node: %s\n", short_name);
1175 (DEVICE(dev))->id = g_strdup(short_name);
1176 qdev_init_nofail(DEVICE(dev));
1177 qemu_register_reset((void (*)(void *))dc->reset, dev);
1178 }
1179
1180 if (object_dynamic_cast(dev, TYPE_SYS_BUS_DEVICE) ||
1181 object_dynamic_cast(dev, TYPE_FDT_GENERIC_MMAP)) {
1182 FDTGenericRegPropInfo reg = {0};
1183 char parent_path[DT_PATH_LENGTH];
1184 int cell_idx = 0;
1185 bool extended = true;
1186
1187 qemu_fdt_getprop_cell(fdti->fdt, node_path, "reg-extended", 0, false,
1188 &errp);
1189 if (errp) {
1190 error_free(errp);
1191 errp = NULL;
1192 extended = false;
1193 qemu_devtree_getparent(fdti->fdt, parent_path, node_path);
1194 }
1195
1196 for (reg.n = 0;; reg.n++) {
1197 char ph_parent[DT_PATH_LENGTH];
1198 const char *pnp = parent_path;
1199
1200 reg.parents = g_renew(Object *, reg.parents, reg.n + 1);
1201 reg.parents[reg.n] = parent;
1202
1203 if (extended) {
1204 int p_ph = qemu_fdt_getprop_cell(fdti->fdt, node_path,
1205 "reg-extended", cell_idx++,
1206 false, &errp);
1207 if (errp) {
1208 error_free(errp);
1209 errp = NULL;
1210 goto exit_reg_parse;
1211 }
1212 if (qemu_devtree_get_node_by_phandle(fdti->fdt, ph_parent,
1213 p_ph)) {
1214 goto exit_reg_parse;
1215 }
1216 while (!fdt_init_has_opaque(fdti, ph_parent)) {
1217 fdt_init_yield(fdti);
1218 }
1219 reg.parents[reg.n] = fdt_init_get_opaque(fdti, ph_parent);
1220 pnp = ph_parent;
1221 }
1222
1223 for (i = 0; i < FDT_GENERIC_REG_TUPLE_LENGTH; ++i) {
1224 const char *size_prop_name = fdt_generic_reg_size_prop_names[i];
1225 int nc = qemu_fdt_getprop_cell(fdti->fdt, pnp, size_prop_name,
1226 0, true, &errp);
1227
1228 if (errp) {
1229 int size_default = fdt_generic_reg_cells_defaults[i];
1230
1231 DB_PRINT_NP(0, "WARNING: no %s for %s container, assuming "
1232 "default of %d\n", size_prop_name, pnp,
1233 size_default);
1234 nc = size_default;
1235 error_free(errp);
1236 errp = NULL;
1237 }
1238
1239 reg.x[i] = g_renew(uint64_t, reg.x[i], reg.n + 1);
1240 reg.x[i][reg.n] = nc ?
1241 qemu_fdt_getprop_sized_cell(fdti->fdt, node_path,
1242 extended ? "reg-extended"
1243 : "reg",
1244 cell_idx, nc, &errp)
1245 : 0;
1246 cell_idx += nc;
1247 if (errp) {
1248 goto exit_reg_parse;
1249 }
1250 }
1251 }
1252exit_reg_parse:
1253
1254 if (object_dynamic_cast(dev, TYPE_FDT_GENERIC_MMAP)) {
1255 FDTGenericMMapClass *fmc = FDT_GENERIC_MMAP_GET_CLASS(dev);
1256 if (fmc->parse_reg) {
1257 while (fmc->parse_reg(FDT_GENERIC_MMAP(dev), reg,
1258 &error_abort)) {
1259 fdt_init_yield(fdti);
1260 }
1261 }
1262 }
1263 }
1264
1265 if (object_dynamic_cast(dev, TYPE_SYS_BUS_DEVICE)) {
1266 {
1267 int len;
1268 fdt_get_property(fdti->fdt, fdt_path_offset(fdti->fdt, node_path),
1269 "interrupt-controller", &len);
1270 is_intc = len >= 0;
1271 DB_PRINT_NP(is_intc ? 0 : 1, "is interrupt controller: %c\n",
1272 is_intc ? 'y' : 'n');
1273 }
1274
1275 j = 0;
1276 for (i = 0;; i++) {
1277 char irq_info[1024];
1278 char *irq_info_p = irq_info;
1279 bool map_mode;
1280 int len = -1;
1281 qemu_irq *irqs = fdt_get_irq_info(fdti, node_path, i, irq_info,
1282 &map_mode);
1283
1284 fdt_get_property(fdti->fdt, fdt_path_offset(fdti->fdt, node_path),
1285 "interrupts-extended", &len);
1286 if (!irqs && is_intc && i == 0 && len <= 0) {
1287 FDTGenericIntc *id = (FDTGenericIntc *)object_dynamic_cast(
1288 dev, TYPE_FDT_GENERIC_INTC);
1289 FDTGenericIntcClass *idc = FDT_GENERIC_INTC_GET_CLASS(id);
1290 if (id && idc->auto_parent) {
1291 Error *err = NULL;
1292 idc->auto_parent(id, &err);
1293 } else {
1294 irqs = fdti->irq_base;
1295 }
1296 }
1297 if (!irqs) {
1298 break;
1299 }
1300 while (*irqs) {
1301 FDTIRQConnection *irq = g_new0(FDTIRQConnection, 1);
1302 *irq = (FDTIRQConnection) {
1303 .dev = DEVICE(dev),
1304 .name = SYSBUS_DEVICE_GPIO_IRQ,
1305 .merge_fn = qemu_irq_shared_or_handler,
1306 .i = j,
1307 .irq = *irqs,
1308 .sink_info = g_strdup(irq_info_p),
1309 .next = fdti->irqs
1310 };
1311 if (!map_mode) {
1312 j++;
1313 } else {
1314 irq_info_p += strlen(irq_info_p) + 1;
1315 }
1316 fdti->irqs = irq;
1317 irqs++;
1318 }
1319 if (map_mode) {
1320 j++;
1321 }
1322 }
1323 }
1324
1325 if (object_dynamic_cast(dev, TYPE_FDT_GENERIC_GPIO)) {
1326 fggc = FDT_GENERIC_GPIO_GET_CLASS(dev);
1327 gpio_set = fggc->client_gpios;
1328 }
1329
1330 if (!gpio_set) {
1331 gpio_set = default_gpio_sets;
1332 }
1333
1334 for (; object_dynamic_cast(dev, TYPE_DEVICE) && gpio_set->names;
1335 gpio_set++) {
1336 bool end = false;
1337 int cur_cell = 0;
1338
1339 for (i = 0; !end; i++) {
1340 char *debug_success;
1341 const FDTGenericGPIOConnection *c = gpio_set->gpios;
1342 const char *gpio_name = NULL;
1343 uint16_t named_idx = 0;
1344 qemu_irq input, output;
1345 memset(&input, 0, sizeof(input));
1346
1347 if (c) {
1348 uint16_t range = c->range ? c->range : 1;
1349 while ((c->fdt_index > i || c->fdt_index + range <= i)
1350 && c->name) {
1351 c++;
1352 }
1353 named_idx = i - c->fdt_index;
1354 gpio_name = c->name;
1355 }
1356 if (!gpio_name) {
1357 const char *names_propname = gpio_set->names->names_propname;
1358 gpio_name = qemu_fdt_getprop_string(fdti->fdt, node_path,
1359 names_propname, i, false,
1360 NULL);
1361 }
1362 if (!gpio_name) {
1363 input = qdev_get_gpio_in(DEVICE(dev), i);
1364 } else {
1365 input = qdev_get_gpio_in_named(DEVICE(dev), gpio_name,
1366 named_idx);
1367 }
1368 debug_success = g_strdup_printf("Wiring GPIO input %s[%" PRId16 "] "
1369 "to", gpio_name, named_idx);
1370 output = fdt_get_gpio(fdti, node_path, &cur_cell, input, gpio_set,
1371 debug_success, &end);
1372 g_free(debug_success);
1373 if (output) {
1374 FDTIRQConnection *irq = g_new0(FDTIRQConnection, 1);
1375 *irq = (FDTIRQConnection) {
1376 .dev = DEVICE(dev),
1377 .name = gpio_name,
1378 .merge_fn = qemu_irq_shared_or_handler,
1379 .i = named_idx,
1380 .irq = output,
1381 .sink_info = NULL,
1382 .next = fdti->irqs
1383 };
1384 fdti->irqs = irq;
1385 DB_PRINT_NP(1, "... GPIO output %s[%" PRId16 "]\n", gpio_name,
1386 named_idx);
1387 }
1388 }
1389 }
1390
1391 if (dev_type) {
1392 g_free(dev_type);
1393 }
1394
1395 return 0;
1396}
1397
1398static const TypeInfo fdt_generic_intc_info = {
1399 .name = TYPE_FDT_GENERIC_INTC,
1400 .parent = TYPE_INTERFACE,
1401 .class_size = sizeof(FDTGenericIntcClass),
1402};
1403
1404static const TypeInfo fdt_generic_mmap_info = {
1405 .name = TYPE_FDT_GENERIC_MMAP,
1406 .parent = TYPE_INTERFACE,
1407 .class_size = sizeof(FDTGenericMMapClass),
1408};
1409
1410static const TypeInfo fdt_generic_gpio_info = {
1411 .name = TYPE_FDT_GENERIC_GPIO,
1412 .parent = TYPE_INTERFACE,
1413 .class_size = sizeof(FDTGenericGPIOClass),
1414};
1415
1416static void fdt_generic_intc_register_types(void)
1417{
1418 type_register_static(&fdt_generic_intc_info);
1419 type_register_static(&fdt_generic_mmap_info);
1420 type_register_static(&fdt_generic_gpio_info);
1421}
1422
1423type_init(fdt_generic_intc_register_types)
1424