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