From d2032635ec21ce135468b0679260783d81ad1486 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 29 Apr 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-04-29 --- alphapc/axp.h | 2 +- alphapc/clock.c | 99 ++++++++++++++------------- alphapc/dat.h | 11 +-- alphapc/fns.h | 2 + ip/il.c | 10 +-- pc/devlml.c | 173 ++++++++++++++++++++++++++++++------------------ pc/devlml.h | 2 + 7 files changed, 176 insertions(+), 123 deletions(-) diff --git a/alphapc/axp.h b/alphapc/axp.h index 8ce9c6f15239238f7e6ae525b5976ea7d55cc840..102a6b66de57de6ca0cba0b4c722aee4a9156eb1 100644 --- a/alphapc/axp.h +++ b/alphapc/axp.h @@ -12,7 +12,7 @@ struct Hwrpb uvlong by2pg; uvlong pabits; uvlong maxasn; - char ssn[16]; + char ssn[16]; uvlong systype; uvlong sysvar; uvlong sysrev; diff --git a/alphapc/clock.c b/alphapc/clock.c index 02922f2eed37302a1998f2f5c994dc0be9440494..46950b030acbc0843ddc21be60bc4037046d4559 100644 --- a/alphapc/clock.c +++ b/alphapc/clock.c @@ -4,6 +4,7 @@ #include "dat.h" #include "fns.h" #include "io.h" +#include "axp.h" #include "ureg.h" @@ -34,57 +35,69 @@ addclock0link(void (*clock)(void)) iunlock(&clock0lock); } - -/* - * delay for l milliseconds more or less. delayloop is set by - * clockinit() to match the actual CPU speed. - */ void -delay(int l) +clockinit(void) +{ +} + +uvlong +cycletimer(void) +{ + ulong pcc; + + pcc = rpcc(nil) & 0xFFFFFFFF; + if(m->cpuhz == 0){ + /* + * pcclast is needed to detect wraparound of + * the cycle timer which is only 32-bits. + * m->cpuhz is set from the info passed from + * the firmware. + * This could be in clockinit if can + * guarantee no wraparound between then and now. + * + * All the clock stuff needs work. + */ + m->cpuhz = hwrpb->cfreq; + m->pcclast = pcc; + } + if(pcc < m->pcclast) + m->fastclock += 0x100000000LL; + m->fastclock += pcc; + m->pcclast = pcc; + + return MACHP(0)->fastclock; +} + +vlong +fastticks(uvlong* hz) { - ulong i, j; + uvlong ticks; + int x; + + x = splhi(); + ticks = cycletimer(); + splx(x); - j = m->delayloop; - while(l-- > 0) - for(i=0; i < j; i++) - ; + if(hz) + *hz = m->cpuhz; + + return (vlong)ticks; } void -microdelay(int l) +microdelay(int us) { - ulong i, j; + uvlong eot; -// j = m->delayloop/1000; -j = 10000; - while(l-- > 0) - for(i=0; i < j; i++) - ; + eot = cycletimer() + (m->cpuhz/1000000)*us; + while(cycletimer() < eot) + ; } void -clockinit(void) +/*milli*/delay(int ms) { -m->delayloop = 250*1000; /* BUG */ -#ifdef NOTYET - long x; - - m->delayloop = m->speed*100; - do { - x = rdcount(); - delay(10); - x = rdcount() - x; - } while(x < 0); - - /* - * fix count - */ - m->delayloop = (m->delayloop*m->speed*1000*10)/x; - if(m->delayloop == 0) - m->delayloop = 1; - -/* wrcompare(rdcount()+(m->speed*1000000)/HZ); */ -#endif + microdelay(ms*1000); } void @@ -136,11 +149,3 @@ clock(Ureg *ur) segclock(ur->pc); } } - -vlong -fastticks(uvlong *hz) -{ - if (hz) - *hz = 100; - return m->ticks; -} diff --git a/alphapc/dat.h b/alphapc/dat.h index be53548d71ed666ead0de691effe1e995d717d9d..9ed070a0ce6d1dbea8e5cdbc73dae598a697cd2c 100644 --- a/alphapc/dat.h +++ b/alphapc/dat.h @@ -135,24 +135,25 @@ struct Mach Proc *proc; /* current process on this processor */ /* ordering from here on irrelevant */ - int tlbfault; /* only used by devproc; no access to tlb */ - int tlbpurge; /* ... */ + int tlbfault; /* only used by devproc; no access to tlb */ + int tlbpurge; /* ... */ ulong ticks; /* of the clock since boot time */ Label sched; /* scheduler wakeup */ Lock alarmlock; /* access to alarm list */ void *alarm; /* alarms bound to this clock */ Page *ufreeme; /* address of upage of exited process */ - int speed; /* cpu speed */ - ulong delayloop; /* for the delay() routine */ int nrdy; ulong fairness; /* for runproc */ + ulong cpuhz; /* hwrpb->cfreq */ + ulong pcclast; + uvlong fastclock; + int pfault; int cs; int syscall; int load; int intr; - int nettime; int flushmmu; /* make current proc flush it's mmu state */ PCB; diff --git a/alphapc/fns.h b/alphapc/fns.h index 53c899ab7a33e49ac9df248979ae6429864b85ef..a44245b108df22d65ba33bdad4e950b2d7a81e4c 100644 --- a/alphapc/fns.h +++ b/alphapc/fns.h @@ -69,12 +69,14 @@ void pcicfgw32(Pcidev*, int, int); void pcihinv(Pcidev*); Pcidev* pcimatch(Pcidev*, int, int); void pcireset(void); +void pcisetbme(Pcidev*); void prflush(void); void printinit(void); #define procrestore(p) #define procsave(p) #define procsetup(p) ((p)->fpstate = FPinit) void restfpregs(FPsave*); +uvlong rpcc(uvlong*); void screeninit(void); void (*screenputs)(char*, int); void setpcb(PCB *); diff --git a/ip/il.c b/ip/il.c index a15fab4e63be4e846993c571983bfe82a2eb8657..757ba465ca414c2955c9ec07e3c11a15b66039c2 100644 --- a/ip/il.c +++ b/ip/il.c @@ -265,6 +265,7 @@ ilclose(Conv *c) case Ilsyncee: case Ilestablished: ic->state = Ilclosing; + ilsettimeout(ic); ilsendctl(c, nil, Ilclose, ic->next, ic->recvd, 0); break; case Illistening: @@ -349,7 +350,7 @@ ilkick(Conv *c, int l) ic->rttlen = dlen + IL_IPSIZE + IL_HDRSIZE; } - if(ic->timeout <= msec) + if(later(msec, ic->timeout, "ilkick")) ilsettimeout(ic); ipoput(f, bp, 0, c->ttl); } @@ -727,6 +728,7 @@ _ilprocess(Conv *s, Ilhdr *h, Block *bp) break; ilsendctl(s, nil, Ilclose, ic->next, ic->recvd, 0); ic->state = Ilclosing; + ilsettimeout(ic); ilfreeq(ic); break; } @@ -1066,7 +1068,7 @@ loop: case Illistening: break; case Ilclosing: - if(later(msec, ic->timeout, "timeout")) { + if(later(msec, ic->timeout, "timeout0")) { if(ic->rexmit > MaxRexmit){ ilhangup(p, nil); break; @@ -1078,7 +1080,7 @@ loop: case Ilsyncee: case Ilsyncer: - if(later(msec, ic->timeout, "timeout")) { + if(later(msec, ic->timeout, "timeout1")) { if(ic->rexmit > MaxRexmit){ ilhangup(p, etime); break; @@ -1104,7 +1106,7 @@ loop: } if(ic->unacked != nil) - if(later(msec, ic->timeout, "timeout")) { + if(later(msec, ic->timeout, "timeout2")) { if(ic->rexmit > MaxRexmit){ netlog(il->f, Logil, "il: hangup: too many rexmits\n"); ilhangup(p, etime); diff --git a/pc/devlml.c b/pc/devlml.c index 397dd3d207c92bc12979d6f48f7ec6b077356f77..7208d0167ca925285ce974a8e32b2248be2cf167 100644 --- a/pc/devlml.c +++ b/pc/devlml.c @@ -38,6 +38,7 @@ int singleFrame; int bufferPrepared; int hdrPos; int nopens; +uchar q856[3]; static FrameHeader frameHeader = { MRK_SOI, MRK_APP3, (sizeof(FrameHeader)-4) << 8, @@ -46,13 +47,13 @@ static FrameHeader frameHeader = { }; static void -lml33_i2c_pause(void) { +i2c_pause(void) { microdelay(I2C_DELAY); } static void -lml33_i2c_waitscl(void) { +i2c_waitscl(void) { int i; ulong a; @@ -64,68 +65,68 @@ lml33_i2c_waitscl(void) { } static void -lml33_i2c_start(void) { +i2c_start(void) { writel(ZR36057_I2C_SCL|ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); - lml33_i2c_waitscl(); - lml33_i2c_pause(); + i2c_waitscl(); + i2c_pause(); writel(ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS); - lml33_i2c_pause(); + i2c_pause(); writel(0, pciBaseAddr + ZR36057_I2C_BUS); - lml33_i2c_pause(); + i2c_pause(); } static void -lml33_i2c_stop(void) { +i2c_stop(void) { // the clock should already be low, make sure data is writel(0, pciBaseAddr + ZR36057_I2C_BUS); - lml33_i2c_pause(); + i2c_pause(); // set clock high and wait for device to catch up writel(ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS); - lml33_i2c_waitscl(); - lml33_i2c_pause(); + i2c_waitscl(); + i2c_pause(); // set the data high to indicate the stop bit writel(ZR36057_I2C_SCL|ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); - lml33_i2c_pause(); + i2c_pause(); } -static void lml33_i2c_wrbit(int bit) { +static void i2c_wrbit(int bit) { if (bit){ writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); // set data - lml33_i2c_pause(); + i2c_pause(); writel(ZR36057_I2C_SDA|ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS); - lml33_i2c_waitscl(); - lml33_i2c_pause(); + i2c_waitscl(); + i2c_pause(); writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); - lml33_i2c_pause(); + i2c_pause(); } else { writel(0, pciBaseAddr + ZR36057_I2C_BUS); // clr data - lml33_i2c_pause(); + i2c_pause(); writel(ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS); - lml33_i2c_waitscl(); - lml33_i2c_pause(); + i2c_waitscl(); + i2c_pause(); writel(0, pciBaseAddr + ZR36057_I2C_BUS); - lml33_i2c_pause(); + i2c_pause(); } } static int -lml33_i2c_rdbit(void) { +i2c_rdbit(void) { int bit; // the clk line should be low // ensure we are not asserting the data line writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); - lml33_i2c_pause(); + i2c_pause(); // set the clock high and wait for device to catch up writel(ZR36057_I2C_SDA|ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS); - lml33_i2c_waitscl(); - lml33_i2c_pause(); + i2c_waitscl(); + i2c_pause(); // the data line should be a valid bit bit = readl(pciBaseAddr+ZR36057_I2C_BUS); @@ -137,23 +138,23 @@ lml33_i2c_rdbit(void) { // set the clock low to indicate end of cycle writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); - lml33_i2c_pause(); + i2c_pause(); return bit; } static int -lml33_i2c_rdbyte(uchar *v) { +i2c_rdbyte(uchar *v) { int i, ack; uchar res; res = 0; for (i=0;i<8;i++){ res = res << 1; - res += lml33_i2c_rdbit(); + res += i2c_rdbit(); } - ack = lml33_i2c_rdbit(); + ack = i2c_rdbit(); *v = res; @@ -161,77 +162,93 @@ lml33_i2c_rdbyte(uchar *v) { } static int -lml33_i2c_wrbyte(uchar v) { +i2c_wrbyte(uchar v) { int i, ack; for (i=0;i<8;i++){ - lml33_i2c_wrbit(v & 0x80); + i2c_wrbit(v & 0x80); v = v << 1; } - ack = lml33_i2c_rdbit(); + ack = i2c_rdbit(); return ack; } static void -lml33_i2c_write_bytes(uchar addr, uchar sub, uchar *bytes, long num) { +i2c_write_bytes(uchar addr, uchar sub, uchar *bytes, long num) { int ack; long i; - lml33_i2c_start(); + i2c_start(); - ack = lml33_i2c_wrbyte(addr); + ack = i2c_wrbyte(addr); if (ack == 1) error(Eio); - ack = lml33_i2c_wrbyte(sub); + ack = i2c_wrbyte(sub); if (ack == 1) error(Eio); for(i=0;i 0x20) return 0; for (i = 0; i < n; i++) { - if ((d = lml33_i2c_rd8(BT819Addr, off++)) < 0) break; + if ((d = i2c_rd8(BT819Addr, off++)) < 0) break; *buf++ = d; } return n - i; case Q856: - if (off < 0xda || off + n > 0xe0) + 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; - for (i = 0; i < n; i++) { - if ((d = lml33_i2c_rd8(BT856Addr, off++)) < 0) break; - *buf++ = d; } - return n - i; + return 1; case Qreg: if (off < 0 || off + n > 0x200 || (off & 0x3)) return 0; @@ -610,16 +641,26 @@ vidwrite(Chan *c, void *va, long n, vlong off) { if (off < 0 || off + n > 0x20) return 0; for (i = n; i > 0; i--) - if (lml33_i2c_wr8(BT819Addr, off++, *buf++) == 0) + if (i2c_wr8(BT819Addr, off++, *buf++) == 0) break; return n - i; case Q856: - if (off < 0xda || off + n > 0xe0) + if (n != 1 || off < 0xda || off + n > 0xe0) return 0; - for (i = n; i > 0; i--) - if (lml33_i2c_wr8(BT856Addr, off++, *buf++) == 0) - break; - return n - i; + 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 > 0x200 || (off & 0x3)) return 0; diff --git a/pc/devlml.h b/pc/devlml.h index d6ab309f45fbe3285d6d74022a1794576c9b40c6..d22414d902e9c6be74cce242d8394e3c50bd633b 100644 --- a/pc/devlml.h +++ b/pc/devlml.h @@ -40,6 +40,8 @@ // which bit of ZR36057_I2C_BUS is which #define ZR36057_I2C_SCL 1 #define ZR36057_I2C_SDA 2 +#define ZR36057_INTR_JPEGREP 0x08000000 +#define ZR36057_INTR_STAT 0x03c // A Device records the properties of the various card types supported. typedef struct {