Browse Source

Added code for read and write in virtcon.

Signed-off-by: golubovsky <golubovsky@gmail.com>
golubovsky 7 years ago
parent
commit
7a15fcc99f
3 changed files with 167 additions and 13 deletions
  1. 1 1
      rc/bin/termrc
  2. 5 5
      sys/include/virtio_lib.h
  3. 161 7
      sys/src/9/port/devvcon.c

+ 1 - 1
rc/bin/termrc

@@ -9,7 +9,7 @@ terminal = "ninep"
 mntgen -s slashn && chmod 666 /srv/slashn
 
 # bind all likely devices (#S was bound in boot)
-for(i in f t m v L P u U '$' Σ κ)
+for(i in f t m v L P u U '$' Σ κ C)
 	/bin/bind -a '#'^$i /dev >/dev/null >[2=1]
 
 # ONLY FOR LOCAL DISK! We need better hack checking

+ 5 - 5
sys/include/virtio_lib.h

@@ -76,13 +76,13 @@ uint32_t getvdevsbypciid(int pciid, Vqctl **vqs, uint32_t n);
 static inline struct vring_desc * q2descr(Virtq *q, int i) { return q->vr.desc + i; }
 
 // Unified QID conversions between values and device/queue indices. We allocate bits:
-// 0 - 7 for QID type (specific to each driver)
-// 16 - 27 for device index (to use with vdevbyidx)
-// 32 - 63 for queue index within device
+// 0 - 3 for QID type (specific to each driver)
+// 4 - 15 for device index (to use with vdevbyidx)
+// 16 - 32 for queue index within device
 
 // Extract QID type
 
-#define TYPE(q)			((uint32_t)(q).path & 0xFF)
+#define TYPE(q)			((uint32_t)(q).path & 0x0F)
 
 // Extract device index
 
