M alphapc/devether.c => alphapc/devether.c +1 -1
@@ 356,7 356,7 @@ etherreset(void)
ether->irq = 9;
intrenable(VectorPCI+ether->irq, ether->interrupt, ether, ether->tbdf);
- i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %d",
+ i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %ld",
ctlrno, ether->type, ether->mbps, ether->port, ether->irq);
if(ether->mem)
i += sprint(buf+i, " addr 0x%luX", PADDR(ether->mem));
M alphapc/fns.h => alphapc/fns.h +2 -2
@@ 71,8 71,8 @@ void pcisetbme(Pcidev*);
void prflush(void);
void printinit(void);
#define procrestore(p)
-#define procsave(p)
-#define procsetup(p) ((p)->fpstate = FPinit)
+void procsave(Proc*);
+void procsetup(Proc*);
void restfpregs(FPsave*);
uvlong rpcc(uvlong*);
void screeninit(void);
M alphapc/l.s => alphapc/l.s +37 -34
@@ 1,6 1,6 @@
#include "mem.h"
-#define SP R30
+#define SP R30
#define HI_IPL 6 /* use 7 to disable mchecks */
@@ 23,48 23,45 @@ clrbss:
MOVL R0, bootconf(SB) /* passed in from boot loader */
_fpinit:
- MOVQ R0, R16
+ MOVQ $1, R16
CALL_PAL $PALwrfen
- MOVQ $1, R1
- SLLQ $59, R1 /* normal rounding mode */
+
+ MOVQ initfpcr(SB), R1 /* MOVQ $0x2800800000000000, R1 */
MOVQ R1, (R30)
MOVT (R30), F1
- EXCB
MOVT F1, FPCR
- EXCB
MOVT $0.5, F28
ADDT F28, F28, F29
ADDT F29, F29, F30
- SUBT F28, F28, F0
- MOVT F0, F1
- MOVT F0, F2
- MOVT F0, F3
- MOVT F0, F4
- MOVT F0, F5
- MOVT F0, F6
- MOVT F0, F7
- MOVT F0, F8
- MOVT F0, F9
- MOVT F0, F10
- MOVT F0, F11
- MOVT F0, F12
- MOVT F0, F13
- MOVT F0, F14
- MOVT F0, F15
- MOVT F0, F16
- MOVT F0, F17
- MOVT F0, F18
- MOVT F0, F19
- MOVT F0, F20
- MOVT F0, F21
- MOVT F0, F22
- MOVT F0, F23
- MOVT F0, F24
- MOVT F0, F25
- MOVT F0, F26
- MOVT F0, F27
+ MOVT F31, F1
+ MOVT F31, F2
+ MOVT F31, F3
+ MOVT F31, F4
+ MOVT F31, F5
+ MOVT F31, F6
+ MOVT F31, F7
+ MOVT F31, F8
+ MOVT F31, F9
+ MOVT F31, F10
+ MOVT F31, F11
+ MOVT F31, F12
+ MOVT F31, F13
+ MOVT F31, F14
+ MOVT F31, F15
+ MOVT F31, F16
+ MOVT F31, F17
+ MOVT F31, F18
+ MOVT F31, F19
+ MOVT F31, F20
+ MOVT F31, F21
+ MOVT F31, F22
+ MOVT F31, F23
+ MOVT F31, F24
+ MOVT F31, F25
+ MOVT F31, F26
+ MOVT F31, F27
JSR main(SB)
MOVQ $_divq(SB), R31 /* touch _divq etc.; doesn't need to execute */
@@ 380,9 377,15 @@ TEXT savefpregs(SB), $-8
MOVT F31, 0xF8(R0)
MOVT FPCR, F0
MOVT F0, 0x100(R0)
+
+ MOVQ $0, R16
+ CALL_PAL $PALwrfen /* disable */
RET
TEXT restfpregs(SB), $-8
+ MOVQ $1, R16
+ CALL_PAL $PALwrfen /* enable */
+
MOVT 0x100(R0), F0
MOVT F0, FPCR
MOVT 0x00(R0), F0
M alphapc/main.c => alphapc/main.c +44 -7
@@ 15,6 15,7 @@ Hwrpb *hwrpb;
Bootconf *bootconf;
Conf conf;
FPsave initfp;
+uvlong initfpcr = 0x2800800000000000LL;
void
main(void)
@@ 26,8 27,6 @@ main(void)
clockinit();
confinit();
archinit();
- savefpregs(&initfp);
- fpenab(0);
mmuinit();
xinit();
printinit();
@@ 47,8 46,8 @@ main(void)
#ifdef NEVER
percpu = hwrpb + (hwrpb[40]>>2);
-// percpu[32] |= 2; /* restart capable */
- percpu[32] &= ~1; /* boot in progress - not */
+// percpu[32] |= 2; /* restart capable */
+ percpu[32] &= ~1; /* boot in progress - not */
// percpu[32] |= (3<<16); /* warm boot requested */
// percpu[32] |= (2<<16); /* cold boot requested */
// percpu[32] |= (4<<16); /* stay halted */
@@ 61,6 60,8 @@ main(void)
chandevreset();
pageinit();
swapinit();
+ savefpregs(&initfp);
+initfp.fpstatus = 0x68028000;
userinit();
schedinit();
}
@@ 131,9 132,7 @@ userinit(void)
strcpy(p->text, "*init*");
strcpy(p->user, eve);
- p->fpstate = FPinit;
- p->fpsave.fpstatus = initfp.fpstatus;
- fpenab(0);
+ procsetup(p);
/*
* Kernel Stack
@@ 171,6 170,44 @@ userinit(void)
}
void
+procsetup(Proc *p)
+{
+ p->fpstate = FPinit;
+ fpenab(0);
+}
+
+void
+procsave(Proc *p)
+{
+ if(p->fpstate == FPactive){
+ if(p->state == Moribund)
+ fpenab(0);
+ else{
+ /*
+ * Fpsave() stores without handling pending
+ * unmasked exeptions. Postnote() can't be called
+ * here as sleep() already has up->rlock, so
+ * the handling of pending exceptions is delayed
+ * until the process runs again and generates an
+ * emulation fault to activate the FPU.
+ */
+ savefpregs(&up->fpsave);
+//print("PS=%lux+", up->fpsave.fpstatus);
+ }
+ p->fpstate = FPinactive;
+ }
+
+ /*
+ * Switch to the prototype page tables for this processor.
+ * While this processor is in the scheduler, the process could run
+ * on another processor and exit, returning the page tables to
+ * the free list where they could be reallocated and overwritten.
+ * When this processor eventually has to get an entry from the
+ * trashed page tables it will crash.
+ */
+}
+
+void
exit(int)
{
canlock(&active);
M alphapc/trap.c => alphapc/trap.c +26 -40
@@ 46,11 46,6 @@ trap(Ureg *ur)
if(user){
up = m->proc;
up->dbgreg = ur;
- if(up && up->fpstate == FPactive) {
- up->fpstate = FPinactive;
- savefpregs(&up->fpsave);
- fpenab(0);
- }
}
switch ((int)ur->type) {
case 1: /* arith */
@@ 82,15 77,9 @@ trap(Ureg *ur)
break;
}
- splhi();
- if(!user)
- return;
-
- notify(ur);
- if(up->fpstate == FPinactive) {
- fpenab(1);
- restfpregs(&up->fpsave);
- up->fpstate = FPactive;
+ if(user && (up->procctl || up->nnote)){
+ splhi();
+ notify(ur);
}
}
@@ 500,32 489,32 @@ syscall(Ureg *aur)
up->dbgreg = aur;
ur->type = 5; /* for debugging */
- if(up->fpstate == FPactive) {
- up->fpsave.fpstatus = getfcr();
- up->fpstate = FPinit;
- fpenab(0);
+ up->scallnr = ur->r0;
+
+ if(up->scallnr == RFORK && up->fpstate == FPactive){
+ savefpregs(&up->fpsave);
+ up->fpstate = FPinactive;
+//print("SR=%lux+", up->fpsave.fpstatus);
}
spllo();
- if(up->procctl)
- procctl(up);
-
- up->scallnr = ur->r0;
- up->nerrlab = 0;
sp = ur->sp;
+ up->nerrlab = 0;
ret = -1;
if(waserror())
goto error;
if(up->scallnr >= nsyscall){
- pprint("bad sys call %d pc %lux\n", up->scallnr, (ulong)ur->pc);
+ pprint("bad sys call %d pc %lux\n",
+ up->scallnr, (ulong)ur->pc);
print("bad sys call %d pc %lux\n", up->scallnr, (ulong)ur->pc);
postnote(up, 1, "sys: bad sys call", NDebug);
error(Ebadarg);
}
if(sp & (BY2WD-1)){ /* XXX too weak? */
- pprint("odd sp in sys call pc %lux sp %lux\n", (ulong)ur->pc, (ulong)ur->sp);
+ pprint("odd sp in sys call pc %lux sp %lux\n",
+ (ulong)ur->pc, (ulong)ur->sp);
postnote(up, 1, "sys: odd stack", NDebug);
error(Ebadarg);
}
@@ 543,19 532,15 @@ error:
up->nerrlab = 0;
up->psstate = 0;
up->insyscall = 0;
- if(up->scallnr == NOTED) /* ugly hack */
+ if(up->scallnr == NOTED) /* ugly hack */
noted(ur, &aur, *(ulong*)(sp+2*BY2WD)); /* doesn't return */
- splhi();
if(up->scallnr!=RFORK && (up->procctl || up->nnote)){
ur->r0 = ret; /* load up for noted() */
if(notify(ur))
return ur->r0;
}
- if(up->fpstate == FPinactive) /* due to race with intr */
- up->fpstate = FPinit;
-
return ret;
}
@@ 605,7 590,6 @@ execregs(ulong entry, ulong ssize, ulong nargs)
ur = (Ureg*)up->dbgreg;
ur->usp = (ulong)sp;
ur->pc = entry;
- up->fpsave.fpstatus = initfp.fpstatus;
return USTKTOP-BY2WD; /* address of user-level clock */
}
@@ 683,18 667,20 @@ illegal(Ureg *ur)
void
fen(Ureg *ur)
{
- ulong fpcr;
-
- if ((ur->status&UMODE) && up) {
- if(up->fpstate == FPinit) {
+ if(up){
+ switch(up->fpstate){
+ case FPinit:
+ restfpregs(&initfp);
up->fpstate = FPactive;
- fpcr = up->fpsave.fpstatus;
- up->fpsave = initfp;
- up->fpsave.fpstatus = fpcr;
- fpenab(1);
+//print("EI=%lux+", initfp.fpstatus);
+ return;
+
+ case FPinactive:
restfpregs(&up->fpsave);
+ up->fpstate = FPactive;
+//print("EIA=%lux+", up->fpsave.fpstatus);
return;
}
}
- fataltrap(ur, "trap: floating enable"); /* should never happen */
+ fataltrap(ur, "trap: floating enable"); /* should never happen */
}
M pc/devlml.c => pc/devlml.c +116 -13
@@ 8,6 8,11 @@
#include "devlml.h"
+#define DBGREGS 0x1
+#define DBGREAD 0x2
+#define DBGWRIT 0x4
+int debug = DBGREAD|DBGWRIT;
+
// Lml 22 driver
enum{
@@ 15,6 20,7 @@ enum{
Q819,
Q856,
Qreg,
+ Qmap,
Qjvideo,
Qjframe,
};
@@ 24,6 30,7 @@ static Dirtab lmldir[]={
"lml819", {Q819}, 0, 0644,
"lml856", {Q856}, 0, 0644,
"lmlreg", {Qreg}, 0, 0644,
+ "lmlmap", {Qmap}, 0, 0444,
"jvideo", {Qjvideo}, 0, 0666,
"jframe", {Qjframe}, 0, 0666,
};
@@ 41,12 48,75 @@ 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'},
-1, 0, 0, 0, 0
};
+ulong
+writel(ulong v, ulong a) {
+ if (debug&DBGREGS)
+ pprint("writing %.8lux to %.8lux (%.4lux)\n",
+ v, a, (ulong)a-pciBaseAddr);
+ 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);
+ 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);
+ return *(uchar *)a = v;
+}
+
+ulong
+readl(ulong a) {
+ ulong v;
+
+ v = *(ulong*)a;
+ if (debug&DBGREGS)
+ pprint("reading %.8lux from %.8lux (%.4lux)\n",
+ v, a, (ulong)a-pciBaseAddr);
+ return v;
+}
+
+ushort
+readw(ulong a) {
+ ushort v;
+
+ v = *(ushort*)a;
+ if (debug&DBGREGS)
+ pprint("reading %.4ux from %.8lux (%.4lux)\n",
+ v, a, (ulong)a-pciBaseAddr);
+ return v;
+}
+
+uchar
+readb(ulong a) {
+ uchar v;
+
+ v = *(uchar*)a;
+ if (debug&DBGREGS)
+ pprint("reading %.2ux from %.8lux (%.4lux)\n",
+ v, a, (ulong)a-pciBaseAddr);
+ return v;
+}
+
static void
i2c_pause(void) {
@@ 222,6 292,7 @@ i2c_rd8(int addr, int sub)
if (i2c_wrbyte(addr) == 1
|| i2c_wrbyte(sub) == 1) {
+ if (debug&DBGREGS) pprint("i2c_rd8, failure 1\n");
i2c_stop();
return -1;
}
@@ 230,6 301,7 @@ i2c_rd8(int addr, int sub)
if (i2c_wrbyte(addr+1) == 1
|| i2c_rdbyte(&msb) == 0){
+ if (debug&DBGREGS) pprint("i2c_rd8, failure 2\n");
i2c_stop();
return -1;
}
@@ 303,10 375,13 @@ vread(Chan *, void *va, long count, vlong pos) {
vlong thetime;
uchar *buf = va;
- //print("devlml::vread() count=%ld pos=%lld\n", count, pos);
+ if(debug&DBGREAD)
+ pprint("devlml::vread() count=%ld pos=%lld\n", count, pos);
// If we just begin reading a file, pos would never be 0 otherwise
if (pos == 0 && hdrPos == -1) {
+ if(debug&DBGREAD)
+ pprint("devlml::first read\n");
currentBuffer = -1;
currentBufferLength = 0;
frameNo = -1;
@@ 316,12 391,18 @@ vread(Chan *, void *va, long count, vlong pos) {
// We get to the end of the current buffer, also covers just
// open file, since 0 >= -1
if(hdrPos == -1 && pos >= currentBufferLength) {
+ if(debug&DBGREAD)
+ pprint("devlml::prepareBuffer\n");
prepareBuffer(codeData, currentBuffer);
// if not the first buffer read and single frame mode - return EOF
if (currentBuffer != -1 && singleFrame)
return 0;
+ if(debug&DBGREAD)
+ pprint("devlml::sleep\n");
while((currentBuffer = getProcessedBuffer(codeData)) == -1)
sleep(&sleeper, return0, 0);
+ if(debug&DBGREAD)
+ pprint("devlml::wokeup\n");
currentBufferLength = getBuffer(codeData, currentBuffer,
¤tBufferPtr, &frameNo);
@@ 362,7 443,7 @@ vread(Chan *, void *va, long count, vlong pos) {
memmove(buf + retcount, (char *)currentBufferPtr + pos, cpcount);
retcount += cpcount;
- //pr_debug("return %d %d\n",cpcount,retcount);
+ //pr_debug&DBGREGS("return %d %d\n",cpcount,retcount);
return retcount;
}
@@ 511,6 592,10 @@ lmlreset(void)
// Interrupt handler
intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf);
+ lmlmap.pci = pciBaseAddr;
+ lmlmap.dma = PADDR(codeData);
+ lmlmap.codedata = (ulong)codeData;
+
return;
}
@@ 540,6 625,7 @@ lmlopen(Chan *c, int omode)
case Q819:
case Q856:
case Qreg:
+ case Qmap:
break;
case Qjvideo:
case Qjframe:
@@ 566,8 652,12 @@ lmlclose(Chan *c)
case Q819:
case Q856:
case Qreg:
+ case Qmap:
+ authclose(c);
+ break;
case Qjvideo:
case Qjframe:
+ nopens = 0;
authclose(c);
}
}
@@ 577,7 667,6 @@ lmlread(Chan *c, void *va, long n, vlong voff) {
int i, d;
uchar *buf = va;
long off = voff;
- long v;
switch(c->qid.path & ~CHDIR){
@@ 591,7 680,7 @@ lmlread(Chan *c, void *va, long n, vlong voff) {
if ((d = i2c_rd8(BT819Addr, off++)) < 0) break;
*buf++ = d;
}
- return n - i;
+ return i;
case Q856:
if (n != 1)
return 0;
@@ 614,6 703,15 @@ lmlread(Chan *c, void *va, long n, vlong voff) {
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;
@@ 627,9 725,7 @@ lmlread(Chan *c, void *va, long n, vlong voff) {
break;
case 4:
if (off & (n-1)) return 0;
- v = readl(pciBaseAddr + off);
- *(long *)buf = v;
-print("reading %lux at %lux (%lux)\n", v, pciBaseAddr + off, off);
+ *(long *)buf = readl(pciBaseAddr + off);
break;
default:
return 0;
@@ 658,7 754,7 @@ lmlwrite(Chan *c, void *va, long n, vlong voff) {
for (i = n; i > 0; i--)
if (i2c_wr8(BT819Addr, off++, *buf++) == 0)
break;
- return n - i;
+ return i;
case Q856:
if (n != 1 || off < 0xda || off + n > 0xe0)
return 0;
@@ 677,17 773,20 @@ lmlwrite(Chan *c, void *va, long n, vlong voff) {
}
return 1;
case Qreg:
- if (off < 0 || off + n > 0x200 || (off & 0x3))
+ 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:
-print("writing %lux to %lux (%lux)\n", *(long *)buf, pciBaseAddr + off, off);
+ if (off & 0x3)
+ return 0;
writel(*(long *)buf, pciBaseAddr + off);
break;
default:
@@ 725,12 824,16 @@ static void
lmlintr(Ureg *, void *) {
ulong flags = readl(pciBaseAddr+ZR36057_INTR_STAT);
-// print("MjpgDrv_intrHandler stat=0x%08x\n", flags);
+ if(debug&(DBGREAD|DBGWRIT))
+ print("MjpgDrv_intrHandler stat=0x%.8lux\n", flags);
// Reset all interrupts from 067
writel(0xff000000, pciBaseAddr + ZR36057_INTR_STAT);
- if(flags & ZR36057_INTR_JPEGREP)
- wakeup(&sleeper);
+ if(flags & ZR36057_INTR_JPEGREP) {
+ if(debug&(DBGREAD|DBGWRIT))
+ print("MjpgDrv_intrHandler wakeup\n");
+ wakeup(&sleeper);
+ }
return;
}
M pc/devlml.h => pc/devlml.h +0 -7
@@ 89,13 89,6 @@ typedef struct {
#define FRAGM_FINAL_B 1
#define STAT_BIT 1
-#define writel(v, a) (*(ulong *)(a) = (v))
-#define writew(v, a) (*(ushort *)(a) = (v))
-#define writeb(v, a) (*(uchar *)(a) = (v))
-#define readl(a) (*(ulong *)(a))
-#define readw(a) (*(ushort *)(a))
-#define readb(a) (*(uchar *)(a))
-
typedef struct FrameHeader FrameHeader;
typedef struct MjpgDrv MjpgDrv;
typedef struct Fragment Fragment;