コード例 #1
0
ファイル: xenfb.c プロジェクト: CTU-IIG/qemu
static int common_bind(struct common *c)
{
    uint64_t val;
    xen_pfn_t mfn;

    if (xenstore_read_fe_uint64(&c->xendev, "page-ref", &val) == -1)
        return -1;
    mfn = (xen_pfn_t)val;
    assert(val == mfn);

    if (xenstore_read_fe_int(&c->xendev, "event-channel", &c->xendev.remote_port) == -1)
        return -1;

    c->page = xenforeignmemory_map(xen_fmem, c->xendev.dom,
                                   PROT_READ | PROT_WRITE, 1, &mfn, NULL);
    if (c->page == NULL)
        return -1;

    xen_be_bind_evtchn(&c->xendev);
    xen_pv_printf(&c->xendev, 1,
                  "ring mfn %"PRI_xen_pfn", remote-port %d, local-port %d\n",
                  mfn, c->xendev.remote_port, c->xendev.local_port);

    return 0;
}
コード例 #2
0
ファイル: xen_console.c プロジェクト: 8tab/qemu
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;
}
コード例 #3
0
ファイル: xenfb.c プロジェクト: Epeius/qemu
static int xenfb_map_fb(struct XenFB *xenfb)
{
    struct xenfb_page *page = xenfb->c.page;
    char *protocol = xenfb->c.xendev.protocol;
    int n_fbdirs;
    xen_pfn_t *pgmfns = NULL;
    xen_pfn_t *fbmfns = NULL;
    void *map, *pd;
    int mode, ret = -1;

    /* default to native */
    pd = page->pd;
    mode = sizeof(unsigned long) * 8;

    if (!protocol) {
	/*
	 * Undefined protocol, some guesswork needed.
	 *
	 * Old frontends which don't set the protocol use
	 * one page directory only, thus pd[1] must be zero.
	 * pd[1] of the 32bit struct layout and the lower
	 * 32 bits of pd[0] of the 64bit struct layout have
	 * the same location, so we can check that ...
	 */
	uint32_t *ptr32 = NULL;
	uint32_t *ptr64 = NULL;
#if defined(__i386__)
	ptr32 = (void*)page->pd;
	ptr64 = ((void*)page->pd) + 4;
#elif defined(__x86_64__)
	ptr32 = ((void*)page->pd) - 4;
	ptr64 = (void*)page->pd;
#endif
	if (ptr32) {
	    if (ptr32[1] == 0) {
		mode = 32;
		pd   = ptr32;
	    } else {
		mode = 64;
		pd   = ptr64;
	    }
	}
#if defined(__x86_64__)
    } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_32) == 0) {
	/* 64bit dom0, 32bit domU */
	mode = 32;
	pd   = ((void*)page->pd) - 4;
#elif defined(__i386__)
    } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_64) == 0) {
	/* 32bit dom0, 64bit domU */
	mode = 64;
	pd   = ((void*)page->pd) + 4;
#endif
    }

    if (xenfb->pixels) {
        munmap(xenfb->pixels, xenfb->fbpages * XC_PAGE_SIZE);
        xenfb->pixels = NULL;
    }

    xenfb->fbpages = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
    n_fbdirs = xenfb->fbpages * mode / 8;
    n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;

    pgmfns = g_malloc0(sizeof(xen_pfn_t) * n_fbdirs);
    fbmfns = g_malloc0(sizeof(xen_pfn_t) * xenfb->fbpages);

    xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
    map = xenforeignmemory_map(xen_fmem, xenfb->c.xendev.dom,
                               PROT_READ, n_fbdirs, pgmfns, NULL);
    if (map == NULL)
	goto out;
    xenfb_copy_mfns(mode, xenfb->fbpages, fbmfns, map);
    xenforeignmemory_unmap(xen_fmem, map, n_fbdirs);

    xenfb->pixels = xenforeignmemory_map(xen_fmem, xenfb->c.xendev.dom,
            PROT_READ, xenfb->fbpages, fbmfns, NULL);
    if (xenfb->pixels == NULL)
	goto out;

    ret = 0; /* all is fine */

out:
    g_free(pgmfns);
    g_free(fbmfns);
    return ret;
}