M alphapc/axp.h => alphapc/axp.h +1 -1
@@ 12,7 12,7 @@ struct Hwrpb
uvlong by2pg;
uvlong pabits;
uvlong maxasn;
- char ssn[16];
+ char ssn[16];
uvlong systype;
uvlong sysvar;
uvlong sysrev;
M alphapc/clock.c => alphapc/clock.c +52 -47
@@ 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;
-}
M alphapc/dat.h => alphapc/dat.h +6 -5
@@ 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;
M alphapc/fns.h => alphapc/fns.h +2 -0
@@ 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 *);
M ip/il.c => ip/il.c +6 -4
@@ 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);
M pc/devlml.c => pc/devlml.c +107 -66
@@ 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<num;i+=1){
- ack = lml33_i2c_wrbyte(bytes[i]);
+ ack = i2c_wrbyte(bytes[i]);
if (ack == 1) error(Eio);
}
- lml33_i2c_stop();
+ i2c_stop();
}
static int
-lml33_i2c_rd8(int addr, int sub)
+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;
- lml33_i2c_start();
+ i2c_start();
- if (lml33_i2c_wrbyte(addr) == 1
- || lml33_i2c_wrbyte(sub) == 1) {
- lml33_i2c_stop();
+ if (i2c_wrbyte(addr) == 1
+ || i2c_wrbyte(sub) == 1) {
+ i2c_stop();
return -1;
}
- lml33_i2c_start();
+ i2c_start();
- if (lml33_i2c_wrbyte(addr+1) == 1
- || lml33_i2c_rdbyte(&msb) == 0){
- lml33_i2c_stop();
+ if (i2c_wrbyte(addr+1) == 1
+ || i2c_rdbyte(&msb) == 0){
+ i2c_stop();
return -1;
}
- lml33_i2c_stop();
+ i2c_stop();
return msb;
}
static int
-lml33_i2c_wr8(uchar addr, uchar sub, uchar msb) {
+i2c_wr8(uchar addr, uchar sub, uchar msb) {
- lml33_i2c_start();
+ i2c_start();
- if (lml33_i2c_wrbyte(addr) == 1
- || lml33_i2c_wrbyte(sub) == 1
- || lml33_i2c_wrbyte(msb) == 1)
+ if (i2c_wrbyte(addr) == 1
+ || i2c_wrbyte(sub) == 1
+ || i2c_wrbyte(msb) == 1)
return 0;
- lml33_i2c_stop();
+ i2c_stop();
return 1;
}
@@ 565,18 582,32 @@ vidread(Chan *c, void *va, long n, vlong off) {
if (off < 0 || off + n > 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;
M pc/devlml.h => pc/devlml.h +2 -0
@@ 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 {