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