From 2105602d9855c19fcf7bef0e710ebb4774906cbc Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 1 Jun 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-06-01 --- pc/devlml.c | 232 ++-------------------------------------------- pc/trap.c | 42 +-------- port/devns16552.c | 52 ++++++++++- 3 files changed, 61 insertions(+), 265 deletions(-) diff --git a/pc/devlml.c b/pc/devlml.c index 3ccdcec6007d343da461827a2950793d4d88c09f..38ffbb711af0bb4beb0eb85272668a995b481fa3 100644 --- a/pc/devlml.c +++ b/pc/devlml.c @@ -23,40 +23,20 @@ int debug = 0; enum{ Qdir, - Qjvideo, - Qjframe, Qjcount, }; static Dirtab lmldir[]={ // name, qid, size, mode - "jvideo", {Qjvideo}, 0, 0666, - "jframe", {Qjframe}, 0, 0666, "jcount", {Qjcount}, 0, 0444, }; CodeData * codeData; -typedef enum { - New, - Header, - Body, - Error, -} State; - int frameNo; Rendez sleeper; int singleFrame; int nopens; -uchar q856[3]; -State state = New; - -static FrameHeader frameHeader = { - MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8, - { 'L', 'M', 'L', '\0'}, - -1, 0, 0, 0, 0 -}; - #define writel(v, a) *(ulong *)(a) = (v) #define readl(a) *(ulong*)(a) @@ -86,177 +66,6 @@ vcount(Chan *, void *va, long nbytes, vlong) { return 1; } -static long -vread(Chan *, void *va, long nbytes, vlong) { - static int bufpos; - static char *bufptr; - static int curbuf; - static int fragsize; - static int frameno; - static int frameprev; - char *p; - long count = nbytes; - int i; - vlong thetime; - - p = (char *)va; - while (count > 0) { - switch (state) { - case New: - curbuf = getbuffer(); - frameNo = codeData->statCom[curbuf] >> 24; - fragsize = (codeData->statCom[curbuf] & 0x00ffffff)>>1; - if (debug & DBGREAD) - pprint("devlml: got read buf %d, fr %d, size %d\n", - curbuf, frameNo, fragsize); - if (!singleFrame && frameno != (frameprev + 1) % 256) - pprint("Frame out of sequence: %d %d\n", - frameprev, frameno); - frameprev = frameno; - if (fragsize <= 0 || fragsize > sizeof(Fragment)) { - pprint("Wrong sized fragment, %d (ignored)\n", - fragsize); - codeData->statCom[curbuf] = PADDR(&(codeData->fragdesc[curbuf])); - break; - } - // Fill in APP marker fields here - thetime = todget(nil); - frameHeader.sec = (ulong)(thetime / 1000000000LL); - frameHeader.usec = (ulong)(thetime % 1000000000LL) / 1000; - frameHeader.frameSize = fragsize - 2 + sizeof(FrameHeader); - frameHeader.frameSeqNo++; - frameHeader.frameNo = frameno; - bufpos = 0; - state = Header; - bufptr = (char *)(&frameHeader); - // Fall through - case Header: - i = sizeof(FrameHeader) - bufpos; - if (count <= i) { - memmove(p, bufptr, count); - bufptr += count; - bufpos += count; - return nbytes; - } - memmove(p, bufptr, i); - count -= i; - p += i; - bufpos = 2; - bufptr = codeData->frag[curbuf].fb + 2; - state = Body; - // Fall through - case Body: - i = fragsize - bufpos; - if (count < i) { - memmove(p, bufptr, count); - bufptr += count; - bufpos += count; - return nbytes; - } - memmove(p, bufptr, i); - count -= i; - p += i; - - // Allow reuse of current buffer - codeData->statCom[curbuf] = PADDR(&(codeData->fragdesc[curbuf])); - state = New; - if (singleFrame) { - state = Error; - return nbytes - count; - } - break; - case Error: - return 0; - } - } -} - -static long -vwrite(Chan *, void *va, long nbytes, vlong) { - static int bufpos; - static char *bufptr; - static int curbuf; - static int fragsize; - char *p; - long count = nbytes; - int i; - - p = (char *)va; - while (count > 0) { - switch (state) { - case New: - curbuf = getbuffer(); - if (debug&DBGWRIT) - pprint("current buffer %d\n", curbuf); - bufptr = codeData->frag[curbuf].fb; - bufpos = 0; - state = Header; - // Fall through - case Header: - if (count < sizeof(FrameHeader) - bufpos) { - memmove(bufptr, p, count); - bufptr += count; - bufpos += count; - return nbytes; - } - // Fill remainder of header - i = sizeof(FrameHeader) - bufpos; - memmove(bufptr, p, i); - bufptr += i; - bufpos += i; - p += i; - count -= i; - // verify header - if (codeData->frag[curbuf].fh.mrkSOI != MRK_SOI - || codeData->frag[curbuf].fh.mrkAPP3 != MRK_APP3 - || strcmp(codeData->frag[curbuf].fh.nm, APP_NAME)) { - // Header is bad - pprint("devlml: header error: 0x%.4ux, 0x%.4ux, `%.4s'\n", - codeData->frag[curbuf].fh.mrkSOI, - codeData->frag[curbuf].fh.mrkAPP3, - codeData->frag[curbuf].fh.nm); - state = Error; - return nbytes - count; - } - fragsize = codeData->frag[curbuf].fh.frameSize; - if (fragsize <= sizeof(FrameHeader) - || fragsize > sizeof(Fragment)) { - pprint("devlml: frame size error: 0x%.8ux\n", - fragsize); - state = Error; - return nbytes - count; - } - state = Body; - // Fall through - case Body: - i = fragsize - bufpos; - if (count < i) { - memmove(bufptr, p, count); - bufptr += count; - bufpos += count; - return nbytes; - } - memmove(bufptr, p, i); - bufptr += i; - bufpos += i; - p += i; - count -= i; - // We have written the frame, time to display it - codeData->statCom[curbuf] = PADDR(&(codeData->fragdesc[curbuf])); - if (debug&DBGWRIT) - pprint("Sending buffer %d\n", curbuf); - if (singleFrame) { - state = Error; - return nbytes - count; - } - state = New; - break; - case Error: - return 0; - } - } -} - static void lmlintr(Ureg *, void *); static void @@ -289,14 +98,11 @@ lmlreset(void) return; } - memset(grabbuf, 0x33, grablen); - print("Installing Motion JPEG driver %s\n", MJPG_VERSION); print("MJPG buffer at 0x%.8lux, size 0x%.8lux\n", codeData, cdsize); print("Grab buffer at 0x%.8lux, size 0x%.8lux\n", grabbuf, grablen); // Get access to DMA memory buffer - memset(codeData, 0xAA, sizeof(CodeData)); codeData->pamjpg = PADDR(codeData->statCom); codeData->pagrab = PADDR(grabbuf); for (i = 0; i < NBUF; i++) { @@ -306,8 +112,6 @@ lmlreset(void) codeData->fragdesc[i].leng = ((sizeof codeData->frag[i]) >> 1) | FRAGM_FINAL_B; } - print("initializing LML33 board..."); - pciPhysBaseAddr = (void *)(pcidev->mem[0].bar & ~0x0F); print("zr36067 found at 0x%.8lux", pciPhysBaseAddr); @@ -320,9 +124,6 @@ lmlreset(void) pciBaseAddr = (ulong)KADDR(regpa); print(", mapped at 0x%.8lux\n", pciBaseAddr); - // Interrupt handler - intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf); - memset(&segbuf, 0, sizeof(segbuf)); segbuf.attr = SG_PHYSICAL; segbuf.name = smalloc(NAMELEN); @@ -355,6 +156,10 @@ lmlreset(void) print("lml: physsegment: lmlgrab\n"); return; } + + // Interrupt handler + intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf); + return; } @@ -378,22 +183,14 @@ lmlstat(Chan *c, char *dp) static Chan* lmlopen(Chan *c, int omode) { - int i; c->aux = 0; switch(c->qid.path){ - case Qjframe: - case Qjvideo: case Qjcount: + // allow one open if (nopens) error(Einuse); nopens = 1; - singleFrame = (c->qid.path == Qjframe) ? 1 : 0;; - state = New; - for (i = 0; i < NBUF; i++) - codeData->statCom[i] = PADDR(&(codeData->fragdesc[i])); - - // allow one open total for these two break; } return devopen(c, omode, lmldir, nelem(lmldir), devgen); @@ -403,8 +200,6 @@ static void lmlclose(Chan *c) { switch(c->qid.path){ - case Qjvideo: - case Qjframe: case Qjcount: nopens = 0; authclose(c); @@ -420,27 +215,16 @@ lmlread(Chan *c, void *va, long n, vlong voff) { case Qdir: return devdirread(c, (char *)buf, n, lmldir, nelem(lmldir), devgen); - case Qjvideo: - case Qjframe: - return vread(c, buf, n, off); case Qjcount: return vcount(c, buf, n, off); } } static long -lmlwrite(Chan *c, void *va, long n, vlong voff) { - uchar *buf = va; - long off = voff; +lmlwrite(Chan *, void *, long, vlong) { - switch(c->qid.path & ~CHDIR){ - case Qdir: - case Qjcount: - error(Eperm); - case Qjvideo: - case Qjframe: - return vwrite(c, buf, n, off); - } + error(Eperm); + return 0; } Dev lmldevtab = { diff --git a/pc/trap.c b/pc/trap.c index 5142b7fb08345ed0779c1fc76d36e8c1a5a57eaa..7201e1af3bec386be15940314003eaa0966ca4f7 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -15,16 +15,8 @@ static void fault386(Ureg*, void*); static Lock vctllock; static Vctl *vctl[256]; -/* interrupt timestamps, l.s knows fills intrts each interupt */ - uvlong intrts; -static struct { - Lock; - int vno; /* vector to save timestamps for */ - int n; /* number of valid timestamps in ts[] */ - uvlong ts[128]; /* time stamps */ -} tsalloc; - -static void savets(void); +/* interrupt timestamps, l.s fills intrts each interupt */ +uvlong intrts; void intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf) @@ -41,8 +33,6 @@ intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf) ilock(&vctllock); vno = arch->intrenable(v); - if(irq == IrqUART0) - tsalloc.vno = vno; if(vno == -1){ iunlock(&vctllock); print("intrenable: couldn't enable irq %d, tbdf 0x%uX\n", @@ -192,8 +182,6 @@ trap(Ureg* ureg) } vno = ureg->trap; - if(vno == tsalloc.vno) - savets(); if(ctl = vctl[vno]){ if(ctl->isintr){ m->intr++; @@ -752,29 +740,3 @@ dbgpc(Proc *p) return ureg->pc; } - -/* called with interrupts off */ -static void -savets(void) -{ - lock(&tsalloc); - if(tsalloc.n < nelem(tsalloc.ts)) - tsalloc.ts[tsalloc.n++] = intrts; - unlock(&tsalloc); -} - -/* read interrupt timestamps */ -long -readintrts(void *buf, int n) -{ - n /= sizeof(uvlong); - if(n <= 0) - return 0; - ilock(&tsalloc); - if(n > tsalloc.n) - n = tsalloc.n; - memmove(buf, tsalloc.ts, n*sizeof(uvlong)); - tsalloc.n = 0; - iunlock(&tsalloc); - return n*sizeof(uvlong); -} diff --git a/port/devns16552.c b/port/devns16552.c index e326e63607d34d8825f59b4dfabc8c21df410c69..5edbf0f9f77f233df49d713e1c034b51b525397b 100644 --- a/port/devns16552.c +++ b/port/devns16552.c @@ -131,7 +131,7 @@ struct Uart int modem; /* hardware flow control on */ int xonoff; /* software flow control on */ int blocked; - int cts, dsr, dcd; /* keep track of modem status */ + int cts, dsr, dcd, dcdts; /* keep track of modem status */ int ctsbackoff; int hup_dsr, hup_dcd; /* send hangup upstream? */ int dohup; @@ -149,6 +149,41 @@ struct Uartalloc { void ns16552intr(int); +/* interrupt timestamps, l.s fills intrts each interupt */ +uvlong intrts; +static struct { + Lock; + int vno; /* vector to save timestamps for */ + int n; /* number of valid timestamps in ts[] */ + uvlong ts[128]; /* time stamps */ +} tsalloc; + +/* called with interrupts off by interrupt routine */ +static void +savets(void) +{ + lock(&tsalloc); + if(tsalloc.n < nelem(tsalloc.ts)) + tsalloc.ts[tsalloc.n++] = intrts; + unlock(&tsalloc); +} + +/* read interrupt timestamps */ +long +readintrts(void *buf, int n) +{ + n /= sizeof(uvlong); + if(n <= 0) + return 0; + ilock(&tsalloc); + if(n > tsalloc.n) + n = tsalloc.n; + memmove(buf, tsalloc.ts, n*sizeof(uvlong)); + tsalloc.n = 0; + iunlock(&tsalloc); + return n*sizeof(uvlong); +} + /* * pick up architecture specific routines and definitions */ @@ -253,6 +288,15 @@ ns16552rts(Uart *p, int n) uartwrreg(p, Mctl, 0); } +/* + * save dcd timestamps for gps clock + */ +static void +ns16552dcdts(Uart *p, int n) +{ + p->dcdts = n; +} + /* * send break */ @@ -669,6 +713,8 @@ ns16552intr(int dev) } if (ch & Dcdc) { l = ch & Dcd; + if(l == 0 && p->dcd != 0 && p->dcdts) + savets(); if(p->hup_dcd && p->dcd && !l){ ilock(&p->rlock); p->dohup = 1; @@ -997,6 +1043,10 @@ ns16552ctl(Uart *p, char *cmd) qsetlimit(p->iq, n); qsetlimit(p->oq, n); break; + case 'T': + case 't': + ns16552dcdts(p, n); + break; case 'W': case 'w': /* obsolete */