Ejemplo n.º 1
0
static void virtconsole_realize(DeviceState *dev, Error **errp)
{
    VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
    VirtConsole *vcon = VIRTIO_CONSOLE(dev);
    VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(dev);

    if (port->id == 0 && !k->is_console) {
        error_setg(errp, "Port number 0 on virtio-serial devices reserved "
                   "for virtconsole devices for backward compatibility.");
        return;
    }

    if (qemu_chr_fe_backend_connected(&vcon->chr)) {
        /*
         * For consoles we don't block guest data transfer just
         * because nothing is connected - we'll just let it go
         * whetherever the chardev wants - /dev/null probably.
         *
         * For serial ports we need 100% reliable data transfer
         * so we use the opened/closed signals from chardev to
         * trigger open/close of the device
         */
        if (k->is_console) {
            qemu_chr_fe_set_handlers(&vcon->chr, chr_can_read, chr_read,
                                     NULL, chr_be_change,
                                     vcon, NULL, true);
            virtio_serial_open(port);
        } else {
            qemu_chr_fe_set_handlers(&vcon->chr, chr_can_read, chr_read,
                                     chr_event, chr_be_change,
                                     vcon, NULL, false);
        }
    }
}
Ejemplo n.º 2
0
static void colo_compare_iothread(CompareState *s)
{
    object_ref(OBJECT(s->iothread));
    s->worker_context = iothread_get_g_main_context(s->iothread);

    qemu_chr_fe_set_handlers(&s->chr_pri_in, compare_chr_can_read,
                             compare_pri_chr_in, NULL, NULL,
                             s, s->worker_context, true);
    qemu_chr_fe_set_handlers(&s->chr_sec_in, compare_chr_can_read,
                             compare_sec_chr_in, NULL, NULL,
                             s, s->worker_context, true);

    colo_compare_timer_init(s);
}
Ejemplo n.º 3
0
static void milkymist_uart_realize(DeviceState *dev, Error **errp)
{
    MilkymistUartState *s = MILKYMIST_UART(dev);

    qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx,
                             uart_event, s, NULL, true);
}
Ejemplo n.º 4
0
static void usb_serial_realize(USBDevice *dev, Error **errp)
{
    USBSerialState *s = USB_SERIAL_DEV(dev);
    Error *local_err = NULL;
    CharDriverState *chr = qemu_chr_fe_get_driver(&s->cs);

    usb_desc_create_serial(dev);
    usb_desc_init(dev);
    dev->auto_attach = 0;

    if (!chr) {
        error_setg(errp, "Property chardev is required");
        return;
    }

    usb_check_attach(dev, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }

    qemu_chr_fe_set_handlers(&s->cs, usb_serial_can_read, usb_serial_read,
                             usb_serial_event, s, NULL, true);
    usb_serial_handle_reset(dev);

    if (chr->be_open && !dev->attached) {
        usb_device_attach(dev, &error_abort);
    }
}
Ejemplo n.º 5
0
static void lm32_uart_realize(DeviceState *dev, Error **errp)
{
    LM32UartState *s = LM32_UART(dev);

    qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx,
                             uart_event, s, NULL, true);
}
Ejemplo n.º 6
0
static void mcf_uart_realize(DeviceState *dev, Error **errp)
{
    mcf_uart_state *s = MCF_UART(dev);

    qemu_chr_fe_set_handlers(&s->chr, mcf_uart_can_receive, mcf_uart_receive,
                             mcf_uart_event, s, NULL, true);
}
Ejemplo n.º 7
0
/* Create a S3C serial port, the port implementation is common to all
 * current s3c devices only differing in the I/O base address and number of
 * ports.
 */