@@ -94,7 +94,7 @@ static inline struct vring_desc * q2descr(Virtq *q, int i) { return q->vr.desc +
 
 // Construct a non-queue aware QID (to address a per-device file)
 
-#define QID(c, t)		((((c) & 0x0FFF)<<4) | ((t) & 0xFF))
+#define QID(c, t)		((((c) & 0x0FFF)<<4) | ((t) & 0x0F))
 
 // Construct a queue-aware QID (to address a per-queue file)
 

+ 161 - 7
sys/src/9/port/devvcon.c

@@ -26,12 +26,166 @@
 
 #include	"virtio_lib.h"
 
+enum
+{
+	Qtopdir = 0,			// top directory
+	Qvirtcon,				// virtcon directory under the top where all consoles live
+	Qvcpipe,				// console pipe for reading/writing
+};
+
+static Dirtab topdir[] = {
+	".",		{ Qtopdir, 0, QTDIR },	0,	DMDIR|0555,
+	"virtcon",	{ Qvirtcon, 0, QTDIR },	0,	DMDIR|0555,
+};
+
+extern Dev vcondevtab;
+
 // Array of defined virtconsoles and their number
 
 static uint32_t nvcon;
 
 static Vqctl **vcons;
 
+// Read-write common code
+
+static int
+rwcommon(Vqctl *d, void *va, int32_t n, int qidx)
+{
+	uint16_t descr[1];
+	Virtq *vq = d->vqs[qidx];
+	int nd = getdescr(vq, 1, descr);
+	if(nd < 1)
+	{
+		error("virtcon: queue low");
+		return -1;
+	}
+	uint8_t buf[n];
+	if(qidx) {
+		memmove(buf, va, n);
+	}
+	q2descr(vq, descr[0])->addr = PADDR(buf);
+	q2descr(vq, descr[0])->len = n;	
+	if(qidx) {
+		q2descr(vq, descr[0])->flags = VRING_DESC_F_WRITE;
+	}
+	int rc = queuedescr(vq, 1, descr);
+print("rwcommon rc=%d\n", rc);
+	if(!qidx) {
+		memmove(va, buf, n);
+	}
+	reldescr(vq, 1, descr);
+	return (rc >= 0)?n:rc;
+}
+
+static int
+vcongen(Chan *c, char *d, Dirtab* dir, int i, int s, Dir *dp)
+{
+	Proc *up = externup();
+	Qid q;
+	int t = TYPE(c->qid);
+	int vdidx = DEV(c->qid);
+	if(vdidx >= nvcon)
+		error(Ebadarg);
+	switch(t){
+	case Qtopdir:
+		if(s == DEVDOTDOT){
+			q = (Qid){QID(0, Qtopdir), 0, QTDIR};
+			snprint(up->genbuf, sizeof up->genbuf, "#%C", vcondevtab.dc);
+			devdir(c, q, up->genbuf, 0, eve, DMDIR|0555, dp);
+			return 1;
+		}
+		return devgen(c, nil, topdir, nelem(topdir), s, dp);
+	case Qvirtcon:
+		if(s == DEVDOTDOT){
+			q = (Qid){QID(0, Qtopdir), 0, QTDIR};
+			snprint(up->genbuf, sizeof up->genbuf, "#%C", vcondevtab.dc);
+			devdir(c, q, up->genbuf, 0, eve, DMDIR|0555, dp);
+			return 1;
+		}
+		if(s >= nvcon)
+			return -1;
+		snprint(up->genbuf, sizeof up->genbuf, "vcons%d", s);
+		q = (Qid) {QID(s, Qvcpipe), 0, 0};
+		devdir(c, q, up->genbuf, 0, eve, 0666, dp);
+		return 1;
+	}
+	return -1;
+}
+
+static Chan*
+vconattach(char *spec)
+{
+	return devattach(vcondevtab.dc, spec);
+}
+
+
+Walkqid*
+vconwalk(Chan* c, Chan *nc, char** name, int nname)
+{
+	return devwalk(c, nc, name, nname, (Dirtab *)0, 0, vcongen);
+}
+
+static int32_t
+vconstat(Chan* c, uint8_t* dp, int32_t n)
+{
+	return devstat(c, dp, n, (Dirtab *)0, 0L, vcongen);
+}
+
+static Chan*
+vconopen(Chan *c, int omode)
+{
+	uint t = TYPE(c->qid);
+	uint vdidx = DEV(c->qid);
+	if(vdidx >= nvcon)
+		error(Ebadarg);
+	c = devopen(c, omode, (Dirtab*)0, 0, vcongen);
+	switch(t) {
+	default:
+		break;
+	}
+	return c;
+}
+
+static int32_t
+vconread(Chan *c, void *va, int32_t n, int64_t offset)
+{
+	int vdidx = DEV(c->qid);
+	if(vdidx >= nvcon)
+		error(Ebadarg);
+	switch(TYPE(c->qid)) {
+	case Qtopdir:
+	case Qvirtcon:
+		return devdirread(c, va, n, (Dirtab *)0, 0L, vcongen);
+	case Qvcpipe:
+print("vconread dev %d addr %08p len %d\n", vdidx, va, n);
+		return rwcommon(vcons[vdidx], va, n, 0);
+	}
+	return -1;
+}
+
+static int32_t
+vconwrite(Chan *c, void *va, int32_t n, int64_t offset)
+{
+	int vdidx = DEV(c->qid);
+	if(vdidx >= nvcon)
+		error(Ebadarg);
+	switch(TYPE(c->qid)) {
+	case Qtopdir:
+	case Qvirtcon:
+		error(Eperm);
+		return -1;
+	case Qvcpipe:
+print("vconwrite dev %d addr %08p len %d\n", vdidx, va, n);
+		return rwcommon(vcons[vdidx], va, n, 1);
+	}
+	return -1;
+}
+
+static void
+vconclose(Chan* c)
+{
+}
+
 static void
 vconinit(void)
 {
@@ -66,15 +220,15 @@ Dev vcondevtab = {
 	.reset = devreset,
 	.init = vconinit,
 	.shutdown = devshutdown,
-//	.attach = vconattach,
-//	.walk = vconwalk,
-//	.stat = vconstat,
-//	.open = vconopen,
+	.attach = vconattach,
+	.walk = vconwalk,
+	.stat = vconstat,
+	.open = vconopen,
 	.create = devcreate,
-//	.close = vconclose,
-//	.read = vconread,
+	.close = vconclose,
+	.read = vconread,
 	.bread = devbread,
-//	.write = vconwrite,
+	.write = vconwrite,
 	.bwrite = devbwrite,
 	.remove = devremove,
 	.wstat = devwstat,