aboutsummaryrefslogtreecommitdiffstats
path: root/netbsd-2.0-xen-sparse
diff options
context:
space:
mode:
authorcl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>2004-10-04 13:15:55 +0000
committercl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>2004-10-04 13:15:55 +0000
commite6521d710d81d983ed87a1f27be7f33a0ed8576d (patch)
tree67e6814f3551e2c4516ffbbc961fdd588e957f5b /netbsd-2.0-xen-sparse
parent5595355e81b907b1a496711dbfbc306d956642a5 (diff)
downloadxen-e6521d710d81d983ed87a1f27be7f33a0ed8576d.tar.gz
xen-e6521d710d81d983ed87a1f27be7f33a0ed8576d.tar.bz2
xen-e6521d710d81d983ed87a1f27be7f33a0ed8576d.zip
bitkeeper revision 1.1159.99.1 (41614d0bCFm_w7iZTkZCC7k5oNSaqw)
Cleanup device initialization. Add support for bidirectional virtual consoles.
Diffstat (limited to 'netbsd-2.0-xen-sparse')
-rw-r--r--netbsd-2.0-xen-sparse/sys/arch/xen/i386/hypervisor_machdep.c3
-rw-r--r--netbsd-2.0-xen-sparse/sys/arch/xen/include/if_xennetvar.h3
-rw-r--r--netbsd-2.0-xen-sparse/sys/arch/xen/include/xbdvar.h1
-rw-r--r--netbsd-2.0-xen-sparse/sys/arch/xen/xen/ctrl_if.c74
-rw-r--r--netbsd-2.0-xen-sparse/sys/arch/xen/xen/hypervisor.c15
-rw-r--r--netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c92
-rw-r--r--netbsd-2.0-xen-sparse/sys/arch/xen/xen/xbd.c28
-rw-r--r--netbsd-2.0-xen-sparse/sys/arch/xen/xen/xencons.c87
8 files changed, 223 insertions, 80 deletions
diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/i386/hypervisor_machdep.c b/netbsd-2.0-xen-sparse/sys/arch/xen/i386/hypervisor_machdep.c
index 82e998d3b6..241a8a9b83 100644
--- a/netbsd-2.0-xen-sparse/sys/arch/xen/i386/hypervisor_machdep.c
+++ b/netbsd-2.0-xen-sparse/sys/arch/xen/i386/hypervisor_machdep.c
@@ -127,8 +127,7 @@ stipending()
hypervisor_acknowledge_irq(irq);
ci->ci_ipending |= (1 << irq);
if (ret == 0 && ci->ci_ilevel <
- ci->ci_isources[irq]->is_handlers
- ->ih_level)
+ ci->ci_isources[irq]->is_maxlevel)
ret = 1;
}
#if 0 /* XXXcl dev/evtchn */
diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/include/if_xennetvar.h b/netbsd-2.0-xen-sparse/sys/arch/xen/include/if_xennetvar.h
index 32a774b1b6..5e84f5af86 100644
--- a/netbsd-2.0-xen-sparse/sys/arch/xen/include/if_xennetvar.h
+++ b/netbsd-2.0-xen-sparse/sys/arch/xen/include/if_xennetvar.h
@@ -81,6 +81,8 @@ struct xennet_softc {
netif_tx_interface_t *sc_tx;
netif_rx_interface_t *sc_rx;
+ struct vm_page *sc_pg_tx;
+ struct vm_page *sc_pg_rx;
uint32_t sc_tx_entries;
uint32_t sc_tx_resp_cons;
@@ -102,6 +104,7 @@ struct xennet_attach_args {
struct nfs_diskless;
int xennet_scan(struct device *, struct xennet_attach_args *, cfprint_t);
+void xennet_scan_finish(struct device *);
void xennet_start(struct ifnet *);
int xennet_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
void xennet_watchdog(struct ifnet *ifp);
diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/include/xbdvar.h b/netbsd-2.0-xen-sparse/sys/arch/xen/include/xbdvar.h
index 8c1c57c692..089d365a0d 100644
--- a/netbsd-2.0-xen-sparse/sys/arch/xen/include/xbdvar.h
+++ b/netbsd-2.0-xen-sparse/sys/arch/xen/include/xbdvar.h
@@ -52,5 +52,6 @@ struct xbd_attach_args {
};
int xbd_scan(struct device *, struct xbd_attach_args *, cfprint_t);
+void xbd_scan_finish(struct device *);
#endif /* _XEN_XBDVAR_H_ */
diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/ctrl_if.c b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/ctrl_if.c
index 39b4febdd3..d81068b0a1 100644
--- a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/ctrl_if.c
+++ b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/ctrl_if.c
@@ -20,8 +20,9 @@ __KERNEL_RCSID(0, "$NetBSD$");
#include <machine/ctrl_if.h>
#include <machine/evtchn.h>
+void printk(char *, ...);
#if 0
-#define DPRINTK(_f, _a...) printf("(file=%s, line=%d) " _f, \
+#define DPRINTK(_f, _a...) printk("(file=%s, line=%d) " _f, \
__FILE__ , __LINE__ , ## _a )
#else
#define DPRINTK(_f, _a...) ((void)0)
@@ -34,7 +35,7 @@ __KERNEL_RCSID(0, "$NetBSD$");
*/
int initdom_ctrlif_domcontroller_port = -1;
-static int ctrl_if_evtchn;
+/* static */ int ctrl_if_evtchn = -1;
static int ctrl_if_irq;
static struct simplelock ctrl_if_lock;
@@ -148,9 +149,10 @@ static void __ctrl_if_rxmsg_deferred(void *unused)
while ( ctrl_if_rxmsg_deferred_cons != dp )
{
- msg = &ctrl_if_rxmsg_deferred[MASK_CONTROL_IDX(
- ctrl_if_rxmsg_deferred_cons++)];
+ msg = &ctrl_if_rxmsg_deferred[
+ MASK_CONTROL_IDX(ctrl_if_rxmsg_deferred_cons)];
(*ctrl_if_rxmsg_handler[msg->type])(msg, 0);
+ ctrl_if_rxmsg_deferred_cons++;
}
}
@@ -166,7 +168,7 @@ static void __ctrl_if_rx_tasklet(unsigned long data)
while ( ctrl_if_rx_req_cons != rp )
{
- pmsg = &ctrl_if->rx_ring[MASK_CONTROL_IDX(ctrl_if_rx_req_cons++)];
+ pmsg = &ctrl_if->rx_ring[MASK_CONTROL_IDX(ctrl_if_rx_req_cons)];
memcpy(&msg, pmsg, offsetof(ctrl_msg_t, msg));
DPRINTK("Rx-Req %u/%u :: %d/%d\n",
@@ -184,6 +186,8 @@ static void __ctrl_if_rx_tasklet(unsigned long data)
&msg, offsetof(ctrl_msg_t, msg) + msg.length);
else
(*ctrl_if_rxmsg_handler[msg.type])(&msg, 0);
+
+ ctrl_if_rx_req_cons++;
}
if ( dp != ctrl_if_rxmsg_deferred_prod )
@@ -206,11 +210,15 @@ static int ctrl_if_interrupt(void *arg)
if ( ctrl_if_tx_resp_cons != ctrl_if->tx_resp_prod ||
ctrl_if_rx_req_cons != ctrl_if->rx_req_prod ) {
#if 0
+#if 0
wakeup(&ctrl_if_kthread);
#else
if (ctrl_if_softintr)
softintr_schedule(ctrl_if_softintr);
#endif
+#else
+ ctrl_if_kthread((void *)1);
+#endif
}
return 0;
@@ -225,6 +233,7 @@ ctrl_if_send_message_noblock(
control_if_t *ctrl_if = get_ctrl_if();
unsigned long flags;
int i;
+ int s;
save_and_cli(flags);
simple_lock(&ctrl_if_lock);
@@ -233,7 +242,11 @@ ctrl_if_send_message_noblock(
{
simple_unlock(&ctrl_if_lock);
restore_flags(flags);
- return -EAGAIN;
+ s = splhigh();
+ if ( ctrl_if_tx_resp_cons != ctrl_if->tx_resp_prod )
+ __ctrl_if_tx_tasklet(0);
+ splx(s);
+ return EAGAIN;
}
msg->id = 0xFF;
@@ -275,10 +288,13 @@ ctrl_if_send_message_block(
while ((rc = ctrl_if_send_message_noblock(msg, hnd, id)) == EAGAIN) {
/* XXXcl possible race -> add a lock and ltsleep */
+#if 1
+#else
rc = tsleep((caddr_t) &ctrl_if_tx_wait, PUSER | PCATCH,
"ctrl_if", 0);
if (rc)
break;
+#endif
}
return rc;
@@ -456,7 +472,6 @@ ctrl_if_kthread(void *arg)
{
control_if_t *ctrl_if = get_ctrl_if();
- // printf("ctrl_if_kthread starting\n");
for (;;) {
if ( ctrl_if_tx_resp_cons != ctrl_if->tx_resp_prod )
__ctrl_if_tx_tasklet(0);
@@ -464,10 +479,6 @@ ctrl_if_kthread(void *arg)
if ( ctrl_if_rx_req_cons != ctrl_if->rx_req_prod )
__ctrl_if_rx_tasklet(0);
- if ( ctrl_if_rxmsg_deferred_cons !=
- ctrl_if_rxmsg_deferred_prod )
- __ctrl_if_rxmsg_deferred(NULL);
-
if (arg) {
// printf("ctrl_if_kthread one-shot done\n");
return;
@@ -479,13 +490,19 @@ ctrl_if_kthread(void *arg)
}
static void
-ctrl_if_create_kthread(void *arg)
+ctrl_if_softintr_handler(void *arg)
{
+ static int in_handler = 0;
- printf("ctrl_if_kthread creating\n");
- if (kthread_create1(ctrl_if_kthread, arg, NULL, "ctrl_if"))
- printf("ctrl_if_kthread create failed\n");
- softintr_schedule(ctrl_if_softintr);
+ if (in_handler++ != 0) {
+ ctrl_if_evtchn = -1;
+ panic("recurse");
+ }
+
+ if ( ctrl_if_rxmsg_deferred_cons != ctrl_if_rxmsg_deferred_prod )
+ __ctrl_if_rxmsg_deferred(NULL);
+
+ in_handler--;
}
#ifdef notyet
@@ -528,20 +545,29 @@ void ctrl_if_resume(void)
hypervisor_enable_irq(ctrl_if_irq);
}
+void ctrl_if_early_init(void);
+void ctrl_if_early_init(void)
+{
+
+ simple_lock_init(&ctrl_if_lock);
+
+ ctrl_if_evtchn = xen_start_info.domain_controller_evtchn;
+}
+
void ctrl_if_init(void)
{
- int i;
+ int i;
- for ( i = 0; i < 256; i++ )
- ctrl_if_rxmsg_handler[i] = ctrl_if_rxmsg_default_handler;
+ for ( i = 0; i < 256; i++ )
+ ctrl_if_rxmsg_handler[i] = ctrl_if_rxmsg_default_handler;
- simple_lock_init(&ctrl_if_lock);
+ if (ctrl_if_evtchn == -1)
+ ctrl_if_early_init();
- if (0) kthread_create(ctrl_if_create_kthread, NULL);
- ctrl_if_softintr =
- softintr_establish(IPL_SOFTNET, ctrl_if_kthread, (void *)1);
+ ctrl_if_softintr = softintr_establish(IPL_SOFTNET,
+ ctrl_if_softintr_handler, NULL);
- ctrl_if_resume();
+ ctrl_if_resume();
}
diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/hypervisor.c b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/hypervisor.c
index 0f5a9fe788..294f79830a 100644
--- a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/hypervisor.c
+++ b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/hypervisor.c
@@ -133,6 +133,18 @@ hypervisor_match(parent, match, aux)
return 0;
}
+static void
+scan_finish(struct device *parent)
+{
+
+#if NXENNET > 0
+ xennet_scan_finish(parent);
+#endif
+#if NXBD > 0
+ xbd_scan_finish(parent);
+#endif
+}
+
/*
* Attach the hypervisor.
*/
@@ -183,6 +195,9 @@ hypervisor_attach(parent, self, aux)
xenvfr_init();
}
#endif
+#if NXENNET > 0 || NXBD > 0
+ config_interrupts(self, scan_finish);
+#endif
}
int
diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c
index a48f854f13..1670da4ea3 100644
--- a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c
+++ b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c
@@ -106,8 +106,9 @@ __KERNEL_RCSID(0, "$NetBSD: if_xennet.c,v 1.1.2.1 2004/05/22 15:58:29 he Exp $")
#define XEDB_MBUF 0x08
#define XEDB_MEM 0x10
int xennet_debug = 0x0;
-#define DPRINTF(x) if (xennet_debug) printf x;
-#define DPRINTFN(n,x) if (xennet_debug & (n)) printf x;
+void printk(char *, ...);
+#define DPRINTF(x) if (xennet_debug) printk x;
+#define DPRINTFN(n,x) if (xennet_debug & (n)) printk x;
#else
#define DPRINTF(x)
#define DPRINTFN(n,x)
@@ -174,13 +175,21 @@ static int nxennet_media = (sizeof(xennet_media)/sizeof(xennet_media[0]));
#endif
+static int
+xennet_wait_for_interfaces(void)
+{
+
+ while (netctrl.xc_interfaces != netctrl.xc_connected)
+ HYPERVISOR_yield();
+ return 0;
+}
+
int
xennet_scan(struct device *self, struct xennet_attach_args *xneta,
cfprint_t print)
{
ctrl_msg_t cmsg;
netif_fe_driver_status_t st;
- int err = 0;
if ((xen_start_info.flags & SIF_INITDOMAIN) ||
(xen_start_info.flags & SIF_NET_BE_DOMAIN))
@@ -203,13 +212,17 @@ xennet_scan(struct device *self, struct xennet_attach_args *xneta,
memcpy(cmsg.msg, &st, sizeof(st));
ctrl_if_send_message_block(&cmsg, NULL, 0, 0);
-#if 0
+ return 0;
+}
+
+void
+xennet_scan_finish(struct device *parent)
+{
+ int err;
+
err = xennet_wait_for_interfaces();
if (err)
ctrl_if_unregister_receiver(CMSG_NETIF_FE, xennet_ctrlif_rx);
-#endif
-
- return err;
}
int
@@ -270,7 +283,7 @@ find_device(int handle)
if (xs->sc_ifno == handle)
break;
}
- return xs;
+ return dv ? xs : NULL;
}
static void
@@ -278,6 +291,7 @@ xennet_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
{
int respond = 1;
+ DPRINTFN(XEDB_EVENT, ("> ctrlif_rx=%d\n", msg->subtype));
switch (msg->subtype) {
case CMSG_NETIF_FE_INTERFACE_STATUS:
if (msg->length != sizeof(netif_fe_interface_status_t))
@@ -307,7 +321,8 @@ static void
xennet_driver_status_change(netif_fe_driver_status_t *status)
{
- DPRINTFN(XEDB_EVENT, ("> status=%d\n", status->status));
+ DPRINTFN(XEDB_EVENT, ("xennet_driver_status_change(%d)\n",
+ status->status));
netctrl.xc_up = status->status;
xennet_driver_count_connected();
@@ -340,10 +355,9 @@ xennet_interface_status_change(netif_fe_interface_status_t *status)
netif_fe_interface_connect_t up;
struct xennet_softc *sc;
struct ifnet *ifp;
- struct vm_page *pg_tx, *pg_rx;
struct xennet_attach_args xneta;
- DPRINTFN(XEDB_EVENT, ("> status=%d handle=%d mac=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ DPRINTFN(XEDB_EVENT, ("xennet_interface_status_change(%d,%d,%02x:%02x:%02x:%02x:%02x:%02x)\n",
status->status,
status->handle,
status->mac[0], status->mac[1], status->mac[2],
@@ -363,6 +377,11 @@ xennet_interface_status_change(netif_fe_interface_status_t *status)
}
ifp = &sc->sc_ethercom.ec_if;
+ DPRINTFN(XEDB_EVENT, ("xennet_interface_status_change(%d,%p,%02x:%02x:%02x:%02x:%02x:%02x)\n",
+ status->handle, sc,
+ status->mac[0], status->mac[1], status->mac[2],
+ status->mac[3], status->mac[4], status->mac[5]));
+
switch (status->status) {
case NETIF_INTERFACE_STATUS_CLOSED:
printf("Unexpected netif-CLOSED message in state %d\n",
@@ -411,28 +430,30 @@ xennet_interface_status_change(netif_fe_interface_status_t *status)
}
#endif
- /* Move from CLOSED to DISCONNECTED state. */
- sc->sc_tx = (netif_tx_interface_t *)
- uvm_km_valloc_align(kernel_map, PAGE_SIZE, PAGE_SIZE);
- if (sc->sc_tx == NULL)
- panic("netif: no tx va");
- sc->sc_rx = (netif_rx_interface_t *)
- uvm_km_valloc_align(kernel_map, PAGE_SIZE, PAGE_SIZE);
- if (sc->sc_rx == NULL)
- panic("netif: no rx va");
- pg_tx = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO);
- if (pg_tx == NULL) {
- panic("netif: no tx pages");
- }
- pmap_kenter_pa((vaddr_t)sc->sc_tx, VM_PAGE_TO_PHYS(pg_tx),
- VM_PROT_READ | VM_PROT_WRITE);
- pg_rx = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO);
- if (pg_rx == NULL) {
- panic("netif: no rx pages");
+ if (sc->sc_backend_state == BEST_CLOSED) {
+ /* Move from CLOSED to DISCONNECTED state. */
+ sc->sc_tx = (netif_tx_interface_t *)
+ uvm_km_valloc_align(kernel_map, PAGE_SIZE, PAGE_SIZE);
+ if (sc->sc_tx == NULL)
+ panic("netif: no tx va");
+ sc->sc_rx = (netif_rx_interface_t *)
+ uvm_km_valloc_align(kernel_map, PAGE_SIZE, PAGE_SIZE);
+ if (sc->sc_rx == NULL)
+ panic("netif: no rx va");
+ sc->sc_pg_tx = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO);
+ if (sc->sc_pg_tx == NULL) {
+ panic("netif: no tx pages");
+ }
+ pmap_kenter_pa((vaddr_t)sc->sc_tx, VM_PAGE_TO_PHYS(sc->sc_pg_tx),
+ VM_PROT_READ | VM_PROT_WRITE);
+ sc->sc_pg_rx = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO);
+ if (sc->sc_pg_rx == NULL) {
+ panic("netif: no rx pages");
+ }
+ pmap_kenter_pa((vaddr_t)sc->sc_rx, VM_PAGE_TO_PHYS(sc->sc_pg_rx),
+ VM_PROT_READ | VM_PROT_WRITE);
+ sc->sc_backend_state = BEST_DISCONNECTED;
}
- pmap_kenter_pa((vaddr_t)sc->sc_rx, VM_PAGE_TO_PHYS(pg_rx),
- VM_PROT_READ | VM_PROT_WRITE);
- sc->sc_backend_state = BEST_DISCONNECTED;
/* Construct an interface-CONNECT message for the
* domain controller. */
@@ -440,8 +461,8 @@ xennet_interface_status_change(netif_fe_interface_status_t *status)
cmsg.subtype = CMSG_NETIF_FE_INTERFACE_CONNECT;
cmsg.length = sizeof(netif_fe_interface_connect_t);
up.handle = status->handle;
- up.tx_shmem_frame = xpmap_ptom(VM_PAGE_TO_PHYS(pg_tx)) >> PAGE_SHIFT;
- up.rx_shmem_frame = xpmap_ptom(VM_PAGE_TO_PHYS(pg_rx)) >> PAGE_SHIFT;
+ up.tx_shmem_frame = xpmap_ptom(VM_PAGE_TO_PHYS(sc->sc_pg_tx)) >> PAGE_SHIFT;
+ up.rx_shmem_frame = xpmap_ptom(VM_PAGE_TO_PHYS(sc->sc_pg_rx)) >> PAGE_SHIFT;
memcpy(cmsg.msg, &up, sizeof(up));
/* Tell the controller to bring up the interface. */
@@ -514,6 +535,7 @@ xennet_interface_status_change(netif_fe_interface_status_t *status)
status->status);
break;
}
+ DPRINTFN(XEDB_EVENT, ("xennet_interface_status_change()\n"));
}
static void
@@ -806,8 +828,6 @@ network_alloc_rx_buffers(struct xennet_softc *sc)
int s;
ringidx = sc->sc_rx->req_prod;
- if (0) printf("network_alloc_rx_buffers prod %d cons %d\n", ringidx,
- sc->sc_rx_resp_cons);
if ((ringidx - sc->sc_rx_resp_cons) > (RX_MAX_ENTRIES / 2))
return;
diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/xbd.c b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/xbd.c
index 9cfab063a9..a8034a2116 100644
--- a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/xbd.c
+++ b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/xbd.c
@@ -809,7 +809,7 @@ send_driver_status(int ok)
.subtype = CMSG_BLKIF_FE_DRIVER_STATUS,
.length = sizeof(blkif_fe_driver_status_t),
};
- blkif_fe_driver_status_t *msg = (void*)cmsg.msg;
+ blkif_fe_driver_status_t *msg = (blkif_fe_driver_status_t *)cmsg.msg;
msg->status = ok ? BLKIF_DRIVER_STATUS_UP : BLKIF_DRIVER_STATUS_DOWN;
@@ -825,7 +825,8 @@ send_interface_connect(void)
.subtype = CMSG_BLKIF_FE_INTERFACE_CONNECT,
.length = sizeof(blkif_fe_interface_connect_t),
};
- blkif_fe_interface_connect_t *msg = (void*)cmsg.msg;
+ blkif_fe_interface_connect_t *msg =
+ (blkif_fe_interface_connect_t *)cmsg.msg;
paddr_t pa;
pmap_extract(pmap_kernel(), (vaddr_t)blk_ring, &pa);
@@ -866,6 +867,15 @@ setup_sysctl(void)
diskcookies = pnode;
}
+static int
+xbd_wait_for_interfaces(void)
+{
+
+ while (state != STATE_CONNECTED)
+ HYPERVISOR_yield();
+ return 0;
+}
+
int
xbd_scan(struct device *self, struct xbd_attach_args *mainbus_xbda,
cfprint_t print)
@@ -912,13 +922,19 @@ xbd_scan(struct device *self, struct xbd_attach_args *mainbus_xbda,
send_driver_status(1);
-#if 0
- enable_update_events(self);
-#endif
-
return 0;
}
+void
+xbd_scan_finish(struct device *parent)
+{
+ int err;
+
+ err = xbd_wait_for_interfaces();
+ if (err)
+ ctrl_if_unregister_receiver(CMSG_NETIF_FE, xbd_ctrlif_rx);
+}
+
#if NXBD > 0
int
xbd_match(struct device *parent, struct cfdata *match, void *aux)
diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/xencons.c b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/xencons.c
index a151e3dd83..91fbccd9ed 100644
--- a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/xencons.c
+++ b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/xencons.c
@@ -46,6 +46,8 @@ __KERNEL_RCSID(0, "$NetBSD: xencons.c,v 1.1.2.1 2004/05/22 15:59:21 he Exp $");
#include <machine/stdarg.h>
#include <machine/xen.h>
#include <machine/hypervisor.h>
+#include <machine/evtchn.h>
+#include <machine/ctrl_if.h>
#include <dev/cons.h>
@@ -87,6 +89,7 @@ const struct cdevsw xencons_cdevsw = {
};
+static void xencons_rx(ctrl_msg_t *, unsigned long);
void xenconscn_attach(void);
int xenconscn_getc(dev_t);
void xenconscn_putc(dev_t, int);
@@ -131,6 +134,8 @@ xencons_attach(struct device *parent, struct device *self, void *aux)
/* Set db_max_line to avoid paging. */
db_max_line = 0x7fffffff;
+
+ (void)ctrl_if_register_receiver(CMSG_CONSOLE, xencons_rx, 0);
}
}
@@ -258,7 +263,6 @@ xencons_start(struct tty *tp)
{
struct clist *cl;
int s, len;
- u_char buf[XENCONS_BURST+1];
s = spltty();
if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
@@ -271,8 +275,22 @@ xencons_start(struct tty *tp)
* expensive and we don't want our serial ports to overflow.
*/
cl = &tp->t_outq;
- len = q_to_b(cl, buf, XENCONS_BURST);
- (void)HYPERVISOR_console_io(CONSOLEIO_write, len, buf);
+ if (xen_start_info.flags & SIF_INITDOMAIN) {
+ u_char buf[XENCONS_BURST+1];
+
+ len = q_to_b(cl, buf, XENCONS_BURST);
+ (void)HYPERVISOR_console_io(CONSOLEIO_write, len, buf);
+ } else {
+ ctrl_msg_t msg;
+
+ len = q_to_b(cl, msg.msg, sizeof(msg.msg));
+ msg.type = CMSG_CONSOLE;
+ msg.subtype = CMSG_CONSOLE_DATA;
+ msg.length = len;
+ ctrl_if_send_message_noblock(&msg, NULL, 0);
+ /* XXX check return value and queue wait for space
+ * thread/softint */
+ }
s = spltty();
tp->t_state &= ~TS_BUSY;
@@ -298,13 +316,47 @@ xencons_stop(struct tty *tp, int flag)
}
+/* Non-privileged receive callback. */
+static void
+xencons_rx(ctrl_msg_t *msg, unsigned long id)
+{
+ int i;
+ int s;
+ // unsigned long flags;
+ struct xencons_softc *sc;
+ struct tty *tp;
+
+ sc = device_lookup(&xencons_cd, XENCONS_UNIT(cn_tab->cn_dev));
+ if (sc == NULL)
+ goto out;
+
+ tp = sc->sc_tty;
+ if (tp == NULL)
+ goto out;
+
+ s = spltty();
+ // save_and_cli(flags);
+ // simple_lock(&xencons_lock);
+ for (i = 0; i < msg->length; i++)
+ (*tp->t_linesw->l_rint)(msg->msg[i], tp);
+ // simple_unlock(&xencons_lock);
+ // restore_flags(flags);
+ splx(s);
+ out:
+ msg->length = 0;
+ ctrl_if_send_response(msg);
+}
+
+void ctrl_if_early_init(void);
void
xenconscn_attach()
{
cn_tab = &xencons;
+ ctrl_if_early_init();
+
xencons_isconsole = 1;
}
@@ -316,18 +368,29 @@ xenconscn_getc(dev_t dev)
for (;;);
}
-#define MAXLINELEN 1024
void
xenconscn_putc(dev_t dev, int c)
{
- static char buf[1024+1];
- static int bufpos = 0;
-
- buf[bufpos++] = c;
- if (c == '\n') {
- buf[bufpos] = 0;
- (void)HYPERVISOR_console_io(CONSOLEIO_write, bufpos, buf);
- bufpos = 0;
+ extern int ctrl_if_evtchn;
+
+ if (xen_start_info.flags & SIF_INITDOMAIN ||
+ ctrl_if_evtchn == -1) {
+ u_char buf[1];
+
+ buf[0] = c;
+ (void)HYPERVISOR_console_io(CONSOLEIO_write, 1, buf);
+ } else {
+ ctrl_msg_t msg;
+
+ msg.type = CMSG_CONSOLE;
+ msg.subtype = CMSG_CONSOLE_DATA;
+ msg.length = 1;
+ msg.msg[0] = c;
+ while (ctrl_if_send_message_noblock(&msg, NULL, 0) == EAGAIN) {
+ HYPERVISOR_yield();
+ /* XXX check return value and queue wait for space
+ * thread/softint */
+ }
}
}