From 12bb3867cea8b5ebc9fa18e6804338ac82b1cc0d Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 26 May 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-05-26 --- pc/devlml.c | 675 +++------------------------------------------------ port/alloc.c | 6 +- 2 files changed, 41 insertions(+), 640 deletions(-) diff --git a/pc/devlml.c b/pc/devlml.c index fd84384e4a55a609f9847d462e281731afcaf83b..06819221c445ec4e34587d171500871c719da8cf 100644 --- a/pc/devlml.c +++ b/pc/devlml.c @@ -12,51 +12,27 @@ static void * pciPhysBaseAddr; static ulong pciBaseAddr; static Pcidev * pcidev; -#define DBGREGS 0x01 -#define DBGREAD 0x02 -#define DBGWRIT 0x04 -#define DBG819 0x08 -#define DBGINTR 0x10 -#define DBGINTS 0x20 +#define DBGREAD 0x01 +#define DBGWRIT 0x02 +#define DBGINTR 0x04 +#define DBGINTS 0x08 int debug = 0; // Lml 22 driver -#ifdef MEMMAP -struct { - ulong pci; - ulong statcom; - ulong codedata; -} lmlmap; -#endif - enum{ Qdir, -#ifdef MEMMAP - Q060, - Q819, - Q856, - Qreg, - Qmap, - Qbuf, -#endif Qjvideo, Qjframe, + Qjcount, }; static Dirtab lmldir[]={ // name, qid, size, mode -#ifdef MEMMAP - "lml060", {Q060}, 0x400, 0644, - "lml819", {Q819}, 0, 0644, - "lml856", {Q856}, 0, 0644, - "lmlreg", {Qreg}, 0x400, 0644, - "lmlmap", {Qmap}, sizeof lmlmap, 0444, - "lmlbuf", {Qbuf}, 0, 0644, -#endif "jvideo", {Qjvideo}, 0, 0666, "jframe", {Qjframe}, 0, 0666, + "jcount", {Qjcount}, 0, 0444, }; CodeData * codeData; @@ -82,402 +58,34 @@ static FrameHeader frameHeader = { }; -#ifndef MEMMAP #define writel(v, a) *(ulong *)(a) = (v) #define readl(a) *(ulong*)(a) -#else -ulong -writel(ulong v, ulong a) { - if (debug&DBGREGS) - pprint("%.8lux (%.8lux) <-- %.8lux\n", - a, (ulong)a-pciBaseAddr, v); - return *(ulong *)a = v; -} - -ulong -readl(ulong a) { - ulong v; - - v = *(ulong*)a; - if (debug&DBGREGS) - pprint("%.8lux (%.8lux) --> %.8lux\n", - a, (ulong)a-pciBaseAddr, v); - return v; -} -ushort -writew(ushort v, ulong a) { - if (debug&DBGREGS) - pprint("%.8lux (%.8lux) <-- %.4ux\n", - a, (ulong)a-pciBaseAddr, v); - return *(ushort *)a = v; -} - -uchar -writeb(uchar v, ulong a) { - if (debug&DBGREGS) - pprint("%.8lux (%.8lux) <-- %.2ux\n", - a, (ulong)a-pciBaseAddr, v); - return *(uchar *)a = v; -} - -ushort -readw(ulong a) { - ushort v; - - v = *(ushort*)a; - if (debug&DBGREGS) - pprint("%.8lux (%.8lux) --> %.4ux\n", - a, (ulong)a-pciBaseAddr, v); - return v; -} - -uchar -readb(ulong a) { - uchar v; - - v = *(uchar*)a; - if (debug&DBGREGS) - pprint("%.8lux (%.8lux) --> %.2ux\n", - a, (ulong)a-pciBaseAddr, v); - return v; -} - -static void -i2c_pause(void) { - - microdelay(I2C_DELAY); -} - -static void -i2c_waitscl(void) { - int i; - - for (i = 0; i < I2C_TIMEOUT; i++) - if (readl(pciBaseAddr + I2C_BUS) & I2C_SCL) - return; - error(Eio); -} - -static void -i2c_start(void) { - - writel(I2C_SCL|I2C_SDA, pciBaseAddr + I2C_BUS); - i2c_waitscl(); - i2c_pause(); - - writel(I2C_SCL, pciBaseAddr + I2C_BUS); - i2c_pause(); - - writel(0, pciBaseAddr + I2C_BUS); - i2c_pause(); -} - -static void -i2c_stop(void) { - // the clock should already be low, make sure data is - writel(0, pciBaseAddr + I2C_BUS); - i2c_pause(); - - // set clock high and wait for device to catch up - writel(I2C_SCL, pciBaseAddr + I2C_BUS); - i2c_waitscl(); - i2c_pause(); - - // set the data high to indicate the stop bit - writel(I2C_SCL|I2C_SDA, pciBaseAddr + I2C_BUS); - i2c_pause(); -} - -static void i2c_wrbit(int bit) { - if (bit){ - writel(I2C_SDA, pciBaseAddr + I2C_BUS); // set data - i2c_pause(); - writel(I2C_SDA|I2C_SCL, pciBaseAddr + I2C_BUS); - i2c_waitscl(); - i2c_pause(); - writel(I2C_SDA, pciBaseAddr + I2C_BUS); - i2c_pause(); - } else { - writel(0, pciBaseAddr + I2C_BUS); // clr data - i2c_pause(); - writel(I2C_SCL, pciBaseAddr + I2C_BUS); - i2c_waitscl(); - i2c_pause(); - writel(0, pciBaseAddr + I2C_BUS); - i2c_pause(); - } -} static int -i2c_rdbit(void) { - int bit; - // the clk line should be low - - // ensure we are not asserting the data line - writel(I2C_SDA, pciBaseAddr + I2C_BUS); - i2c_pause(); - - // set the clock high and wait for device to catch up - writel(I2C_SDA|I2C_SCL, pciBaseAddr + I2C_BUS); - i2c_waitscl(); - i2c_pause(); - - // the data line should be a valid bit - bit = readl(pciBaseAddr+I2C_BUS); - if (bit & I2C_SDA){ - bit = 1; - } else { - bit = 0; +getbuffer(void){ + static last = NBUF-1; + int l = last; + + for (;;) { + last = (last+1) % NBUF; + if (codeData->statCom[last] & STAT_BIT) + return last; + if (last == l) + sleep(&sleeper, return0, 0); } - - // set the clock low to indicate end of cycle - writel(I2C_SDA, pciBaseAddr + I2C_BUS); - i2c_pause(); - - return bit; + return 0; } -static int -i2c_rdbyte(uchar *v) { - int i, ack; - uchar res; - - res = 0; - for (i = 0; i < 8; i++) { - res = res << 1; - res += i2c_rdbit(); - } - - ack = i2c_rdbit(); - - *v = res; - - return ack; -} - -static int -i2c_wrbyte(uchar v) { - int i, ack; - - for (i = 0; i < 8; i++) { - i2c_wrbit(v & 0x80); - v = v << 1; - } - - ack = i2c_rdbit(); - - return ack; -} - -static void -i2c_write_bytes(uchar addr, uchar sub, uchar *bytes, long num) { - int ack; - long i; - - i2c_start(); - - ack = i2c_wrbyte(addr); - if (ack == 1) error(Eio); - - ack = i2c_wrbyte(sub); - if (ack == 1) error(Eio); - - for (i = 0; i < num; i++) { - ack = i2c_wrbyte(bytes[i]); - if (ack == 1) error(Eio); - } - - i2c_stop(); -} - -static int -i2c_bt856rd8(void) { - uchar ret; - - i2c_start (); - - if (i2c_wrbyte(BT856Addr + 1) == 1 - || i2c_rdbyte(&ret) == 0) { - i2c_stop (); - return -1; - } - - i2c_stop (); - return ret; -} - -static int -i2c_rd8(int addr, int sub) -{ - uchar msb; - - i2c_start(); - - if (i2c_wrbyte(addr) == 1 - || i2c_wrbyte(sub) == 1) { - if (debug&DBGREGS) pprint("i2c_rd8, failure 1\n"); - i2c_stop(); - return -1; - } - - i2c_start(); - - if (i2c_wrbyte(addr+1) == 1 - || i2c_rdbyte(&msb) == 0){ - if (debug&DBGREGS) pprint("i2c_rd8, failure 2\n"); - i2c_stop(); - return -1; - } - - i2c_stop(); - - return msb; -} - -static int -i2c_wr8(uchar addr, uchar sub, uchar msb) { - - i2c_start(); +static long +vcount(Chan *, void *va, long nbytes, vlong) { + char *p = (char *)va; - if (i2c_wrbyte(addr) == 1 - || i2c_wrbyte(sub) == 1 - || i2c_wrbyte(msb) == 1) - return 0; - - i2c_stop(); - + // reads always return one byte: the next available buffer number + if (nbytes <= 0) return 0; + *p = getbuffer(); return 1; } -/* - * The following mapping applies for the guests in the LML33 - * - * Guest Device - * 0 zr36060 - * uses subaddress GADR[0..1] - * 1 zr36060 START# - * 2 - - * 3 zr36060 RESET# - * 4 - - * 5 - - * 6 - - * 7 - - */ - -// post_idle waits for the guest bus to become free -static int -post_idle(void) { - ulong a; - int timeout; - - for (timeout = 0; timeout < GUEST_TIMEOUT; timeout++){ - a = readl(pciBaseAddr + POST_OFFICE); - if ((a & POST_PEND) == 0) - return a; - } - pprint("post_idle timeout\n"); - return -1; -} - -// post_write writes a byte to a guest using postoffice mechanism -int -post_write(unsigned int guest, unsigned int reg, unsigned int v) { - int w; - - // wait for postoffice not busy - post_idle(); - - // Trim the values, just in case - guest &= 0x07; - reg &= 0x07; - v &= 0xFF; - - // write postoffice operation - w = POST_DIR | (guest<<20) | (reg<<16) | v; - writel(w, pciBaseAddr + POST_OFFICE); - - // wait for postoffice not busy - return post_idle() == -1; -} - -// post_read reads a byte from a guest using postoffice mechanism -int -post_read(int guest, int reg) { - int w; - - // wait for postoffice not busy - post_idle(); - - // Trim the values, just in case - guest &= 0x07; - reg &= 0x07; - - // write postoffice operation - w = (guest<<20) + (reg<<16); - writel(w, pciBaseAddr + POST_OFFICE); - - // wait for postoffice not busy, get result - w = post_idle(); - - // decide if read went ok - if (w == -1) return -1; - - return w & 0xFF; -} - -static int -zr060_write(int reg, int v) { - - if (post_write(GID060, 1, (reg>>8) & 0x03) - || post_write(GID060, 2, reg & 0xff) - || post_write(GID060, 3, v)) - return -1; -} - -static int -zr060_read(int reg) { - - if (post_write(GID060, 1, (reg>>8) & 0x03) - || post_write(GID060, 2, reg & 0xff)) - return -1; - return post_read(GID060, 3); -} -#endif - -static int -prepareBuffer(int i) { - if (i >= 0 && i < NBUF && (codeData->statCom[i] & STAT_BIT)) { - codeData->statCom[i] = PADDR(&(codeData->fragdesc[i])); - return codeData->fragdesc[i].leng; - } else - return -1; -} - -static int -getProcessedBuffer(void){ - static lastBuffer = NBUF-1; - int l = lastBuffer; - - while (1) { - lastBuffer = (lastBuffer+1) % NBUF; - if (codeData->statCom[lastBuffer] & STAT_BIT) - return lastBuffer; - if (lastBuffer == l) - break; - } - return -1; -} - -static int -getBuffer(int i, int* frameNo) { - - if(codeData->statCom[i] & STAT_BIT) { - *frameNo = codeData->statCom[i] >> 24; - return (codeData->statCom[i] & 0x00FFFFFF) >> 1; - } else - return -1; -} - static long vread(Chan *, void *va, long nbytes, vlong) { static int bufpos; @@ -495,20 +103,20 @@ vread(Chan *, void *va, long nbytes, vlong) { while (count > 0) { switch (state) { case New: - while ((curbuf = getProcessedBuffer()) == -1) - sleep(&sleeper, return0, 0); - fragsize = getBuffer(curbuf, &frameno); + 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 (frameno != (frameprev + 1) % 256) + 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); - prepareBuffer(curbuf); + codeData->statCom[curbuf] = PADDR(&(codeData->fragdesc[curbuf])); break; } // Fill in APP marker fields here @@ -550,7 +158,7 @@ vread(Chan *, void *va, long nbytes, vlong) { p += i; // Allow reuse of current buffer - prepareBuffer(curbuf); + codeData->statCom[curbuf] = PADDR(&(codeData->fragdesc[curbuf])); state = New; if (singleFrame) { state = Error; @@ -577,11 +185,7 @@ vwrite(Chan *, void *va, long nbytes, vlong) { while (count > 0) { switch (state) { case New: - while((curbuf = getProcessedBuffer()) == -1) { - if (debug&DBGWRIT) - pprint("devlml::sleep\n"); - sleep(&sleeper, return0, 0); - } + curbuf = getbuffer(); if (debug&DBGWRIT) pprint("current buffer %d\n", curbuf); bufptr = codeData->frag[curbuf].fb; @@ -638,9 +242,9 @@ vwrite(Chan *, void *va, long nbytes, vlong) { p += i; count -= i; // We have written the frame, time to display it - i = prepareBuffer(curbuf); + codeData->statCom[curbuf] = PADDR(&(codeData->fragdesc[curbuf])); if (debug&DBGWRIT) - pprint("Sending buffer %d: %d\n", curbuf, i); + pprint("Sending buffer %d\n", curbuf); if (singleFrame) { state = Error; return nbytes - count; @@ -658,10 +262,8 @@ static void lmlintr(Ureg *, void *); static void lmlreset(void) { -// LMLSEG Physseg segbuf; Physseg segreg; -// ulong regpa; ulong cdsize; int i; @@ -682,7 +284,7 @@ lmlreset(void) // Get access to DMA memory buffer memset(codeData, 0xAA, sizeof(CodeData)); - codeData->physaddr = PADDR(&(codeData->statCom[0])); + codeData->physaddr = PADDR(codeData->statCom); for (i = 0; i < NBUF; i++) { codeData->statCom[i] = PADDR(&(codeData->fragdesc[i])); codeData->fragdesc[i].addr = PADDR(&(codeData->frag[i])); @@ -704,23 +306,9 @@ lmlreset(void) pciBaseAddr = (ulong)KADDR(regpa); print(", mapped at 0x%.8lux\n", pciBaseAddr); - // make sure the device will respond to mem accesses - // (pcicmd_master | pcicmd_memory) -- probably superfluous -// pcicfgw32(pcidev, PciPCR, 0x04 | 0x02); - - // set bus latency -- probably superfluous -// pcicfgw8(pcidev, PciLTR, 64); - // Interrupt handler intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf); -#ifdef MEMMAP - lmlmap.pci = pciBaseAddr; - lmlmap.statcom = PADDR(codeData->statCom); - lmlmap.codedata = (ulong)codeData; -#endif - -// LMLSEG memset(&segbuf, 0, sizeof(segbuf)); segbuf.attr = SG_PHYSICAL; segbuf.name = smalloc(NAMELEN); @@ -742,8 +330,6 @@ lmlreset(void) print("lml: physsegment: lmlmjpg\n"); return; } -// - return; } @@ -771,17 +357,9 @@ lmlopen(Chan *c, int omode) { c->aux = 0; switch(c->qid.path){ -#ifdef MEMMAP - case Q060: - case Q819: - case Q856: - case Qreg: - case Qmap: - case Qbuf: - break; -#endif case Qjframe: case Qjvideo: + case Qjcount: if (nopens) error(Einuse); nopens = 1; @@ -800,18 +378,9 @@ static void lmlclose(Chan *c) { switch(c->qid.path){ -#ifdef MEMMAP - case Q060: - case Q819: - case Q856: - case Qreg: - case Qmap: - case Qbuf: - authclose(c); - break; -#endif case Qjvideo: case Qjframe: + case Qjcount: nopens = 0; authclose(c); } @@ -819,9 +388,6 @@ lmlclose(Chan *c) { static long lmlread(Chan *c, void *va, long n, vlong voff) { -#ifdef MEMMAP - int i, d; -#endif uchar *buf = va; long off = voff; @@ -829,188 +395,23 @@ lmlread(Chan *c, void *va, long n, vlong voff) { case Qdir: return devdirread(c, (char *)buf, n, lmldir, nelem(lmldir), devgen); - -#ifdef MEMMAP - case Q060: - if (off < 0 || off + n > 0x400) - return 0; - for (i = 0; i < n; i++) { - if ((d = zr060_read(off + i)) < 0) break; - *buf++ = d; - } - return i; - case Q819: - if (off < 0 || off + n > 0x20) - return 0; - for (i = 0; i < n; i++) { - if ((d = i2c_rd8(BT819Addr, off++)) < 0) break; - *buf++ = d; - } - return i; - case Q856: - if (n != 1) - return 0; - switch ((int)off) { - case 0: - if ((d = i2c_bt856rd8()) < 0) - return 0; - *buf = d; - break; - case 0xDA: - *buf = q856[0]; - break; - case 0xDC: - *buf = q856[1]; - break; - case 0xDE: - *buf = q856[2]; - break; - default: - return 0; - } - return 1; - case Qmap: - if (off < 0) - return 0; - for (i = 0; i < n; i++) { - if (off + i >= sizeof lmlmap) - break; - buf[i] = ((uchar *)&lmlmap)[off + i]; - } - return i; - case Qreg: - if (off < 0 || off + n >= 0x400) - return 0; - switch(n) { - case 1: - *buf = readb(pciBaseAddr + off); - break; - case 2: - if (off & (n-1)) return 0; - *(short *)buf = readw(pciBaseAddr + off); - break; - case 4: - if (off & (n-1)) return 0; - *(long *)buf = readl(pciBaseAddr + off); - break; - default: - return 0; - } - return n; - case Qbuf: - if (off < 0 || off + n >= sizeof *codeData) - return 0; - switch(n) { - case 1: - *buf = readb((ulong)codeData + off); - break; - case 2: - if (off & (n-1)) return 0; - *(short *)buf = readw((ulong)codeData + off); - break; - case 4: - if (off & (n-1)) return 0; - *(long *)buf = readl((ulong)codeData + off); - break; - default: - return 0; - } - return n; -#endif 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) { -#ifdef MEMMAP - int i; -#endif uchar *buf = va; long off = voff; switch(c->qid.path & ~CHDIR){ - case Qdir: + case Qjcount: error(Eperm); - -#ifdef MEMMAP - case Q060: - if (off < 0 || off + n > 0x400) - return 0; - for (i = 0; i < n; i++) { - if (zr060_write(off + i, *buf++) < 0) break; - } - return i; - case Q819: - if (off < 0 || off + n >= 0x20) - return 0; - for (i = 0; i < n; i++) - if (i2c_wr8(BT819Addr, off + i, *buf++) == 0) - break; - return i; - case Q856: - if (n != 1 || off < 0xda || off + n > 0xe0) - return 0; - if (i2c_wr8(BT856Addr, off, *buf) == 0) - return 0; - switch ((int)off) { - case 0xDA: - q856[0] = *buf; - break; - case 0xDC: - q856[1] = *buf; - break; - case 0xDE: - q856[2] = *buf; - break; - } - return 1; - case Qreg: - if (off < 0 || off + n >= 0x400) - return 0; - switch (n) { - case 1: - writeb(*buf, pciBaseAddr + off); - break; - case 2: - if (off & 0x1) - return 0; - writew(*(short *)buf, pciBaseAddr + off); - break; - case 4: - if (off & 0x3) - return 0; - writel(*(long *)buf, pciBaseAddr + off); - break; - default: - return 0; - } - return n; - case Qbuf: - if (off < 0 || off + n >= sizeof *codeData) - return 0; - switch (n) { - case 1: - writeb(*buf, (ulong)codeData + off); - break; - case 2: - if (off & 0x1) - return 0; - writew(*(short *)buf, (ulong)codeData + off); - break; - case 4: - if (off & 0x3) - return 0; - writel(*(long *)buf, (ulong)codeData + off); - break; - default: - return 0; - } - return n; -#endif case Qjvideo: case Qjframe: return vwrite(c, buf, n, off); diff --git a/port/alloc.c b/port/alloc.c index 7048b5b76ada9d792eb5b33add5d9b4e728a7b09..676b33512a101abbab08f281eb7e0971324c8287 100644 --- a/port/alloc.c +++ b/port/alloc.c @@ -368,7 +368,7 @@ malloc(ulong size) v = poolalloc(mainmem, size); if(v != nil) memset(v, 0, size); -{ +if(v != nil){ Bhdr *h; D2B(h, v); B2T(h)->pad = getcallerpc(&size); @@ -403,11 +403,11 @@ mallocz(ulong size, int clr) v = poolalloc(mainmem, size); if(clr && v != nil) -{ + memset(v, 0, size); +if(v != nil){ Bhdr *h; D2B(h, v); B2T(h)->pad = getcallerpc(&size); - memset(v, 0, size); } return v; }