struct s3c24xx_serial_dev_s *
s3c24xx_serial_init(S3CState *soc,
                    Chardev *chr,
                    hwaddr base_addr,
                    int irqn)
{
    /* Initialise a serial port at the given port address */
    s3c24xx_serial_dev *s = g_new0(s3c24xx_serial_dev, 1);

    /* initialise serial port context */
    s->rx_irq = s3c24xx_get_irq(soc->irq, irqn);
    s->rx_level = s3c24xx_get_irq(soc->irq, irqn + 64);

    s->tx_irq = s3c24xx_get_irq(soc->irq, irqn + 1);
    s->tx_level = s3c24xx_get_irq(soc->irq, irqn + 1 + 64);

    /* Register the MMIO region. */
    memory_region_init_io(&s->mmio, OBJECT(s), &s3c24xx_serial_ops, s,
                          "s3c24xx.serial", 44);
    memory_region_add_subregion(get_system_memory(), base_addr, &s->mmio);

    qemu_chr_fe_set_handlers(&s->chr,
                             s3c24xx_serial_can_receive,
                             s3c24xx_serial_receive,
                             s3c24xx_serial_event,
                             NULL, s, NULL, true);

    return s;
}
Ejemplo n.º 8
0
static void chr_closed_bh(void *opaque)
{
    const char *name = opaque;
    NetClientState *ncs[MAX_QUEUE_NUM];
    VhostUserState *s;
    Error *err = NULL;
    int queues;

    queues = qemu_find_net_clients_except(name, ncs,
                                          NET_CLIENT_DRIVER_NIC,
                                          MAX_QUEUE_NUM);
    assert(queues < MAX_QUEUE_NUM);

    s = DO_UPCAST(VhostUserState, nc, ncs[0]);

    qmp_set_link(name, false, &err);
    vhost_user_stop(queues, ncs);

    qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, net_vhost_user_event,
                             NULL, opaque, NULL, true);

    if (err) {
        error_report_err(err);
    }
}
Ejemplo n.º 9
0
static int uart_be_change(void *opaque)
{
    SiFiveUARTState *s = opaque;

    qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, uart_event,
        uart_be_change, s, NULL, true);

    return 0;
}
Ejemplo n.º 10
0
static void virtconsole_enable_backend(VirtIOSerialPort *port, bool enable)
{
    VirtConsole *vcon = VIRTIO_CONSOLE(port);

    if (!qemu_chr_fe_backend_connected(&vcon->chr)) {
        return;
    }

    if (enable) {
        VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port);

        qemu_chr_fe_set_handlers(&vcon->chr, chr_can_read, chr_read,
                                 k->is_console ? NULL : chr_event,
                                 chr_be_change, vcon, NULL, false);
    } else {
        qemu_chr_fe_set_handlers(&vcon->chr, NULL, NULL, NULL,
                                 NULL, NULL, NULL, false);
    }
}
Ejemplo n.º 11
0
static void ipmi_bmc_extern_realize(DeviceState *dev, Error **errp)
{
    IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(dev);

    if (!qemu_chr_fe_backend_connected(&ibe->chr)) {
        error_setg(errp, "IPMI external bmc requires chardev attribute");
        return;
    }

    qemu_chr_fe_set_handlers(&ibe->chr, can_receive, receive,
                             chr_event, NULL, ibe, NULL, true);
}
Ejemplo n.º 12
0
/*
 * Called from the main thread on the primary for packets
 * arriving over the socket from the secondary.
 */
static void compare_sec_chr_in(void *opaque, const uint8_t *buf, int size)
{
    CompareState *s = COLO_COMPARE(opaque);
    int ret;

    ret = net_fill_rstate(&s->sec_rs, buf, size);
    if (ret == -1) {
        qemu_chr_fe_set_handlers(&s->chr_sec_in, NULL, NULL, NULL, NULL,
                                 NULL, NULL, true);
        error_report("colo-compare secondary_in error");
    }
}
Ejemplo n.º 13
0
static void xlx_iom_realize(DeviceState *dev, Error **errp)
{
    XilinxUART *s = XILINX_IO_MODULE_UART(dev);
    unsigned int i, rmap;
    uint32_t *regmaps[3] = { &s->regs[0], &s->baud };

    s->prefix = object_get_canonical_path(OBJECT(dev));

    for (rmap = 0; rmap < ARRAY_SIZE(uart_reginfos); rmap++) {
        for (i = 0; i < uart_reginfo_sizes[rmap]; ++i) {
            DepRegisterInfo *r = &s->regs_infos[rmap][i];

            *r = (DepRegisterInfo) {
                .data = (uint8_t *)&regmaps[rmap][i],
                .data_size = sizeof(uint32_t),
                .access = &uart_reginfos[rmap][i],
                .debug = XILINX_IO_MODULE_UART_ERR_DEBUG,
                .prefix = s->prefix,
                .opaque = s,
            };
            memory_region_init_io(&r->mem, OBJECT(dev), &iom_uart_ops, r,
                                  r->access->name, 4);
            memory_region_add_subregion(&s->iomem[rmap], i * 4, &r->mem);
        }
    }

    if (s->cfg.use_rx || s->cfg.use_tx) {
        qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, uart_event,
                                 NULL, s, NULL, true);
    }
}

