M gnot/devincon.c => gnot/devincon.c +1 -1
@@ 264,7 264,7 @@ inconreset(void)
incon[0].dev = INCON;
incon[0].state = Selected;
incon[0].ri = incon[0].wi = 0;
- inconset(&incon[0], 8, 9);
+/* inconset(&incon[0], 8, 9); /**/
for(i=1; i<Nincon; i++){
incon[i].dev = INCON+i;
incon[i].state = Dead;
M gnot/fns.h => gnot/fns.h +3 -0
@@ 31,6 31,8 @@ int devno(int, int);
Chan* devopen(Chan*, int, Dirtab*, int, Devgen*);
void devstat(Chan*, char*, Dirtab*, int, Devgen*);
int devwalk(Chan*, char*, Dirtab*, int, Devgen*);
+void duartstarttimer(void);
+void duartstoptimer(void);
void dumpregs(Ureg*);
void dumpstack(void);
int eqchan(Chan*, Chan*, long);
@@ 62,6 64,7 @@ void kbdchar(int);
void kbdrepeat(int);
void kbdclock(void);
void kproc(char*, void(*)(void*), void*);
+void kproftimer(ulong);
void lock(Lock*);
void lockinit(void);
Orig *lookorig(ulong, ulong, int, Chan*);
M gnot/screen.c => gnot/screen.c +40 -1
@@ 4,6 4,7 @@
#include "dat.h"
#include "fns.h"
#include "io.h"
+#include "ureg.h"
#include "gnot.h"
@@ 201,8 202,35 @@ duartinit(void)
duart[0].data = 0x02;
}
+enum{
+ Kptime=200 /* about once per ms */
+};
+void
+duartstarttimer(void)
+{
+ Duart *duart;
+ char x;
+
+ duart = DUARTREG;
+ duart[0].ctur = (Kptime)>>8;
+ duart[0].ctlr = (Kptime)&255;
+ duart[0].is_imr = IM_IPC|IM_RRDYB|IM_XRDYB|IM_RRDYA|IM_CRDY;
+ x = duart[1].scc_sopbc;
+}
+
+void
+duartstoptimer(void)
+{
+ Duart *duart;
+ char x;
+
+ duart = DUARTREG;
+ x = duart[1].scc_ropbc;
+ duart[0].is_imr = IM_IPC|IM_RRDYB|IM_XRDYB|IM_RRDYA;
+}
+
void
-duartintr(void)
+duartintr(Ureg *ur)
{
int cause, status, c;
Duart *duart;
@@ 213,6 241,17 @@ duartintr(void)
* I can guess your interrupt.
*/
/*
+ * Is it 0?
+ */
+ if(cause & IM_CRDY){
+ kproftimer(ur->pc);
+ c = duart[1].scc_ropbc;
+ duart[0].ctur = (Kptime)>>8;
+ duart[0].ctlr = (Kptime)&255;
+ c = duart[1].scc_sopbc;
+ return;
+ }
+ /*
* Is it 1?
*/
if(cause & IM_RRDYA){ /* keyboard input */
M gnot/stream.c => gnot/stream.c +1 -2
@@ 627,7 627,6 @@ streamnew(Chan *c, Qinfo *qi)
if(qi->open)
(*qi->open)(RD(s->devq), s);
- c->flag |= COPEN;
unlock(s);
poperror();
return s;
@@ 681,7 680,7 @@ streamclose(Chan *c)
/*
* if not open, ignore it
*/
- if(!(c->flag & COPEN))
+ if(!c->stream)
return;
/*
M gnot/sysfile.c => gnot/sysfile.c +1 -5
@@ 126,7 126,7 @@ unionread(Chan *c, void *va, long n)
mnt = c->mnt;
lock(pg);
if(c->mountid != mnt->mountid){
- print("unionread: changed underfoot?\n");
+ pprint("unionread: changed underfoot?\n");
unlock(pg);
return 0;
}
@@ 406,10 406,6 @@ syspipe(ulong *arg)
c[1] = (*d->clone)(c[0], 0);
c[0] = (*d->open)(c[0], ORDWR);
c[1] = (*d->open)(c[1], ORDWR);
- c[0]->mode = 2;
- c[1]->mode = 2;
- c[0]->flag |= COPEN;
- c[1]->flag |= COPEN;
fd[0] = newfd();
u->fd[fd[0]] = c[0];
fd[1] = newfd();
M port/devbit.c => port/devbit.c +10 -7
@@ 199,18 199,19 @@ bitread(Chan *c, void *va, long n)
/*
* init:
* 'I' 1
- * ldepth 2
+ * ldepth 1
* rectangle 16
*/
- if(n < 19)
+ if(n < 18)
error(0, Ebadblt);
p[0] = 'I';
- PSHORT(p+1, screen.ldepth);
- PLONG(p+3, screen.r.min.x);
- PLONG(p+7, screen.r.min.y);
- PLONG(p+11, screen.r.max.x);
- PLONG(p+15, screen.r.max.y);
+ p[1] = screen.ldepth;
+ PLONG(p+2, screen.r.min.x);
+ PLONG(p+6, screen.r.min.y);
+ PLONG(p+10, screen.r.max.x);
+ PLONG(p+14, screen.r.max.y);
bit.init = 0;
+ n = 18;
goto done;
}
if(bit.lastid > 0){
@@ 450,6 451,8 @@ bitwrite(Chan *c, void *va, long n)
error(0, Ebadbitmap);
miny = GLONG(p+3);
maxy = GLONG(p+7);
+ if(miny>maxy || miny<dst->r.min.y || maxy>dst->r.max.y)
+ error(0, Ebadblt);
ws = 1<<(3-dst->ldepth); /* pixels per byte */
/* set l to number of bytes of incoming data per scan line */
if(dst->r.min.x >= 0)
A port/devkprof.c => port/devkprof.c +166 -0
@@ 0,0 1,166 @@
+#include "u.h"
+#include "lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "errno.h"
+
+#include "devtab.h"
+
+#define MAXPC (100*1024L)
+#define RES 8
+#define LRES 3
+#define NBUF (MAXPC>>LRES)
+
+long timerbuf[NBUF];
+
+enum{
+ Kprofdirqid,
+ Kprofdataqid,
+ Kprofstartqid,
+ Kprofstartclrqid,
+ Kprofstopqid,
+ Nkproftab=Kprofstopqid,
+ Kprofmaxqid,
+};
+Dirtab kproftab[Nkproftab]={
+ "kpdata", Kprofdataqid, NBUF*sizeof timerbuf[0], 0600,
+ "kpstart", Kprofstartqid, 0, 0600,
+ "kpstartclr", Kprofstartclrqid, 0, 0600,
+ "kpstop", Kprofstopqid, 0, 0600,
+};
+
+void
+kprofreset(void)
+{
+}
+
+void
+kprofinit(void)
+{
+ extern void *etext;
+ if((((unsigned long)&etext)-KTZERO)>MAXPC)
+ print("kernel profiling limited to %lud\n", MAXPC);
+}
+
+Chan *
+kprofattach(char *spec)
+{
+ return devattach('t', spec);
+}
+Chan *
+kprofclone(Chan *c, Chan *nc)
+{
+ return devclone(c, nc);
+}
+
+int
+kprofwalk(Chan *c, char *name)
+{
+ return devwalk(c, name, kproftab, (long)Nkproftab, devgen);
+}
+
+void
+kprofstat(Chan *c, char *db)
+{
+ devstat(c, db, kproftab, (long)Nkproftab, devgen);
+}
+
+Chan *
+kprofopen(Chan *c, int omode)
+{
+ if(c->qid == CHDIR){
+ if(omode != OREAD)
+ error(0, Eperm);
+ }
+ c->mode = openmode(omode);
+ c->flag |= COPEN;
+ c->offset = 0;
+ return c;
+}
+
+void
+kprofcreate(Chan *c, char *name, int omode, ulong perm)
+{
+ error(0, Eperm);
+}
+
+void
+kprofremove(Chan *c)
+{
+ error(0, Eperm);
+}
+
+void
+kprofwstat(Chan *c, char *dp)
+{
+ error(0, Eperm);
+}
+
+void
+kprofclose(Chan *c)
+{
+}
+
+void
+kprofuserstr(Error *e, char *buf)
+{
+ consuserstr(e, buf);
+}
+
+void
+kproferrstr(Error *e, char *buf)
+{
+ rooterrstr(e, buf);
+}
+
+long
+kprofread(Chan *c, void *a, long n)
+{
+ switch((int)(c->qid&~CHDIR)){
+ case Kprofdirqid:
+ return devdirread(c, a, n, kproftab, Nkproftab, devgen);
+ case Kprofdataqid:
+ if(c->offset >= NBUF*sizeof timerbuf[0]){
+ n = 0;
+ break;
+ }
+ if(c->offset+n > NBUF*sizeof timerbuf[0])
+ n = NBUF*sizeof timerbuf[0]-c->offset;
+ memcpy(a, ((char *)timerbuf)+c->offset, n);
+ break;
+ default:
+ n=0;
+ break;
+ }
+ return n;
+}
+
+long
+kprofwrite(Chan *c, char *a, long n)
+{
+ switch((int)(c->qid&~CHDIR)){
+ case Kprofstartclrqid:
+ memset((char *)timerbuf, 0, NBUF*sizeof timerbuf[0]);
+ case Kprofstartqid:
+ duartstarttimer();
+ break;
+ case Kprofstopqid:
+ duartstoptimer();
+ break;
+ default:
+ error(0, Ebadusefd);
+ }
+ return n;
+}
+
+void
+kproftimer(ulong pc)
+{
+ timerbuf[0]++;
+ if(KTZERO<=pc && pc<KTZERO+MAXPC){
+ pc -= KTZERO;
+ pc >>= LRES;
+ timerbuf[pc]++;
+ }
+}
M port/proc.c => port/proc.c +1 -6
@@ 518,7 518,7 @@ proctab(int i)
#include <ureg.h>
DEBUG()
{
- int i, j;
+ int i;
Proc *p;
Orig *o;
@@ 529,11 529,6 @@ DEBUG()
print("%d:%s upc %lux %s ut %ld st %ld\n",
p->pid, p->text, p->pc, statename[p->state],
p->time[0], p->time[1]);
- for(j=0; j<NSEG; j++){
- o = p->seg[j].o;
- if(o)
- print(" s%d %d %d\n", j, o->nmod, o->npte);
- }
}
}
}
M port/stream.c => port/stream.c +5 -7
@@ 51,7 51,7 @@ static Lock garbagelock;
typedef struct {
int size;
Blist;
- QLock q; /* qlock for sleepers on r */
+ QLock; /* qlock for sleepers on r */
Rendez r; /* sleep here waiting for blocks */
} Bclass;
Bclass bclass[Nclass]={
@@ 123,12 123,11 @@ allocb(ulong size)
lock(bcp);
while(bcp->first == 0){
unlock(bcp);
- print("waiting for block %d\n", size);
if(loop++ > 10)
- panic("waiting for blocks");
- qlock(&bcp->q);
+ panic("waiting for blocks\n");
+ qlock(bcp);
tsleep(&bcp->r, isblock, (void *)bcp, 250);
- qunlock(&bcp->q);
+ qunlock(bcp);
lock(bcp);
}
bp = bcp->first;
@@ 628,7 627,6 @@ streamnew(Chan *c, Qinfo *qi)
if(qi->open)
(*qi->open)(RD(s->devq), s);
- c->flag |= COPEN;
unlock(s);
poperror();
return s;
@@ 682,7 680,7 @@ streamclose(Chan *c)
/*
* if not open, ignore it
*/
- if(!(c->flag & COPEN))
+ if(!c->stream)
return;
/*
M port/sysfile.c => port/sysfile.c +0 -4
@@ 406,10 406,6 @@ syspipe(ulong *arg)
c[1] = (*d->clone)(c[0], 0);
c[0] = (*d->open)(c[0], ORDWR);
c[1] = (*d->open)(c[1], ORDWR);
- c[0]->mode = 2;
- c[1]->mode = 2;
- c[0]->flag |= COPEN;
- c[1]->flag |= COPEN;
fd[0] = newfd();
u->fd[fd[0]] = c[0];
fd[1] = newfd();
M port/sysproc.c => port/sysproc.c +1 -1
@@ 6,7 6,7 @@
#include "ureg.h"
#include "errno.h"
-#include <v.out.h>
+#include <a.out.h>
int shargs(char*, int, char**);