M gnot/devpipe.c => gnot/devpipe.c +4 -2
@@ 75,7 75,8 @@ pipeattach(char *spec)
}
p = pipealloc.free;
pipealloc.free = p->next;
- p->ref = 1;
+ if(incref(p) != 1)
+ panic("pipeattach");
unlock(&pipealloc);
c->qid = CHDIR|STREAMQID(2*(p - pipealloc.pipe), 0);
@@ 89,7 90,8 @@ pipeclone(Chan *c, Chan *nc)
p = &pipealloc.pipe[STREAMID(c->qid)/2];
nc = devclone(c, nc);
- incref(p);
+ if(incref(p) <= 1)
+ panic("pipeclone");
return nc;
}
M port/devpipe.c => port/devpipe.c +4 -2
@@ 75,7 75,8 @@ pipeattach(char *spec)
}
p = pipealloc.free;
pipealloc.free = p->next;
- p->ref = 1;
+ if(incref(p) != 1)
+ panic("pipeattach");
unlock(&pipealloc);
c->qid = CHDIR|STREAMQID(2*(p - pipealloc.pipe), 0);
@@ 89,7 90,8 @@ pipeclone(Chan *c, Chan *nc)
p = &pipealloc.pipe[STREAMID(c->qid)/2];
nc = devclone(c, nc);
- incref(p);
+ if(incref(p) <= 1)
+ panic("pipeclone");
return nc;
}
M port/fault.c => port/fault.c +1 -1
@@ 142,7 142,7 @@ fault(Ureg *ur, int user, int code)
/*
* Add to mod list
*/
- pte = newmod();
+ pte = newmod(o);
o->nmod++;
pte->proc = u->p;
pte->page = opte->page;
M port/page.c => port/page.c +3 -3
@@ 382,7 382,7 @@ o->nmod = 0;
}
PTE*
-newmod(void)
+newmod(Orig *o)
{
PTEA *pte;
@@ 397,7 397,7 @@ loop:
unlock(&modalloc);
print("no mods\n");
DEBUG();
-panic("mods");
+panic("mods %lux %d %d", o->va, o->npte, o->nmod);
if(u == 0)
panic("newmod");
u->p->state = Wakeme;
@@ 423,7 423,7 @@ forkmod(Seg *old, Seg *new, Proc *p)
while(pte){
if(pte->page==0) panic("forkmod zero page");
if(pte->proc != u->p) panic("forkmod wrong page");
- npte = newmod();
+ npte = newmod(o);
o->nmod++;
npte->proc = p;
npte->page = pte->page;
A power/devhotrod.c => power/devhotrod.c +214 -0
@@ 0,0 1,214 @@
+#include "u.h"
+#include "lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "errno.h"
+#include "devtab.h"
+
+#include "io.h"
+
+typedef struct Hotrod Hotrod;
+typedef struct Device Device;
+
+enum {
+ Vmevec= 0xd2, /* vme vector for interrupts */
+ Intlevel= 5, /* level to interrupt on */
+ Nhotrod= 1,
+};
+
+/*
+ * the hotrod fiber interface responds to 1MB
+ * of either user or supervisor accesses at:
+ * 0x30000000 to 0x300FFFFF in A32 space
+ * and 0xB00000 to 0xBFFFFF in A24 space
+ */
+struct Device {
+ uchar mem[1*1024*1024];
+};
+#define HOTROD VMEA32SUP(Device, 0x30000000)
+
+struct Hotrod {
+ QLock;
+
+ Device *addr;
+ int vec;
+ char name[NAMELEN];
+};
+
+Hotrod hotrod[Nhotrod];
+
+static void hotrodintr(int);
+
+int
+hotrodgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp)
+{
+ if(i || c->dev>=Nhotrod)
+ return -1;
+ devdir(c, 0, hotrod[c->dev].name, sizeof(Device), 0666, dp);
+ return 1;
+}
+
+/*
+ * reset all hotrod boards
+ */
+void
+hotrodreset(void)
+{
+ int i;
+ Hsvme *hp;
+
+ for(i=0; i<Nhotrod; i++){
+ hotrod[i].addr = HOTROD+i;
+ hotrod[i].vec = Vmevec+i;
+ sprint(hotrod[i].name, "hotrod%d", i);
+ setvmevec(hotrod[i].vec, hotrodintr);
+ }
+ wbflush();
+ delay(20);
+}
+
+void
+hotrodinit(void)
+{
+}
+
+/*
+ * enable the device for interrupts, spec is the device number
+ */
+Chan*
+hotrodattach(char *spec)
+{
+ int i;
+ Chan *c;
+
+ i = strtoul(spec, 0, 0);
+ if(i >= Nhotrod)
+ error(0, Ebadarg);
+
+ c = devattach('H', spec);
+ c->dev = i;
+ c->qid = CHDIR;
+ return c;
+}
+
+Chan*
+hotrodclone(Chan *c, Chan *nc)
+{
+ return devclone(c, nc);
+}
+
+int
+hotrodwalk(Chan *c, char *name)
+{
+ return devwalk(c, name, 0, 0, hotrodgen);
+}
+
+void
+hotrodstat(Chan *c, char *dp)
+{
+ devstat(c, dp, 0, 0, hotrodgen);
+}
+
+Chan*
+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;
+ return c;
+}
+
+void
+hotrodcreate(Chan *c, char *name, int omode, ulong perm)
+{
+ error(0, Eperm);
+}
+
+void
+hotrodclose(Chan *c)
+{
+}
+
+/*
+ * read the hotrod memory
+ */
+long
+hotrodread(Chan *c, void *buf, long n)
+{
+ Hotrod *hp;
+ Device *dp;
+
+ hp = &hotrod[c->dev];
+ dp = hp->addr;
+ if(c->offset >= sizeof(dp->mem))
+ return 0;
+ if(c->offset+n > sizeof(dp->mem))
+ n = sizeof(dp->mem) - c->offset;
+ qlock(hp);
+ memcpy(buf, &dp->mem[c->offset], n);
+ qunlock(hp);
+ return n;
+}
+
+/*
+ * write hotrod memory
+ */
+long
+hotrodwrite(Chan *c, void *buf, long n)
+{
+ Hotrod *hp;
+ Device *dp;
+
+ hp = &hotrod[c->dev];
+ dp = hp->addr;
+ if(c->offset >= sizeof(dp->mem))
+ return 0;
+ if(c->offset+n > sizeof(dp->mem))
+ n = sizeof(dp->mem) - c->offset;
+ qlock(hp);
+ memcpy(&dp->mem[c->offset], buf, n);
+ qunlock(hp);
+ return n;
+}
+
+void
+hotrodremove(Chan *c)
+{
+ error(0, Eperm);
+}
+
+void
+hotrodwstat(Chan *c, char *dp)
+{
+ error(0, Eperm);
+}
+
+void
+hotroduserstr(Error *e, char *buf)
+{
+ consuserstr(e, buf);
+}
+
+void
+hotroderrstr(Error *e, char *buf)
+{
+ rooterrstr(e, buf);
+}
+
+hotrodintr(int vec)
+{
+ Hotrod *hp;
+
+ print("hotrod%d interrupt\n", vec - Vmevec);
+ hp = &hotrod[vec - Vmevec];
+ if(hp < hotrod || hp > &hotrod[Nhotrod]){
+ print("bad hotrod vec\n");
+ return;
+ }
+}
M power/fns.h => power/fns.h +1 -1
@@ 100,7 100,7 @@ Chan *namec(char*, int, int, ulong);
void nexterror(void);
Alarm *newalarm(void);
Chan *newchan(void);
-PTE *newmod(void);
+PTE *newmod(Orig*);
Mount *newmount(void);
Orig *neworig(ulong, ulong, int, Chan*);
Page *newpage(int, Orig*, ulong);
M power/io.h => power/io.h +1 -0
@@ 1,6 1,7 @@
#define UNCACHED 0xA0000000
#define IO2(t,x) ((t *)(UNCACHED|0x17000000|(x)))
#define VMEA24SUP(t, x) ((t *)(UNCACHED|0x13000000|(x)))
+#define VMEA32SUP(t, x) ((t *)(UNCACHED|0x30000000|(x)))
#define SYNCBUS(t,x) ((t *)(UNCACHED|0x1E000000|(x)))
#define SBSEM SYNCBUS(ulong, 0)
#define SBSEMTOP SYNCBUS(ulong, 0x400000)
M power/main.c => power/main.c +1 -1
@@ 590,7 590,7 @@ confinit(void)
* set minimal default values
*/
conf.nmach = 2;
- conf.nmod = 2000;
+ conf.nmod = 10000;
conf.nalarm = 10000;
conf.norig = 500;
conf.nchan = 1000;