M gnot/lock.c => gnot/lock.c +18 -28
@@ 7,55 7,45 @@
#define PCOFF -1
-/*
- * N.B. Ken's compiler generates a TAS instruction for the sequence:
- *
- * if(l->key >= 0){
- * l->key |= 0x80;
- * ...
- *
- * DO NOT TAKE THE ADDRESS OF l->key or the TAS will disappear.
- */
void
lock(Lock *l)
{
- Lock *ll = l; /* do NOT take the address of ll */
int i;
/*
* Try the fast grab first
*/
- if(ll->key >= 0){
- ll->key |= 0x80;
- ll->pc = ((ulong*)&l)[PCOFF];
+ if(tas(&l->key) == 0){
if(u && u->p)
u->p->hasspin = 1;
+ l->pc = ((ulong*)&l)[PCOFF];
return;
}
- for(i=0; i<10000000; i++)
- if(ll->key >= 0){
- ll->key |= 0x80;
- ll->pc = ((ulong*)&l)[PCOFF];
+ for(i = 0; i < 1000; i++){
+ sched();
+ if (tas(&l->key) == 0){
if(u && u->p)
u->p->hasspin = 1;
+ l->pc = ((ulong*)&l)[PCOFF];
return;
}
- ll->key = 0;
- print("lock loop %lux pc %lux held by pc %lux\n", l, ((ulong*)&l)[PCOFF], l->pc);
+ }
+ i = l->key;
+ l->key = 0;
+
+ panic("lock loop 0x%lux key 0x%lux pc 0x%lux held by pc 0x%lux\n", l, i,
+ ((ulong*)&l)[PCOFF], l->pc);
}
int
canlock(Lock *l)
{
- Lock *ll = l; /* do NOT take the address of ll */
- if(ll->key >= 0){
- ll->key |= 0x80;
- ll->pc = ((ulong*)&l)[PCOFF];
- if(u && u->p)
- u->p->hasspin = 1;
- return 1;
- }
- return 0;
+ if(tas(&l->key))
+ return 0;
+ l->pc = ((ulong*)&l)[PCOFF];
+ if(u && u->p)
+ u->p->hasspin = 1;
+ return 1;
}
void
M pc/fault386.c => pc/fault386.c +0 -3
@@ 16,7 16,6 @@ fault386(Ureg *ur)
int user;
int n;
int insyscall;
- static int times;
insyscall = u->p->insyscall;
u->p->insyscall = 1;
@@ 29,8 28,6 @@ dumpregs(ur);
read = !(ur->ecode & 2);
user = (ur->ecode & 4);
n = fault(addr, read);
-if(++times==3)
- panic("3rd time in fault");
if(n < 0){
if(user){
pprint("user %s error addr=0x%lux\n", read?"read":"write", addr);
M pc/fns.h => pc/fns.h +1 -0
@@ 64,4 64,5 @@ void systrap(void);
void touser(void);
void trapinit(void);
int tas(Lock*);
+void vgainit(void);
#define waserror() (u->nerrlab++, setlabel(&u->errlab[u->nerrlab-1]))
M pc/main.c => pc/main.c +36 -0
@@ 19,6 19,7 @@ main(void)
screeninit();
printinit();
mmuinit();
+ vgainit();
trapinit();
kbdinit();
clockinit();
@@ 273,3 274,38 @@ mouseputc(IOQ *q, int c)
{
return c;
}
+
+/*
+ * headland hip set for the safari.
+ *
+ * serious magic!!!
+ */
+
+enum
+{
+ Head= 0x92, /* control port */
+ Reset= (1<<0), /* reset the 386 */
+ A20ena= (1<<1), /* enable address line 20 */
+};
+
+/*
+ * enable address bit 20
+ */
+void
+a20enable(void)
+{
+ outb(Head, A20ena);
+}
+
+/*
+ * reset the chip
+ */
+void
+exit(void)
+{
+ int i;
+
+ u = 0;
+ print("exiting\n");
+ outb(Head, Reset);
+}
M pc/mmu.c => pc/mmu.c +6 -5
@@ 178,8 178,8 @@ mapstack(Proc *p)
/*
* point top level page table to bottom level ones
*/
- memmove(toppt, p->mmu, MAXMMU*sizeof(ulong));
- memmove(&toppt[TOPOFF(USTKBTM)], &p->mmu[MAXMMU], MAXSMMU*sizeof(ulong));
+ memmove(toppt, p->mmue, MAXMMU*sizeof(ulong));
+ memmove(&toppt[TOPOFF(USTKBTM)], &p->mmue[MAXMMU], MAXSMMU*sizeof(ulong));
/* map in u area */
upt[0] = PPN(p->upage->pa) | PTEVALID | PTEKERNEL | PTEWRITE;
@@ 216,7 216,7 @@ putmmu(ulong va, ulong pa, Page *pg)
int topoff;
ulong *pt;
Proc *p;
- int i;
+ int i = 0;
print("putmmu %lux %lux\n", va, pa); /**/
if(u==0)
@@ 238,18 238,19 @@ print("putmmu %lux %lux\n", va, pa); /**/
* if bottom level page table missing, allocate one
*/
pg = p->mmu[i];
+print("toppt[%d] was %lux\n", topoff, toppt[topoff]);
if(pg == 0){
pg = p->mmu[i] = newpage(1, 0, 0);
p->mmue[i] = PPN(pg->pa) | PTEVALID | PTEUSER | PTEWRITE;
toppt[topoff] = p->mmue[i];
-print("toppt[%d] = %lux\n", topoff, toppt[topoff]);
+print("toppt[%d] now %lux\n", topoff, toppt[topoff]);
}
/*
* fill in the bottom level page table
*/
-print("%lux[%d] was %lux\n", pt, BTMOFF(va), pt[BTMOFF(va)]);
pt = (ulong*)(p->mmu[i]->pa|KZERO);
+print("%lux[%d] was %lux\n", pt, BTMOFF(va), pt[BTMOFF(va)]);
pt[BTMOFF(va)] = pa | PTEUSER;
print("%lux[%d] now %lux\n", pt, BTMOFF(va), pt[BTMOFF(va)]);
M pc/trap.c => pc/trap.c +0 -8
@@ 223,8 223,6 @@ syscall(Ureg *ur)
ulong sp;
long ret;
int i;
- static int times;
-ulong *z;
u->p->insyscall = 1;
u->p->pc = ur->pc;
@@ 240,11 238,6 @@ ulong *z;
sp = ur->usp;
u->nerrlab = 0;
ret = -1;
-z = (ulong *)sp;
-print("syscall %lux %lux %lux %lux\n", *z, *(z+1), *(z+2), *(z+3));
-dumpregs(ur);
-if(++times==3)
- panic("3rd time in syscall");
if(!waserror()){
if(ax >= sizeof systab/BY2WD){
pprint("bad sys call number %d pc %lux\n", ax, ur->pc);
@@ 256,7 249,6 @@ if(++times==3)
ret = (*systab[ax])((ulong*)(sp+BY2WD));
poperror();
}
-print("return from syscall\n");
if(u->nerrlab){
print("bad errstack [%d]: %d extra\n", ax, u->nerrlab);
for(i = 0; i < NERR; i++)
A pc/vga.c => pc/vga.c +29 -0
@@ 0,0 1,29 @@
+#include "u.h"
+#include "lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+
+enum
+{
+ GRX= 0x3CE, /* index to graphics registers */
+ GR= 0x3CF, /* graphics registers 0-8 */
+};
+
+/*
+ * look at VGA registers
+ */
+void
+vgainit(void)
+{
+ int i;
+ uchar x;
+
+ for(i = 0; i < 9; i++){
+ outb(GRX, i);
+ x = inb(GR);
+ print("GR%d == %ux\n", i, x);
+ }
+ panic("for the hell of it");
+}
M port/chan.c => port/chan.c +2 -10
@@ 34,17 34,9 @@ decref(Ref *r)
lock(r);
x = --r->ref;
unlock(r);
- if(x < 0) {
- if(u) {
- print("%d: %s %lux %lux\n", u->p->pid, u->p->text, *(ulong*)((Ureg*)UREGADDR)->pc, r);
- for(i = 0; i < NSEG; i++) {
- s = u->p->seg[i];
- if(s)
- print("%d: %lux %lux %lux", i, s, s->base, s->top);
- }
- }
+ if(x < 0)
panic("decref");
- }
+
return x;
}
M port/devcons.c => port/devcons.c +2 -1
@@ 11,7 11,7 @@
struct {
IOQ; /* lock to klogputs */
QLock; /* qlock to getc */
-} klogq;
+}klogq;
IOQ lineq; /* lock to getc; interrupt putc's */
IOQ printq;
@@ 141,6 141,7 @@ panic(char *fmt, ...)
char buf[PRINTSIZE];
int n;
+ print("panic: %lux m=%lux\n", &fmt, m);
strcpy(buf, "panic: ");
n = doprint(buf+7, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
buf[n] = '\n';
M port/devdk.c => port/devdk.c +1 -1
@@ 1464,7 1464,7 @@ dkcsckproc(void *a)
break;
case T_SRV: /* ignore it, it's useless */
- print("dksrvmesg(%d)\n", line);
+/* print("dksrvmesg(%d)\n", line); /**/
break;
case T_RESTART: /* datakit reboot */
M port/devip.c => port/devip.c +0 -31
@@ 708,37 708,6 @@ tcpstclose(Queue *q)
}
}
-/*
- * Network byte order functions
- */
-
-void
-hnputs(uchar *ptr, ushort val)
-{
- ptr[0] = val>>8;
- ptr[1] = val;
-}
-
-void
-hnputl(uchar *ptr, ulong val)
-{
- ptr[0] = val>>24;
- ptr[1] = val>>16;
- ptr[2] = val>>8;
- ptr[3] = val;
-}
-
-ulong
-nhgetl(uchar *ptr)
-{
- return ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
-}
-
-ushort
-nhgets(uchar *ptr)
-{
- return ((ptr[0]<<8) | ptr[1]);
-}
/*
* ptcl_csum - protcol cecksum routine
M port/sysproc.c => port/sysproc.c +26 -10
@@ 96,6 96,15 @@ sysfork(ulong *arg)
return pid;
}
+static ulong
+l2be(long l)
+{
+ uchar *cp;
+
+ cp = (uchar*)&l;
+ return (cp[0]<<24) | (cp[1]<<16) | (cp[2]<<8) | cp[3];
+}
+
long
sysexec(ulong *arg)
{
@@ 114,6 123,7 @@ sysexec(ulong *arg)
char line[sizeof(Exec)];
Fgrp *f;
Image *img;
+ ulong magic, text, entry, data, bss;
p = u->p;
validaddr(arg[0], 1, 0);
@@ 132,10 142,13 @@ sysexec(ulong *arg)
if(n < 2)
Err:
error(Ebadexec);
- if(n==sizeof(Exec) && exec.magic==AOUT_MAGIC){
- if((exec.text&KZERO)
- || (ulong)exec.entry < UTZERO+sizeof(Exec)
- || (ulong)exec.entry >= UTZERO+sizeof(Exec)+exec.text)
+ magic = l2be(exec.magic);
+ text = l2be(exec.text);
+ entry = l2be(exec.entry);
+ if(n==sizeof(Exec) && magic==AOUT_MAGIC){
+ if((text&KZERO)
+ || entry < UTZERO+sizeof(Exec)
+ || entry >= UTZERO+sizeof(Exec)+text)
goto Err;
goto Binary;
}
@@ 165,9 178,11 @@ sysexec(ulong *arg)
Binary:
poperror();
- t = (UTZERO+sizeof(Exec)+exec.text+(BY2PG-1)) & ~(BY2PG-1);
- d = (t + exec.data + (BY2PG-1)) & ~(BY2PG-1);
- bssend = t + exec.data + exec.bss;
+ data = l2be(exec.data);
+ bss = l2be(exec.bss);
+ t = (UTZERO+sizeof(Exec)+text+(BY2PG-1)) & ~(BY2PG-1);
+ d = (t + data + (BY2PG-1)) & ~(BY2PG-1);
+ bssend = t + data + bss;
b = (bssend + (BY2PG-1)) & ~(BY2PG-1);
if((t|d|b) & KZERO)
error(Ebadexec);
@@ 254,7 269,7 @@ sysexec(ulong *arg)
p->seg[TSEG] = ts;
ts->flushme = 1;
ts->fstart = 0;
- ts->flen = sizeof(Exec)+exec.text;
+ ts->flen = sizeof(Exec)+text;
/* Data. Shared. */
s = newseg(SG_DATA, t, (d-t)>>PGSHIFT);
@@ 264,7 279,7 @@ sysexec(ulong *arg)
incref(img);
s->image = img;
s->fstart = ts->fstart+ts->flen;
- s->flen = exec.data;
+ s->flen = data;
/* BSS. Zero fill on demand */
p->seg[BSEG] = newseg(SG_BSS, d, (b-d)>>PGSHIFT);
@@ 288,7 303,7 @@ sysexec(ulong *arg)
*/
flushmmu();
clearmmucache();
- execpc(exec.entry);
+ execpc(entry);
sp = (ulong*)(USTKTOP - ssize);
*--sp = nargs;
((Ureg*)UREGADDR)->usp = (ulong)sp;
@@ 488,6 503,7 @@ syssegdetach(ulong *arg)
int i;
Segment *s;
+ s = 0;
for(i = 0; i < NSEG; i++)
if(s = u->p->seg[i]) {
qlock(&s->lk);
M port/tcpoutput.c => port/tcpoutput.c +32 -0
@@ 282,3 282,35 @@ tcprcvwin(Ipconv *s)
else
tcb->rcv.wnd = Streamhi;
}
+
+/*
+ * Network byte order functions
+ */
+
+void
+hnputs(uchar *ptr, ushort val)
+{
+ ptr[0] = val>>8;
+ ptr[1] = val;
+}
+
+void
+hnputl(uchar *ptr, ulong val)
+{
+ ptr[0] = val>>24;
+ ptr[1] = val>>16;
+ ptr[2] = val>>8;
+ ptr[3] = val;
+}
+
+ulong
+nhgetl(uchar *ptr)
+{
+ return ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
+}
+
+ushort
+nhgets(uchar *ptr)
+{
+ return ((ptr[0]<<8) | ptr[1]);
+}
M power/devhotrod.c => power/devhotrod.c +1 -0
@@ 13,6 13,7 @@
/*
* If defined, ENABMEMTEST causes memory test to be run at device open
*/
+#define ENABMEMTEST
#ifdef ENABMEMTEST
void mem(Hot*, ulong*, ulong);
#define NTESTBUF 256
A ss/bbmalloc.c => ss/bbmalloc.c +73 -0
@@ 0,0 1,73 @@
+#include "u.h"
+#include "lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+
+/*
+ * Allocate memory for use in kernel bitblts.
+ * The allocated memory must have a flushed instruction
+ * cache, and the data cache must be flushed by bbdflush().
+ * To avoid the need for frequent cache flushes, the memory
+ * is allocated out of an arena, and the i-cache is only
+ * flushed when it has to be reused. By returning an
+ * address in non-cached space, the need for flushing the
+ * d-cache is avoided.
+ *
+ * Currently, the only kernel users of bitblt are devbit,
+ * print, and the cursor stuff in devbit. The cursor
+ * can get drawn at clock interrupt time, so it might need
+ * to bbmalloc while another bitblt is going on.
+ *
+ * This code will have to be interlocked if we ever get
+ * a multiprocessor with a bitmapped display.
+ */
+
+/* a 0->3 bitblt can take 900 words */
+enum {
+ nbbarena=8192 /* number of words in an arena */
+};
+
+static ulong bbarena[nbbarena];
+static ulong *bbcur = bbarena;
+static ulong *bblast = 0;
+
+void *
+bbmalloc(int nbytes)
+{
+ int nw;
+ int s;
+ ulong *ans;
+
+ nw = nbytes/sizeof(long);
+ s = splhi();
+ if(bbcur + nw > &bbarena[nbbarena])
+ ans = bbarena;
+ else
+ ans = bbcur;
+ bbcur = ans + nw;
+ splx(s);
+/*
+ if(ans == bbarena)
+ icflush(ans, sizeof(bbarena));
+*/
+ bblast = ans;
+ ans = (void *)ans;
+ return ans;
+}
+
+void
+bbfree(void *p, int n)
+{
+ ulong *up;
+
+ if(p == bblast)
+ bbcur = (ulong *)(((char *)bblast) + n);
+}
+
+void *
+bbdflush(void *p, int n)
+{
+ return p;
+}
M ss/clock.c => ss/clock.c +1 -1
@@ 60,7 60,7 @@ clock(Ureg *ur)
if(anyready())
sched();
if((ur->psr&PSRPSUPER) == 0){
- *(ulong*)(USTKTOP-BY2WD) += TK2MS(1);
+/* *(ulong*)(USTKTOP-BY2WD) += TK2MS(1); /**/
if(u->nnote)
notify(ur);
}