/*
 * halt on the hypervisor after a delay to drain console output
 */
void
dboot_halt(void)
{
	uint_t i = 10000;

	while (--i)
		(void) HYPERVISOR_yield();
	(void) HYPERVISOR_shutdown(SHUTDOWN_poweroff);
}
int
xb_read(void *data, unsigned len)
{
	volatile struct xenstore_domain_interface *intf =
	    xs_domain_interface(xb_addr);
	XENSTORE_RING_IDX cons, prod;
	extern int do_polled_io;

	while (len != 0) {
		unsigned int avail;
		const char *src;

		mutex_enter(&xb_wait_lock);
		while (intf->rsp_cons == intf->rsp_prod) {
			if (interrupts_unleashed && !do_polled_io) {
				if (cv_wait_sig(&xb_wait_cv,
				    &xb_wait_lock) == 0) {
					mutex_exit(&xb_wait_lock);
					return (EINTR);
				}
			} else { /* polled mode needed for early probes */
				(void) HYPERVISOR_yield();
			}
		}
		mutex_exit(&xb_wait_lock);
		/* Read indexes, then verify. */
		cons = intf->rsp_cons;
		prod = intf->rsp_prod;
		membar_enter();
		if (!check_indexes(cons, prod))
			return (EIO);

		src = get_input_chunk(cons, prod, (char *)intf->rsp, &avail);
		if (avail == 0)
			continue;
		if (avail > len)
			avail = len;

		/* We must read header before we read data. */
		membar_consumer();

		(void) memcpy(data, src, avail);
		data = (void *)((uintptr_t)data + avail);
		len -= avail;

		/* Other side must not see free space until we've copied out */
		membar_enter();
		intf->rsp_cons += avail;

		/* Implies mb(): they will see new header. */
		ec_notify_via_evtchn(xen_info->store_evtchn);
	}

	return (0);
}
int
xb_write(const void *data, unsigned len)
{
	volatile struct xenstore_domain_interface *intf =
	    xs_domain_interface(xb_addr);
	XENSTORE_RING_IDX cons, prod;
	extern int do_polled_io;

	while (len != 0) {
		void *dst;
		unsigned int avail;

		mutex_enter(&xb_wait_lock);
		while ((intf->req_prod - intf->req_cons) ==
		    XENSTORE_RING_SIZE) {
			if (interrupts_unleashed && !do_polled_io) {
				if (cv_wait_sig(&xb_wait_cv,
				    &xb_wait_lock) == 0) {
					mutex_exit(&xb_wait_lock);
					return (EINTR);
				}
			} else { /* polled mode needed for early probes */
				(void) HYPERVISOR_yield();
			}
		}
		mutex_exit(&xb_wait_lock);
		/* Read indexes, then verify. */
		cons = intf->req_cons;
		prod = intf->req_prod;
		membar_enter();
		if (!check_indexes(cons, prod))
			return (EIO);

		dst = get_output_chunk(cons, prod, (char *)intf->req, &avail);
		if (avail == 0)
			continue;
		if (avail > len)
			avail = len;

		(void) memcpy(dst, data, avail);
		data = (void *)((uintptr_t)data + avail);
		len -= avail;

		/* Other side must not see new header until data is there. */
		membar_producer();
		intf->req_prod += avail;

		/* This implies mb() before other side sees interrupt. */
		ec_notify_via_evtchn(xen_info->store_evtchn);
	}

	return (0);
}
Beispiel #4
0
int
xenconscn_getc(dev_t dev)
{
    char c;
    int s = spltty();
    XENCONS_RING_IDX cons, prod;

    if (xencons_console_device && xencons_console_device->polling == 0) {
        printf("xenconscn_getc() but not polling\n");
        splx(s);
        return 0;
    }
    if (xendomain_is_dom0()) {
        while (HYPERVISOR_console_io(CONSOLEIO_read, 1, &c) == 0)
            ;
        cn_check_magic(dev, c, xencons_cnm_state);
        splx(s);
        return c;
    }
    if (xencons_console_device == NULL) {
        printf("xenconscn_getc(): not console\n");
        while (1)
            ;  /* loop here instead of in ddb */
        splx(s);
        return 0;
    }

    if (xencons_console_device->polling == 0) {
        printf("xenconscn_getc() but not polling\n");
        splx(s);
        return 0;
    }

    cons = xencons_interface->in_cons;
    prod = xencons_interface->in_prod;
    xen_rmb();
    while (cons == prod) {
        HYPERVISOR_yield();
        prod = xencons_interface->in_prod;
    }
    xen_rmb();
    c = xencons_interface->in[MASK_XENCONS_IDX(xencons_interface->in_cons,
                              xencons_interface->in)];
    xen_rmb();
    xencons_interface->in_cons = cons + 1;
    cn_check_magic(dev, c, xencons_cnm_state);
    splx(s);
    return c;
}