M gnot/dat.h => gnot/dat.h +2 -3
@@ 4,12 4,10 @@ typedef struct Blist Blist;
typedef struct Chan Chan;
typedef struct Conf Conf;
typedef struct Dev Dev;
-typedef struct Dir Dir;
typedef struct Dirtab Dirtab;
typedef struct Env Env;
typedef struct Envp Envp;
typedef struct Envval Envval;
-typedef struct Error Error;
typedef struct FFrame FFrame;
typedef struct FPsave FPsave;
typedef struct KMap KMap;
@@ 175,7 173,7 @@ struct Dev
struct Dirtab
{
char name[NAMELEN];
- long qid;
+ ulong qid;
long length;
long perm;
};
@@ 445,6 443,7 @@ struct Queue {
Queue *other; /* opposite direction, same line discipline */
Queue *next; /* next queue in the stream */
void (*put)(Queue*, Block*);
+ QLock rlock; /* mutex for processes sleeping at r */
Rendez r;
void *ptr; /* private info for the queue */
};
M gnot/devdk.c => gnot/devdk.c +3 -6
@@ 118,7 118,7 @@ struct Line {
struct Dk {
QLock;
int ref;
- char name[64]; /* dk name */
+ char name[64]; /* dk name */
Queue *wq; /* dk output queue */
int lines; /* number of lines */
int ncsc; /* csc line number */
@@ 420,11 420,8 @@ dkoput(Queue *q, Block *bp)
bp->rptr[0] = line;
bp->rptr[1] = line>>8;
- if(QFULL(dp->wq->next)){
- print("dk wq full\n");
- freeb(bp);
- } else
- PUTNEXT(dp->wq, bp);
+ FLOWCTL(dp->wq);
+ PUTNEXT(dp->wq, bp);
}
/*
M gnot/stream.c => gnot/stream.c +2 -0
@@ 1047,7 1047,9 @@ notfull(void *arg)
void
flowctl(Queue *q)
{
+ qlock(&q->rlock);
sleep(&q->r, notfull, q->next);
+ qunlock(&q->rlock);
}
/*
M port/devcons.c => port/devcons.c +81 -50
@@ 36,15 36,15 @@ struct IOQ{
IOQ kbdq; /* qlock to getc; interrupt putc's */
IOQ lineq; /* lock to getc; interrupt putc's */
-#define SYSLOGMAGIC 0x23456789
-#define SYSLOG ((Syslog *)(UNCACHED | KZERO | 0x1B00))
+#define SYSLOGMAGIC 0xdeadbeaf
+#define SYSLOG ((Syslog *)(UNCACHED | 0x1B00))
typedef struct Syslog Syslog;
struct Syslog
{
ulong magic;
- char *start;
+ int wrapped;
char *next;
- char buf[2*BY2PG - 3*BY2WD];
+ char buf[2*1024];
};
@@ 67,7 67,6 @@ printinit(void)
unlock(&lineq);
duartinit();
- sysloginit(); /* must be at the end of printinit */
}
/*
@@ 177,15 176,12 @@ panic(char *fmt, ...)
{
char buf[PRINTSIZE];
int n;
- Syslog *s;
strcpy(buf, "panic: ");
n = doprint(buf+7, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
buf[n] = '\n';
putstrn(buf, n+1);
dumpstack();
- s = SYSLOG;
- print("start/next is %lux/%lux\n", s->start, s->next);
exit();
}
@@ 309,6 305,7 @@ enum{
Qcputime,
Qlog,
Qnull,
+/* Qpanic, /**/
Qpgrpid,
Qpid,
Qppid,
@@ 321,6 318,7 @@ Dirtab consdir[]={
"cputime", Qcputime, 72, 0600,
"log", Qlog, BY2PG-8, 0600,
"null", Qnull, 0, 0600,
+/* "panic", Qpanic, 0, 0666, /**/
"pgrpid", Qpgrpid, 12, 0600,
"pid", Qpid, 12, 0600,
"ppid", Qppid, 12, 0600,
@@ 618,78 616,111 @@ void
sysloginit(void)
{
Syslog *s;
- char *start, *next;
+ int i;
s = SYSLOG;
- next = s->next;
- start = s->start;
- if(s->magic!=SYSLOGMAGIC || next>=&s->buf[sizeof(s->buf)]
- || start>=&s->buf[sizeof(s->buf)] || next<s->buf){
- s->start = s->buf;
+ if(s->magic!=SYSLOGMAGIC || s->next>=&s->buf[sizeof(s->buf)] || s->next<s->buf){
+ s->wrapped = 0;
s->next = s->buf;
s->magic = SYSLOGMAGIC;
}
- print("start/next is %lux/%lux was %lux/%lux\n", s->start, s->next,
- start, next);
}
void
syslog(char *p, int n)
{
- int restart;
Syslog *s;
char *end;
+ int m;
+ sysloginit();
s = SYSLOG;
end = &s->buf[sizeof(s->buf)];
- restart = 0;
- while(n-- > 0){
- *s->next++ = *p++;
- if(s->next >= end)
+ while(n){
+ if(s->next + n > end)
+ m = end - s->next;
+ else
+ m = n;
+ memcpy(s->next, p, m);
+ s->next += m;
+ p += m;
+ n -= m;
+ if(s->next >= end){
+ s->wrapped = 1;
s->next = s->buf;
- if(s->next == s->start)
- restart = 1;
- }
- if(restart){
- s->start = s->next + 1;
- if(s->start >= end)
- s->start = s->buf;
+ }
}
wbflush();
}
long
-readlog(ulong off, char *buf, ulong n)
+readlog(ulong off, char *buf, ulong len)
{
Syslog *s;
- char *p;
char *end;
- char *a = buf;
+ char *start;
+ int n, m;
+ char *p;
+ n = len;
+ p = buf;
+
+ sysloginit();
s = SYSLOG;
+ end = &s->buf[sizeof(s->buf)];
- /* past end */
- if(off >= sizeof(s->buf))
+ if(s->wrapped){
+ start = s->next;
+ m = sizeof(s->buf);
+ } else {
+ start = s->buf;
+ m = s->next - start;
+ }
+
+ if(off > m)
return 0;
+ if(off + n > m)
+ n = m - off;
+ start += off;
+ if(start > end)
+ start -= sizeof(s->buf);
- /* point to start of area to be read */
+ while(n > 0){
+ if(start + n > end)
+ m = end - start;
+ else
+ m = n;
+ memcpy(p, start, m);
+ start += m;
+ p += m;
+ n -= m;
+ if(start >= end)
+ start = s->buf;
+ }
+
+ return p-buf;
+}
+
+/*
+ * Read and write every byte of the log. This seems to ensure that
+ * on reboot, the bytes will really be in memory. I don't understand -- presotto
+ */
+void
+flushsyslog(void)
+{
+ Syslog *s;
+ char *p, *end;
+ int x;
+
+ s = SYSLOG;
end = &s->buf[sizeof(s->buf)];
- p = s->start;
- /* skip offset */
- while(off-- > 0){
- if(p == s->next)
- return 0;
- p++;
- }
+ x = splhi();
+ lock(&printq);
+ for(p = s->buf; p < end; p++)
+ *p = *p;
+ unlock(&printq);
+ splx(x);
- /* copy out */
- while(n-- > 0){
- if(p == s->next)
- break;
- *a++ = *p++;
- if(p >= end)
- p = s->buf;
- }
- return a-buf;
+ wbflush();
}
M port/devdk.c => port/devdk.c +3 -6
@@ 118,7 118,7 @@ struct Line {
struct Dk {
QLock;
int ref;
- char name[64]; /* dk name */
+ char name[64]; /* dk name */
Queue *wq; /* dk output queue */
int lines; /* number of lines */
int ncsc; /* csc line number */
@@ 420,11 420,8 @@ dkoput(Queue *q, Block *bp)
bp->rptr[0] = line;
bp->rptr[1] = line>>8;
- if(QFULL(dp->wq->next)){
-/* print("dk wq full\n");/**/
- freeb(bp);
- } else
- PUTNEXT(dp->wq, bp);
+ FLOWCTL(dp->wq);
+ PUTNEXT(dp->wq, bp);
}
/*
M port/page.c => port/page.c +1 -0
@@ 463,6 463,7 @@ freesegs(int save)
if(i == save)
continue;
o = s->o;
+ s->o = 0; /* seg() won't match it (e.g. in procread()) */
if(o == 0)
continue;
lock(o);
M port/stream.c => port/stream.c +2 -0
@@ 1047,7 1047,9 @@ notfull(void *arg)
void
flowctl(Queue *q)
{
+ qlock(&q->rlock);
sleep(&q->r, notfull, q->next);
+ qunlock(&q->rlock);
}
/*
M power/dat.h => power/dat.h +2 -2
@@ 9,7 9,6 @@ typedef struct Dirtab Dirtab;
typedef struct Env Env;
typedef struct Envp Envp;
typedef struct Envval Envval;
-typedef struct Error Error;
typedef struct FPsave FPsave;
typedef struct Label Label;
typedef struct List List;
@@ 174,7 173,7 @@ struct Dev
struct Dirtab
{
char name[NAMELEN];
- long qid;
+ ulong qid;
long length;
long perm;
};
@@ 439,6 438,7 @@ struct Queue {
Queue *other; /* opposite direction, same line discipline */
Queue *next; /* next queue in the stream */
void (*put)(Queue*, Block*);
+ QLock rlock; /* mutex for r */
Rendez r;
void *ptr; /* private info for the queue */
};
M power/devhotrod.c => power/devhotrod.c +45 -8
@@ 14,7 14,7 @@ typedef struct Device Device;
enum {
Vmevec= 0xd2, /* vme vector for interrupts */
Intlevel= 5, /* level to interrupt on */
- Nhotrod= 1,
+ Nhotrod= 2,
};
/*
@@ 24,9 24,9 @@ enum {
* and 0xB00000 to 0xBFFFFF in A24 space
*/
struct Device {
- uchar mem[1*1024*1024];
+ ulong mem[1024*1024/sizeof(ulong)];
};
-#define HOTROD VMEA32SUP(Device, 0x30000000)
+#define HOTROD VMEA24SUP(Device, 0xB00000)
struct Hotrod {
QLock;
@@ 56,7 56,7 @@ void
hotrodreset(void)
{
int i;
- Hsvme *hp;
+ Hotrod *hp;
for(i=0; i<Nhotrod; i++){
hotrod[i].addr = HOTROD+i;
@@ 116,8 116,7 @@ hotrodopen(Chan *c, int omode)
if(c->qid == CHDIR){
if(omode != OREAD)
error(0, Eperm);
- }else
- streamopen(c, &hotrodinfo);
+ }
c->mode = openmode(omode);
c->flag |= COPEN;
c->offset = 0;
@@ 143,6 142,18 @@ hotrodread(Chan *c, void *buf, long n)
{
Hotrod *hp;
Device *dp;
+ ulong *from;
+ ulong *to;
+ ulong *end;
+
+ if(c->qid&CHDIR)
+ return devdirread(c, buf, n, 0, 0, hotrodgen);
+
+ /*
+ * allow full word access only
+ */
+ if((c->offset&(sizeof(ulong)-1)) || (n&(sizeof(ulong)-1)))
+ error(0, Ebadarg);
hp = &hotrod[c->dev];
dp = hp->addr;
@@ 150,8 161,16 @@ hotrodread(Chan *c, void *buf, long n)
return 0;
if(c->offset+n > sizeof(dp->mem))
n = sizeof(dp->mem) - c->offset;
+
+ /*
+ * avoid memcpy to ensure VME 32-bit reads
+ */
qlock(hp);
- memcpy(buf, &dp->mem[c->offset], n);
+ to = buf;
+ from = &dp->mem[c->offset/sizeof(ulong)];
+ end = to + (n/sizeof(ulong));
+ while(to != end)
+ *to++ = *from++;
qunlock(hp);
return n;
}
@@ 164,6 183,15 @@ hotrodwrite(Chan *c, void *buf, long n)
{
Hotrod *hp;
Device *dp;
+ ulong *from;
+ ulong *to;
+ ulong *end;
+
+ /*
+ * allow full word access only
+ */
+ if((c->offset&(sizeof(ulong)-1)) || (n&(sizeof(ulong)-1)))
+ error(0, Ebadarg);
hp = &hotrod[c->dev];
dp = hp->addr;
@@ 171,8 199,16 @@ hotrodwrite(Chan *c, void *buf, long n)
return 0;
if(c->offset+n > sizeof(dp->mem))
n = sizeof(dp->mem) - c->offset;
+
+ /*
+ * avoid memcpy to ensure VME 32-bit writes
+ */
qlock(hp);
- memcpy(&dp->mem[c->offset], buf, n);
+ from = buf;
+ to = &dp->mem[c->offset/sizeof(ulong)];
+ end = to + (n/sizeof(ulong));
+ while(to != end)
+ *to++ = *from++;
qunlock(hp);
return n;
}
@@ 201,6 237,7 @@ hotroderrstr(Error *e, char *buf)
rooterrstr(e, buf);
}
+static void
hotrodintr(int vec)
{
Hotrod *hp;