static void xlx_iom_init(Object *obj)
{
    XilinxUART *s = XILINX_IO_MODULE_UART(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    unsigned int i;

    s->regs_infos[0] = s->regs_info0;
    s->regs_infos[1] = s->regs_info1;

    for (i = 0; i < ARRAY_SIZE(s->iomem); i++) {
        char *region_name = g_strdup_printf("%s-%d", TYPE_XILINX_IO_MODULE_UART,
                                            i);
        memory_region_init_io(&s->iomem[i], obj, &iom_uart_ops, s,
                              region_name, uart_reginfo_sizes[i] * 4);
        g_free(region_name);
        sysbus_init_mmio(sbd, &s->iomem[i]);
    }
    sysbus_init_irq(sbd, &s->irq_err);
    sysbus_init_irq(sbd, &s->irq_tx);
    sysbus_init_irq(sbd, &s->irq_rx);
}
Ejemplo n.º 14
0
static void test_server_create_chr(TestServer *server, const gchar *opt)
{
    gchar *chr_path;
    Chardev *chr;

    chr_path = g_strdup_printf("unix:%s%s", server->socket_path, opt);
    chr = qemu_chr_new(server->chr_name, chr_path);
    g_free(chr_path);

    qemu_chr_fe_init(&server->chr, chr, &error_abort);
    qemu_chr_fe_set_handlers(&server->chr, chr_can_read, chr_read,
                             chr_event, NULL, server, NULL, true);
}
Ejemplo n.º 15
0
/*
 * Create UART device.
 */
SiFiveUARTState *sifive_uart_create(MemoryRegion *address_space, hwaddr base,
    Chardev *chr, qemu_irq irq)
{
    SiFiveUARTState *s = g_malloc0(sizeof(SiFiveUARTState));
    s->irq = irq;
    qemu_chr_fe_init(&s->chr, chr, &error_abort);
    qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, uart_event,
        uart_be_change, s, NULL, true);
    memory_region_init_io(&s->mmio, NULL, &uart_ops, s,
                          TYPE_SIFIVE_UART, SIFIVE_UART_MAX);
    memory_region_add_subregion(address_space, base, &s->mmio);
    return s;
}
Ejemplo n.º 16
0
void mux_chr_set_handlers(Chardev *chr, GMainContext *context)
{
    MuxChardev *d = MUX_CHARDEV(chr);

    /* Fix up the real driver with mux routines */
    qemu_chr_fe_set_handlers(&d->chr,
                             mux_chr_can_read,
                             mux_chr_read,
                             mux_chr_event,
                             NULL,
                             chr,
                             context, true);
}
Ejemplo n.º 17
0
static int altera_juart_init(SysBusDevice *dev)
{
    AlteraJUARTState *s = ALTERA_JUART(dev);

    sysbus_init_irq(dev, &s->irq);

    memory_region_init_io(&s->mmio,  OBJECT(s), &juart_ops, s,
                          TYPE_ALTERA_JUART, 2 * 4);
    sysbus_init_mmio(dev, &s->mmio);
    qemu_chr_fe_set_handlers(&s->chr, juart_can_receive, juart_receive,
                             juart_event, NULL, s, NULL, true);
    return 0;
}
Ejemplo n.º 18
0
static void net_vhost_user_event(void *opaque, int event)
{
    const char *name = opaque;
    NetClientState *ncs[MAX_QUEUE_NUM];
    VhostUserState *s;
    Chardev *chr;
    Error *err = NULL;
    int queues;

    queues = qemu_find_net_clients_except(name, ncs,
                                          NET_CLIENT_DRIVER_NIC,
                                          MAX_QUEUE_NUM);
    assert(queues < MAX_QUEUE_NUM);

    s = DO_UPCAST(VhostUserState, nc, ncs[0]);
    chr = qemu_chr_fe_get_driver(&s->chr);
    trace_vhost_user_event(chr->label, event);
    switch (event) {
    case CHR_EVENT_OPENED:
        if (vhost_user_start(queues, ncs, &s->chr) < 0) {
            qemu_chr_fe_disconnect(&s->chr);
            return;
        }
        s->watch = qemu_chr_fe_add_watch(&s->chr, G_IO_HUP,
                                         net_vhost_user_watch, s);
        qmp_set_link(name, true, &err);
        s->started = true;
        break;
    case CHR_EVENT_CLOSED:
        /* a close event may happen during a read/write, but vhost
         * code assumes the vhost_dev remains setup, so delay the
         * stop & clear to idle.
         * FIXME: better handle failure in vhost code, remove bh
         */
        if (s->watch) {
            AioContext *ctx = qemu_get_current_aio_context();

            g_source_remove(s->watch);
            s->watch = 0;
            qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, NULL, NULL,
                                     NULL, NULL, false);

            aio_bh_schedule_oneshot(ctx, chr_closed_bh, opaque);
        }
        break;
    }

    if (err) {
        error_report_err(err);
    }
}
Ejemplo n.º 19
0
static int chr_be_change(void *opaque)
{
    VirtConsole *vcon = opaque;
    VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(vcon);
    VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port);

    if (k->is_console) {
        qemu_chr_fe_set_handlers(&vcon->chr, chr_can_read, chr_read,
                                 NULL, chr_be_change, vcon, NULL, true);
    } else {
        qemu_chr_fe_set_handlers(&vcon->chr, chr_can_read, chr_read,
                                 chr_event, chr_be_change, vcon, NULL, false);
    }

    if (vcon->watch) {
        g_source_remove(vcon->watch);
        vcon->watch = qemu_chr_fe_add_watch(&vcon->chr,
                                            G_IO_OUT | G_IO_HUP,
                                            chr_write_unblocked, vcon);
    }

    return 0;
}
Ejemplo n.º 20
0
static void redirector_chr_event(void *opaque, int event)
{
    NetFilterState *nf = opaque;
    MirrorState *s = FILTER_REDIRECTOR(nf);

    switch (event) {
    case CHR_EVENT_CLOSED:
        qemu_chr_fe_set_handlers(&s->chr_in, NULL, NULL, NULL,
                                 NULL, NULL, true);
        break;
    default:
        break;
    }
}
Ejemplo n.º 21
0
static void filter_redirector_setup(NetFilterState *nf, Error **errp)
{
    MirrorState *s = FILTER_REDIRECTOR(nf);
    Chardev *chr;

    if (!s->indev && !s->outdev) {
        error_setg(errp, "filter redirector needs 'indev' or "
                   "'outdev' at least one property set");
        return;
    } else if (s->indev && s->outdev) {
        if (!strcmp(s->indev, s->outdev)) {
            error_setg(errp, "'indev' and 'outdev' could not be same "
                       "for filter redirector");
            return;
        }
    }

    net_socket_rs_init(&s->rs, redirector_rs_finalize);

    if (s->indev) {
        chr = qemu_chr_find(s->indev);
        if (chr == NULL) {
            error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
                      "IN Device '%s' not found", s->indev);
            return;
        }

        if (!qemu_chr_fe_init(&s->chr_in, chr, errp)) {
            return;
        }

        qemu_chr_fe_set_handlers(&s->chr_in, redirector_chr_can_read,
                                 redirector_chr_read, redirector_chr_event,
                                 nf, NULL, true);
    }

    if (s->outdev) {
        chr = qemu_chr_find(s->outdev);
        if (chr == NULL) {
            error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
                      "OUT Device '%s' not found", s->outdev);
            return;
        }
        if (!qemu_chr_fe_init(&s->chr_out, chr, errp)) {
            return;
        }
    }
}
Ejemplo n.º 22
0
static int console_init(SCLPEvent *event)
{
    static bool console_available;

    SCLPConsoleLM *scon = SCLPLM_CONSOLE(event);

    if (console_available) {
        error_report("Multiple line-mode operator consoles are not supported");
        return -1;
    }
    console_available = true;

    qemu_chr_fe_set_handlers(&scon->chr, chr_can_read,
                             chr_read, NULL, NULL, scon, NULL, true);

    return 0;
}
Ejemplo n.º 23
0
static int net_vhost_user_init(NetClientState *peer, const char *device,
                               const char *name, Chardev *chr,
                               int queues)
{
    Error *err = NULL;
    NetClientState *nc, *nc0 = NULL;
    VhostUserState *s;
    int i;

    assert(name);
    assert(queues > 0);

    for (i = 0; i < queues; i++) {
        nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name);
        snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user%d to %s",
                 i, chr->label);
        nc->queue_index = i;
        if (!nc0) {
            nc0 = nc;
            s = DO_UPCAST(VhostUserState, nc, nc);
            if (!qemu_chr_fe_init(&s->chr, chr, &err)) {
                error_report_err(err);
                return -1;
            }
        }

    }

    s = DO_UPCAST(VhostUserState, nc, nc0);
    do {
        if (qemu_chr_fe_wait_connected(&s->chr, &err) < 0) {
            error_report_err(err);
            return -1;
        }
        qemu_chr_fe_set_handlers(&s->chr, NULL, NULL,
                                 net_vhost_user_event, NULL, nc0->name, NULL,
                                 true);
    } while (!s->started);

    assert(s->vhost_net);

    return 0;
}
Ejemplo n.º 24
0
static int grlib_apbuart_init(SysBusDevice *dev)
{
    UART *uart = GRLIB_APB_UART(dev);

    qemu_chr_fe_set_handlers(&uart->chr,
                             grlib_apbuart_can_receive,
                             grlib_apbuart_receive,
                             grlib_apbuart_event,
                             uart, NULL, true);

    sysbus_init_irq(dev, &uart->irq);

    memory_region_init_io(&uart->iomem, OBJECT(uart), &grlib_apbuart_ops, uart,
                          "uart", UART_REG_SIZE);

    sysbus_init_mmio(dev, &uart->iomem);

    return 0;
}
Ejemplo n.º 25
0
static int mad_init(RdmaBackendDev *backend_dev, CharBackend *mad_chr_be)
{
    int ret;

    backend_dev->rdmacm_mux.chr_be = mad_chr_be;

    ret = qemu_chr_fe_backend_connected(backend_dev->rdmacm_mux.chr_be);
    if (!ret) {
        rdma_error_report("Missing chardev for MAD multiplexer");
        return -EIO;
    }

    rdma_protected_qlist_init(&backend_dev->recv_mads_list);

    enable_rdmacm_mux_async(backend_dev);

    qemu_chr_fe_set_handlers(backend_dev->rdmacm_mux.chr_be,
                             rdmacm_mux_can_receive, rdmacm_mux_read, NULL,
                             NULL, backend_dev, NULL, true);

    return 0;
}
Ejemplo n.º 26
0
static void redirector_to_filter(NetFilterState *nf,
                                 const uint8_t *buf,
                                 int len)
{
    struct iovec iov = {
        .iov_base = (void *)buf,
        .iov_len = len,
    };

    if (nf->direction == NET_FILTER_DIRECTION_ALL ||
        nf->direction == NET_FILTER_DIRECTION_TX) {
        qemu_netfilter_pass_to_next(nf->netdev, 0, &iov, 1, nf);
    }

    if (nf->direction == NET_FILTER_DIRECTION_ALL ||
        nf->direction == NET_FILTER_DIRECTION_RX) {
        qemu_netfilter_pass_to_next(nf->netdev->peer, 0, &iov, 1, nf);
     }
}

