| plan 9 kernel history: overview | file list | diff list |
1990/11211/power/devhotrod.c (diff list | history)
| power/devhotrod.c on 1990/1013 | ||
| 1990/1013 | #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; | |
| 1990/1106 | typedef struct Printbuf Printbuf; | |
| 1990/1013 | enum { Vmevec= 0xd2, /* vme vector for interrupts */ Intlevel= 5, /* level to interrupt on */ | |
| 1990/1018 | Nhotrod= 2, | |
| 1990/1013 | }; /* | |
| 1990/1106 | * circular 2 pointer queue for hotrod prnt's */ struct Printbuf { char *rptr; char *wptr; char *lim; char buf[4*1024]; }; /* | |
| 1990/1013 | * 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 { | |
| 1990/1018 | ulong mem[1024*1024/sizeof(ulong)]; | |
| 1990/1013 | }; | |
| 1990/1018 | #define HOTROD VMEA24SUP(Device, 0xB00000) | |
| 1990/1013 | struct Hotrod { QLock; | |
| 1990/1106 | Device *addr; /* address of the device */ int vec; /* vme interrupt vector */ char name[NAMELEN]; /* hot rod name */ Printbuf pbuf; /* circular queue for hotrod print's */ int kprocstarted; Rendez r; | |
| 1990/1013 | }; Hotrod hotrod[Nhotrod]; | |
| 1990/1106 | void hotrodintr(int); void hotrodkproc(void *a); | |
| 1990/1013 | int hotrodgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) { if(i || c->dev>=Nhotrod) return -1; | |
| 1990/11211 | devdir(c, (Qid){0,0}, hotrod[c->dev].name, sizeof(Device), 0666, dp); | |
| 1990/1013 | return 1; } /* * reset all hotrod boards */ void hotrodreset(void) { int i; | |
| 1990/1018 | Hotrod *hp; | |
| 1990/1013 | 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) { | |
| 1990/1106 | Hotrod *hp; | |
| 1990/1013 | int i; Chan *c; i = strtoul(spec, 0, 0); if(i >= Nhotrod) | |
| 1990/11211 | error(Ebadarg); | |
| 1990/1013 | ||
| 1990/1106 | hp = &hotrod[i]; if(hp->kprocstarted == 0) kproc(hp->name, hotrodkproc, hp); | |
| 1990/1013 | c = devattach('H', spec); c->dev = i; | |
| 1990/11211 | c->qid.path = CHDIR; c->qid.vers = 0; | |
| 1990/1013 | 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) { | |
| 1990/1106 | Device *dp; Hotrod *hp; | |
| 1990/1110 | #ifdef asdf | |
| 1990/1106 | /* * Remind hotrod where the print buffer is. The address we store * is the address of the printbuf in VME A32 space. */ hp = &hotrod[c->dev]; dp = hp->addr; dp->mem[256*1024/sizeof(ulong)] = (((ulong)&hp->pbuf) - KZERO) | (SLAVE<<28); | |
| 1990/1110 | #endif | |
| 1990/1106 | ||
| 1990/11211 | if(c->qid.path == CHDIR){ | |
| 1990/1013 | if(omode != OREAD) | |
| 1990/11211 | error(Eperm); | |
| 1990/1018 | } | |
| 1990/1013 | c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; return c; } void hotrodcreate(Chan *c, char *name, int omode, ulong perm) { | |
| 1990/11211 | error(Eperm); | |
| 1990/1013 | } void hotrodclose(Chan *c) { } /* * read the hotrod memory */ long hotrodread(Chan *c, void *buf, long n) { Hotrod *hp; Device *dp; | |
| 1990/1018 | ulong *from; ulong *to; ulong *end; | |
| 1990/1013 | ||
| 1990/11211 | if(c->qid.path & CHDIR) | |
| 1990/1018 | return devdirread(c, buf, n, 0, 0, hotrodgen); /* * allow full word access only */ if((c->offset&(sizeof(ulong)-1)) || (n&(sizeof(ulong)-1))) | |
| 1990/11211 | error(Ebadarg); | |
| 1990/1018 | ||
| 1990/1013 | 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; | |
| 1990/1018 | /* * avoid memcpy to ensure VME 32-bit reads */ | |
| 1990/1013 | qlock(hp); | |
| 1990/1018 | to = buf; from = &dp->mem[c->offset/sizeof(ulong)]; end = to + (n/sizeof(ulong)); | |
| 1990/1020 | while(to != end){ | |
| 1990/1018 | *to++ = *from++; | |
| 1990/1020 | } | |
| 1990/1013 | qunlock(hp); return n; } /* * write hotrod memory */ long hotrodwrite(Chan *c, void *buf, long n) { Hotrod *hp; Device *dp; | |
| 1990/1018 | ulong *from; ulong *to; ulong *end; | |
| 1990/1013 | ||
| 1990/1018 | /* * allow full word access only */ if((c->offset&(sizeof(ulong)-1)) || (n&(sizeof(ulong)-1))) | |
| 1990/11211 | error(Ebadarg); | |
| 1990/1018 | ||
| 1990/1013 | 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; | |
| 1990/1018 | /* * avoid memcpy to ensure VME 32-bit writes */ | |
| 1990/1013 | qlock(hp); | |
| 1990/1018 | from = buf; to = &dp->mem[c->offset/sizeof(ulong)]; end = to + (n/sizeof(ulong)); while(to != end) *to++ = *from++; | |
| 1990/1013 | qunlock(hp); return n; } void hotrodremove(Chan *c) { | |
| 1990/11211 | error(Eperm); | |
| 1990/1013 | } void hotrodwstat(Chan *c, char *dp) { | |
| 1990/11211 | error(Eperm); | |
| 1990/1013 | } | |
| 1990/1106 | void | |
| 1990/1013 | 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; | |
| 1990/1106 | } } /* * print hotrod processor messages on the console */ void hotrodkproc(void *a) { Hotrod *hp = a; char *p; hp->kprocstarted = 1; hp->pbuf.rptr = hp->pbuf.wptr = hp->pbuf.buf; hp->pbuf.lim = &hp->pbuf.buf[sizeof(hp->pbuf.buf)]; for(;;){ p = hp->pbuf.wptr; if(p != hp->pbuf.rptr){ if(p > hp->pbuf.rptr){ putstrn(hp->pbuf.rptr, p - hp->pbuf.rptr); } else { putstrn(hp->pbuf.rptr, hp->pbuf.lim - hp->pbuf.rptr); putstrn(hp->pbuf.buf, hp->pbuf.wptr - hp->pbuf.buf); } hp->pbuf.rptr = p; } tsleep(&(hp->r), return0, 0, 1000); | |
| 1990/1013 | } } | |