From d23bd1d0fb49964f11de408d55552b28b8ca2f8f Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 3 Mar 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-03-03 --- power/devhotrod.c | 165 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 148 insertions(+), 17 deletions(-) diff --git a/power/devhotrod.c b/power/devhotrod.c index 03679967c0b9663be202dee857365b254a677e59..eae99dbb9bf9c6fb10be7dc7131f8cd570b4ed4e 100644 --- a/power/devhotrod.c +++ b/power/devhotrod.c @@ -10,6 +10,13 @@ #include "io.h" #include "hrod.h" +void mem(Hot*, ulong*, ulong); + +/* + * If set, causes data transfers to have checksums + */ +#define ENABCKSUM 1 + typedef struct Hotrod Hotrod; typedef struct HotQ HotQ; @@ -55,8 +62,8 @@ void hotrodintr(int); enum{ RESET= 0, /* params: Q address, length of queue */ REBOOT= 1, /* params: none */ - READ= 2, /* params: buffer, count, returned count */ - WRITE= 3, /* params: buffer, count */ + READ= 2, /* params: buffer, count, sum, returned count */ + WRITE= 3, /* params: buffer, count, sum */ TEST= 7, /* params: none */ }; @@ -192,7 +199,11 @@ hotrodopen(Chan *c, int omode) mp->param[1] = NTESTBUF; hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); delay(100); - print("tested\n"); + print("testing addr %lux size %ld\n", mp->param[0], mp->param[1]); + for(;;){ + print("-"); + mem(hp->addr, &hp->addr->ram[(mp->param[0]-0x40000)/sizeof(ulong)], mp->param[1]); + } #endif } c->mode = openmode(omode); @@ -220,6 +231,20 @@ hotrodclose(Chan *c) } } +ulong +hotsum(ulong *p, int n, ulong doit) +{ + ulong sum; + + if(!doit) + return 0; + sum = 0; + n = (n+sizeof(ulong)-1)/sizeof(ulong); + while(--n >= 0) + sum += *p++; + return sum; +} + /* * Read and write use physical addresses if they can, which they usually can. * Most I/O is from devmnt, which has local buffers. Therefore just check @@ -231,7 +256,7 @@ hotrodread(Chan *c, void *buf, long n) { Hotrod *hp; Hotmsg *mp; - ulong l; + ulong l, m; hp = &hotrod[c->dev]; switch(c->qid.path){ @@ -245,7 +270,8 @@ hotrodread(Chan *c, void *buf, long n) * use supplied buffer, no need to lock for reply */ mp = &u->khot; - mp->param[2] = 0; /* reply count */ + mp->param[2] = 0; /* checksum */ + mp->param[3] = 0; /* reply count */ qlock(hp); mp->cmd = READ; mp->param[0] = MP2VME(buf); @@ -254,18 +280,24 @@ hotrodread(Chan *c, void *buf, long n) qunlock(hp); l = 100*1000*1000; do - n = mp->param[2]; - while(n==0 && --l>0); - if(n == 0){ - print("devhotrod: give up\n"); + m = mp->param[3]; + while(m==0 && --l>0); + if(m==0 || m>n){ + print("devhotrod: count %ld %ld\n", m, n); error(Egreg); } + if(mp->param[2] != hotsum(buf, m, mp->param[2])){ + print("hotrod cksum err is %lux sb %lux\n", + hotsum(buf, n, 1), mp->param[2]); + error(Eio); + } }else{ /* * use hotrod buffer. lock the buffer until the reply */ mp = &u->uhot; - mp->param[2] = 0; /* reply count */ + mp->param[2] = 0; /* checksum */ + mp->param[3] = 0; /* reply count */ qlock(&hp->buflock); qlock(hp); mp->cmd = READ; @@ -275,16 +307,23 @@ hotrodread(Chan *c, void *buf, long n) qunlock(hp); l = 100*1000*1000; do - n = mp->param[2]; - while(n==0 && --l>0); - memcpy(buf, hp->buf, n); - qunlock(&hp->buflock); - if(n == 0){ - print("devhotrod: give up\n"); + m = mp->param[3]; + while(m==0 && --l>0); + if(m==0 || m>n){ + print("devhotrod: count %ld %ld\n", m, n); + qunlock(&hp->buflock); error(Egreg); } + if(mp->param[2] != hotsum((ulong*)hp->buf, m, mp->param[2])){ + print("hotrod cksum err is %lux sb %lux\n", + hotsum((ulong*)hp->buf, n, 1), mp->param[2]); + qunlock(&hp->buflock); + error(Eio); + } + memcpy(buf, hp->buf, m); + qunlock(&hp->buflock); } - return n; + return m; } print("hotrod read unk\n"); error(Egreg); @@ -316,6 +355,7 @@ hotrodwrite(Chan *c, void *buf, long n) mp->cmd = WRITE; mp->param[0] = MP2VME(buf); mp->param[1] = n; + mp->param[2] = hotsum(buf, n, ENABCKSUM); hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); qunlock(hp); }else{ @@ -329,6 +369,7 @@ hotrodwrite(Chan *c, void *buf, long n) mp->cmd = WRITE; mp->param[0] = MP2VME(hp->buf); mp->param[1] = n; + mp->param[2] = hotsum((ulong*)hp->buf, n, ENABCKSUM); hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->uhot); qunlock(hp); qunlock(&hp->buflock); @@ -365,3 +406,93 @@ hotrodintr(int vec) } hp->addr->lcsr3 &= ~INT_VME; } + +void +mem(Hot *hot, ulong *buf, ulong size) +{ + long i, j, k, l; + ulong *p, bit, u; + int q; + +goto part4; + /* one bit */ + bit = 0; + p = buf; + for(i=0; ierror++; + delay(500); + } + bit <<= 1; + } + /* all but one bit */ + bit = 0; + p = buf; + for(i=0; ierror++; + delay(500); + } + bit <<= 1; + } + /* rand bit */ + bit = 0; + p = buf; + for(i=0; ierror++; + delay(500); + } + bit += PRIME; + } +part4: + /* address */ + p = buf; + for(i=0; ierror++; + delay(500); + } + *p = i+j+1; + } + } +}