qemu/hw/core/remote-port.c
<<
>>
Prefs
   1/*
   2 * QEMU remote attach
   3 *
   4 * Copyright (c) 2013 Xilinx Inc
   5 * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
   6 *
   7 * This code is licensed under the GNU GPL.
   8 */
   9
  10#include "qemu/osdep.h"
  11#include "sysemu/sysemu.h"
  12#include "sysemu/dma.h"
  13#include "sysemu/char.h"
  14#include "sysemu/cpus.h"
  15#include "hw/sysbus.h"
  16#include "hw/ptimer.h"
  17#include "qemu/sockets.h"
  18#include "qemu/thread.h"
  19#include "qemu/log.h"
  20#include "qapi/error.h"
  21#include "qemu/error-report.h"
  22#include "qom/cpu.h"
  23
  24#include <semaphore.h>
  25#ifndef _WIN32
  26#include <sys/mman.h>
  27#endif
  28
  29#include "hw/fdt_generic_util.h"
  30#include "hw/remote-port-proto.h"
  31#include "hw/remote-port-device.h"
  32#include "hw/remote-port.h"
  33
  34#define D(x)
  35#define SYNCD(x)
  36
  37#ifndef REMOTE_PORT_ERR_DEBUG
  38#define REMOTE_PORT_DEBUG_LEVEL 0
  39#else
  40#define REMOTE_PORT_DEBUG_LEVEL 1
  41#endif
  42
  43#define DB_PRINT_L(level, ...) do { \
  44    if (REMOTE_PORT_DEBUG_LEVEL > level) { \
  45        fprintf(stderr,  ": %s: ", __func__); \
  46        fprintf(stderr, ## __VA_ARGS__); \
  47    } \
  48} while (0);
  49
  50#define TYPE_REMOTE_PORT "remote-port"
  51#define REMOTE_PORT(obj) OBJECT_CHECK(RemotePort, (obj), TYPE_REMOTE_PORT)
  52#define REMOTE_PORT_CLASS(klass)    \
  53     OBJECT_CLASS_CHECK(RemotePortClass, (klass), TYPE_REMOTE_PORT)
  54
  55typedef struct RemotePortMap {
  56    RemotePort *parent;
  57    MemoryRegion iomem;
  58    int id;
  59} RemotePortMap;
  60
  61struct RemotePort {
  62    DeviceState parent;
  63
  64    QemuThread thread;
  65    union {
  66       int pipes[2];
  67       struct {
  68           int read;
  69           int write;
  70       } pipe;
  71    } event;
  72    CharDriverState *chr;
  73    bool do_sync;
  74    /* To serialize writes to fd.  */
  75    QemuMutex write_mutex;
  76
  77    char *chardesc;
  78    struct rp_peer_state peer;
  79
  80    struct {
  81        QEMUBH *bh;
  82        QEMUBH *bh_resp;
  83        ptimer_state *ptimer;
  84        ptimer_state *ptimer_resp;
  85        bool resp_timer_enabled;
  86        bool need_sync;
  87        struct rp_pkt rsp;
  88        uint64_t quantum;
  89    } sync;
  90
  91    QemuMutex rsp_mutex;
  92    QemuCond progress_cond;
  93
  94    struct {
  95        /* This array must be sized minimum 2 and always a power of 2.  */
  96        RemotePortDynPkt pkt[16];
  97        QemuSemaphore sem;
  98        unsigned int wpos;
  99        unsigned int rpos;
 100    } rx_queue;
 101
 102    /*
 103     * rsp holds responses for the remote side.
 104     * Used by the slave.
 105     */
 106    RemotePortDynPkt rsp;
 107
 108    /*
 109     * rspqueue holds received responses from the remote side.
 110     * Only one for the moment but it might grow.
 111     * Used by the master.
 112     */
 113    RemotePortDynPkt rspqueue;
 114
 115    bool resets[32];
 116
 117    const char *prefix;
 118    const char *remote_prefix;
 119
 120    uint32_t current_id;
 121
 122#define REMOTE_PORT_MAX_DEVS 16
 123    RemotePortDevice *devs[REMOTE_PORT_MAX_DEVS];
 124};
 125
 126static bool time_warp_enable = true;
 127
 128bool rp_time_warp_enable(bool en)
 129{
 130    bool ret = time_warp_enable;
 131
 132    time_warp_enable = en;
 133    return ret;
 134}
 135
 136static void rp_process(RemotePort *s);
 137static void rp_event_read(void *opaque);
 138static void sync_timer_hit(void *opaque);
 139static void syncresp_timer_hit(void *opaque);
 140
 141static void rp_pkt_dump(const char *prefix, const char *buf, size_t len)
 142{
 143    qemu_hexdump(buf, stdout, prefix, len);
 144}
 145
 146uint32_t rp_new_id(RemotePort *s)
 147{
 148    return s->current_id++;
 149}
 150
 151void rp_rsp_mutex_lock(RemotePort *s)
 152{
 153    qemu_mutex_lock(&s->rsp_mutex);
 154}
 155
 156void rp_rsp_mutex_unlock(RemotePort *s)
 157{
 158    qemu_mutex_unlock(&s->rsp_mutex);
 159}
 160
 161int64_t rp_normalized_vmclk(RemotePort *s)
 162{
 163    int64_t clk;
 164
 165    clk = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 166    clk -= s->peer.clk_base;
 167    return clk;
 168}
 169
 170static inline int64_t rp_denormalize_clk(RemotePort *s, int64_t rclk)
 171{
 172    int64_t clk;
 173    clk = rclk + s->peer.clk_base;
 174    return clk;
 175}
 176
 177void rp_restart_sync_timer(RemotePort *s)
 178{
 179    if (!use_icount || !s->do_sync) {
 180        return;
 181    }
 182
 183    if (s->sync.quantum) {
 184        ptimer_stop(s->sync.ptimer);
 185        ptimer_set_limit(s->sync.ptimer, s->sync.quantum, 1);
 186        ptimer_run(s->sync.ptimer, 1);
 187    } else {
 188        ptimer_stop(s->sync.ptimer);
 189        ptimer_set_limit(s->sync.ptimer, 10 * 1000, 1);
 190        ptimer_run(s->sync.ptimer, 1);
 191    }
 192}
 193
 194static void rp_fatal_error(RemotePort *s, const char *reason)
 195{
 196    int64_t clk = rp_normalized_vmclk(s);
 197    error_report("%s: %s clk=%" PRIu64 " ns\n", s->prefix, reason, clk);
 198    exit(EXIT_FAILURE);
 199}
 200
 201static ssize_t rp_recv(RemotePort *s, void *buf, size_t count)
 202{
 203    ssize_t r;
 204
 205    r = qemu_chr_fe_read_all(s->chr, buf, count);
 206    if (r <= 0) {
 207        rp_fatal_error(s, "Disconnected");
 208    }
 209    if (r != count) {
 210        error_report("%s: Bad read, expected %zd but got %zd\n",
 211                     s->prefix, count, r);
 212        rp_fatal_error(s, "Bad read");
 213    }
 214
 215    return r;
 216}
 217
 218ssize_t rp_write(RemotePort *s, const void *buf, size_t count)
 219{
 220    ssize_t r;
 221
 222    qemu_mutex_lock(&s->write_mutex);
 223    r = qemu_chr_fe_write(s->chr, buf, count);
 224    qemu_mutex_unlock(&s->write_mutex);
 225    if (r <= 0) {
 226        error_report("%s: Disconnected r=%zd buf=%p count=%zd\n",
 227                     s->prefix, r, buf, count);
 228        rp_fatal_error(s, "Bad read");
 229    }
 230    return r;
 231}
 232
 233/* Warp time if cpus are idle. diff is max time in ns to warp.  */
 234static int64_t rp_time_warp(RemotePort *s, int64_t diff)
 235{
 236    int64_t future = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + diff;
 237    int64_t clk;
 238
 239    if (!time_warp_enable) {
 240        return 0;
 241    }
 242
 243    /* If cpus are idle. warp.  */
 244    do {
 245        bool cpus_idle;
 246
 247        cpus_idle = tcg_idle_clock_warp(future);
 248        clk = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 249        if (!cpus_idle) {
 250            break;
 251        }
 252    } while (clk < future);
 253
 254    return future - clk;
 255}
 256
 257static void rp_idle(void *opaque)
 258{
 259    int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
 260    if (deadline == INT32_MAX) {
 261            return;
 262    }
 263    rp_time_warp(opaque, deadline);
 264}
 265
 266void rp_leave_iothread(RemotePort *s)
 267{
 268    if (use_icount && all_cpu_threads_idle() && time_warp_enable) {
 269        async_run_on_cpu(first_cpu, rp_idle, s);
 270    }
 271}
 272
 273RemotePortDynPkt rp_wait_resp(RemotePort *s)
 274{
 275    while (!rp_dpkt_is_valid(&s->rspqueue)) {
 276        rp_event_read(s);
 277        qemu_cond_wait(&s->progress_cond, &s->rsp_mutex);
 278    }
 279    return s->rspqueue;
 280}
 281
 282void rp_sync_vmclock(RemotePort *s, int64_t lclk, int64_t rclk)
 283{
 284    int64_t diff;
 285
 286    /* FIXME: syncing is broken at the moment.  */
 287    return;
 288
 289    if (!time_warp_enable) {
 290        return;
 291    }
 292
 293    /* Warp all the way to dest. We need to account for
 294       spent time in the remote call.  */
 295    while (lclk < rclk) {
 296        diff = rclk - lclk;
 297        tcg_clock_warp(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + diff);
 298        lclk = rp_normalized_vmclk(s);
 299    }
 300
 301    if (lclk < rclk) {
 302        printf("Wrong sync! local=%" PRIu64 " remote=%" PRIu64 "\n", lclk, rclk);
 303    }
 304}
 305
 306static void rp_cmd_hello(RemotePort *s, struct rp_pkt *pkt)
 307{
 308    s->peer.version = pkt->hello.version;
 309    if (pkt->hello.version.major != RP_VERSION_MAJOR) {
 310        error_report("remote-port version missmatch remote=%d.%d local=%d.%d\n",
 311                      pkt->hello.version.major, pkt->hello.version.minor,
 312                      RP_VERSION_MAJOR, RP_VERSION_MINOR);
 313        rp_fatal_error(s, "Bad version");
 314    }
 315}
 316
 317static void rp_cmd_sync(RemotePort *s, struct rp_pkt *pkt)
 318{
 319    size_t enclen;
 320    int64_t clk;
 321    int64_t diff;
 322
 323    assert(!(pkt->hdr.flags & RP_PKT_FLAGS_response));
 324
 325    /* If cpus are idle. warp.  */
 326    clk = rp_normalized_vmclk(s);
 327    diff = pkt->sync.timestamp - clk;
 328    if (diff > 0LL && use_icount && time_warp_enable) {
 329        diff = rp_time_warp(s, diff);
 330    }
 331
 332    enclen = rp_encode_sync_resp(pkt->hdr.id, pkt->hdr.dev, &s->sync.rsp.sync,
 333                                 pkt->sync.timestamp);
 334    assert(enclen == sizeof s->sync.rsp.sync);
 335
 336    /* We are already a head of time.  */
 337    if (all_cpu_threads_idle() || 0) {
 338        if (pkt->sync.timestamp >  clk && use_icount)
 339            rp_sync_vmclock(s, clk, pkt->sync.timestamp);
 340    }
 341
 342    /* We have temporarily disabled blocking syncs into QEMU.  */
 343    if (diff <= 0LL || true) {
 344        /* We are already a head of time. Respond and issue a sync.  */
 345        SYNCD(printf("%s: sync resp %lu\n", s->prefix, pkt->sync.timestamp));
 346        rp_write(s, (void *) &s->sync.rsp, enclen);
 347        return;
 348    }
 349
 350    SYNCD(printf("%s: delayed sync resp - start diff=%ld (ts=%lu clk=%lu)\n",
 351          s->prefix, pkt->sync.timestamp - clk, pkt->sync.timestamp, clk));
 352    ptimer_set_limit(s->sync.ptimer_resp, diff, 1);
 353    ptimer_run(s->sync.ptimer_resp, 1);
 354    s->sync.resp_timer_enabled = true;
 355}
 356
 357static void rp_say_hello(RemotePort *s)
 358{
 359    struct rp_pkt_hello pkt;
 360    size_t len;
 361
 362    len = rp_encode_hello(s->current_id++, 0, &pkt, RP_VERSION_MAJOR,
 363                          RP_VERSION_MINOR);
 364    rp_write(s, (void *) &pkt, len);
 365}
 366
 367static void rp_say_sync(RemotePort *s, int64_t clk)
 368{
 369    struct rp_pkt_sync pkt;
 370    size_t len;
 371
 372    len = rp_encode_sync(s->current_id++, 0, &pkt, clk);
 373    rp_write(s, (void *) &pkt, len);
 374}
 375
 376static void syncresp_timer_hit(void *opaque)
 377{
 378    RemotePort *s = REMOTE_PORT(opaque);
 379
 380    s->sync.resp_timer_enabled = false;
 381    SYNCD(printf("%s: delayed sync response - send\n", s->prefix));
 382    rp_write(s, (void *) &s->sync.rsp, sizeof s->sync.rsp.sync);
 383    memset(&s->sync.rsp, 0, sizeof s->sync.rsp);
 384
 385    rp_leave_iothread(s);
 386}
 387
 388static void sync_timer_hit(void *opaque)
 389{
 390    RemotePort *s = REMOTE_PORT(opaque);
 391    int64_t clk;
 392    int64_t rclk;
 393    RemotePortDynPkt rsp;
 394
 395    if (!use_icount) {
 396        hw_error("Sync timer without icount??\n");
 397    }
 398
 399    clk = rp_normalized_vmclk(s);
 400    if (s->sync.resp_timer_enabled) {
 401        SYNCD(printf("%s: sync while delaying a resp! clk=%lu\n",
 402                     s->prefix, clk));
 403        s->sync.need_sync = true;
 404        rp_restart_sync_timer(s);
 405        rp_leave_iothread(s);
 406        return;
 407    }
 408
 409    /* Sync.  */
 410    s->sync.need_sync = false;
 411    qemu_mutex_lock(&s->rsp_mutex);
 412    /* Send the sync.  */
 413    rp_say_sync(s, clk);
 414
 415    SYNCD(printf("%s: syncing wait for resp %lu\n", s->prefix, clk));
 416    rsp = rp_wait_resp(s);
 417    rclk = rsp.pkt->sync.timestamp;
 418    rp_dpkt_invalidate(&rsp);
 419    qemu_mutex_unlock(&s->rsp_mutex);
 420
 421    rp_sync_vmclock(s, clk, rclk);
 422    rp_restart_sync_timer(s);
 423}
 424
 425static char *rp_sanitize_prefix(RemotePort *s)
 426{
 427    char *sanitized_name;
 428    char *c;
 429
 430    sanitized_name = g_strdup(s->prefix);
 431    for (c = sanitized_name; *c != '\0'; c++) {
 432        if (*c == '/')
 433            *c = '_';
 434    }
 435    return sanitized_name;
 436}
 437
 438static char *rp_autocreate_chardesc(RemotePort *s, bool server)
 439{
 440    char *prefix;
 441    char *chardesc;
 442    int r;
 443
 444    prefix = rp_sanitize_prefix(s);
 445    r = asprintf(&chardesc, "unix:%s/qemu-rport-%s,wait%s",
 446                 machine_path, prefix, server ? ",server" : "");
 447    assert(r > 0);
 448    free(prefix);
 449    return chardesc;
 450}
 451
 452static CharDriverState *rp_autocreate_chardev(RemotePort *s, char *name)
 453{
 454    CharDriverState *chr;
 455    char *chardesc;
 456
 457    chardesc = rp_autocreate_chardesc(s, false);
 458    chr = qemu_chr_new(name, chardesc, NULL);
 459    free(chardesc);
 460
 461    if (!chr) {
 462        chardesc = rp_autocreate_chardesc(s, true);
 463        chr = qemu_chr_new(name, chardesc, NULL);
 464        free(chardesc);
 465    }
 466    return chr;
 467}
 468
 469static unsigned int rp_has_work(RemotePort *s)
 470{
 471    unsigned int work = s->rx_queue.wpos - s->rx_queue.rpos;
 472    return work;
 473}
 474
 475static void rp_process(RemotePort *s)
 476{
 477    while (rp_has_work(s)) {
 478        struct rp_pkt *pkt;
 479        unsigned int rpos = s->rx_queue.rpos;
 480        bool actioned = false;
 481        RemotePortDevice *dev;
 482        RemotePortDeviceClass *rpdc;
 483
 484        rpos &= ARRAY_SIZE(s->rx_queue.pkt) - 1;
 485
 486        pkt = s->rx_queue.pkt[rpos].pkt;
 487        D(printf("%s: io-thread rpos=%d wpos=%d cmd=%d\n", s->prefix,
 488                 s->rx_queue.rpos, s->rx_queue.wpos, pkt->hdr.cmd));
 489
 490        dev = s->devs[pkt->hdr.dev];
 491        if (dev) {
 492            rpdc = REMOTE_PORT_DEVICE_GET_CLASS(dev);
 493            if (rpdc->ops[pkt->hdr.cmd]) {
 494                rpdc->ops[pkt->hdr.cmd](dev, pkt);
 495                actioned = true;
 496            }
 497        }
 498
 499        switch (pkt->hdr.cmd) {
 500        case RP_CMD_sync:
 501            rp_cmd_sync(s, pkt);
 502            break;
 503        default:
 504            assert(actioned);
 505        }
 506
 507        s->rx_queue.rpos++;
 508        qemu_sem_post(&s->rx_queue.sem);
 509    }
 510}
 511
 512static void rp_event_read(void *opaque)
 513{
 514    RemotePort *s = REMOTE_PORT(opaque);
 515    unsigned char buf[32];
 516    ssize_t r;
 517
 518    /* We don't care about the data. Just read it out to clear the event.  */
 519    do {
 520        r = read(s->event.pipe.read, buf, sizeof buf);
 521        if (r == 0) {
 522            hw_error("%s: pipe closed?\n", s->prefix);
 523        }
 524    } while (r == sizeof buf || (r < 0 && errno == EINTR));
 525
 526    rp_process(s);
 527    rp_leave_iothread(s);
 528}
 529
 530static void rp_event_notify(RemotePort *s)
 531{
 532    unsigned char d = 0;
 533    ssize_t r;
 534
 535#ifdef _WIN32
 536    /* Mingw is sensitive about doing write's to socket descriptors.  */
 537    r = qemu_send_wrap(s->event.pipe.write, &d, sizeof d, 0);
 538#else
 539    r = qemu_write_full(s->event.pipe.write, &d, sizeof d);
 540#endif
 541    if (r == 0) {
 542        hw_error("%s: pipe closed\n", s->prefix);
 543    }
 544}
 545
 546/* Handover a pkt to CPU or IO-thread context.  */
 547static void rp_pt_handover_pkt(RemotePort *s, RemotePortDynPkt *dpkt)
 548{
 549    /* Take the rsp lock around the wpos update, otherwise
 550       rp_wait_resp will race with us.  */
 551    qemu_mutex_lock(&s->rsp_mutex);
 552    s->rx_queue.wpos++;
 553    smp_mb();
 554    rp_event_notify(s);
 555    qemu_cond_signal(&s->progress_cond);
 556    qemu_mutex_unlock(&s->rsp_mutex);
 557    while (1) {
 558        if (qemu_sem_timedwait(&s->rx_queue.sem, 2 * 1000) == 0) {
 559            break;
 560        }
 561#ifndef _WIN32
 562        {
 563            int sval;
 564            sem_getvalue(&s->rx_queue.sem.sem, &sval);
 565            printf("semwait: %d rpos=%u wpos=%u\n", sval,
 566                   s->rx_queue.rpos, s->rx_queue.wpos);
 567        }
 568#endif
 569    }
 570}
 571
 572static bool rp_pt_cmd_sync(RemotePort *s, struct rp_pkt *pkt)
 573{
 574    size_t enclen;
 575    int64_t clk;
 576    int64_t diff = 0;
 577    struct rp_pkt rsp;
 578
 579    assert(!(pkt->hdr.flags & RP_PKT_FLAGS_response));
 580
 581    if (use_icount) {
 582        clk = rp_normalized_vmclk(s);
 583        diff = pkt->sync.timestamp - clk;
 584    }
 585    enclen = rp_encode_sync_resp(pkt->hdr.id, pkt->hdr.dev, &rsp.sync,
 586                                 pkt->sync.timestamp);
 587    assert(enclen == sizeof rsp.sync);
 588
 589    if (!use_icount || diff < s->sync.quantum) {
 590        /* We are still OK.  */
 591        rp_write(s, (void *) &rsp, enclen);
 592        return true;
 593    }
 594
 595    /* We need IO or CPU thread sync.  */
 596    return false;
 597}
 598
 599static void rp_pt_process_pkt(RemotePort *s, RemotePortDynPkt *dpkt)
 600{
 601    struct rp_pkt *pkt = dpkt->pkt;
 602
 603    D(printf("%s: cmd=%x rsp=%d\n", __func__, pkt->hdr.cmd,
 604             pkt->hdr.flags & RP_PKT_FLAGS_response));
 605
 606    if (pkt->hdr.dev >= ARRAY_SIZE(s->devs)) {
 607        /* FIXME: Respond with an error.  */
 608        return;
 609    }
 610
 611    if (pkt->hdr.flags & RP_PKT_FLAGS_response) {
 612        qemu_mutex_lock(&s->rsp_mutex);
 613        rp_dpkt_swap(&s->rspqueue, dpkt);
 614        qemu_cond_signal(&s->progress_cond);
 615        qemu_mutex_unlock(&s->rsp_mutex);
 616        return;
 617    }
 618
 619    switch (pkt->hdr.cmd) {
 620    case RP_CMD_hello:
 621        rp_cmd_hello(s, pkt);
 622        break;
 623    case RP_CMD_sync:
 624        if (rp_pt_cmd_sync(s, pkt)) {
 625            return;
 626        }
 627        /* Fall-through.  */
 628    case RP_CMD_read:
 629    case RP_CMD_write:
 630    case RP_CMD_interrupt:
 631        rp_pt_handover_pkt(s, dpkt);
 632        break;
 633    default:
 634        assert(0);
 635        break;
 636    }
 637}
 638
 639static void rp_read_pkt(RemotePort *s, RemotePortDynPkt *dpkt)
 640{
 641    struct rp_pkt *pkt = dpkt->pkt;
 642    int used;
 643
 644    rp_recv(s, pkt, sizeof pkt->hdr);
 645    used = rp_decode_hdr((void *) &pkt->hdr);
 646    assert(used == sizeof pkt->hdr);
 647
 648    if (pkt->hdr.len) {
 649        rp_dpkt_alloc(dpkt, sizeof pkt->hdr + pkt->hdr.len);
 650        /* pkt may move due to realloc.  */
 651        pkt = dpkt->pkt;
 652        rp_recv(s, &pkt->hdr + 1, pkt->hdr.len);
 653        rp_decode_payload(pkt);
 654    }
 655}
 656
 657static void *rp_protocol_thread(void *arg)
 658{
 659    RemotePort *s = REMOTE_PORT(arg);
 660    unsigned int i;
 661
 662    /* Make sure we have a decent bufsize to start with.  */
 663    rp_dpkt_alloc(&s->rsp, sizeof s->rsp.pkt->busaccess + 1024);
 664    rp_dpkt_alloc(&s->rspqueue, sizeof s->rspqueue.pkt->busaccess + 1024);
 665    for (i = 0; i < ARRAY_SIZE(s->rx_queue.pkt); i++) {
 666        rp_dpkt_alloc(&s->rx_queue.pkt[i],
 667                      sizeof s->rx_queue.pkt[i].pkt->busaccess + 1024);
 668    }
 669
 670    rp_say_hello(s);
 671
 672    while (1) {
 673        RemotePortDynPkt *dpkt;
 674        unsigned int wpos = s->rx_queue.wpos;
 675
 676        wpos &= ARRAY_SIZE(s->rx_queue.pkt) - 1;
 677        dpkt = &s->rx_queue.pkt[wpos];
 678
 679        rp_read_pkt(s, dpkt);
 680        if (0) {
 681            rp_pkt_dump("rport-pkt", (void *) dpkt->pkt,
 682                        sizeof dpkt->pkt->hdr + dpkt->pkt->hdr.len);
 683        }
 684        rp_pt_process_pkt(s, dpkt);
 685    }
 686    return NULL;
 687}
 688
 689static void rp_realize(DeviceState *dev, Error **errp)
 690{
 691    RemotePort *s = REMOTE_PORT(dev);
 692    int r;
 693
 694    s->prefix = object_get_canonical_path(OBJECT(dev));
 695
 696    s->peer.clk_base = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 697
 698    qemu_mutex_init(&s->write_mutex);
 699    qemu_mutex_init(&s->rsp_mutex);
 700    qemu_cond_init(&s->progress_cond);
 701
 702    if (!s->chr) {
 703        char *name;
 704        static int nr = 0;
 705        int r;
 706
 707        r = asprintf(&name, "rport%d", nr);
 708        nr++;
 709        assert(r > 0);
 710
 711        if (s->chardesc) {
 712            s->chr = qemu_chr_new(name, s->chardesc, NULL);
 713        } else {
 714            if (!machine_path) {
 715                error_report("%s: Missing chardesc prop."
 716                             " Forgot -machine-path?\n",
 717                             s->prefix);
 718                exit(EXIT_FAILURE);
 719            }
 720            s->chr = rp_autocreate_chardev(s, name);
 721        }
 722        free(name);
 723        if (!s->chr) {
 724            error_report("%s: Unable to create remort-port channel %s\n",
 725                         s->prefix, s->chardesc);
 726            exit(EXIT_FAILURE);
 727        }
 728    }
 729
 730
 731#ifdef _WIN32
 732    /* Create a socket connection between two sockets. We auto-bind
 733     * and read out the port selected by the kernel.
 734     */
 735    {
 736        char *name;
 737        int port;
 738
 739        s->event.pipe.read = inet_listen("127.0.0.1:0", NULL,
 740                                         256, SOCK_STREAM, 0, &error_abort);
 741        if (s->event.pipe.read < 0) {
 742            perror("socket read");
 743            exit(EXIT_FAILURE);
 744        }
 745
 746        {
 747            struct sockaddr_in saddr;
 748            socklen_t slen = sizeof saddr;
 749            int r;
 750
 751            r = getsockname(s->event.pipe.read, &saddr, &slen);
 752            if (r < 0) {
 753                perror("getsockname");
 754                exit(EXIT_FAILURE);
 755            }
 756            port = htons(saddr.sin_port);
 757        }
 758
 759        qemu_set_fd_handler(s->event.pipe.read, rp_event_read, NULL, s);
 760        name = g_strdup_printf("127.0.0.1:%d", port);
 761        s->event.pipe.write = inet_connect(name, &error_abort);
 762        g_free(name);
 763        if (s->event.pipe.write < 0) {
 764            perror("socket write");
 765            exit(EXIT_FAILURE);
 766        }
 767    }
 768#else
 769    r = qemu_pipe(s->event.pipes);
 770    if (r < 0) {
 771        error_report("%s: Unable to create remort-port internal pipes\n",
 772                    s->prefix);
 773        exit(EXIT_FAILURE);
 774    }
 775    qemu_set_nonblock(s->event.pipe.read);
 776    qemu_set_fd_handler(s->event.pipe.read, rp_event_read, NULL, s);
 777#endif
 778
 779
 780    /* Pick up the quantum from the local property setup.
 781       After config negotiation with the peer, sync.quantum value might
 782       change.  */
 783    s->sync.quantum = s->peer.local_cfg.quantum;
 784
 785    s->sync.bh = qemu_bh_new(sync_timer_hit, s);
 786    s->sync.bh_resp = qemu_bh_new(syncresp_timer_hit, s);
 787    s->sync.ptimer = ptimer_init(s->sync.bh);
 788    s->sync.ptimer_resp = ptimer_init(s->sync.bh_resp);
 789
 790    /* The Sync-quantum is expressed in nano-seconds.  */
 791    ptimer_set_freq(s->sync.ptimer, 1000 * 1000 * 1000);
 792    ptimer_set_freq(s->sync.ptimer_resp, 1000 * 1000 * 1000);
 793
 794    qemu_sem_init(&s->rx_queue.sem, ARRAY_SIZE(s->rx_queue.pkt) - 1);
 795    qemu_thread_create(&s->thread, "remote-port", rp_protocol_thread, s,
 796                       QEMU_THREAD_JOINABLE);
 797    rp_restart_sync_timer(s);
 798}
 799
 800static const VMStateDescription vmstate_rp = {
 801    .name = TYPE_REMOTE_PORT,
 802    .version_id = 1,
 803    .minimum_version_id = 1,
 804    .minimum_version_id_old = 1,
 805    .fields = (VMStateField[]) {
 806        VMSTATE_END_OF_LIST(),
 807    }
 808};
 809
 810static Property rp_properties[] = {
 811    DEFINE_PROP_CHR("chardev", RemotePort, chr),
 812    DEFINE_PROP_STRING("chardesc", RemotePort, chardesc),
 813    DEFINE_PROP_BOOL("sync", RemotePort, do_sync, false),
 814    DEFINE_PROP_UINT64("sync-quantum", RemotePort, peer.local_cfg.quantum, 0),
 815    DEFINE_PROP_END_OF_LIST(),
 816};
 817
 818static void rp_init(Object *obj)
 819{
 820    RemotePort *s = REMOTE_PORT(obj);
 821    int i;
 822
 823    /* Disable icount IDLE time warping. remoteport will take care of it.  */
 824    qemu_icount_enable_idle_timewarps(false);
 825
 826    for (i = 0; i < REMOTE_PORT_MAX_DEVS; ++i) {
 827        char *name = g_strdup_printf("remote-port-dev%d", i);
 828        object_property_add_link(obj, name, TYPE_REMOTE_PORT_DEVICE,
 829                             (Object **)&s->devs[i],
 830                             qdev_prop_allow_set_link,
 831                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
 832                             &error_abort);
 833        g_free(name);
 834    }
 835}
 836
 837static void rp_class_init(ObjectClass *klass, void *data)
 838{
 839    DeviceClass *dc = DEVICE_CLASS(klass);
 840
 841    dc->realize = rp_realize;
 842    dc->vmsd = &vmstate_rp;
 843    dc->props = rp_properties;
 844}
 845
 846static const TypeInfo rp_info = {
 847    .name          = TYPE_REMOTE_PORT,
 848    .parent        = TYPE_DEVICE,
 849    .instance_size = sizeof(RemotePort),
 850    .instance_init = rp_init,
 851    .class_init    = rp_class_init,
 852    .interfaces    = (InterfaceInfo[]) {
 853        { },
 854    },
 855};
 856
 857static const TypeInfo rp_device_info = {
 858    .name          = TYPE_REMOTE_PORT_DEVICE,
 859    .parent        = TYPE_INTERFACE,
 860    .class_size    = sizeof(RemotePortDeviceClass),
 861};
 862
 863static void rp_register_types(void)
 864{
 865    type_register_static(&rp_info);
 866    type_register_static(&rp_device_info);
 867}
 868
 869type_init(rp_register_types)
 870