static int redirector_chr_can_read(void *opaque)
{
    return REDIRECTOR_MAX_LEN;
}

static void redirector_chr_read(void *opaque, const uint8_t *buf, int size)
{
    NetFilterState *nf = opaque;
    MirrorState *s = FILTER_REDIRECTOR(nf);
    int ret;

    ret = net_fill_rstate(&s->rs, buf, size);

    if (ret == -1) {
        qemu_chr_fe_set_handlers(&s->chr_in, NULL, NULL, NULL,
                                 NULL, NULL, true);
    }
}
Ejemplo n.º 27
0
static int con_initialise(struct XenDevice *xendev)
{
    struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
    int limit;

    if (xenstore_read_int(con->console, "ring-ref", &con->ring_ref) == -1)
	return -1;
    if (xenstore_read_int(con->console, "port", &con->xendev.remote_port) == -1)
	return -1;
    if (xenstore_read_int(con->console, "limit", &limit) == 0)
	con->buffer.max_capacity = limit;

    if (!xendev->dev) {
        xen_pfn_t mfn = con->ring_ref;
        con->sring = xenforeignmemory_map(xen_fmem, con->xendev.dom,
                                          PROT_READ|PROT_WRITE,
                                          1, &mfn, NULL);
    } else {
        con->sring = xengnttab_map_grant_ref(xendev->gnttabdev, con->xendev.dom,
                                             con->ring_ref,
                                             PROT_READ|PROT_WRITE);
    }
    if (!con->sring)
	return -1;

    xen_be_bind_evtchn(&con->xendev);
    qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive,
                             xencons_receive, NULL, NULL, con, NULL, true);

    xen_pv_printf(xendev, 1,
                  "ring mfn %d, remote port %d, local port %d, limit %zd\n",
		  con->ring_ref,
		  con->xendev.remote_port,
		  con->xendev.local_port,
		  con->buffer.max_capacity);
    return 0;
}
Ejemplo n.º 28
0
static void char_mux_test(void)
{
    QemuOpts *opts;
    Chardev *chr, *base;
    char *data;
    FeHandler h1 = { 0, }, h2 = { 0, };
    CharBackend chr_be1, chr_be2;

    opts = qemu_opts_create(qemu_find_opts("chardev"), "mux-label",
                            1, &error_abort);
    qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
    qemu_opt_set(opts, "size", "128", &error_abort);
    qemu_opt_set(opts, "mux", "on", &error_abort);
    chr = qemu_chr_new_from_opts(opts, &error_abort);
    g_assert_nonnull(chr);
    qemu_opts_del(opts);

    qemu_chr_fe_init(&chr_be1, chr, &error_abort);
    qemu_chr_fe_set_handlers(&chr_be1,
                             fe_can_read,
                             fe_read,
                             fe_event,
                             NULL,
                             &h1,
                             NULL, true);

    qemu_chr_fe_init(&chr_be2, chr, &error_abort);
    qemu_chr_fe_set_handlers(&chr_be2,
                             fe_can_read,
                             fe_read,
                             fe_event,
                             NULL,
                             &h2,
                             NULL, true);
    qemu_chr_fe_take_focus(&chr_be2);

    base = qemu_chr_find("mux-label-base");
    g_assert_cmpint(qemu_chr_be_can_write(base), !=, 0);

    qemu_chr_be_write(base, (void *)"hello", 6);
    g_assert_cmpint(h1.read_count, ==, 0);
    g_assert_cmpint(h2.read_count, ==, 6);
    g_assert_cmpstr(h2.read_buf, ==, "hello");
    h2.read_count = 0;

    /* switch focus */
    qemu_chr_be_write(base, (void *)"\1c", 2);

    qemu_chr_be_write(base, (void *)"hello", 6);
    g_assert_cmpint(h2.read_count, ==, 0);
    g_assert_cmpint(h1.read_count, ==, 6);
    g_assert_cmpstr(h1.read_buf, ==, "hello");
    h1.read_count = 0;

    /* remove first handler */
    qemu_chr_fe_set_handlers(&chr_be1, NULL, NULL, NULL, NULL,
                             NULL, NULL, true);
    qemu_chr_be_write(base, (void *)"hello", 6);
    g_assert_cmpint(h1.read_count, ==, 0);
    g_assert_cmpint(h2.read_count, ==, 0);

    qemu_chr_be_write(base, (void *)"\1c", 2);
    qemu_chr_be_write(base, (void *)"hello", 6);
    g_assert_cmpint(h1.read_count, ==, 0);
    g_assert_cmpint(h2.read_count, ==, 6);
    g_assert_cmpstr(h2.read_buf, ==, "hello");
    h2.read_count = 0;

    /* print help */
    qemu_chr_be_write(base, (void *)"\1?", 2);
    data = qmp_ringbuf_read("mux-label-base", 128, false, 0, &error_abort);
    g_assert_cmpint(strlen(data), !=, 0);
    g_free(data);

    qemu_chr_fe_deinit(&chr_be1, false);
    qemu_chr_fe_deinit(&chr_be2, true);
}
Ejemplo n.º 29
0
static void ss_realize(DeviceState *dev, Error **errp)
{
    SlaveBootInt *s = SBI(dev);
    const char *prefix = object_get_canonical_path(OBJECT(dev));
    unsigned int i;
    const char *port_name;
    Chardev *chr;

    for (i = 0; i < ARRAY_SIZE(slave_boot_regs_info); ++i) {
        DepRegisterInfo *r = &s->regs_info[
                                slave_boot_regs_info[i].decode.addr / 4];

        *r = (DepRegisterInfo) {
            .data = (uint8_t *)&s->regs[
                    slave_boot_regs_info[i].decode.addr / 4],
            .data_size = sizeof(uint32_t),
            .access = &slave_boot_regs_info[i],
            .debug = SBI_ERR_DEBUG,
            .prefix = prefix,
            .opaque = s,
        };
   }

    port_name = g_strdup("smap_busy_b");
    qdev_init_gpio_out_named(dev, &s->smap_busy, port_name, 1);
    g_free((gpointer) port_name);

    port_name = g_strdup("smap_in_b");
    qdev_init_gpio_in_named(dev, smap_update, port_name, 2);
    g_free((gpointer) port_name);

    chr = qemu_chr_find("sbi");
    qdev_prop_set_chr(dev, "chardev", chr);
    if (!qemu_chr_fe_get_driver(&s->chr)) {
        DPRINT("SBI interface not connected\n");
    } else {
        qemu_chr_fe_set_handlers(&s->chr, ss_sbi_can_receive, ss_sbi_receive,
                                 NULL, NULL, s, NULL, true);
    }

    fifo_create8(&s->fifo, 1024 * 4);
}

