From 4f839b7c6128baf19bfd353e19f6c36085cd67dc Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 17 May 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-05-17 --- pc/devlml.c | 66 ++++++++++++++++++++++++++++---------------------- pc/devlml.h | 36 ++++++--------------------- pc/trap.c | 7 +++++- port/portdat.h | 1 + port/print.c | 10 ++++++++ port/tod.c | 40 ++++++++++++------------------ 6 files changed, 77 insertions(+), 83 deletions(-) diff --git a/pc/devlml.c b/pc/devlml.c index 4eef957263df17957f1939f9ddef15f94bf9e938..bf375bf62eb3a2949ad08261c146458af775d8d0 100644 --- a/pc/devlml.c +++ b/pc/devlml.c @@ -11,10 +11,16 @@ #define DBGREGS 0x1 #define DBGREAD 0x2 #define DBGWRIT 0x4 -int debug = DBGREAD|DBGWRIT; +int debug = DBGREAD|DBGWRIT|DBGREGS; // Lml 22 driver +struct { + ulong pci; + ulong dma; + ulong codedata; +} lmlmap; + enum{ Qdir, Q819, @@ -29,8 +35,8 @@ static Dirtab lmldir[]={ // name, qid, size, mode "lml819", {Q819}, 0, 0644, "lml856", {Q856}, 0, 0644, - "lmlreg", {Qreg}, 0, 0644, - "lmlmap", {Qmap}, 0, 0444, + "lmlreg", {Qreg}, 0x400, 0644, + "lmlmap", {Qmap}, sizeof lmlmap, 0444, "jvideo", {Qjvideo}, 0, 0666, "jframe", {Qjframe}, 0, 0666, }; @@ -48,12 +54,6 @@ int hdrPos; int nopens; uchar q856[3]; -struct { - ulong pci; - ulong dma; - ulong codedata; -} lmlmap; - static FrameHeader frameHeader = { MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8, { 'L', 'M', 'L', '\0'}, @@ -63,24 +63,24 @@ static FrameHeader frameHeader = { ulong writel(ulong v, ulong a) { if (debug&DBGREGS) - pprint("writing %.8lux to %.8lux (%.4lux)\n", - v, a, (ulong)a-pciBaseAddr); + pprint("%.8lux (%.8lux) <-- %.8lux\n", + a, (ulong)a-pciBaseAddr, v); return *(ulong *)a = v; } ushort writew(ushort v, ulong a) { if (debug&DBGREGS) - pprint("writing %.4ux to %.8lux (%.4lux)\n", - v, a, (ulong)a-pciBaseAddr); + pprint("%.8lux (%.8lux) <-- %.4ux\n", + a, (ulong)a-pciBaseAddr, v); return *(ushort *)a = v; } uchar writeb(uchar v, ulong a) { if (debug&DBGREGS) - pprint("writing %.2ux to %.8lux (%.4lux)\n", - v, a, (ulong)a-pciBaseAddr); + pprint("%.8lux (%.8lux) <-- %.2ux\n", + a, (ulong)a-pciBaseAddr, v); return *(uchar *)a = v; } @@ -90,8 +90,8 @@ readl(ulong a) { v = *(ulong*)a; if (debug&DBGREGS) - pprint("reading %.8lux from %.8lux (%.4lux)\n", - v, a, (ulong)a-pciBaseAddr); + pprint("%.8lux (%.8lux) --> %.8lux\n", + a, (ulong)a-pciBaseAddr, v); return v; } @@ -101,8 +101,8 @@ readw(ulong a) { v = *(ushort*)a; if (debug&DBGREGS) - pprint("reading %.4ux from %.8lux (%.4lux)\n", - v, a, (ulong)a-pciBaseAddr); + pprint("%.8lux (%.8lux) --> %.4ux\n", + a, (ulong)a-pciBaseAddr, v); return v; } @@ -112,8 +112,8 @@ readb(ulong a) { v = *(uchar*)a; if (debug&DBGREGS) - pprint("reading %.2ux from %.8lux (%.4lux)\n", - v, a, (ulong)a-pciBaseAddr); + pprint("%.8lux (%.8lux) --> %.2ux\n", + a, (ulong)a-pciBaseAddr, v); return v; } @@ -330,7 +330,7 @@ static int prepareBuffer(CodeData * this, int bufferNo) { if(bufferNo >= 0 && bufferNo < NBUF && (this->statCom[bufferNo] & STAT_BIT)) { this->statCom[bufferNo] = this->statComInitial[bufferNo]; - return this->fragmDescr[bufferNo].fragmLength; + return this->fragdesc[bufferNo].leng; } else return -1; } @@ -354,7 +354,7 @@ static int getBuffer(CodeData *this, int bufferNo, void** bufferPtr, int* frameNo) { int codeLength; if(this->statCom[bufferNo] & STAT_BIT) { - *bufferPtr = (void*)this->fragmDescr[bufferNo].fragmAddress; + *bufferPtr = (void*)this->fragdesc[bufferNo].addr; *frameNo = this->statCom[bufferNo] >> 24; codeLength=((this->statCom[bufferNo] & 0x00FFFFFF) >> 1); return codeLength; @@ -560,12 +560,11 @@ lmlreset(void) strncpy(codeData->idString, MJPG_VERSION, strlen(MJPG_VERSION)); for(i = 0; i < NBUF; i++) { - codeData->statCom[i] = PADDR(&(codeData->fragmDescr[i])); + codeData->statCom[i] = PADDR(&(codeData->fragdesc[i])); codeData->statComInitial[i] = codeData->statCom[i]; - codeData->fragmDescr[i].fragmAddress = - (Fragment *)PADDR(&(codeData->frag[i])); + codeData->fragdesc[i].addr = PADDR(&(codeData->frag[i])); // Length is in double words, in position 1..20 - codeData->fragmDescr[i].fragmLength = (FRAGSIZE >> 1) | FRAGM_FINAL_B; + codeData->fragdesc[i].leng = (FRAGSIZE >> 1) | FRAGM_FINAL_B; } print("initializing LML33 board..."); @@ -620,6 +619,8 @@ lmlstat(Chan *c, char *dp) static Chan* lmlopen(Chan *c, int omode) { + int i; + c->aux = 0; switch(c->qid.path){ case Q819: @@ -639,7 +640,14 @@ lmlopen(Chan *c, int omode) frameNo = 0; bufferPrepared = 0; hdrPos = -1; + + for (i = 0; i < 4; i++) { + codeData->statCom[i] = codeData->statComInitial[i]; + // Also memset the buffer with some fill value + memset(&(codeData->frag[i]),0x55,sizeof codeData->frag[i]); + } // allow one open total for these two + intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf); break; } return devopen(c, omode, lmldir, nelem(lmldir), devgen); @@ -707,7 +715,7 @@ lmlread(Chan *c, void *va, long n, vlong voff) { if (off < 0) return 0; for (i = 0; i < n; i++) { - if (off + i > sizeof lmlmap) + if (off + i >= sizeof lmlmap) break; buf[i] = ((uchar *)&lmlmap)[off + i]; } @@ -749,7 +757,7 @@ lmlwrite(Chan *c, void *va, long n, vlong voff) { error(Eperm); case Q819: - if (off < 0 || off + n > 0x20) + if (off < 0 || off + n >= 0x20) return 0; for (i = n; i > 0; i--) if (i2c_wr8(BT819Addr, off++, *buf++) == 0) diff --git a/pc/devlml.h b/pc/devlml.h index 5cd88e1c7f2e0a11c010ea7143b2d93ecfa76cba..9b5862ada871938d9f57224b392d0fb8f7d66542 100644 --- a/pc/devlml.h +++ b/pc/devlml.h @@ -50,28 +50,6 @@ typedef struct { int zr060addr; // Which guest bus address for the ZR36060 } Device; -// An entry in the fragment table -typedef struct { - ulong address; // bus address of page - int length; // length of page -} RingPage; - -// The structure that we will use to tell the '57 about the buffers -// The sizeof(RingData) should not exceed page size -typedef struct { - void *buffer[4]; - ulong i_stat_com[4]; - RingPage ring_pages[4][PAGES]; -} RingData; - -typedef struct { - int expect; // the buffer the int routine expects next - int which; // which ring buffer the read or write uses - int filled; // the current number of filled buffers - int pages; // the number of complete pages - int remainder; // the number of bytes in incomplete page -} RingPtr; - // The remainder of the #defs are constants which should not need changing. // The PCI vendor and device ids of the zoran chipset on the dc30 @@ -103,16 +81,16 @@ struct Fragment { }; struct FragmentTable { // Don't modify this struct, used by h/w - Fragment * fragmAddress; // Physical address - ulong fragmLength; + ulong addr; // Physical address + ulong leng; }; struct CodeData { // Don't modify this struct, used by h/w - char idString[16]; - ulong statCom[4]; // Physical address - ulong statComInitial[4]; // Physical address - FragmentTable fragmDescr[4]; - Fragment frag[4]; + char idString[16]; + ulong statCom[4]; // Physical address + ulong statComInitial[4]; // Physical address + FragmentTable fragdesc[4]; + Fragment frag[4]; }; static void * pciPhysBaseAddr; diff --git a/pc/trap.c b/pc/trap.c index 8581ba568b877dd49d41360d92652e139f1d9a1b..f4ce7d2c75f67f3bbbc6c32a26eaa4a10b6c4a03 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -681,8 +681,13 @@ linkproc(void) void kprocchild(Proc* p, void (*func)(void*), void* arg) { + /* + * gotolabel() needs a word on the stack in + * which to place the return PC used to jump + * to linkproc(). + */ p->sched.pc = (ulong)linkproc; - p->sched.sp = (ulong)p->kstack+KSTACK; + p->sched.sp = (ulong)p->kstack+KSTACK-BY2WD; p->kpfun = func; p->kparg = arg; diff --git a/port/portdat.h b/port/portdat.h index 2509e712e4d086a6e0f4f61c35fb81cc7ff5816e..4c35a2c8fa3defd3036dc6c3ce443eb992b7cbdf 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -784,3 +784,4 @@ extern int nsyscall; #pragma varargck type "V" uchar* #pragma varargck type "E" uchar* #pragma varargck type "M" uchar* +#pragma varargck type "p" void* diff --git a/port/print.c b/port/print.c index c48b244db9f2e8efa59837ca5b6f834163f1fadf..2292913245bbb72468a4ab65952a0228c731acce 100644 --- a/port/print.c +++ b/port/print.c @@ -18,6 +18,7 @@ enum FSHORT = 1<<4, FUNSIGN = 1<<5, FVLONG = 1<<6, + FPOINTER = 1<<7, }; int printcol; @@ -64,6 +65,7 @@ initfmt(void) fmtindex['o'] = cc; fmtindex['x'] = cc; fmtindex['X'] = cc; + fmtindex['p'] = cc; cc++; fmtconv[cc] = cconv; @@ -242,6 +244,10 @@ numbconv(va_list *arg, Fconv *fp) case 'x': b = 16; break; + case 'p': + fp->f3 |= FPOINTER|FUNSIGN; + b = 16; + break; } f = 0; @@ -272,6 +278,10 @@ numbconv(va_list *arg, Fconv *fp) v = (ushort)h; break; + case FUNSIGN|FPOINTER: + v = (ulong)va_arg(*arg, void*); + break; + default: v = va_arg(*arg, int); break; diff --git a/port/tod.c b/port/tod.c index c98310cb3611792b96e582cbb367bb83e03e9a88..441f13b1dc9e085944448d45720a1e859b037a25 100644 --- a/port/tod.c +++ b/port/tod.c @@ -29,9 +29,7 @@ struct { Lock; - int s1; // time = ((ticks>>s2)*multiplier)>>(s1-s2) - vlong multiplier; // ... - int s2; // ... + vlong multiplier; // t = off + (multiplier*ticks)>>31 vlong hz; // frequency of fast clock vlong last; // last reading of fast clock vlong off; // offset from epoch to last @@ -55,19 +53,6 @@ todinit(void) void todsetfreq(vlong f) { - // the shift is an attempt to maintain precision - // during the caculations. the number of bits in - // the multiplier should be log(TODFREQ) + 31 - log(f). - // - // Freq bits - // 167 MHZ 34 - // 267 MHZ 33 - // 500 MHZ 32 - // - // in all cases, we need to call todget() at least once - // a second to keep the subsequent calculations from - // overflowing. - ilock(&tod); tod.hz = f; tod.multiplier = (TODFREQ<<31)/f; @@ -81,11 +66,12 @@ void todset(vlong t, vlong delta, int n) { ilock(&tod); - tod.sstart = tod.send = 0; if(t >= 0){ tod.off = t; tod.last = fastticks(nil); tod.lasttime = 0; + tod.delta = 0; + tod.sstart = tod.send; } else { if(n <= 0) n = 1; @@ -121,7 +107,7 @@ todget(void) diff = ticks - tod.last; // add in correction - if(tod.sstart < tod.send){ + if(tod.sstart != tod.send){ t = MACHP(0)->ticks; if(t >= tod.send) t = tod.send; @@ -129,13 +115,15 @@ todget(void) tod.sstart = t; } - // convert to epoch, make sure calculation is unsigned - x = (((uvlong)diff) * ((uvlong)tod.multiplier)) >> 31; + // convert to epoch + x = (diff * tod.multiplier) >> 31; x += tod.off; - // protect against overflows (gettod is called at least once a second) - tod.last = ticks; - tod.off = x; + // protect against overflows + if(diff > tod.hz){ + tod.last = ticks; + tod.off = x; + } // time can't go backwards if(x < tod.lasttime) @@ -152,9 +140,13 @@ todget(void) void todfix(void) { + static ulong last; + // once a second, make sure we don't overflow - if((MACHP(0)->ticks % HZ) == 0) + if(MACHP(0)->ticks - last >= HZ){ + last = MACHP(0)->ticks; todget(); + } } long