From 8c434f55d5ae88abd4ad1303c86bc013b574a1be Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 12 Jun 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-06-12 --- port/malloc.c | 466 ++++++---------------------------------------- power/devhotrod.c | 7 +- power/devhs.c | 248 ++++++++++++------------ power/io.h | 16 ++ power/trap.c | 2 +- 5 files changed, 206 insertions(+), 533 deletions(-) diff --git a/port/malloc.c b/port/malloc.c index 71b0bd9f9a2502616df5324262904257b7ff33fb..d8783b5900e6dff99e39a25734616bd888794c01 100644 --- a/port/malloc.c +++ b/port/malloc.c @@ -1,430 +1,86 @@ -/* compile-time features - IALLOC use all blocks given to ifree, otherwise ignore unordered blocks - MSTATS enable statistics - debug enable assertion checking - longdebug full arena checks at every transaction -*/ -#include "u.h" -#include "lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" +#include +#include -#define INT int -#define ALIGN int -#define NALIGN 1 -#define WORD sizeof(union store) -#define BLOCK 4096 -#define BUSY 1 -#define NULL 0 -#define testbusy(p) ((INT)(p)&BUSY) -#define setbusy(p) (union store *)((INT)(p)|BUSY) -#define clearbusy(p) (union store *)((INT)(p)&~BUSY) -#define IALLOC - -typedef -union store +enum { - union store *ptr; - ALIGN dummy[NALIGN]; - int calloc; /*calloc clears an array of integers*/ -} Store; - -static int draincache(void); -static void* stdmalloc(long); -static int stdfree(Store*); -static void ifree(char*, long); + MAGIC = 0xDEADBABE, + MAX2SIZE = 20 +}; -#ifdef longdebug -#define debug 1 -#endif -#ifdef debug -#define ASSERT(p) if(!(p))botch("p");else -static -botch(char *s) +typedef struct Bucket Bucket; +struct Bucket { - char *c; - - c = "assertion botched: "; - write(2, c, strlen(c)); - write(2, s, strlen(s)); - write(2, "\n", 1); - abort(); -} -static int allock(Store*); -#else -#define ASSERT(p) -#endif - -/* C storage allocator - * circular first-fit strategy - * works with noncontiguous, but monotonically linked, arena - * each block is preceded by a ptr to the (pointer of) - * the next following block - * blocks are exact number of words long - * aligned to the data type requirements of ALIGN - * pointers to blocks must have BUSY bit 0 - * bit in ptr is 1 for busy, 0 for idle - * gaps in arena are merely noted as busy blocks - * last block of arena is empty and - * has a pointer to first - * idle blocks are coalesced during space search - * - * a different implementation may need to redefine - * ALIGN, NALIGN, BLOCK, BUSY, INT - * where INT is integer type to which a pointer can be cast - */ - - -/* alloca should have type union store. - * The funny business gets it initialized without complaint - */ -#define addr(a) (Store*)&a -static char *alloca; -static char *alloca = (char*)&alloca + BUSY; /* initial arena */ -static Store *allocs = addr(alloca); /*arena base*/ -static Store *allocc = addr(alloca); /*all prev blocks known busy*/ -static Store *allocp = addr(alloca); /*search ptr*/ -static Store *alloct = addr(alloca); /*top cell*/ -static Store *allocx; /*for benefit of realloc*/ - -/* a cache list of frequently-used sizes is maintained. From each - * cache entry hangs a chain of available blocks - * malloc(0) shuts off caching (to keep freed data clean) - */ - -#define CACHEMAX 256 /* largest block to be cached (in words) */ -#define CACHESIZ 53 /* number of entries (prime) */ - -static Store *cache[CACHESIZ]; -static int cachemax = CACHEMAX; - -#ifdef MSTATS -#define Mstats(e) e -static long nmalloc, nrealloc, nfree; /* call statistics */ -static long walloc, wfree; /* space statistics */ -static long chit, ccoll, cdrain, cavail; /* cache statistics */ -#else -#define Mstats(e) -#endif + int size; + int magic; + Bucket *next; + char data[1]; +}; + +typedef struct Arena Arena; +struct Arena +{ + Lock; + Bucket *btab[MAX2SIZE]; +}; -static QLock mlock; +static Arena arena; +#define datoff ((int)&((Bucket*)0)->data) void* -malloc(ulong nbytes) +malloc(uint size) { - Store *p; - long nw; - Store **cp; - void *mem; + int pow; + Bucket *bp; - nw = (nbytes+WORD+WORD-1)/WORD; - qlock(&mlock); - Mstats((nmalloc++, walloc += nw)); - if(nw= 2) { - cp = &cache[nw%CACHESIZ]; - p = *cp; - if(p && nw == clearbusy(p->ptr)-p) { - ASSERT(testbusy(p->ptr)); - *cp = (++p)->ptr; - Mstats((chit++, cavail--)); - qunlock(&mlock); - return (char*)p; - } - } else { - draincache(); - cachemax = 0; - } + for(pow = 1; pow < MAX2SIZE; pow++) { + if(size <= (1<ptr)) { - allocp = p; - while(!testbusy((q=p->ptr)->ptr)) { - ASSERT(q>p); - p->ptr = q->ptr; - } - if(q>=p+nw && p+nw>=p) - goto found; - } - q = p; - p = clearbusy(p->ptr); - if(p <= q) { - ASSERT(p == allocs && q == alloct); - if(++temp>1) - break; - ASSERT(allock(allocc)); - p = allocc; - } - } + return nil; +good: + /* Allocate off this list */ + lock(&arena); + bp = arena.btab[pow]; + if(bp) { + arena.btab[pow] = bp->next; + arena.unlock(); - /* No memory in the free list. Call newpage and kmap to get - * some more, and ifree to put it in the list. - */ - page = newpage(1, 0, 0); - page->va = VA(kmap(page)); - draincache(); - ifree((char *) page->va, 1 << PGSHIFT); - } -found: - allocp += nw; - if(q>allocp) { - allocx = allocp->ptr; - allocp->ptr = p->ptr; - } - p->ptr = setbusy(allocp); - if(p<=allocc) { - ASSERT(p==allocc); - while(testbusy(allocc->ptr) - && (q=clearbusy(allocc->ptr))>allocc) - allocc = q; - } - return(p+1); -} + if(bp->magic != 0) + abort(); -void -free(void *ap) -{ - Store *p = ap, *q; - long nw; - Store **cp; + bp->magic = MAGIC; - if(p==NULL) - return; - --p; - qlock(&mlock); - ASSERT(allock(p)); - ASSERT(testbusy(p->ptr)); - ASSERT(!cached(p)); - nw = clearbusy(p->ptr) - p; - Mstats((nfree++, wfree += nw)); - ASSERT(nw>0); - if(nw=2) { - cp = &cache[nw%CACHESIZ]; - q = *cp; - if(!q || nw==clearbusy(q->ptr)-q) { - p[1].ptr = q; - *cp = p; - Mstats(cavail++); - qunlock(&mlock); - return; - } else Mstats(q && ccoll++); + memset(bp->data, 0, size); + return bp->data; } - stdfree(p+1); - qunlock(&mlock); -} - -/* freeing strategy tuned for LIFO allocation -*/ -static -stdfree(Store *p) -{ - allocp = --p; - if(p < allocc) - allocc = p; - ASSERT(allock(allocp)); - p->ptr = clearbusy(p->ptr); - ASSERT(p->ptr > allocp); -} + unlock(&arena); + size = sizeof(Bucket)+(1<size = pow; + bp->magic = MAGIC; - while(--cp>=cache) { - while(q = *cp) { - ASSERT(testbusy(q->ptr)); - ASSERT((clearbusy(q->ptr)-q)%CACHESIZ==cp-cache); - ASSERT(q>=allocs&&q<=alloct); - stdfree(++q); - anyfreed++; - *cp = q->ptr; - } - } - Mstats((cdrain+=anyfreed, cavail=0)); - return anyfreed; + return bp->data; } -/* ifree(q, nbytes) inserts a block that did not come - * from malloc into the arena - * - * q points to new block - * r points to last of new block - * p points to last cell of arena before new block - * s points to first cell of arena after new block -*/ - -static void -ifree(char *qq, long nbytes) -{ - Store *p, *q, *r, *s; - - q = (Store *)qq; - r = q + (nbytes/WORD) - 1; - q->ptr = r; - if(q > alloct) { - p = alloct; - s = allocs; - alloct = r; - } else { -#ifdef IALLOC - /* useful only in small address spaces */ - for(p=allocs; ; p=s) { - s = clearbusy(p->ptr); - if(s==allocs) - break; - ASSERT(s>p); - if(s>r) { - if(pr); - } - } - if(allocs > q) - allocs = q; - if(allocc > q) - allocc = q; - allocp = allocc; -#else - return; -#endif - } - p->ptr = q==p+1? q: setbusy(q); - r->ptr = s==r+1? s: setbusy(s); - while(testbusy(allocc->ptr)) - allocc = clearbusy(allocc->ptr); -} - -/* realloc(p, nbytes) reallocates a block obtained from malloc() - * and freed since last call of malloc() - * to have new size nbytes, and old content - * returns new location, or 0 on failure -*/ - -void* -realloc(void *pp, ulong nbytes) -{ - Store *p = pp; - Store *s, *t; - Store *q; - long nw, onw; - - if(p==NULL) - return malloc(nbytes); - qlock(&mlock); - Mstats(nrealloc++); - ASSERT(allock(p-1)); - if(testbusy(p[-1].ptr)) - stdfree(p); - onw = p[-1].ptr - p; - nw = (nbytes+WORD-1)/WORD; - q = (Store *)stdmalloc(nw+1); - if(q!=NULL && q!=p) { - ASSERT(qp[-1].ptr); - if(nw=p) - (q+(q+nw-p))->ptr = allocx; - ASSERT(allock(q-1)); - } - qunlock(&mlock); - return q; -} - -#ifdef debug -static -allock(Store *q) -{ -#ifdef longdebug - register Store *p, *r; - register Store **cp; - int x, y; - for(cp=cache+CACHESIZ; --cp>=cache; ) { - if((p= *cp)==0) - continue; - x = clearbusy(p->ptr) - p; - ASSERT(x%CACHESIZ==cp-cache); - for( ; p; p = p[1].ptr) { - ASSERT(testbusy(p->ptr)); - ASSERT(clearbusy(p->ptr)-p==x); - } - } - x = 0, y = 0; - p = allocs; - for( ; (r=clearbusy(p->ptr)) > p; p=r) { - if(p==allocc) - y++; - ASSERT(y||testbusy(p->ptr)); - if(p==q) - x++; - } - ASSERT(r==allocs); - ASSERT(x==1||p==q); - ASSERT(y||p==allocc); - return(1); -#else - ASSERT((unsigned)q/WORD*WORD==(unsigned)q); - ASSERT(q>=allocs&&q<=alloct); -#endif -} -#endif - -mstats(void) +free(void *ptr) { -#ifdef MSTATS - fprint(2, "Malloc statistics, including overhead bytes\n"); - fprint(2, "Arena: bottom %ld, top %ld\n", - (long)clearbusy(alloca), (long)alloct); - fprint(2, "Calls: malloc %ld, realloc %ld, free %ld\n", - nmalloc, nrealloc, nfree); - fprint(2, "Bytes: allocated or extended %ld, ", - walloc*WORD); - fprint(2, "freed or cut %ld\n", wfree*WORD); - fprint(2,"Cache: hits %ld, collisions %ld, discards %ld, avail %ld\n", - chit, ccoll, cdrain, cavail); -#endif -} + Bucket *bp, **l; -#ifdef debug -cached(Store *p) -{ - Store *q = cache[(clearbusy(p->ptr)-p)%CACHESIZ]; - for( ; q; q=q[1].ptr) - ASSERT(p!=q); - return 0; -} -#endif + /* Find the start of the structure */ + bp = (Bucket*)((uint)ptr - datoff); -void *calloc(ulong n, ulong size){ - void *p; + if(bp->magic != MAGIC) + panic("free"); - size = size*n; - p = malloc(size); - memset(p, 0, size); - return p; + bp->magic = 0; + lock(&arena); + l = &arena.btab[bp->size]; + bp->next = *l; + *l = bp; + unlock(&arena); } diff --git a/power/devhotrod.c b/power/devhotrod.c index 3fbe2f8647d9ab6a64aef85f8bcbf66bc7083e6f..725151084d39c165d7479a52b122bd37afb92c45 100644 --- a/power/devhotrod.c +++ b/power/devhotrod.c @@ -261,7 +261,7 @@ hotrodread(Chan *c, void *buf, long n, ulong offset) isflush = 1; } mp->param[2] = 0; /* reply checksum */ - mp->param[3] = 0; /* reply count */ + mp->param[3] = 0xDEADBEEF; /* reply count */ mp->cmd = Uread; mp->param[0] = MP2VME(buf); mp->param[1] = n; @@ -273,6 +273,7 @@ hotrodread(Chan *c, void *buf, long n, ulong offset) do m = mp->param[3]; while(m==0 && --l>0); + print("isflush blocked\n"); }else{ if(waserror()){ if(*hmp && *hmp==mp) @@ -284,7 +285,7 @@ hotrodread(Chan *c, void *buf, long n, ulong offset) m = mp->param[3]; } if(m==0 || m>n){ - print("devhotrod: count %ld %ld\n", m, n); + print("devhotrod: count 0x%lux 0x%lux\n", m, n); error(Egreg); } if(mp->param[2] != hotsum(buf, m, mp->param[2])){ @@ -424,6 +425,8 @@ hotrodintr(int vec) if(h->ri >= NRQ) h->ri = 0; hm->intr = 1; + if(hm->param[3]==0 || hm->param[3] > 10000) + print("hotrodintr count 0x%lux\n", hm->param[3]); if(!hm->abort) wakeup(&hm->r); } diff --git a/power/devhs.c b/power/devhs.c index 75442057ec762b59add00171af9d4ff39be2b1b3..37ed13e7022abdc90ccea5e8913cb19bc7d79b58 100644 --- a/power/devhs.c +++ b/power/devhs.c @@ -8,37 +8,53 @@ #include "io.h" -typedef struct Hsvme Hsvme; -typedef struct Device Device; +typedef struct Hs Hs; enum { Maxburst= 1023, /* maximum transmit burst size */ - Vmevec= 0xd0, /* vme vector for interrupts */ + Intvec= 0xd0, /* vme vector for interrupts */ Intlevel= 5, /* level to interrupt on */ - Nhsvme= 1, -}; + Nhs= 1, -#define NOW (MACHP(0)->ticks*MS2HZ) + /* + * csr flags + */ + ALIVE = 0x0001, + IENABLE = 0x0004, + EXOFLOW = 0x0008, + IRQ = 0x0010, + EMUTE = 0x0020, + EPARITY = 0x0040, + EFRAME = 0x0080, + EROFLOW = 0x0100, + REF = 0x0800, + XFF = 0x4000, + XHF = 0x8000, -/* - * hsvme datakit board - */ -struct Device { - ushort version; - ushort pad0x02; - ushort vector; - ushort pad0x06; - ushort csr; - ushort pad0x0A; - ushort data; + /* + * csr reset flags + */ + FORCEW = 0x0008, + NORESET = 0xFF00, + RESET = 0x0000, + + /* + * data flags + */ + CTL = 0x0100, + CHNO = 0x0200, + TXEOD = 0x0400, + NND = 0x8000, }; -#define HSVME VMEA24SUP(Device, 0xF90000) -struct Hsvme { +#define NOW (MACHP(0)->ticks*MS2HZ) +#define IPL(x) ((x)<<5) + +struct Hs { QLock; QLock xmit; - Device *addr; + HSdev *addr; int vec; /* interupt vector */ Rendez r; /* output process */ Rendez kr; /* input kernel process */ @@ -59,55 +75,30 @@ struct Hsvme { ulong out; /* bytes out */ }; -Hsvme hsvme[Nhsvme]; - -#define ALIVE 0x0001 -#define IENABLE 0x0004 -#define EXOFLOW 0x0008 -#define IRQ 0x0010 -#define EMUTE 0x0020 -#define EPARITY 0x0040 -#define EFRAME 0x0080 -#define EROFLOW 0x0100 -#define REF 0x0800 -#define XFF 0x4000 -#define XHF 0x8000 - -#define FORCEW 0x0008 -#define IPL(x) ((x)<<5) -#define NORESET 0xFF00 -#define RESET 0x0000 - -#define CTL 0x0100 -#define CHNO 0x0200 -#define TXEOD 0x0400 -#define NND 0x8000 +Hs hs[Nhs]; -static void hsvmeintr(int); -static void hsvmekproc(void*); +static void hsintr(int); +static void hskproc(void*); /* - * hsvme stream module definition + * hs stream module definition */ -static void hsvmeoput(Queue*, Block*); -static void hsvmestopen(Queue*, Stream*); -static void hsvmestclose(Queue*); -Qinfo hsvmeinfo = +static void hsoput(Queue*, Block*); +static void hsstopen(Queue*, Stream*); +static void hsstclose(Queue*); +Qinfo hsinfo = { nullput, - hsvmeoput, - hsvmestopen, - hsvmestclose, - "hsvme" + hsoput, + hsstopen, + hsstclose, + "hs" }; -/* - * restart a VME board - */ void -hsvmerestart(Hsvme *hp) +hsrestart(Hs *hp) { - Device *addr; + HSdev *addr; addr = hp->addr; @@ -117,7 +108,7 @@ hsvmerestart(Hsvme *hp) /* * set interrupt vector - * turn on addrice + * turn on device * set forcew to a known value * interrupt on level `Intlevel' */ @@ -135,23 +126,24 @@ hsvmerestart(Hsvme *hp) * reset all vme boards */ void -hsvmereset(void) +hsreset(void) { int i; - Hsvme *hp; - - for(i=0; icsr = RESET; - setvmevec(hsvme[i].vec, hsvmeintr); + Hs *hp; + + for(i=0; iaddr = HSDEV+i; + hp->vec = Intvec+i; + hp->addr->csr = RESET; + setvmevec(hp->vec, hsintr); } wbflush(); delay(20); } void -hsvmeinit(void) +hsinit(void) { } @@ -159,18 +151,18 @@ hsvmeinit(void) * enable the device for interrupts, spec is the device number */ Chan* -hsvmeattach(char *spec) +hsattach(char *spec) { - Hsvme *hp; + Hs *hp; int i; Chan *c; i = strtoul(spec, 0, 0); - if(i >= Nhsvme) + if(i >= Nhs) error(Ebadarg); - hp = &hsvme[i]; + hp = &hs[i]; if(!hp->started) - hsvmerestart(hp); + hsrestart(hp); c = devattach('h', spec); c->dev = i; @@ -179,31 +171,31 @@ hsvmeattach(char *spec) } Chan* -hsvmeclone(Chan *c, Chan *nc) +hsclone(Chan *c, Chan *nc) { return devclone(c, nc); } int -hsvmewalk(Chan *c, char *name) +hswalk(Chan *c, char *name) { return devwalk(c, name, 0, 0, streamgen); } void -hsvmestat(Chan *c, char *dp) +hsstat(Chan *c, char *dp) { devstat(c, dp, 0, 0, streamgen); } Chan* -hsvmeopen(Chan *c, int omode) +hsopen(Chan *c, int omode) { if(c->qid.path == CHDIR){ if(omode != OREAD) error(Eperm); }else - streamopen(c, &hsvmeinfo); + streamopen(c, &hsinfo); c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; @@ -211,40 +203,40 @@ hsvmeopen(Chan *c, int omode) } void -hsvmecreate(Chan *c, char *name, int omode, ulong perm) +hscreate(Chan *c, char *name, int omode, ulong perm) { USED(c); error(Eperm); } void -hsvmeclose(Chan *c) +hsclose(Chan *c) { if(c->qid.path != CHDIR) streamclose(c); } long -hsvmeread(Chan *c, void *buf, long n, ulong offset) +hsread(Chan *c, void *buf, long n, ulong offset) { return streamread(c, buf, n); } long -hsvmewrite(Chan *c, void *buf, long n, ulong offset) +hswrite(Chan *c, void *buf, long n, ulong offset) { return streamwrite(c, buf, n, 0); } void -hsvmeremove(Chan *c) +hsremove(Chan *c) { USED(c); error(Eperm); } void -hsvmewstat(Chan *c, char *dp) +hswstat(Chan *c, char *dp) { USED(c); error(Eperm); @@ -258,40 +250,45 @@ hsvmewstat(Chan *c, char *dp) * create the kernel process for input */ static void -hsvmestopen(Queue *q, Stream *s) +hsstopen(Queue *q, Stream *s) { - Hsvme *hp; + Hs *hp; char name[32]; - hp = &hsvme[s->dev]; - sprint(name, "hsvme%d", s->dev); + hp = &hs[s->dev]; + sprint(name, "hs%d", s->dev); q->ptr = q->other->ptr = hp; hp->rq = q; - kproc(name, hsvmekproc, hp); + kproc(name, hskproc, hp); } /* - * kill off the kernel process + * ask kproc to die and wait till it happens */ static int kdead(void *arg) { - Hsvme *hp; + Hs *hp; - hp = (Hsvme *)arg; + hp = (Hs *)arg; return hp->kstarted == 0; } static void -hsvmestclose(Queue * q) +hsstclose(Queue * q) { - Hsvme *hp; + Hs *hp; - hp = (Hsvme *)q->ptr; + hp = (Hs *)q->ptr; qlock(hp); hp->rq = 0; qunlock(hp); - wakeup(&hp->kr); - sleep(&hp->r, kdead, hp); + while(waserror()) + ; + while(hp->kstarted){ + wakeup(&hp->kr); + sleep(&hp->r, kdead, hp); + } + poperror(); } /* @@ -317,9 +314,9 @@ freemsg(Queue *q, Block *bp) static int halfempty(void *arg) { - Device *addr; + HSdev *addr; - addr = (Device*)arg; + addr = (HSdev*)arg; return addr->csr & XHF; } @@ -331,10 +328,10 @@ halfempty(void *arg) * character. */ void -hsvmeoput(Queue *q, Block *bp) +hsoput(Queue *q, Block *bp) { - Device *addr; - Hsvme *hp; + HSdev *addr; + Hs *hp; int burst; int chan; int ctl; @@ -354,12 +351,12 @@ hsvmeoput(Queue *q, Block *bp) /* * one transmitter at a time */ - hp = (Hsvme *)q->ptr; + hp = (Hs *)q->ptr; + qlock(&hp->xmit); if(waserror()){ qunlock(&hp->xmit); nexterror(); } - qlock(&hp->xmit); addr = hp->addr; /* @@ -369,6 +366,7 @@ hsvmeoput(Queue *q, Block *bp) if(bp->wptr - bp->rptr < 3){ freemsg(q, bp); qunlock(&hp->xmit); + poperror(); return; } chan = CHNO | bp->rptr[0] | (bp->rptr[1]<<8); @@ -435,9 +433,9 @@ hsvmeoput(Queue *q, Block *bp) static int notempty(void *arg) { - Device *addr; + HSdev *addr; - addr = (Device *)arg; + addr = (HSdev *)arg; return addr->csr & REF; } @@ -445,7 +443,7 @@ notempty(void *arg) * fill a block with what is currently buffered and send it upstream */ static void -upstream(Hsvme *hp, unsigned int ctl) +upstream(Hs *hp, unsigned int ctl) { int n; Block *bp; @@ -470,14 +468,14 @@ upstream(Hsvme *hp, unsigned int ctl) * fifo fill up. */ static void -hsvmekproc(void *arg) +hskproc(void *arg) { - Hsvme *hp; - Device *addr; + Hs *hp; + HSdev *addr; unsigned int c; int locked; - hp = (Hsvme *)arg; + hp = (Hs *)arg; addr = hp->addr; hp->kstarted = 1; hp->wptr = hp->buf; @@ -509,7 +507,7 @@ hsvmekproc(void *arg) /* * 0xFFFF means an empty fifo */ - while ((c = addr->data) != 0xFFFF) { + while((c = addr->data) != 0xFFFF){ hp->in++; if(c & CHNO){ c &= 0x1FF; @@ -561,31 +559,31 @@ hsvmekproc(void *arg) * and not empty bits to figure out whom to wake. */ static void -hsvmeintr(int vec) +hsintr(int vec) { ushort csr; - Device *addr; - Hsvme *hp; + HSdev *addr; + Hs *hp; - hp = &hsvme[vec - Vmevec]; - if(hp < hsvme || hp > &hsvme[Nhsvme]){ - print("bad hsvme vec\n"); + hp = &hs[vec - Intvec]; + if(hp < hs || hp > &hs[Nhs]){ + print("bad hs vec\n"); return; } csr = hp->addr->csr; - if (csr & REF) { + if(csr & REF){ hp->rintr++; wakeup(&hp->kr); } - if (csr & XHF) { + if(csr & XHF){ hp->tintr++; wakeup(&hp->r); } - if ((csr^XFF) & (XFF|EROFLOW|EFRAME|EPARITY|EXOFLOW)) { + if((csr^XFF) & (XFF|EROFLOW|EFRAME|EPARITY|EXOFLOW)){ hp->parity++; - hsvmerestart(hp); - print("hsvme %d: reset, csr = 0x%ux\n", - vec - Vmevec, csr); + hsrestart(hp); + print("hs %d: reset, csr = 0x%ux\n", + vec - Intvec, csr); } } diff --git a/power/io.h b/power/io.h index 50085853c8cbefe8d1b1683c93e0e2f5b6276749..72c532047ee480ddeee27a2076f0949036a936d3 100644 --- a/power/io.h +++ b/power/io.h @@ -117,3 +117,19 @@ struct INTVEC { #define PROM_REINIT 3 /* re-init monitor, then cmd loop */ #define PROM_REBOOT 4 /* check bootmode, no config */ #define PROM_AUTOBOOT 5 /* autoboot the system */ + +/* + * hs datakit board + */ +typedef struct HSdev HSdev; +struct HSdev { + ushort version; + ushort pad0x02; + ushort vector; + ushort pad0x06; + ushort csr; + ushort pad0x0A; + ushort data; +}; +#define HSDEV VMEA24SUP(HSdev, 0xF90000) + diff --git a/power/trap.c b/power/trap.c index cedd4cd099559ef32609fe922b21ce40b32cac06..da90224464aab56eaa89eb20173b1491fc697a83 100644 --- a/power/trap.c +++ b/power/trap.c @@ -599,7 +599,7 @@ setvmevec(int v, void (*f)(int)) v &= 0xff; g = vmevec[v]; - if(g && g != novme) + if(g && g != novme && g != f) print("second setvmevec to 0x%.2x\n", v); vmevec[v] = f; }