commit cdae0c6feda7f01b5670b4e8db5454dae42328db
parent c2c1dec20d72b9cd15b700054263b0929fe4d94e
Author: Roberto Vargas <roberto.vargas@arm.com>
Date: Thu, 13 Dec 2018 15:04:13 +0000
[dev] Add dirto9p()
This is the first function of the lib9p library that is going to be in
charge of the translation between internal data structures to the
9p protocol.
Change-Id: Ic99f84d258202518954e51b68f388dd7aac76314
Diffstat:
14 files changed, 158 insertions(+), 70 deletions(-)
diff --git a/drivers/dev.c b/drivers/dev.c
@@ -3,8 +3,8 @@
#include <rcode/rcode.h>
#include <rcode/romfw.h>
+#include <rcode/dev.h>
-#include "dev.h"
struct devdata {
Chan fds[NR_CHANS];
@@ -227,7 +227,7 @@ devwalk(Chan *c, const char *name, const Dirtab *tab, int ntab, Devgen *gen)
int
devdirread(Chan *c, char *buf, int nbytes, const Dirtab *tab, int ntab, Devgen *gen)
{
- int cnt, i;
+ int cnt, i, n;
Dir dir;
cnt = 0;
@@ -239,10 +239,9 @@ devdirread(Chan *c, char *buf, int nbytes, const Dirtab *tab, int ntab, Devgen *
c->offset += DIRLEN;
break;
case 1:
- memcpy(buf + cnt, &dir, DIRLEN);
- /* TODO: We still have to consider using 9p */
- nbytes -= 1;
- cnt += 1;
+ n = dirto9p(dir, buf + cnt);
+ nbytes -= n;
+ cnt += n;
}
}
diff --git a/drivers/dev.h b/drivers/dev.h
@@ -1,58 +0,0 @@
-#include <stddef.h>
-
-#define NR_CHANS 4
-#define NODEV 255
-#define NAMELEN 8
-#define DIRLEN sizeof(Dir)
-#define CHDIR (1 << 15)
-
-typedef struct dev Dev;
-typedef struct chan Chan;
-typedef struct dirtab Dirtab;
-typedef struct dir Dir;
-typedef int Devgen(Chan *, const Dirtab *, int, int, Dir *);
-typedef unsigned short Qid;
-
-struct dir {
- char name[NAMELEN];
- unsigned long long length;
- unsigned char mode;
- unsigned char type;
- unsigned char dev;
- Qid qid;
-};
-
-struct dirtab {
- char name[NAMELEN];
- Qid qid;
- unsigned long long length;
- unsigned char perm;
-};
-
-struct dev {
- char id;
- char name[NAMELEN];
- Chan * (*clone)(Chan *c, Chan *nc);
- int (*walk)(Chan *c, const char *name);
- Chan * (*attach)(const char *spec);
- int (*read)(Chan *c, void *buf, int n);
- int (*write)(Chan *c, void *buf, int n);
-};
-
-struct chan {
- Qid qid;
- unsigned char type;
- unsigned char dev;
- unsigned char mode;
-
- unsigned long long offset; /* 3 bytes of padding here */
-};
-
-extern Dev *const devtab[];
-
-extern Chan *devclone(Chan *c, Chan *nc);
-extern Chan *devattach(const char *spec, int id);
-extern Chan *devclone(Chan *c, Chan *nc);
-extern int devgen(Chan *c, const Dirtab *tab, int ntab, int n, Dir *dir);
-extern int devwalk(Chan *c, const char *name, const Dirtab *tab, int ntab, Devgen *gen);
-extern int devdirread(Chan *c, char *buf, int nbytes, const Dirtab *tab, int ntab, Devgen *gen);
diff --git a/drivers/devroot.c b/drivers/devroot.c
@@ -1,6 +1,5 @@
#include <rcode/rcode.h>
-
-#include "dev.h"
+#include <rcode/dev.h>
enum Orootqid {
Qslash,
diff --git a/drivers/devuart.c b/drivers/devuart.c
@@ -1,4 +1,4 @@
-#include "dev.h"
+#include <rcode/dev.h>
const Dev uartdevtab = {
.id = 't',
diff --git a/drivers/mkdevc b/drivers/mkdevc
@@ -4,7 +4,7 @@ trap 'r=$?; rm -f $$.tmp; exit $r' EXIT HUP INT QUIT TERM
sed -e 's/^#.*//' -e '/^[ \t]*$/d' $@ |
awk '
-BEGIN {print "#include \"dev.h\"\n"}
+BEGIN {print "#include <rcode/dev.h>\n"}
/^dev/ {dev = 1; next}
/^[^ \t]/ {dev = 0; next}
dev && /^[ \t]/ {devs[$1 "devtab"] = 1}
diff --git a/include/rcode/9p.h b/include/rcode/9p.h
@@ -0,0 +1,4 @@
+/*
+ * This file expects rcode/dev.h to be included before
+ */
+extern int dirto9p(Dir *dp, unsigned char *buf, int n);
diff --git a/include/rcode/dev.h b/include/rcode/dev.h
@@ -0,0 +1,61 @@
+#include <stddef.h>
+
+#define NR_CHANS 4
+#define NODEV 255
+#define NAMELEN 8
+#define STATLEN 41
+#define ROOTLEN (2 + 4)
+#define FILNAMLEN (2 + NAMELEN)
+#define DIRLEN (STATLEN + FILNAMLEN + 3*ROOTLEN)
+#define CHDIR (1 << 15)
+
+typedef struct dev Dev;
+typedef struct chan Chan;
+typedef struct dirtab Dirtab;
+typedef struct dir Dir;
+typedef int Devgen(Chan *, const Dirtab *, int, int, Dir *);
+typedef unsigned short Qid;
+
+struct dir {
+ char name[NAMELEN];
+ unsigned long long length;
+ unsigned char mode;
+ unsigned char type;
+ unsigned char dev;
+ Qid qid;
+};
+
+struct dirtab {
+ char name[NAMELEN];
+ Qid qid;
+ unsigned long long length;
+ unsigned char perm;
+};
+
+struct dev {
+ char id;
+ char name[NAMELEN];
+ Chan * (*clone)(Chan *c, Chan *nc);
+ int (*walk)(Chan *c, const char *name);
+ Chan * (*attach)(const char *spec);
+ int (*read)(Chan *c, void *buf, int n);
+ int (*write)(Chan *c, void *buf, int n);
+};
+
+struct chan {
+ Qid qid;
+ unsigned char type;
+ unsigned char dev;
+ unsigned char mode;
+
+ unsigned long long offset; /* 3 bytes of padding here */
+};
+
+extern Dev *const devtab[];
+
+extern Chan *devclone(Chan *c, Chan *nc);
+extern Chan *devattach(const char *spec, int id);
+extern Chan *devclone(Chan *c, Chan *nc);
+extern int devgen(Chan *c, const Dirtab *tab, int ntab, int n, Dir *dir);
+extern int devwalk(Chan *c, const char *name, const Dirtab *tab, int ntab, Devgen *gen);
+extern int devdirread(Chan *c, char *buf, int nbytes, const Dirtab *tab, int ntab, Devgen *gen);
diff --git a/scripts/rules.mk b/scripts/rules.mk
@@ -10,13 +10,14 @@ SRCDIR = $(PROJECTDIR)/src
SCRIPTDIR= $(PROJECTDIR)/scripts
CONFDIR = $(PROJECTDIR)/config
INCLUDES = -I$(INCDIR) -I$(INCDIR)/bits/$(ARCH)/ -I$(INCDIR)/bits/$(SYS)
-LIBS = -lhdl -lrmu -lk -lc
+LIBS = -l9p -lhdl -lrmu -lk -lc
DRIVERS = $(PROJECTDIR)/drivers/builtin.o
LIBDEP = $(LIBDIR)/libhdl.a \
$(LIBDIR)/librmu.a \
$(LIBDIR)/libk.a \
$(LIBDIR)/libc.a \
+ $(LIBDIR)/lib9p.a \
RCODE_CFLAGS = $(MORECFLAGS) \
$(INCLUDES) \
diff --git a/src/Makefile b/src/Makefile
@@ -2,7 +2,7 @@
PROJECTDIR=..
include $(PROJECTDIR)/scripts/rules.mk
-LIBS = libk libc librmu libtypes libhdl
+LIBS = lib9p libk libc librmu libtypes libhdl
IMGS = ramfw romfw
DIRS = $(LIBS) $(IMGS)
diff --git a/src/lib9p/Makefile b/src/lib9p/Makefile
@@ -0,0 +1,15 @@
+.POSIX:
+PROJECTDIR=../..
+include $(PROJECTDIR)/scripts/rules.mk
+
+OBJS = tobytes.o \
+ tostring.o \
+ dirto9p.o \
+
+TARGET = $(LIBDIR)/lib9p.a
+
+all: $(TARGET)
+
+$(TARGET): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $?
+ $(RL) $(RANLIBFLAGS) $@
diff --git a/src/lib9p/conv.h b/src/lib9p/conv.h
@@ -0,0 +1,8 @@
+#define CHAR(x,p) (p = tobytes(p, x, 1))
+#define SHORT(x,p) (p = tobytes(p, x, 2))
+#define LONG(x,p) (p = tobytes(p, x, 4))
+#define LLONG(x,p) (p = tobytes(p, x, 8))
+#define STRING(s,p) (p = tostring(p, s))
+
+unsigned char *tobytes(unsigned char *p, unsigned long long v, int nbytes);
+unsigned char *tostring(unsigned char *p, char *s);
diff --git a/src/lib9p/dirto9p.c b/src/lib9p/dirto9p.c
@@ -0,0 +1,37 @@
+#include <assert.h>
+
+#include <rcode/dev.h>
+#include <rcode/9p.h>
+
+#include "conv.h"
+
+int
+dirto9p(Dir *dp, unsigned char *buf, int n)
+{
+ int len;
+ unsigned char *p;
+
+ if (n < DIRLEN)
+ return 0;
+
+ p = buf + 2;
+ SHORT(dp->type, p); /* type */
+ LONG(dp->dev, p); /* dev */
+ CHAR(dp->qid >> 8, p); /* qid.type */
+ LONG(0, p); /* qid.vers */
+ LLONG(dp->qid, p); /* qid.path */
+ LONG(0, p); /* mode */
+ LONG(0, p); /* atime */
+ LONG(0, p); /* mtime */
+ LLONG(dp->length, p); /* length */
+ STRING(dp->name, p); /* name */
+ STRING("root", p); /* uid */
+ STRING("root", p); /* gid */
+ STRING("root", p); /* muid */
+ len = p -buf;
+ SHORT(len, buf); /* size */
+
+ assert(len < DIRLEN);
+
+ return len;
+}
diff --git a/src/lib9p/tobytes.c b/src/lib9p/tobytes.c
@@ -0,0 +1,9 @@
+#include "conv.h"
+
+unsigned char *
+tobytes(unsigned char *p, unsigned long long v, int n)
+{
+ for ( ; n--; p++)
+ *p = v, v >>= 8;
+ return p;
+}
diff --git a/src/lib9p/tostring.c b/src/lib9p/tostring.c
@@ -0,0 +1,13 @@
+#include <string.h>
+
+#include "conv.h"
+
+unsigned char *
+tostring(unsigned char *p, char *s)
+{
+ int len = strlen(s);
+
+ p = tobytes(p, len, 2);
+ memcpy(p, s, len);
+ return p + len;
+}