static void ss_reset(DeviceState *dev)
{
    SlaveBootInt *s = SBI(dev);
    uint32_t i;

    for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
        dep_register_reset(&s->regs_info[i]);
    }
    fifo_reset(&s->fifo);
    s->busy_line = 1;
    qemu_set_irq(s->smap_busy, s->busy_line);
    ss_update_busy_line(s);
    sbi_update_irq(s);
    /* Note : cs always 0 when rp is not connected
     * i.e slave always respond to master data irrespective of
     * master state
     *
     * as rdwr is also 0, initial state of sbi is data load. Hack this bit
     * to become 1, when sbi changes to write mode. So, its assumed in
     * non remote-port model master should expect data when slave wishes
     * to send.
     */
}
Ejemplo n.º 30
0
Archivo: boston.c Proyecto: mdroth/qemu
static void boston_mach_init(MachineState *machine)
{
    DeviceState *dev;
    BostonState *s;
    Error *err = NULL;
    const char *cpu_model;
    MemoryRegion *flash, *ddr, *ddr_low_alias, *lcd, *platreg;
    MemoryRegion *sys_mem = get_system_memory();
    XilinxPCIEHost *pcie2;
    PCIDevice *ahci;
    DriveInfo *hd[6];
    Chardev *chr;
    int fw_size, fit_err;
    bool is_64b;

    if ((machine->ram_size % G_BYTE) ||
        (machine->ram_size > (2 * G_BYTE))) {
        error_report("Memory size must be 1GB or 2GB");
        exit(1);
    }

    cpu_model = machine->cpu_model ?: "I6400";

    dev = qdev_create(NULL, TYPE_MIPS_BOSTON);
    qdev_init_nofail(dev);

    s = BOSTON(dev);
    s->mach = machine;
    s->cps = g_new0(MIPSCPSState, 1);

    if (!cpu_supports_cps_smp(cpu_model)) {
        error_report("Boston requires CPUs which support CPS");
        exit(1);
    }

    is_64b = cpu_supports_isa(cpu_model, ISA_MIPS64);

    object_initialize(s->cps, sizeof(MIPSCPSState), TYPE_MIPS_CPS);
    qdev_set_parent_bus(DEVICE(s->cps), sysbus_get_default());

    object_property_set_str(OBJECT(s->cps), cpu_model, "cpu-model", &err);
    object_property_set_int(OBJECT(s->cps), smp_cpus, "num-vp", &err);
    object_property_set_bool(OBJECT(s->cps), true, "realized", &err);

    if (err != NULL) {
        error_report("%s", error_get_pretty(err));
        exit(1);
    }

    sysbus_mmio_map_overlap(SYS_BUS_DEVICE(s->cps), 0, 0, 1);

    flash =  g_new(MemoryRegion, 1);
    memory_region_init_rom_device(flash, NULL, &boston_flash_ops, s,
                                  "boston.flash", 128 * M_BYTE, &err);
    memory_region_add_subregion_overlap(sys_mem, 0x18000000, flash, 0);

    ddr = g_new(MemoryRegion, 1);
    memory_region_allocate_system_memory(ddr, NULL, "boston.ddr",
                                         machine->ram_size);
    memory_region_add_subregion_overlap(sys_mem, 0x80000000, ddr, 0);

    ddr_low_alias = g_new(MemoryRegion, 1);
    memory_region_init_alias(ddr_low_alias, NULL, "boston_low.ddr",
                             ddr, 0, MIN(machine->ram_size, (256 * M_BYTE)));
    memory_region_add_subregion_overlap(sys_mem, 0, ddr_low_alias, 0);

    xilinx_pcie_init(sys_mem, 0,
                     0x10000000, 32 * M_BYTE,
                     0x40000000, 1 * G_BYTE,
                     get_cps_irq(s->cps, 2), false);

    xilinx_pcie_init(sys_mem, 1,
                     0x12000000, 32 * M_BYTE,
                     0x20000000, 512 * M_BYTE,
                     get_cps_irq(s->cps, 1), false);

    pcie2 = xilinx_pcie_init(sys_mem, 2,
                             0x14000000, 32 * M_BYTE,
                             0x16000000, 1 * M_BYTE,
                             get_cps_irq(s->cps, 0), true);

    platreg = g_new(MemoryRegion, 1);
    memory_region_init_io(platreg, NULL, &boston_platreg_ops, s,
                          "boston-platregs", 0x1000);
    memory_region_add_subregion_overlap(sys_mem, 0x17ffd000, platreg, 0);

    if (!serial_hds[0]) {
        serial_hds[0] = qemu_chr_new("serial0", "null");
    }

    s->uart = serial_mm_init(sys_mem, 0x17ffe000, 2,
                             get_cps_irq(s->cps, 3), 10000000,
                             serial_hds[0], DEVICE_NATIVE_ENDIAN);

    lcd = g_new(MemoryRegion, 1);
    memory_region_init_io(lcd, NULL, &boston_lcd_ops, s, "boston-lcd", 0x8);
    memory_region_add_subregion_overlap(sys_mem, 0x17fff000, lcd, 0);

    chr = qemu_chr_new("lcd", "vc:320x240");
    qemu_chr_fe_init(&s->lcd_display, chr, NULL);
    qemu_chr_fe_set_handlers(&s->lcd_display, NULL, NULL,
                             boston_lcd_event, s, NULL, true);

    ahci = pci_create_simple_multifunction(&PCI_BRIDGE(&pcie2->root)->sec_bus,
                                           PCI_DEVFN(0, 0),
                                           true, TYPE_ICH9_AHCI);
    g_assert(ARRAY_SIZE(hd) == ICH_AHCI(ahci)->ahci.ports);
    ide_drive_get(hd, ICH_AHCI(ahci)->ahci.ports);
    ahci_ide_create_devs(ahci, hd);

    if (machine->firmware) {
        fw_size = load_image_targphys(machine->firmware,
                                      0x1fc00000, 4 * M_BYTE);
        if (fw_size == -1) {
            error_printf("unable to load firmware image '%s'\n",
                          machine->firmware);
            exit(1);
        }
    } else if (machine->kernel_filename) {
        fit_err = load_fit(&boston_fit_loader, machine->kernel_filename, s);
        if (fit_err) {
            error_printf("unable to load FIT image\n");
            exit(1);
        }

        gen_firmware(memory_region_get_ram_ptr(flash) + 0x7c00000,
                     s->kernel_entry, s->fdt_base, is_64b);
    } else if (!qtest_enabled()) {
        error_printf("Please provide either a -kernel or -bios argument\n");
        exit(1);
    }
}