M gnot/devduart.c => gnot/devduart.c +45 -28
@@ 324,9 324,10 @@ duartxintr(void)
void
duartintr(Ureg *ur)
{
- int cause, status, c;
+ int cause, status, ch, i, nk;
Duart *duart;
- static int kbdstate, k1, k2;
+ static int lstate;
+ static uchar kc[5];
duart = DUARTREG;
cause = duart->is_imr;
@@ 339,12 340,12 @@ duartintr(Ureg *ur)
if(cause & IM_CRDY){
if(kprofp)
(*kprofp)(ur->pc);
- c = duart[1].scc_ropbc;
- USED(c);
+ ch = duart[1].scc_ropbc;
+ USED(ch);
duart[0].ctur = (Kptime)>>8;
duart[0].ctlr = (Kptime)&255;
- c = duart[1].scc_sopbc;
- USED(c);
+ ch = duart[1].scc_sopbc;
+ USED(ch);
return;
}
/*
@@ 352,35 353,51 @@ duartintr(Ureg *ur)
*/
if(cause & IM_RRDYA){ /* keyboard input */
status = duart->sr_csr;
- c = duart->data;
+ ch = duart->data;
if(status & (FRM_ERR|OVR_ERR|PAR_ERR))
duart->cmnd = RESET_ERR;
if(status & PAR_ERR) /* control word: caps lock (0x4) or repeat (0x10) */
- kbdrepeat((c&0x10) == 0);
+ kbdrepeat((ch&0x10) == 0);
else{
- if(c == 0x7F) /* VIEW key (bizarre) */
- c = 0xFF;
- if(c == 0xB6) /* NUM PAD */
- kbdstate = 1;
+ if(ch == 0x7F) /* VIEW key (bizarre) */
+ ch = 0xFF;
+ if(ch == 0xB6) /* NUM PAD */
+ lstate = 1;
else{
- if(c & 0x80)
- c = keymap[c&0x7F];
- switch(kbdstate){
+ if(ch & 0x80)
+ ch = keymap[ch&0x7F];
+ switch(lstate){
case 1:
- k1 = c;
- kbdstate = 2;
+ kc[0] = ch;
+ lstate = 2;
+ if(ch == 'X')
+ lstate = 3;
break;
case 2:
- k2 = c;
- c = latin1(k1, k2);
- if(c == 0){
- kbdputc(&kbdq, k1);
- c = k2;
- }
- /* fall through */
+ kc[1] = ch;
+ ch = latin1(kc);
+ nk = 2;
+ putit:
+ lstate = 0;
+ if(ch != -1)
+ kbdputc(&kbdq, ch);
+ else for(i=0; i<nk; i++)
+ kbdputc(&kbdq, kc[i]);
+ break;
+ case 3:
+ case 4:
+ case 5:
+ kc[lstate-2] = ch;
+ lstate++;
+ break;
+ case 6:
+ kc[4] = ch;
+ ch = unicode(kc);
+ nk = 5;
+ goto putit;
default:
- kbdstate = 0;
- kbdputc(&kbdq, c);
+ kbdputc(&kbdq, ch);
+ break;
}
}
}
@@ 390,11 407,11 @@ duartintr(Ureg *ur)
*/
while(cause & IM_RRDYB){ /* duart input */
status = duart[1].sr_csr;
- c = duart[1].data;
+ ch = duart[1].data;
if(status & (FRM_ERR|OVR_ERR|PAR_ERR))
duart[1].cmnd = RESET_ERR;
else
- duartrintr(c);
+ duartrintr(ch);
cause = duart->is_imr;
}
/*
M gnot/trap.c => gnot/trap.c +8 -2
@@ 323,10 323,16 @@ syscall(Ureg *aur)
return ret;
}
-void
-execpc(ulong entry)
+long
+execregs(ulong entry, ulong ssize, ulong nargs)
{
+ ulong *sp;
+
+ sp = (ulong*)(USTKTOP - ssize);
+ *--sp = nargs;
+ ((Ureg*)UREGADDR)->usp = (ulong)sp;
((Ureg*)UREGADDR)->pc = entry;
+ return USTKTOP-BY2WD; /* address of user-level clock */
}
/* This routine must save the values of registers the user is not permitted to write
M pc/l.s => pc/l.s +10 -0
@@ 71,6 71,8 @@ flush:
MOVW AX,DS
MOVW AX,SS
MOVW AX,ES
+ MOVW AX,FS
+ MOVW AX,GS
/* JMPFAR SELECTOR(2, SELGDT, 0):$mode32bit(SB) /**/
BYTE $0x66
@@ 469,6 471,8 @@ TEXT intrbad(SB),$0
intrcommon:
PUSHL DS
PUSHL ES
+ PUSHL FS
+ PUSHL GS
PUSHAL
MOVL $(KDSEL),AX
MOVW AX,DS
@@ 478,6 482,8 @@ intrcommon:
CALL trap(SB)
POPL AX
POPAL
+ POPL GS
+ POPL FS
POPL ES
POPL DS
ADDL $8,SP /* error code and trap type */
@@ 486,6 492,8 @@ intrcommon:
intrscommon:
PUSHL DS
PUSHL ES
+ PUSHL FS
+ PUSHL GS
PUSHAL
MOVL $(KDSEL),AX
MOVW AX,DS
@@ 495,6 503,8 @@ intrscommon:
CALL trap(SB)
POPL AX
POPAL
+ POPL GS
+ POPL FS
POPL ES
POPL DS
ADDL $8,SP /* error code and trap type */
M pc/mem.h => pc/mem.h +2 -3
@@ 43,7 43,7 @@
#define KZERO 0x80000000 /* base of kernel address space */
#define KTZERO KZERO /* first address in kernel text */
#define USERADDR 0xC0000000 /* struct User */
-#define UREGADDR (USERADDR+BY2PG-4*17)
+#define UREGADDR (USERADDR+BY2PG-4*19)
#define TSTKTOP USERADDR /* end of new stack in sysexec */
#define TSTKSIZ 10
#define USTKTOP (TSTKTOP-TSTKSIZ*BY2PG) /* byte just beyond user stack */
@@ 62,8 62,7 @@
#define KESEG 2 /* kernel executable */
#define UDSEG 3 /* user data/stack */
#define UESEG 4 /* user executable */
-#define SYSGATE 5 /* system call gate */
-#define TSSSEG 6 /* task segment */
+#define TSSSEG 5 /* task segment */
#define SELGDT (0<<3) /* selector is in gdt */
#define SELLDT (1<<3) /* selector is in ldt */
M pc/mmu.c => pc/mmu.c +3 -25
@@ 65,7 65,6 @@ Segdesc gdt[] =
[KESEG] EXECSEGM(0), /* kernel code */
[UDSEG] DATASEGM(3), /* user data/stack */
[UESEG] EXECSEGM(3), /* user code */
-[SYSGATE] CALLGATE(KESEL,0,3), /* call gate for system calls */
[TSSSEG] TSSSEGM(0,0), /* tss segment */
};
@@ 87,19 86,6 @@ static ulong *upt; /* 2nd level page table for struct User */
*/
#define BTMOFF(v) (((v)>>(PGSHIFT))&(WD2PG-1))
-void
-mmudump(void)
-{
- int i;
- ulong *z;
- z = (ulong*)gdt;
- for(i = 0; i < sizeof(gdt)/4; i+=2)
- print("%8.8lux %8.8lux\n", *z++, *z++);
- print("UESEL %lux UDSEL %lux\n", UESEL, UDSEL);
- print("KESEL %lux KDSEL %lux\n", KESEL, KDSEL);
- panic("done");
-}
-
/*
* Create a prototype page map that maps all of memory into
* kernel (KZERO) space. This is the default map. It is used
@@ 115,11 101,10 @@ mmuinit(void)
ulong *top;
/*
- * set up the global descriptor table
+ * set up the global descriptor table. we make the tss entry here
+ * since it requires arithmetic on an address and hence cannot
+ * be a compile or link time constant.
*/
- x = (ulong)systrap;
- gdt[SYSGATE].d0 = (x&0xFFFF)|(KESEL<<16);
- gdt[SYSGATE].d1 = (x&0xFFFF0000)|SEGP|SEGPL(3)|SEGCG;
x = (ulong)&tss;
gdt[TSSSEG].d0 = (x<<16)|sizeof(Tss);
gdt[TSSSEG].d1 = (x&0xFF000000)|((x>>16)&0xFF)|SEGTSS|SEGPL(0)|SEGP;
@@ 128,7 113,6 @@ mmuinit(void)
/*
* set up system page tables.
* map all of physical memory to start at KZERO.
- * map ROM BIOS at the usual place (F0000000).
* leave a map entry for a user area.
*/
@@ 359,9 343,3 @@ invalidateu(void)
/* flush cached mmu entries */
putcr3(ktoppg.pa);
}
-
-void
-systrap(void)
-{
- panic("system trap from user");
-}
M pc/trap.c => pc/trap.c +21 -30
@@ 136,7 136,7 @@ trapinit(void)
sethvec(39, intr39, SEGIG, 0);
/*
- * system calls
+ * system calls and break points
*/
sethvec(Syscallvec, intr64, SEGTG, 3);
setvec(Syscallvec, (void (*)(Ureg*))syscall);
@@ 224,6 224,8 @@ trap(Ureg *ur)
}
if(v>=256 || ivec[v] == 0){
+ if(v == 13)
+ return;
if(v <= 16){
if(user){
sprint(buf, "sys: %s pc=0x%lux", excname[v], ur->pc);
@@ 247,27 249,6 @@ trap(Ureg *ur)
}
/*
- * print 8259 status
- */
-void
-dump8259(void)
-{
- int c;
-
- outb(Int0ctl, 0x0a); /* read ir */
- print("ir0 %lux\n", inb(Int0ctl));
- outb(Int0ctl, 0x0b); /* read is */
- print("is0 %lux\n", inb(Int0ctl));
- print("im0 %lux\n", inb(Int0aux));
-
- outb(Int1ctl, 0x0a); /* read ir */
- print("ir1 %lux\n", inb(Int1ctl));
- outb(Int1ctl, 0x0b); /* read is */
- print("is1 %lux\n", inb(Int1ctl));
- print("im1 %lux\n", inb(Int1aux));
-}
-
-/*
* dump registers
*/
void
@@ 277,13 258,18 @@ dumpregs(Ureg *ur)
print("registers for %s %d\n", u->p->text, u->p->pid);
else
print("registers for kernel\n");
- print("FLAGS=%lux ECODE=%lux CS=%lux PC=%lux SS=%lux USP=%lux\n", ur->flags,
- ur->ecode, ur->cs&0xff, ur->pc, ur->ss&0xff, ur->usp);
-
+ print("FLAGS=%lux ECODE=%lux CS=%lux PC=%lux", ur->flags,
+ ur->ecode, ur->cs&0xff, ur->pc);
+ if(ur == (Ureg*)UREGADDR)
+ print(" SS=%lux USP=%lux\n", ur->ss&0xff, ur->usp);
+ else
+ print("\n");
print(" AX %8.8lux BX %8.8lux CX %8.8lux DX %8.8lux\n",
ur->ax, ur->bx, ur->cx, ur->dx);
- print(" SI %8.8lux DI %8.8lux BP %8.8lux DS %8.8lux\n",
- ur->si, ur->di, ur->bp, ur->ds);
+ print(" SI %8.8lux DI %8.8lux BP %8.8lux\n",
+ ur->si, ur->di, ur->bp);
+ print(" DS %4.4ux ES %4.4ux FS %4.4ux GS %4.4ux\n",
+ ur->ds&0xffff, ur->es&0xffff, ur->fs&0xffff, ur->gs&0xffff);
}
void
@@ 291,10 277,16 @@ dumpstack(void)
{
}
-void
-execpc(ulong entry)
+long
+execregs(ulong entry, ulong ssize, ulong nargs)
{
+ ulong *sp;
+
+ sp = (ulong*)(USTKTOP - ssize);
+ *--sp = nargs;
+ ((Ureg*)UREGADDR)->usp = (ulong)sp;
((Ureg*)UREGADDR)->pc = entry;
+ return USTKTOP-BY2WD; /* address of user-level clock */
}
/*
@@ 312,7 304,6 @@ syscall(Ureg *ur)
u->p->insyscall = 1;
u->p->pc = ur->pc;
- u->dbgreg = ur;
if((ur->cs)&0xffff == KESEL)
panic("recursive system call");
M port/devdk.c => port/devdk.c +2 -0
@@ 777,6 777,7 @@ dkopen(Chan *c, int omode)
void
dkcreate(Chan *c, char *name, int omode, ulong perm)
{
+ USED(c);
error(Eperm);
}
@@ 849,6 850,7 @@ dkwrite(Chan *c, void *a, long n, ulong offset)
void
dkremove(Chan *c)
{
+ USED(c);
error(Eperm);
}
M port/devlance.c => port/devlance.c +12 -12
@@ 319,13 319,6 @@ lanceoput(Queue *q, Block *bp )
}
}
- /* restart the lance if'n it needs it */
- if(l.misses > 4){
- l.misses = 0;
- print("restarting lance\n");
- lancestart(0, 1);
- }
-
/*
* only one transmitter at a time
*/
@@ 338,9 331,17 @@ lanceoput(Queue *q, Block *bp )
}
/*
- * Wait till we get an output buffer
+ * Wait till we get an output buffer, reset the lance if input
+ * or output seems wedged.
*/
- sleep(&l.tr, isobuf, (void *)0);
+ tsleep(&l.tr, isobuf, (void *)0, 1000);
+ if(isobuf(0) == 0 || l.misses > 4){
+ l.misses = 0;
+ print("lance wedged, restarting\n");
+ lancestart(0, 0);
+ freeb(bp);
+ return; /* the interrupt routine will qunlock(&l.tlock) */
+ }
p = &l.tp[l.tc];
/*
@@ 433,10 434,9 @@ lancestart(int mode, int dolock)
* wait till both receiver and transmitter are
* quiescent
*/
- if(dolock){
+ if(dolock)
qlock(&l.tlock);
- qlock(&l.rlock);
- }
+ qlock(&l.rlock);
lancereset();
l.rl = 0;
M port/portfns.h => port/portfns.h +1 -1
@@ 61,7 61,7 @@ int eqchan(Chan*, Chan*, long);
int eqqid(Qid, Qid);
void error(int);
void errors(char*);
-void execpc(ulong);
+long execregs(ulong, ulong, ulong);
void exit(void);
Block* expandb(Block *, int);
int fault(ulong, int);
M port/stil.c => port/stil.c +1 -0
@@ 746,6 746,7 @@ ilstart(Ipconv *ipc, int type, int window)
ic->next = ic->start+1;
ic->recvd = 0;
ic->window = window;
+ ic->oblks = 0;
switch(type) {
case IL_PASSIVE:
M port/stnoether.c => port/stnoether.c +1 -1
@@ 186,7 186,7 @@ noetheriput(Queue *q, Block *bp)
circuit = (nh->circuit[2]<<16) | (nh->circuit[1]<<8) | nh->circuit[0];
s = (nh->sum[1]<<8) | nh->sum[0];
if(s && s!=nonetcksum(bp, ETHERHDRSIZE)){
-/* print("checksum error %ux %ux\n", s, (nh->sum[1]<<8) | nh->sum[0]); /**/
+ print("checksum error %ux %ux\n", s, (nh->sum[1]<<8) | nh->sum[0]); /**/
freeb(bp);
return;
}
M port/sysproc.c => port/sysproc.c +1 -5
@@ 345,10 345,6 @@ sysexec(ulong *arg)
*/
flushmmu();
clearmmucache();
- execpc(entry);
- sp = (ulong*)(USTKTOP - ssize);
- *--sp = nargs;
- ((Ureg*)UREGADDR)->usp = (ulong)sp;
lock(&p->debug);
u->nnote = 0;
u->notify = 0;
@@ 358,7 354,7 @@ sysexec(ulong *arg)
if(p->hang)
p->procctl = Proc_stopme;
- return (USTKTOP-BY2WD); /* address of user-level clock */
+ return execregs(entry, ssize, nargs);
}
int
M power/devduart.c => power/devduart.c +5 -1
@@ 780,6 780,7 @@ duartopen(Chan *c, int omode)
void
duartcreate(Chan *c, char *name, int omode, ulong perm)
{
+ USED(c);
error(Eperm);
}
@@ 825,12 826,14 @@ duartwrite(Chan *c, void *va, long n, ulong offset)
void
duartremove(Chan *c)
{
+ USED(c);
errors("can't remove a duart");
}
void
duartwstat(Chan *c, char *dp)
{
+ USED(c);
errors("can't write a duart");
}
@@ 842,4 845,5 @@ duartactive(void)
for(i = 0; i < nduartport; i++)
if(duartport[i].printing)
return 1;
- return 0; }
+ return 0;
+}
M power/devhs.c => power/devhs.c +3 -0
@@ 210,6 210,7 @@ hsvmeopen(Chan *c, int omode)
void
hsvmecreate(Chan *c, char *name, int omode, ulong perm)
{
+ USED(c);
error(Eperm);
}
@@ 235,12 236,14 @@ hsvmewrite(Chan *c, void *buf, long n, ulong offset)
void
hsvmeremove(Chan *c)
{
+ USED(c);
error(Eperm);
}
void
hsvmewstat(Chan *c, char *dp)
{
+ USED(c);
error(Eperm);
}
M power/devrtc.c => power/devrtc.c +4 -0
@@ 103,12 103,14 @@ rtcopen(Chan *c, int omode)
void
rtccreate(Chan *c, char *name, int omode, ulong perm)
{
+ USED(c);
error(Eperm);
}
void
rtcclose(Chan *c)
{
+ USED(c);
}
long
@@ 203,12 205,14 @@ rtcwrite(Chan *c, void *buf, long n, ulong offset)
void
rtcremove(Chan *c)
{
+ USED(c);
error(Eperm);
}
void
rtcwstat(Chan *c, char *dp)
{
+ USED(c);
error(Eperm);
}
M power/main.c => power/main.c +2 -0
@@ 774,11 774,13 @@ lanceparity(void)
void
buzz(int f, int d)
{
+ USED(f);
}
int
mouseputc(IOQ *q, int c)
{
+ USED(q);
return 0;
}
M power/trap.c => power/trap.c +9 -3
@@ 540,10 540,16 @@ syscall(Ureg *aur)
return ret;
}
-void
-execpc(ulong entry)
+long
+execregs(ulong entry, ulong ssize, ulong nargs)
{
- ((Ureg*)UREGADDR)->pc = entry - 4; /* syscall advances it */
+ ulong *sp;
+
+ sp = (ulong*)(USTKTOP - ssize);
+ *--sp = nargs;
+ ((Ureg*)UREGADDR)->usp = (ulong)sp;
+ ((Ureg*)UREGADDR)->pc = entry - 4; /* syscall advances it */
+ return USTKTOP-BY2WD; /* address of user-level clock */
}
void
M ss/trap.c => ss/trap.c +9 -3
@@ 400,10 400,16 @@ syscall(Ureg *aur)
return ret;
}
-void
-execpc(ulong entry)
+long
+execregs(ulong entry, ulong ssize, ulong nargs)
{
- ((Ureg*)UREGADDR)->pc = entry - 4; /* syscall advances it */
+ ulong *sp;
+
+ sp = (ulong*)(USTKTOP - ssize);
+ *--sp = nargs;
+ ((Ureg*)UREGADDR)->usp = (ulong)sp;
+ ((Ureg*)UREGADDR)->pc = entry - 4; /* syscall advances it */
+ return USTKTOP-BY2WD; /* address of user-level clock */
}
/* This routine must save the values of registers the user is not permitted to write