qemu/hw/core/fdt_generic_util.c
<<
>>
Prefs
   1/*
   2 * Utility functions for fdt generic framework
   3 *
   4 * Copyright (c) 2009 Edgar E. Iglesias.
   5 * Copyright (c) 2009 Michal Simek.
   6 * Copyright (c) 2011 PetaLogix Qld Pty Ltd.
   7 * Copyright (c) 2011 Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com>.
   8 *
   9 * Permission is hereby granted, free of charge, to any person obtaining a copy
  10 * of this software and associated documentation files (the "Software"), to deal
  11 * in the Software without restriction, including without limitation the rights
  12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13 * copies of the Software, and to permit persons to whom the Software is
  14 * furnished to do so, subject to the following conditions:
  15 *
  16 * The above copyright notice and this permission notice shall be included in
  17 * all copies or substantial portions of the Software.
  18 *
  19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25 * THE SOFTWARE.
  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 "qemu/error-report.h"
  37#include "sysemu/sysemu.h"
  38#include "sysemu/reset.h"
  39#include "qemu/cutils.h"
  40#include "sysemu/blockdev.h"
  41#include "sysemu/block-backend.h"
  42#include "chardev/char.h"
  43#include "qemu/log.h"
  44#include "qemu/config-file.h"
  45#include "block/block.h"
  46#include "hw/ssi/ssi.h"
  47#include "hw/boards.h"
  48#include "qemu/option.h"
  49#include "hw/qdev-properties.h"
  50
  51#ifndef FDT_GENERIC_UTIL_ERR_DEBUG
  52#define FDT_GENERIC_UTIL_ERR_DEBUG 3
  53#endif
  54#define DB_PRINT(lvl, ...) do { \
  55    if (FDT_GENERIC_UTIL_ERR_DEBUG > (lvl)) { \
  56        qemu_log_mask(LOG_FDT, ": %s: ", __func__); \
  57        qemu_log_mask(LOG_FDT, ## __VA_ARGS__); \
  58    } \
  59} while (0);
  60
  61#define DB_PRINT_NP(lvl, ...) do { \
  62    if (FDT_GENERIC_UTIL_ERR_DEBUG > (lvl)) { \
  63       qemu_log_mask(LOG_FDT, "%s", node_path); \
  64       DB_PRINT((lvl), ## __VA_ARGS__); \
  65    } \
  66} while (0);
  67
  68#include "hw/remote-port-device.h"
  69#include "hw/remote-port.h"
  70
  71/* FIXME: wrap direct calls into libfdt */
  72
  73#include <libfdt.h>
  74#include <stdlib.h>
  75
  76int fdt_serial_ports;
  77
  78static int simple_bus_fdt_init(char *bus_node_path, FDTMachineInfo *fdti);
  79
  80static void fdt_get_irq_info_from_intc(FDTMachineInfo *fdti, qemu_irq *ret,
  81                                       char *intc_node_path,
  82                                       uint32_t *cells, uint32_t num_cells,
  83                                       uint32_t max, Error **errp);
  84
  85
  86typedef struct QEMUIRQSharedState {
  87    qemu_irq sink;
  88    int num;
  89    bool (*merge_fn)(bool *, int);
  90/* FIXME: remove artificial limit */
  91#define MAX_IRQ_SHARED_INPUTS 128
  92    bool inputs[MAX_IRQ_SHARED_INPUTS];
  93} QEMUIRQSharedState;
  94
  95static bool qemu_irq_shared_or_handler(bool *inputs, int n)
  96{
  97    int i;
  98
  99    assert(n < MAX_IRQ_SHARED_INPUTS);
 100
 101    for (i = 0; i < n; ++i) {
 102        if (inputs[i]) {
 103            return true;
 104        }
 105    }
 106    return false;
 107}
 108
 109static bool qemu_irq_shared_and_handler(bool *inputs, int n)
 110{
 111    int i;
 112
 113    assert(n < MAX_IRQ_SHARED_INPUTS);
 114
 115    for (i = 0; i < n; ++i) {
 116        if (!inputs[i]) {
 117            return false;
 118        }
 119    }
 120    return true;
 121}
 122
 123static void qemu_irq_shared_handler(void *opaque, int n, int level)
 124{
 125    QEMUIRQSharedState *s = opaque;
 126
 127    assert(n < MAX_IRQ_SHARED_INPUTS);
 128    s->inputs[n] = level;
 129    qemu_set_irq(s->sink, s->merge_fn(s->inputs, s->num));
 130}
 131
 132static void fdt_init_all_irqs(FDTMachineInfo *fdti)
 133{
 134    while (fdti->irqs) {
 135        FDTIRQConnection *first = fdti->irqs;
 136        qemu_irq sink = first->irq;
 137        bool (*merge_fn)(bool *, int) = first->merge_fn;
 138        int num_sources = 0;
 139        FDTIRQConnection *irq;
 140
 141        for (irq = first; irq; irq = irq->next) {
 142            if (irq->irq == sink) { /* Same sink */
 143                num_sources++;
 144            }
 145        }
 146        if (num_sources > 1) {
 147            QEMUIRQSharedState *s = g_malloc0(sizeof *s);
 148            s->sink = sink;
 149            s->merge_fn = merge_fn;
 150            qemu_irq *sources = qemu_allocate_irqs(qemu_irq_shared_handler, s,
 151                                                   num_sources);
 152            for (irq = first; irq; irq = irq->next) {
 153                if (irq->irq == sink) {
 154                    char *shared_irq_name = g_strdup_printf("shared-irq-%p",
 155                                                            *sources);
 156
 157                    if (irq->merge_fn != merge_fn) {
 158                        fprintf(stderr, "ERROR: inconsistent IRQ merge fns\n");
 159                        exit(1);
 160                    }
 161
 162                    object_property_add_child(OBJECT(irq->dev), shared_irq_name,
 163                                              OBJECT(*sources));
 164                    g_free(shared_irq_name);
 165                    irq->irq = *(sources++);
 166                    s->num++;
 167                }
 168            }
 169        }
 170        DB_PRINT(0, "%s: connected to %s irq line %d (%s)\n",
 171                 first->sink_info ? first->sink_info : "",
 172                 object_get_canonical_path(OBJECT(first->dev)),
 173                 first->i, first->name ? first->name : "");
 174
 175        qdev_connect_gpio_out_named(DEVICE(first->dev), first->name, first->i,
 176                                    first->irq);
 177        fdti->irqs = first->next;
 178        g_free(first);
 179    }
 180}
 181
 182static void fdt_init_cpu_clusters(FDTMachineInfo *fdti)
 183{
 184        FDTCPUCluster *cl = fdti->clusters;
 185
 186        while (cl) {
 187                qdev_init_nofail(DEVICE(cl->cpu_cluster));
 188                cl = cl->next;
 189        }
 190}
 191
 192FDTMachineInfo *fdt_generic_create_machine(void *fdt, qemu_irq *cpu_irq)
 193{
 194    char node_path[DT_PATH_LENGTH];
 195    FDTMachineInfo *fdti = fdt_init_new_fdti(fdt);
 196
 197    fdti->irq_base = cpu_irq;
 198
 199    fdt_serial_ports = 0;
 200
 201    /* parse the device tree */
 202    if (!qemu_devtree_get_root_node(fdt, node_path)) {
 203        memory_region_transaction_begin();
 204        fdt_init_set_opaque(fdti, node_path, NULL);
 205        simple_bus_fdt_init(node_path, fdti);
 206        while (qemu_co_enter_next(fdti->cq, NULL));
 207        fdt_init_cpu_clusters(fdti);
 208        fdt_init_all_irqs(fdti);
 209        memory_region_transaction_commit();
 210    } else {
 211        fprintf(stderr, "FDT: ERROR: cannot get root node from device tree %s\n"
 212            , node_path);
 213    }
 214
 215    /* FIXME: Populate these from DTS and create CPU clusters.  */
 216    current_machine->smp.cores = fdt_generic_num_cpus;
 217    current_machine->smp.cpus = fdt_generic_num_cpus;
 218    current_machine->smp.max_cpus = fdt_generic_num_cpus;
 219
 220    bdrv_drain_all();
 221    DB_PRINT(0, "FDT: Device tree scan complete\n");
 222    return fdti;
 223}
 224
 225struct FDTInitNodeArgs {
 226    char *node_path;
 227    char *parent_path;
 228    FDTMachineInfo *fdti;
 229};
 230
 231static int fdt_init_qdev(char *node_path, FDTMachineInfo *fdti, char *compat);
 232
 233static int check_compat(const char *prefix, const char *compat,
 234                        char *node_path, FDTMachineInfo *fdti)
 235{
 236    char *compat_prefixed = g_strconcat(prefix, compat, NULL);
 237    const int done = !fdt_init_compat(node_path, fdti, compat_prefixed);
 238    g_free(compat_prefixed);
 239    return done;
 240}
 241
 242static void fdt_init_node(void *args)
 243{
 244    struct FDTInitNodeArgs *a = args;
 245    char *node_path = a->node_path;
 246    FDTMachineInfo *fdti = a->fdti;
 247    g_free(a);
 248
 249    simple_bus_fdt_init(node_path, fdti);
 250
 251    char *all_compats = NULL, *node_name;
 252    char *device_type = NULL;
 253    int compat_len;
 254
 255    DB_PRINT_NP(1, "enter\n");
 256
 257    /* try instance binding first */
 258    node_name = qemu_devtree_get_node_name(fdti->fdt, node_path);
 259    DB_PRINT_NP(1, "node with name: %s\n", node_name ? node_name : "(none)");
 260    if (!node_name) {
 261        printf("FDT: ERROR: nameless node: %s\n", node_path);
 262    }
 263    if (!fdt_init_inst_bind(node_path, fdti, node_name)) {
 264        DB_PRINT_NP(0, "instance bind successful\n");
 265        goto exit;
 266    }
 267
 268    /* fallback to compatibility binding */
 269    all_compats = qemu_fdt_getprop(fdti->fdt, node_path, "compatible",
 270                                   &compat_len, false, NULL);
 271    if (all_compats) {
 272        char *compat = all_compats;
 273        char * const end = &all_compats[compat_len - 1]; /* points to nul */
 274
 275        while (compat < end) {
 276            if (check_compat("compatible:", compat, node_path, fdti)) {
 277                goto exit;
 278            }
 279
 280            if (!fdt_init_qdev(node_path, fdti, compat)) {
 281                goto exit;
 282            }
 283
 284            /* Scan forward to the end of the current compat. */
 285            while (compat < end && *compat) {
 286                ++compat;
 287            }
 288
 289            /* Replace nul with space for the debug printf below. */
 290            if (compat < end) {
 291                *compat++ = ' ';
 292            }
 293        };
 294    } else {
 295        DB_PRINT_NP(0, "no compatibility found\n");
 296    }
 297
 298    /* Try to create the device using device_type property
 299     * Not every device tree node has compatible  property, so
 300     * try with device_type.
 301     */
 302    device_type = qemu_fdt_getprop(fdti->fdt, node_path,
 303                                   "device_type", NULL, false, NULL);
 304    if (device_type) {
 305        if (check_compat("device_type:", device_type, node_path, fdti)) {
 306            goto exit;
 307        }
 308
 309        if (!fdt_init_qdev(node_path, fdti, device_type)) {
 310            goto exit;
 311        }
 312    }
 313
 314    if (all_compats) {
 315        DB_PRINT_NP(0, "FDT: Unsupported peripheral invalidated - "
 316                    "compatibilities %s\n", all_compats);
 317        qemu_fdt_setprop_string(fdti->fdt, node_path, "compatible",
 318                                "invalidated");
 319    }
 320exit:
 321
 322    DB_PRINT_NP(1, "exit\n");
 323
 324    if (!fdt_init_has_opaque(fdti, node_path)) {
 325        fdt_init_set_opaque(fdti, node_path, NULL);
 326    }
 327    g_free(node_path);
 328    g_free(all_compats);
 329    g_free(device_type);
 330    return;
 331}
 332
 333static int simple_bus_fdt_init(char *node_path, FDTMachineInfo *fdti)
 334{
 335    int i;
 336    int num_children = qemu_devtree_get_num_children(fdti->fdt, node_path,
 337                                                        1);
 338    char **children;
 339
 340    if (num_children == 0) {
 341        return 0;
 342    }
 343    children = qemu_devtree_get_children(fdti->fdt, node_path, 1);
 344
 345    DB_PRINT_NP(num_children ? 0 : 1, "num child devices: %d\n", num_children);
 346
 347    for (i = 0; i < num_children; i++) {
 348        struct FDTInitNodeArgs *init_args = g_malloc0(sizeof(*init_args));
 349        init_args->node_path = children[i];
 350        init_args->fdti = fdti;
 351        qemu_coroutine_enter(qemu_coroutine_create(fdt_init_node, init_args));
 352    }
 353
 354    g_free(children);
 355    return 0;
 356}
 357
 358static qemu_irq fdt_get_gpio(FDTMachineInfo *fdti, char *node_path,
 359                             int* cur_cell, qemu_irq input,
 360                             const FDTGenericGPIOSet *gpio_set,
 361                             const char *debug_success, bool *end) {
 362    void *fdt = fdti->fdt;
 363    uint32_t parent_phandle, parent_cells = 0, cells[32];
 364    char parent_node_path[DT_PATH_LENGTH];
 365    DeviceState *parent;
 366    int i;
 367    Error *errp = NULL;
 368    const char *reason = NULL;
 369    bool free_reason = false;
 370    const char *propname = gpio_set->names->propname;
 371    const char *cells_propname = gpio_set->names->cells_propname;
 372
 373    cells[0] = 0;
 374
 375    parent_phandle = qemu_fdt_getprop_cell(fdt, node_path, propname,
 376                                           (*cur_cell)++, false, &errp);
 377    if (errp) {
 378        reason = g_strdup_printf("Cant get phandle from \"%s\" property\n",
 379                                 propname);
 380        *end = true;
 381        free_reason = true;
 382        goto fail_silent;
 383    }
 384    if (qemu_devtree_get_node_by_phandle(fdt, parent_node_path,
 385                                         parent_phandle)) {
 386        *end = true;
 387        reason = "cant get node from phandle\n";
 388        goto fail;
 389    }
 390    parent_cells = qemu_fdt_getprop_cell(fdt, parent_node_path,
 391                                         cells_propname, 0, false, &errp);
 392    if (errp) {
 393        *end = true;
 394        reason = g_strdup_printf("cant get the property \"%s\" from the " \
 395                                 "parent \"%s\"\n",
 396                                 cells_propname, parent_node_path);
 397        free_reason = true;
 398        goto fail;
 399    }
 400
 401    for (i = 0; i < parent_cells; ++i) {
 402        cells[i] = qemu_fdt_getprop_cell(fdt, node_path, propname,
 403                                         (*cur_cell)++, false, &errp);
 404        if (errp) {
 405            *end = true;
 406            reason = "cant get cell value";
 407            goto fail;
 408        }
 409    }
 410
 411    while (!fdt_init_has_opaque(fdti, parent_node_path)) {
 412        fdt_init_yield(fdti);
 413    }
 414    parent = DEVICE(fdt_init_get_opaque(fdti, parent_node_path));
 415
 416    if (!parent) {
 417        reason = "parent is not a device";
 418        goto fail_silent;
 419    }
 420
 421    while (!parent->realized) {
 422        fdt_init_yield(fdti);
 423    }
 424
 425    {
 426        const FDTGenericGPIOConnection *fgg_con = NULL;
 427        uint16_t range, idx;
 428        const char *gpio_name = NULL;
 429        qemu_irq ret;
 430
 431        if (object_dynamic_cast(OBJECT(parent), TYPE_FDT_GENERIC_GPIO)) {
 432            const FDTGenericGPIOSet *set;
 433            FDTGenericGPIOClass *parent_fggc =
 434                        FDT_GENERIC_GPIO_GET_CLASS(parent);
 435
 436            for (set = parent_fggc->controller_gpios; set && set->names;
 437                 set++) {
 438                if (!strcmp(gpio_set->names->cells_propname,
 439                            set->names->cells_propname)) {
 440                    fgg_con = set->gpios;
 441                    break;
 442                }
 443            }
 444        }
 445
 446        /* FIXME: cells[0] is not always the fdt indexing match system */
 447        idx = cells[0] & ~(1ul << 31);
 448        if (fgg_con) {
 449            range = fgg_con->range ? fgg_con->range : 1;
 450            while (!(idx >= fgg_con->fdt_index
 451                     && idx < (fgg_con->fdt_index + range))
 452                   && fgg_con->name) {
 453                fgg_con++;
 454                range = fgg_con->range ? fgg_con->range : 1;
 455            }
 456
 457            idx -= fgg_con->fdt_index;
 458            gpio_name = fgg_con->name;
 459        }
 460
 461        if (input) {
 462            FDTIRQConnection *irq = g_new0(FDTIRQConnection, 1);
 463            bool (*merge_fn)(bool *, int) = qemu_irq_shared_or_handler;
 464
 465            /* FIXME: I am kind of stealing here. Use the msb of the first
 466             * cell to indicate the merge function. This needs to be discussed
 467             * with device-tree community on how this should be done properly.
 468             */
 469            if (cells[0] & (1 << 31)) {
 470                merge_fn = qemu_irq_shared_and_handler;
 471            }
 472
 473            DB_PRINT_NP(1, "%s GPIO output %s[%d] on %s\n", debug_success,
 474                        gpio_name ? gpio_name : "unnamed", idx,
 475                        parent_node_path);
 476            *irq = (FDTIRQConnection) {
 477                .dev = parent,
 478                .name = gpio_name,
 479                .merge_fn = merge_fn,
 480                .i = idx,
 481                .irq = input,
 482                .sink_info = NULL, /* FIMXE */
 483                .next = fdti->irqs
 484            };
 485            fdti->irqs = irq;
 486        }
 487
 488        if (!strcmp(propname, "interrupts-extended") &&
 489            object_dynamic_cast(OBJECT(parent), TYPE_FDT_GENERIC_INTC) &&
 490            parent_cells > 1) {
 491            qemu_irq *irqs = g_new0(qemu_irq, fdt_generic_num_cpus);
 492            int i;
 493
 494            fdt_get_irq_info_from_intc(fdti, irqs, parent_node_path, cells,
 495                                    parent_cells, fdt_generic_num_cpus, &errp);
 496            if (errp) {
 497                reason = "failed to create gpio connection";
 498                goto fail;
 499            }
 500
 501            ret = NULL;
 502            for (i = 0; i < fdt_generic_num_cpus; i++) {
 503                if (irqs[i]) {
 504                    ret = irqs[i];
 505                    break;
 506                }
 507            }
 508            g_free(irqs);
 509        } else {
 510            ret = qdev_get_gpio_in_named(parent, gpio_name, idx);
 511        }
 512
 513        if (ret) {
 514            DB_PRINT_NP(1, "wiring GPIO input %s on %s ...\n",
 515                        fgg_con ? fgg_con->name : "unnamed", parent_node_path);
 516        }
 517        return ret;
 518    }
 519fail:
 520    if (reason) {
 521        fprintf(stderr, "%s Failed: %s\n", node_path, reason);
 522    }
 523
 524fail_silent:
 525    if (free_reason) {
 526        g_free((void *)reason);
 527    }
 528    return NULL;
 529}
 530
 531static void fdt_get_irq_info_from_intc(FDTMachineInfo *fdti, qemu_irq *ret,
 532                                       char *intc_node_path,
 533                                       uint32_t *cells, uint32_t num_cells,
 534                                       uint32_t max, Error **errp)
 535{
 536    FDTGenericIntcClass *intc_fdt_class;
 537    DeviceState *intc;
 538
 539    while (!fdt_init_has_opaque(fdti, intc_node_path)) {
 540        fdt_init_yield(fdti);
 541    }
 542    intc = DEVICE(fdt_init_get_opaque(fdti, intc_node_path));
 543
 544    if (!intc) {
 545        goto fail;
 546    }
 547
 548    while (!intc->realized) {
 549        fdt_init_yield(fdti);
 550    }
 551
 552    intc_fdt_class = FDT_GENERIC_INTC_GET_CLASS(intc);
 553    if (!intc_fdt_class) {
 554        goto fail;
 555    }
 556
 557    intc_fdt_class->get_irq(FDT_GENERIC_INTC(intc), ret, cells, num_cells,
 558                            max, errp);
 559
 560    return;
 561fail:
 562    error_setg(errp, "%s", __func__);
 563}
 564
 565static uint32_t imap_cache[32 * 1024];
 566static bool imap_cached = false;
 567
 568qemu_irq *fdt_get_irq_info(FDTMachineInfo *fdti, char *node_path, int irq_idx,
 569                          char *info, bool *map_mode) {
 570    void *fdt = fdti->fdt;
 571    uint32_t intc_phandle, intc_cells, cells[32];
 572    char intc_node_path[DT_PATH_LENGTH];
 573    qemu_irq *ret = NULL;
 574    int i;
 575    Error *errp = NULL;
 576
 577    intc_phandle = qemu_fdt_getprop_cell(fdt, node_path, "interrupt-parent",
 578                                         0, true, &errp);
 579    if (errp) {
 580        errp = NULL;
 581        intc_cells = qemu_fdt_getprop_cell(fdt, node_path,
 582                                           "#interrupt-cells", 0, true, &errp);
 583        *map_mode = true;
 584    } else {
 585        if (qemu_devtree_get_node_by_phandle(fdt, intc_node_path,
 586                                             intc_phandle)) {
 587            goto fail;
 588        }
 589
 590        /* Check if the device is using interrupt-maps */
 591        qemu_fdt_getprop_cell(fdt, node_path, "interrupt-map-mask", 0,
 592                              false, &errp);
 593        if (!errp) {
 594            errp = NULL;
 595            intc_cells = qemu_fdt_getprop_cell(fdt, node_path,
 596                                               "#interrupt-cells", 0,
 597                                               true, &errp);
 598            *map_mode = true;
 599        } else {
 600            errp = NULL;
 601            intc_cells = qemu_fdt_getprop_cell(fdt, intc_node_path,
 602                                               "#interrupt-cells", 0,
 603                                               true, &errp);
 604            *map_mode = false;
 605        }
 606    }
 607
 608    if (errp) {
 609        goto fail;
 610    }
 611
 612    DB_PRINT_NP(2, "%s intc_phandle: %d\n", node_path, intc_phandle);
 613
 614    for (i = 0; i < intc_cells; ++i) {
 615        cells[i] = qemu_fdt_getprop_cell(fdt, node_path, "interrupts",
 616                                         intc_cells * irq_idx + i, false, &errp);
 617        if (errp) {
 618            goto fail;
 619        }
 620    }
 621
 622    if (*map_mode) {
 623        int k;
 624        ret = g_new0(qemu_irq, 1);
 625        int num_matches = 0;
 626        int len;
 627        uint32_t imap_mask[intc_cells];
 628        uint32_t *imap_p;
 629        uint32_t *imap;
 630        bool use_parent = false;
 631
 632        for (k = 0; k < intc_cells; ++k) {
 633            imap_mask[k] = qemu_fdt_getprop_cell(fdt, node_path,
 634                                                 "interrupt-map-mask", k + 2,
 635                                                 true, &errp);
 636            if (errp) {
 637                goto fail;
 638            }
 639        }
 640
 641        /* Check if the device has an interrupt-map property */
 642        imap = qemu_fdt_getprop(fdt, node_path, "interrupt-map", &len,
 643                                  use_parent, &errp);
 644
 645        if (!imap || errp) {
 646            /* If the device doesn't have an interrupt-map, try again with
 647             * inheritance. This will return the parents interrupt-map
 648             */
 649            use_parent = true;
 650            errp = NULL;
 651
 652            imap_p = qemu_fdt_getprop(fdt, node_path, "interrupt-map",
 653                                      &len, use_parent, &errp);
 654            if (!imap_cached) {
 655                memcpy(imap_cache, imap_p, len);
 656                imap_cached = true;
 657            }
 658            imap = imap_cache;
 659
 660            if (errp) {
 661                goto fail;
 662            }
 663        }
 664
 665        len /= sizeof(uint32_t);
 666
 667        i = 0;
 668        assert(imap);
 669        while (i < len) {
 670            if (!use_parent) {
 671                /* Only re-sync the interrupt-map when the device has it's
 672                 * own map, to save time.
 673                 */
 674                imap = qemu_fdt_getprop(fdt, node_path, "interrupt-map", &len,
 675                                          use_parent, &errp);
 676
 677                if (errp) {
 678                    goto fail;
 679                }
 680
 681                len /= sizeof(uint32_t);
 682            }
 683
 684            bool match = true;
 685            uint32_t new_intc_cells, new_cells[32];
 686            i++; i++; /* FIXME: do address cells properly */
 687            for (k = 0; k < intc_cells; ++k) {
 688                uint32_t  map_val = be32_to_cpu(imap[i++]);
 689                if ((cells[k] ^ map_val) & imap_mask[k]) {
 690                    match = false;
 691                }
 692            }
 693            /* when caching, we hackishly store the number of cells for
 694             * the parent in the MSB. +1, so zero MSB means non cachd
 695             * and the full lookup is needed.
 696             */
 697            intc_phandle = be32_to_cpu(imap[i++]);
 698            if (intc_phandle & (0xffu << 24)) {
 699                new_intc_cells = (intc_phandle >> 24) - 1;
 700            } else {
 701                if (qemu_devtree_get_node_by_phandle(fdt, intc_node_path,
 702                                                     intc_phandle)) {
 703                    goto fail;
 704                }
 705                new_intc_cells = qemu_fdt_getprop_cell(fdt, intc_node_path,
 706                                                       "#interrupt-cells", 0,
 707                                                       false, &errp);
 708                imap[i - 1] = cpu_to_be32(intc_phandle |
 709                                            (new_intc_cells + 1) << 24);
 710                if (errp) {
 711                    goto fail;
 712                }
 713            }
 714            for (k = 0; k < new_intc_cells; ++k) {
 715                new_cells[k] = be32_to_cpu(imap[i++]);
 716            }
 717            if (match) {
 718                num_matches++;
 719                ret = g_renew(qemu_irq, ret, num_matches + 1);
 720                if (intc_phandle & (0xffu << 24)) {
 721                    if (qemu_devtree_get_node_by_phandle(fdt, intc_node_path,
 722                                                         intc_phandle &
 723                                                         ((1 << 24) - 1))) {
 724                        goto fail;
 725                    }
 726                }
 727
 728                DB_PRINT_NP(2, "Getting IRQ information: %s -> 0x%x (%s)\n",
 729                            node_path, intc_phandle, intc_node_path);
 730
 731                memset(&ret[num_matches], 0, sizeof(*ret));
 732                fdt_get_irq_info_from_intc(fdti, &ret[num_matches-1], intc_node_path,
 733                                           new_cells, new_intc_cells, 1, &errp);
 734                if (info) {
 735                   sprintf(info, "%s", intc_node_path);
 736                   info += strlen(info) + 1;
 737                }
 738                if (errp) {
 739                    goto fail;
 740                }
 741            }
 742        }
 743        return ret;
 744    }
 745
 746    DB_PRINT_NP(2, "Getting IRQ information: %s -> %s\n",
 747                node_path, intc_node_path);
 748
 749    ret = g_new0(qemu_irq, fdt_generic_num_cpus + 2);
 750    fdt_get_irq_info_from_intc(fdti, ret, intc_node_path, cells, intc_cells,
 751                               fdt_generic_num_cpus, &errp);
 752
 753    if (errp) {
 754        goto fail;
 755    }
 756
 757    /* FIXME: Phase out this info bussiness */
 758    if (info) {
 759        sprintf(info, "%s", intc_node_path);
 760    }
 761
 762    return ret;
 763
 764fail:
 765    if (errp) {
 766        sprintf(info, "%s", error_get_pretty(errp));
 767    } else {
 768        sprintf(info, "(none)");
 769    }
 770    return NULL;
 771}
 772
 773qemu_irq *fdt_get_irq(FDTMachineInfo *fdti, char *node_path, int irq_idx,
 774                      bool *map_mode)
 775{
 776    return fdt_get_irq_info(fdti, node_path, irq_idx, NULL, map_mode);
 777}
 778
 779/* FIXME: figure out a real solution to this */
 780
 781#define DIGIT(a) ((a) >= '0' && (a) <= '9')
 782#define LOWER_CASE(a) ((a) >= 'a' && (a) <= 'z')
 783
 784static void trim_version(char *x)
 785{
 786    long result;
 787
 788    for (;;) {
 789        x = strchr(x, '-');
 790        if (!x) {
 791            return;
 792        }
 793        if (DIGIT(x[1])) {
 794            /* Try to trim Xilinx version suffix */
 795            const char *p;
 796
 797            qemu_strtol(x + 1, &p, 0, &result);
 798
 799            if ( *p == '.') {
 800                *x = 0;
 801                return;
 802            } else if ( *p == 0) {
 803                return;
 804            }
 805        } else if (x[1] == 'r' && x[3] == 'p') {
 806            /* Try to trim ARM version suffix */
 807            if (DIGIT(x[2]) && DIGIT(x[4])) {
 808                *x = 0;
 809                return;
 810            }
 811        }
 812        x++;
 813    }
 814}
 815
 816static void substitute_char(char *s, char a, char b)
 817{
 818    for (;;) {
 819        s = strchr(s, a);
 820        if (!s) {
 821            return;
 822        }
 823        *s = b;
 824        s++;
 825    }
 826}
 827
 828static inline const char *trim_vendor(const char *s)
 829{
 830    /* FIXME: be more intelligent */
 831    const char *ret = memchr(s, ',', strlen(s));
 832    return ret ? ret + 1 : s;
 833}
 834
 835/*
 836 * Try to attach by matching drive created by '-blockdev node-name=LABEL'
 837 * iff the FDT node contains property 'blockdev-node-name=LABEL'.
 838 *
 839 * Return false unless the given node_path has the property.
 840 *
 841 * Presence of the property also disables the node from ever attached
 842 * to any drive created by the legacy '-drive' QEMU option.
 843 *
 844 * For more on '-blockdev', see:
 845 *   http://events17.linuxfoundation.org/sites/events/files/slides/talk_11.pdf
 846 */
 847static bool fdt_attach_blockdev(FDTMachineInfo *fdti,
 848                                char *node_path, Object *dev)
 849{
 850    static const char propname[] = "blockdev-node-name";
 851    BlockBackend *bdev = NULL;
 852    char *label;
 853
 854    /* Inspect FDT node for blockdev-only binding */
 855    label = qemu_fdt_getprop(fdti->fdt, node_path, propname,
 856                             NULL, false, NULL);
 857
 858    /* Skip legacy node */
 859    if (!label) {
 860        return false;
 861    }
 862
 863    /*
 864     * Missing matching bdev is not an error: attachment is optional.
 865     *
 866     * error_setg() aborts, never returns: 'goto ret' is just sanity.
 867     */
 868    if (!label[0]) {
 869        error_setg(&error_abort, "FDT-node '%s': property '%s' = <empty>",
 870                   node_path, propname);
 871        goto ret;
 872    }
 873
 874    bdev = blk_by_name(label);
 875    if (!bdev) {
 876        goto ret;
 877    }
 878
 879    if (blk_legacy_dinfo(bdev)) {
 880        error_setg(&error_abort,
 881                   "FDT-node '%s': property '%s' = \"%s\" matched to"
 882                   " a '-drive' option. Must use -blockdev instead.",
 883                   node_path, propname, label);
 884        goto ret;
 885    }
 886
 887    qdev_prop_set_drive(DEVICE(dev), "drive", bdev, &error_abort);
 888
 889 ret:
 890    g_free(label);
 891    return true;
 892}
 893
 894static void fdt_attach_drive(FDTMachineInfo *fdti, char *node_path,
 895                             Object *dev, BlockInterfaceType drive_type)
 896{
 897    DriveInfo *dinfo = NULL;
 898    uint32_t *di_val = NULL;
 899    int di_len = 0;
 900
 901    /* Do nothing if the device is not a block front-end */
 902    if (!object_property_find(OBJECT(dev), "drive", NULL)) {
 903        return;
 904    }
 905
 906    /* Try non-legacy */
 907    if (fdt_attach_blockdev(fdti, node_path, dev)) {
 908        return;
 909    }
 910
 911    /*
 912     * Try legacy with explicit 'drive-index' binding, or next-unit
 913     * as fallback binding.
 914     */
 915    di_val = qemu_fdt_getprop(fdti->fdt, node_path, "drive-index",
 916                              &di_len, false, NULL);
 917
 918    if (di_val && (di_len == sizeof(*di_val))) {
 919        dinfo = drive_get_by_index(drive_type, be32_to_cpu(*di_val));
 920    } else {
 921        dinfo = drive_get_next(drive_type);
 922    }
 923
 924    if (dinfo) {
 925        qdev_prop_set_drive(DEVICE(dev), "drive",
 926                            blk_by_legacy_dinfo(dinfo), &error_abort);
 927    }
 928
 929    return;
 930}
 931
 932static Object *fdt_create_from_compat(const char *compat, char **dev_type)
 933{
 934    Object *ret = NULL;
 935    char *c = g_strdup(compat);
 936
 937    /* Try to create the object */
 938    ret = object_new(c);
 939
 940    if (!ret) {
 941        /* Trim the version off the end and try again */
 942        trim_version(c);
 943        ret = object_new(c);
 944
 945        if (!ret) {
 946            /* Replace commas with full stops */
 947            substitute_char(c, ',', '.');
 948            ret = object_new(c);
 949        }
 950    }
 951
 952    if (!ret) {
 953        /* Restart with the orginal string and now replace commas with full stops
 954         * and try again. This means that versions are still included.
 955         */
 956        g_free(c);
 957        c = g_strdup(compat);
 958        substitute_char(c, ',', '.');
 959        ret = object_new(c);
 960    }
 961
 962    if (dev_type) {
 963        *dev_type = c;
 964    } else {
 965        g_free(c);
 966    }
 967
 968    if (!ret) {
 969        const char *no_vendor = trim_vendor(compat);
 970
 971        if (no_vendor != compat) {
 972            return fdt_create_from_compat(no_vendor, dev_type);
 973        }
 974    }
 975    return ret;
 976}
 977
 978/*FIXME: roll into device tree functionality */
 979
 980static inline uint64_t get_int_be(const void *p, int len)
 981{
 982    switch (len) {
 983    case 1:
 984        return *((uint8_t *)p);
 985    case 2:
 986        return be16_to_cpu(*((uint16_t *)p));
 987    case 4:
 988        return be32_to_cpu(*((uint32_t *)p));
 989    case 8:
 990        return be32_to_cpu(*((uint64_t *)p));
 991    default:
 992        fprintf(stderr, "unsupported integer length\n");
 993        abort();
 994    }
 995}
 996
 997/* FIXME: use structs instead of parallel arrays */
 998
 999static const char *fdt_generic_reg_size_prop_names[] = {
1000    "#address-cells",
1001    "#size-cells",
1002    "#bus-cells",
1003    "#priority-cells",
1004};
1005
1006static const int fdt_generic_reg_cells_defaults[] = {
1007    1,
1008    1,
1009    0,
1010    0,
1011};
1012
1013/*
1014 * Error handler for device creation failure.
1015 *
1016 * We look for qemu-fdt-abort-on-error properties up the tree.
1017 * If we find one, we abort with the provided error message.
1018 */
1019static void fdt_dev_error(FDTMachineInfo *fdti, char *node_path, char *compat)
1020{
1021    char *abort_on_error;
1022    char *warn_on_error;
1023
1024    warn_on_error = qemu_fdt_getprop(fdti->fdt, node_path,
1025                                   "qemu-fdt-warn-on-error", 0,
1026                                   true, NULL);
1027    abort_on_error = qemu_fdt_getprop(fdti->fdt, node_path,
1028                                   "qemu-fdt-abort-on-error", 0,
1029                                   true, NULL);
1030    if (warn_on_error) {
1031        if (strncmp("device_type", compat, strlen("device_type"))) {
1032            warn_report("%s: %s", compat, warn_on_error);
1033        }
1034    }
1035
1036    if (abort_on_error) {
1037        error_report("Failed to create %s", compat);
1038        error_setg(&error_fatal, "%s", abort_on_error);
1039    }
1040}
1041
1042static void fdt_init_qdev_array_prop(Object *obj, QEMUDevtreeProp *prop)
1043{
1044    const char *propname = prop->name;
1045    const uint32_t *v32 = prop->value;
1046    int nr = prop->len;
1047    Error *local_err = NULL;
1048    char *len_name;
1049
1050    if (!v32 || !nr || (nr % 4)) {
1051        return;
1052    }
1053    nr /= 4;
1054
1055    /*
1056     * Fail gracefully on setting the 'len-' property, due to:
1057     * 1. The property does not exist, or
1058     * 2. The property is not integer type, or
1059     * 3. The property has been set, e.g., by the '-global' cmd option
1060     */
1061    len_name = g_strconcat(PROP_ARRAY_LEN_PREFIX, propname, NULL);
1062    object_property_set_int(obj, nr, len_name, &local_err);
1063    g_free(len_name);
1064
1065    if (local_err) {
1066        error_free(local_err);
1067        return;
1068    }
1069
1070    while (nr--) {
1071        char *elem_name = g_strdup_printf("%s[%d]", propname, nr);
1072
1073        object_property_set_int(obj, get_int_be(&v32[nr], 4), elem_name,
1074                                &error_abort);
1075        g_free(elem_name);
1076    }
1077}
1078
1079static int fdt_init_qdev(char *node_path, FDTMachineInfo *fdti, char *compat)
1080{
1081    Object *dev, *parent;
1082    char *dev_type = NULL;
1083    int is_intc;
1084    Error *errp = NULL;
1085    int i, j;
1086    QEMUDevtreeProp *prop, *props;
1087    char parent_node_path[DT_PATH_LENGTH];
1088    const FDTGenericGPIOSet *gpio_set = NULL;
1089    FDTGenericGPIOClass *fggc = NULL;
1090
1091    if (!compat) {
1092        return 1;
1093    }
1094    dev = fdt_create_from_compat(compat, &dev_type);
1095    if (!dev) {
1096        DB_PRINT_NP(1, "no match found for %s\n", compat);
1097        fdt_dev_error(fdti, node_path, compat);
1098        return 1;
1099    }
1100    DB_PRINT_NP(1, "matched compat %s\n", compat);
1101
1102    /* Do this super early so fdt_generic_num_cpus is correct ASAP */
1103    if (object_dynamic_cast(dev, TYPE_CPU)) {
1104        fdt_generic_num_cpus++;
1105        DB_PRINT_NP(0, "is a CPU - total so far %d\n", fdt_generic_num_cpus);
1106    }
1107
1108    if (qemu_devtree_getparent(fdti->fdt, parent_node_path, node_path)) {
1109        abort();
1110    }
1111    while (!fdt_init_has_opaque(fdti, parent_node_path)) {
1112        fdt_init_yield(fdti);
1113    }
1114    if (object_dynamic_cast(dev, TYPE_CPU)) {
1115        parent = fdt_init_get_cpu_cluster(fdti, compat);
1116    } else {
1117        parent = fdt_init_get_opaque(fdti, parent_node_path);
1118    }
1119    if (dev->parent) {
1120        DB_PRINT_NP(0, "Node already parented - skipping node\n");
1121    } else if (parent) {
1122        DB_PRINT_NP(1, "parenting node\n");
1123        object_property_add_child(OBJECT(parent),
1124                              qemu_devtree_get_node_name(fdti->fdt, node_path),
1125                              OBJECT(dev));
1126        if (object_dynamic_cast(dev, TYPE_DEVICE)) {
1127            Object *parent_bus = parent;
1128            unsigned int depth = 0;
1129
1130            DB_PRINT_NP(1, "bus parenting node\n");
1131            /* Look for an FDT ancestor that is a Bus.  */
1132            while (parent_bus && !object_dynamic_cast(parent_bus, TYPE_BUS)) {
1133                /*
1134                 * Assert against insanely deep hierarchies which are an
1135                 * indication of loops.
1136                 */
1137                assert(depth < 4096);
1138
1139                parent_bus = parent_bus->parent;
1140                depth++;
1141            }
1142
1143            if (!parent_bus
1144                && object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE)) {
1145                /*
1146                 * Didn't find any bus. Use the default sysbus one.
1147                 * This allows ad-hoc busses belonging to sysbus devices to be
1148                 * visible to -device bus=x.
1149                 */
1150                parent_bus = OBJECT(sysbus_get_default());
1151            }
1152
1153            if (parent_bus) {
1154                qdev_set_parent_bus(DEVICE(dev), BUS(parent_bus));
1155            }
1156        }
1157    } else {
1158        DB_PRINT_NP(1, "orphaning node\n");
1159        /* FIXME: Make this go away (centrally) */
1160        object_property_add_child(
1161                              object_get_root(),
1162                              qemu_devtree_get_node_name(fdti->fdt, node_path),
1163                              OBJECT(dev));
1164    }
1165    fdt_init_set_opaque(fdti, node_path, dev);
1166
1167    /* Set the default sync-quantum based on the global one. Node properties
1168     * in the dtb can later override this value.  */
1169    if (global_sync_quantum) {
1170        ObjectProperty *p;
1171
1172        p = object_property_find(OBJECT(dev), "sync-quantum", NULL);
1173        if (p) {
1174            object_property_set_int(OBJECT(dev), global_sync_quantum,
1175                                    "sync-quantum", &errp);
1176        }
1177    }
1178
1179    /* Call FDT Generic hooks for overriding prop default values.  */
1180    if (object_dynamic_cast(dev, TYPE_FDT_GENERIC_PROPS)) {
1181        FDTGenericPropsClass *k = FDT_GENERIC_PROPS_GET_CLASS(dev);
1182
1183        assert(k->set_props);
1184        k->set_props(OBJECT(dev), &error_fatal);
1185    }
1186
1187    props = qemu_devtree_get_props(fdti->fdt, node_path);
1188    for (prop = props; prop->name; prop++) {
1189        const char *propname = trim_vendor(prop->name);
1190        int len = prop->len;
1191        void *val = prop->value;
1192        ObjectProperty *p = NULL;
1193#ifdef _WIN32
1194        QEMUDevtreeProp *wp;
1195        char *winPropname = g_strdup_printf("windows-%s", propname);
1196        wp = qemu_devtree_prop_search(props, winPropname);
1197        if (wp) {
1198            g_free(prop->value);
1199            prop->len = wp->len;
1200            prop->value = g_memdup(wp->value, wp->len);
1201            val = prop->value;
1202            len = prop->len;
1203            DB_PRINT_NP(1, "Found windows property match: %s\n",
1204                        winPropname);
1205        }
1206        g_free(winPropname);
1207#endif
1208        p = object_property_find(OBJECT(dev), propname, NULL);
1209        if (p) {
1210            DB_PRINT_NP(1, "matched property: %s of type %s, len %d\n",
1211                                            propname, p->type, prop->len);
1212        }
1213        if (!p) {
1214            fdt_init_qdev_array_prop(dev, prop);
1215            continue;
1216        }
1217
1218        if (!strcmp(propname, "type")) {
1219            continue;
1220        }
1221
1222        /* Special case for chardevs. It's an ordered list of strings.  */
1223        if (!strcmp(propname, "chardev") && !strcmp(p->type, "str")) {
1224            const char *chardev = val;
1225            const char *chardevs_end = chardev + len;
1226
1227            assert(errp == NULL);
1228            while (chardev < chardevs_end) {
1229                object_property_set_str(OBJECT(dev), (const char *)chardev,
1230                                        propname, &errp);
1231                if (!errp) {
1232                    DB_PRINT_NP(0, "set property %s to %s\n", propname,
1233                                chardev);
1234                    break;
1235                }
1236                chardev += strlen(chardev) + 1;
1237                errp = NULL;
1238            }
1239            assert(errp == NULL);
1240            continue;
1241        }
1242
1243        /* FIXME: handle generically using accessors and stuff */
1244        if (!strcmp(p->type, "uint8") || !strcmp(p->type, "uint16") ||
1245                !strcmp(p->type, "uint32") || !strcmp(p->type, "uint64")) {
1246            object_property_set_int(OBJECT(dev), get_int_be(val, len), propname,
1247                                    &error_abort);
1248            DB_PRINT_NP(0, "set property %s to %#llx\n", propname,
1249                        (unsigned long long)get_int_be(val, len));
1250        } else if (!strcmp(p->type, "boolean") || !strcmp(p->type, "bool")) {
1251            object_property_set_bool(OBJECT(dev), !!get_int_be(val, len),
1252                                     propname, &error_abort);
1253            DB_PRINT_NP(0, "set property %s to %s\n", propname,
1254                        get_int_be(val, len) ? "true" : "false");
1255        } else if (!strcmp(p->type, "string") || !strcmp(p->type, "str")) {
1256            object_property_set_str(OBJECT(dev), (const char *)val, propname,
1257                                    &error_abort);
1258            DB_PRINT_NP(0, "set property %s to %s\n", propname,
1259                        (const char *)val);
1260        } else if (!strncmp(p->type, "link", 4)) {
1261            char target_node_path[DT_PATH_LENGTH];
1262            char propname_target[1024];
1263            strcpy(propname_target, propname);
1264            strcat(propname_target, "-target");
1265
1266            Object *linked_dev, *proxy;
1267
1268            if (qemu_devtree_get_node_by_phandle(fdti->fdt, target_node_path,
1269                                                get_int_be(val, len))) {
1270                abort();
1271            }
1272            while (!fdt_init_has_opaque(fdti, target_node_path)) {
1273                fdt_init_yield(fdti);
1274            }
1275            linked_dev = fdt_init_get_opaque(fdti, target_node_path);
1276
1277            proxy = linked_dev ? object_property_get_link(linked_dev,
1278                                                          propname_target,
1279                                                          &errp) : NULL;
1280            if (!errp && proxy) {
1281                DB_PRINT_NP(0, "detected proxy object for %s connection\n",
1282                            propname);
1283                linked_dev = proxy;
1284            }
1285            errp = NULL;
1286            if (linked_dev) {
1287                object_property_set_link(OBJECT(dev), linked_dev, propname,
1288                                         &errp);
1289                if (errp) {
1290                    /* Unable to set the property, maybe it is a memory
1291                     * alias?
1292                     */
1293                    MemoryRegion *alias_mr;
1294                    int offset = len / 2;
1295                    alias_mr =
1296                        sysbus_mmio_get_region(SYS_BUS_DEVICE(linked_dev),
1297                                               get_int_be(val + offset,
1298                                                          len - offset));
1299
1300                    object_property_set_link(OBJECT(dev), OBJECT(alias_mr),
1301                                             propname, &error_abort);
1302
1303                    errp = NULL;
1304                }
1305                DB_PRINT_NP(0, "set link %s\n", propname);
1306            }
1307        } else {
1308            DB_PRINT_NP(0, "WARNING: property is of unknown type\n");
1309        }
1310    }
1311
1312    /* FIXME: not pretty, but is half a sane dts binding */
1313    if (object_dynamic_cast(dev, TYPE_REMOTE_PORT_DEVICE)) {
1314        int i;
1315
1316        for (i = 0;;++i) {
1317            char adaptor_node_path[DT_PATH_LENGTH];
1318            uint32_t adaptor_phandle, chan;
1319            DeviceState *adaptor;
1320            char *name;
1321
1322            adaptor_phandle = qemu_fdt_getprop_cell(fdti->fdt, node_path,
1323                                                    "remote-ports",
1324                                                    2 * i, false, &errp);
1325            if (errp) {
1326                DB_PRINT_NP(1, "cant get phandle from \"remote-ports\" "
1327                            "property\n");
1328                break;
1329            }
1330            if (qemu_devtree_get_node_by_phandle(fdti->fdt, adaptor_node_path,
1331                                                 adaptor_phandle)) {
1332                DB_PRINT_NP(1, "cant get node from phandle\n");
1333                break;
1334            }
1335            while (!fdt_init_has_opaque(fdti, adaptor_node_path)) {
1336                fdt_init_yield(fdti);
1337            }
1338            adaptor = DEVICE(fdt_init_get_opaque(fdti, adaptor_node_path));
1339            name = g_strdup_printf("rp-adaptor%" PRId32, i);
1340            object_property_set_link(OBJECT(dev), OBJECT(adaptor), name, &errp);
1341            DB_PRINT_NP(0, "connecting RP to adaptor %s channel %d",
1342                        object_get_canonical_path(OBJECT(adaptor)), i);
1343            g_free(name);
1344            if (errp) {
1345                DB_PRINT_NP(1, "cant set adaptor link for device property\n");
1346                break;
1347            }
1348
1349            chan = qemu_fdt_getprop_cell(fdti->fdt, node_path, "remote-ports",
1350                                         2 * i + 1, false, &errp);
1351            if (errp) {
1352                DB_PRINT_NP(1, "cant get channel from \"remote-ports\" "
1353                            "property\n");
1354                break;
1355            }
1356
1357            name = g_strdup_printf("rp-chan%" PRId32, i);
1358            object_property_set_int(OBJECT(dev), chan, name, &errp);
1359            /* Not critical - device has right to not care about channel
1360             * numbers if its a pure slave (only responses).
1361             */
1362            if (errp) {
1363                DB_PRINT_NP(1, "cant set %s property %s\n", name, error_get_pretty(errp));
1364                errp = NULL;
1365            }
1366            g_free(name);
1367
1368            name = g_strdup_printf("remote-port-dev%d", chan);
1369            object_property_set_link(OBJECT(adaptor), OBJECT(dev), name,
1370                                     &errp);
1371            g_free(name);
1372            if (errp) {
1373                DB_PRINT_NP(1, "cant set device link for adaptor\n");
1374                break;
1375            }
1376        }
1377        errp = NULL;
1378    }
1379
1380    if (object_dynamic_cast(dev, TYPE_DEVICE)) {
1381        DeviceClass *dc = DEVICE_GET_CLASS(dev);
1382        /* connect nic if appropriate */
1383        static int nics;
1384        const char *short_name = qemu_devtree_get_node_name(fdti->fdt, node_path);
1385
1386        if (object_property_find(OBJECT(dev), "mac", NULL) &&
1387                    object_property_find(OBJECT(dev), "netdev", NULL)) {
1388            qdev_set_nic_properties(DEVICE(dev), &nd_table[nics]);
1389        }
1390        if (nd_table[nics].instantiated) {
1391            DB_PRINT_NP(0, "NIC instantiated: %s\n", dev_type);
1392            nics++;
1393        }
1394
1395        /* We don't want to connect remote port chardev's to the user facing
1396         * serial devices.
1397         */
1398        if (!object_dynamic_cast(dev, TYPE_REMOTE_PORT)) {
1399            /* Connect chardev if we can */
1400            if (fdt_serial_ports < serial_max_hds() && serial_hd(fdt_serial_ports)) {
1401                Chardev *value = (Chardev*) serial_hd(fdt_serial_ports);
1402                char *chardev;
1403
1404                /* Check if the device already has a chardev.  */
1405                chardev = object_property_get_str(dev, "chardev", &errp);
1406                if (!errp && !strcmp(chardev, "")) {
1407                    object_property_set_str(dev, value->label,
1408                                            "chardev", &errp);
1409                    if (!errp) {
1410                        /* It worked, the device is a charecter device */
1411                        fdt_serial_ports++;
1412                    }
1413                }
1414                errp = NULL;
1415            }
1416        }
1417
1418        /* We also need to externally connect drives. Let's try to do that
1419         * here.
1420         */
1421        if (object_dynamic_cast(dev, TYPE_SSI_SLAVE)) {
1422            fdt_attach_drive(fdti, node_path, dev, IF_MTD);
1423        }
1424
1425        /* Regular TYPE_DEVICE houskeeping */
1426        DB_PRINT_NP(0, "Short naming node: %s\n", short_name);
1427        (DEVICE(dev))->id = g_strdup(short_name);
1428        qdev_init_nofail(DEVICE(dev));
1429        qemu_register_reset((void (*)(void *))dc->reset, dev);
1430    }
1431
1432    if (object_dynamic_cast(dev, TYPE_SYS_BUS_DEVICE) || 
1433        object_dynamic_cast(dev, TYPE_FDT_GENERIC_MMAP)) {
1434        FDTGenericRegPropInfo reg = {0};
1435        char parent_path[DT_PATH_LENGTH];
1436        int cell_idx = 0;
1437        bool extended = true;
1438
1439        qemu_fdt_getprop_cell(fdti->fdt, node_path, "reg-extended", 0, false,
1440                              &errp);
1441        if (errp) {
1442            error_free(errp);
1443            errp = NULL;
1444            extended = false;
1445            qemu_devtree_getparent(fdti->fdt, parent_path, node_path);
1446        }
1447
1448        for (reg.n = 0;; reg.n++) {
1449            char ph_parent[DT_PATH_LENGTH];
1450            const char *pnp = parent_path;
1451
1452            reg.parents = g_renew(Object *, reg.parents, reg.n + 1);
1453            reg.parents[reg.n] = parent;
1454
1455            if (extended) {
1456                int p_ph = qemu_fdt_getprop_cell(fdti->fdt, node_path,
1457                                                 "reg-extended", cell_idx++,
1458                                                 false, &errp);
1459                if (errp) {
1460                    error_free(errp);
1461                    errp = NULL;
1462                    goto exit_reg_parse;
1463                }
1464                if (qemu_devtree_get_node_by_phandle(fdti->fdt, ph_parent,
1465                                                     p_ph)) {
1466                    goto exit_reg_parse;
1467                }
1468                while (!fdt_init_has_opaque(fdti, ph_parent)) {
1469                    fdt_init_yield(fdti);
1470                }
1471                reg.parents[reg.n] = fdt_init_get_opaque(fdti, ph_parent);
1472                pnp = ph_parent;
1473            }
1474
1475            for (i = 0; i < FDT_GENERIC_REG_TUPLE_LENGTH; ++i) {
1476                const char *size_prop_name = fdt_generic_reg_size_prop_names[i];
1477                int nc = qemu_fdt_getprop_cell(fdti->fdt, pnp, size_prop_name,
1478                                               0, true, &errp);
1479
1480                if (errp) {
1481                    int size_default = fdt_generic_reg_cells_defaults[i];
1482
1483                    DB_PRINT_NP(0, "WARNING: no %s for %s container, assuming "
1484                                "default of %d\n", size_prop_name, pnp,
1485                                size_default);
1486                    nc = size_default;
1487                    error_free(errp);
1488                    errp = NULL;
1489                }
1490                
1491                reg.x[i] = g_renew(uint64_t, reg.x[i], reg.n + 1);
1492                reg.x[i][reg.n] = nc ?
1493                    qemu_fdt_getprop_sized_cell(fdti->fdt, node_path,
1494                                                extended ? "reg-extended"
1495                                                         : "reg",
1496                                                cell_idx, nc, &errp)
1497                    : 0;
1498                cell_idx += nc;
1499                if (errp) {
1500                    goto exit_reg_parse;
1501                }
1502            }
1503        }
1504exit_reg_parse:
1505
1506        if (object_dynamic_cast(dev, TYPE_FDT_GENERIC_MMAP)) {
1507            FDTGenericMMapClass *fmc = FDT_GENERIC_MMAP_GET_CLASS(dev);
1508            if (fmc->parse_reg) {
1509                while (fmc->parse_reg(FDT_GENERIC_MMAP(dev), reg,
1510                                      &error_abort)) {
1511                    fdt_init_yield(fdti);
1512                }
1513            }
1514        }
1515    }
1516    
1517    if (object_dynamic_cast(dev, TYPE_SYS_BUS_DEVICE)) {
1518        {
1519            int len;
1520            fdt_get_property(fdti->fdt, fdt_path_offset(fdti->fdt, node_path),
1521                                    "interrupt-controller", &len);
1522            is_intc = len >= 0;
1523            DB_PRINT_NP(is_intc ? 0 : 1, "is interrupt controller: %c\n",
1524                        is_intc ? 'y' : 'n');
1525        }
1526        /* connect irq */
1527        j = 0;
1528        for (i = 0;; i++) {
1529            char irq_info[6 * 1024];
1530            char *irq_info_p = irq_info;
1531            bool map_mode;
1532            int len = -1;
1533            qemu_irq *irqs = fdt_get_irq_info(fdti, node_path, i, irq_info,
1534                                              &map_mode);
1535            /* INTCs inferr their top level, if no IRQ connection specified */
1536            fdt_get_property(fdti->fdt, fdt_path_offset(fdti->fdt, node_path),
1537                             "interrupts-extended", &len);
1538            if (!irqs && is_intc && i == 0 && len <= 0) {
1539                FDTGenericIntc *id = (FDTGenericIntc *)object_dynamic_cast(
1540                                        dev, TYPE_FDT_GENERIC_INTC);
1541                FDTGenericIntcClass *idc = FDT_GENERIC_INTC_GET_CLASS(id);
1542                if (id && idc->auto_parent) {
1543                    /*
1544                     * Hack alert! auto-parenting the interrupt
1545                     * controller before the first CPU has been
1546                     * realized leads to a segmentation fault in
1547                     * xilinx_intc_fdt_auto_parent.
1548                     */
1549                    while (!DEVICE(first_cpu)) {
1550                        fdt_init_yield(fdti);
1551                    }
1552                    Error *err = NULL;
1553                    idc->auto_parent(id, &err);
1554                } else {
1555                    irqs = fdti->irq_base;
1556                }
1557            }
1558            if (!irqs) {
1559                break;
1560            }
1561            while (*irqs) {
1562                FDTIRQConnection *irq = g_new0(FDTIRQConnection, 1);
1563                *irq = (FDTIRQConnection) {
1564                    .dev = DEVICE(dev),
1565                    .name = SYSBUS_DEVICE_GPIO_IRQ,
1566                    .merge_fn = qemu_irq_shared_or_handler,
1567                    .i = j,
1568                    .irq = *irqs,
1569                    .sink_info = g_strdup(irq_info_p),
1570                    .next = fdti->irqs
1571                };
1572                if (!map_mode) {
1573                    j++;
1574                } else {
1575                    irq_info_p += strlen(irq_info_p) + 1;
1576                }
1577                fdti->irqs = irq;
1578                irqs++;
1579            }
1580            if (map_mode) {
1581                j++;
1582            }
1583        }
1584    }
1585
1586    if (object_dynamic_cast(dev, TYPE_FDT_GENERIC_GPIO)) {
1587        fggc = FDT_GENERIC_GPIO_GET_CLASS(dev);
1588        gpio_set = fggc->client_gpios;
1589    }
1590
1591    if (!gpio_set) {
1592        gpio_set = default_gpio_sets;
1593    }
1594
1595    for (; object_dynamic_cast(dev, TYPE_DEVICE) && gpio_set->names;
1596           gpio_set++) {
1597        bool end = false;
1598        int cur_cell = 0;
1599
1600        for (i = 0; !end; i++) {
1601            char *debug_success;
1602            const FDTGenericGPIOConnection *c = gpio_set->gpios;
1603            const char *gpio_name = NULL;
1604            uint16_t named_idx = 0;
1605            qemu_irq input, output;
1606            memset(&input, 0, sizeof(input));
1607
1608            if (c) {
1609                uint16_t range = c->range ? c->range : 1;
1610                while ((c->fdt_index > i || c->fdt_index + range <= i)
1611                       && c->name) {
1612                    c++;
1613                }
1614                named_idx = i - c->fdt_index;
1615                gpio_name = c->name;
1616            }
1617            if (!gpio_name) {
1618                const char *names_propname = gpio_set->names->names_propname;
1619                gpio_name = qemu_fdt_getprop_string(fdti->fdt, node_path,
1620                                                    names_propname, i, false,
1621                                                    NULL);
1622            }
1623            if (!gpio_name) {
1624                input = qdev_get_gpio_in(DEVICE(dev), i);
1625            } else {
1626                input = qdev_get_gpio_in_named(DEVICE(dev), gpio_name,
1627                                               named_idx);
1628            }
1629            debug_success = g_strdup_printf("Wiring GPIO input %s[%" PRId16 "] "
1630                                            "to", gpio_name, named_idx);
1631            output = fdt_get_gpio(fdti, node_path, &cur_cell, input, gpio_set,
1632                                  debug_success, &end);
1633            g_free(debug_success);
1634            if (output) {
1635                FDTIRQConnection *irq = g_new0(FDTIRQConnection, 1);
1636                *irq = (FDTIRQConnection) {
1637                    .dev = DEVICE(dev),
1638                    .name = gpio_name,
1639                    .merge_fn = qemu_irq_shared_or_handler,
1640                    .i = named_idx,
1641                    .irq = output,
1642                    .sink_info = NULL, /*FIXME */
1643                    .next = fdti->irqs
1644                };
1645                fdti->irqs = irq;
1646                DB_PRINT_NP(1, "... GPIO output %s[%" PRId16 "]\n", gpio_name,
1647                            named_idx);
1648            }
1649        }
1650    }
1651
1652    if (dev_type) {
1653        g_free(dev_type);
1654    }
1655
1656    return 0;
1657}
1658
1659static const TypeInfo fdt_generic_intc_info = {
1660    .name          = TYPE_FDT_GENERIC_INTC,
1661    .parent        = TYPE_INTERFACE,
1662    .class_size = sizeof(FDTGenericIntcClass),
1663};
1664
1665static const TypeInfo fdt_generic_mmap_info = {
1666    .name          = TYPE_FDT_GENERIC_MMAP,
1667    .parent        = TYPE_INTERFACE,
1668    .class_size = sizeof(FDTGenericMMapClass),
1669};
1670
1671static const TypeInfo fdt_generic_gpio_info = {
1672    .name          = TYPE_FDT_GENERIC_GPIO,
1673    .parent        = TYPE_INTERFACE,
1674    .class_size = sizeof(FDTGenericGPIOClass),
1675};
1676
1677static const TypeInfo fdt_generic_props_info = {
1678    .name          = TYPE_FDT_GENERIC_PROPS,
1679    .parent        = TYPE_INTERFACE,
1680    .class_size = sizeof(FDTGenericPropsClass),
1681};
1682
1683static void fdt_generic_intc_register_types(void)
1684{
1685    type_register_static(&fdt_generic_intc_info);
1686    type_register_static(&fdt_generic_mmap_info);
1687    type_register_static(&fdt_generic_gpio_info);
1688    type_register_static(&fdt_generic_props_info);
1689}
1690
1691type_init(fdt_generic_intc_register_types)
1692