M pc/devether.c => pc/devether.c +1 -38
@@ 20,7 20,6 @@ struct Hw {
void (*receive)(Ctlr*);
void (*transmit)(Ctlr*);
void (*intr)(Ureg*);
- void (*tweek)(Ctlr*);
int addr; /* interface address */
uchar *ram; /* interface shared memory address */
int bt16; /* true if a 16 bit interface */
@@ 465,8 464,7 @@ etherkproc(void *arg)
}
cp->kproc = 1;
for(;;){
- tsleep(&cp->rr, isinput, cp, 1000);
- (*cp->hw->tweek)(cp);
+ sleep(&cp->rr, isinput, cp);
/*
* process any internal loopback packets
@@ 713,40 711,6 @@ print("ether width %d addr %lux size %d lvl %d\n", hw->bt16?16:8,
}
static void
-wd8013tweek(Ctlr *cp)
-{
- uchar laar, msr;
- Hw *hw = cp->hw;
- Buffer *tb;
- int s;
-
- s = splhi();
- msr = IN(hw, msr);
- if(msr & MENB){
- splx(s);
- return;
- }
- print("TWEEK\n");
- delay(500);
-
- /* reset the hardware */
- OUT(hw, msr, MENB|msr);
- laar = IN(hw, laar);
- if(hw->bt16)
- OUT(hw, laar, laar|L16EN);
- (*hw->init)(cp);
- (*cp->hw->online)(cp, 1);
-
- /* retransmit the current packet */
- tb = &cp->tb[cp->ti];
- if(tb->owner == Interface){
- tb->busy = 0;
- (*cp->hw->transmit)(cp);
- }
- splx(s);
-}
-
-static void
dp8390rinit(Ctlr *cp)
{
Hw *hw = cp->hw;
@@ 962,6 926,5 @@ static Hw wd8013 =
wd8013receive,
wd8013transmit,
wd8013intr,
- wd8013tweek,
0x360, /* I/O base address */
};
M port/alloc.c => port/alloc.c +3 -0
@@ 5,6 5,7 @@
#include "fns.h"
#include "error.h"
+
/*
* Plan 9 has two kernel allocators, the x... routines provide a first
* fit hole allocator which should be used for permanent or large structures.
@@ 313,6 314,8 @@ good:
bp = xalloc(size);
if(bp == nil)
return nil;
+
+ arena.nbuck[pow]++;
}
bp->size = pow;
M port/devbit.c => port/devbit.c +5 -2
@@ 79,6 79,7 @@ struct
Arena *arena; /* array */
int narena; /* number allocated */
int mouseopen; /* flag: mouse open */
+ int bitbltopen; /* flag: bitblt open */
int bid; /* last allocated bitmap id */
int subfid; /* last allocated subfont id */
int cacheid; /* last cached subfont id */
@@ 363,7 364,7 @@ bitopen(Chan *c, int omode)
break;
case Qbitblt:
lock(&bit);
- if(bit.ref){
+ if(bit.bitbltopen || bit.mouseopen){
unlock(&bit);
error(Einuse);
}
@@ 381,7 382,7 @@ bitopen(Chan *c, int omode)
bit.rid = -1;
bit.mid = -1;
bit.init = 0;
- bit.ref = 1;
+ bit.bitbltopen = 1;
Cursortocursor(&arrow);
unlock(&bit);
break;
@@ 434,6 435,8 @@ bitclose(Chan *c)
lock(&bit);
if(c->qid.path == Qmouse)
bit.mouseopen = 0;
+ if(c->qid.path == Qbitblt)
+ bit.bitbltopen = 0;
if(--bit.ref == 0){
ebp = &bit.map[bit.nmap];
for(bp = bit.map; bp<ebp; bp++){
M port/devlance.c => port/devlance.c +19 -8
@@ 281,7 281,7 @@ isobuf(void *x)
Msg *m;
m = x;
- return (MPus(m->flags)&LANCEOWNER) == 0;
+ return l.wedged || (MPus(m->flags)&LANCEOWNER) == 0;
}
static void
@@ 343,10 343,20 @@ lanceoput(Queue *q, Block *bp)
return;
}
+ if(l.wedged) {
+ freeb(bp);
+ return;
+ }
+
/*
* only one transmitter at a time
*/
qlock(&l.tlock);
+ if(l.wedged) {
+ qunlock(&l.tlock);
+ freeb(bp);
+ return;
+ }
if(waserror()){
qunlock(&l.tlock);
@@ 360,17 370,18 @@ lanceoput(Queue *q, Block *bp)
*/
m = &(LANCEMEM->tmr[l.tc]);
p = &l.tp[l.tc];
- if((MPus(m->flags)&LANCEOWNER) != 0)
+ while((MPus(m->flags)&LANCEOWNER) != 0) {
tsleep(&l.tr, isobuf, m, 128);
if(l.wedged || isobuf(m) == 0){
qunlock(&l.tlock);
freeb(bp);
poperror();
- l.wedged = 0;
print("lance wedged, dumping block & restarting\n");
lancestart(0);
+ l.wedged = 0;
return;
}
+ }
/*
* copy message into lance RAM
@@ 704,12 715,12 @@ lanceintr(void)
*/
if(csr & (BABL|MISS|MERR)){
if(l.misses++ < 4)
- print("lance err %ux\n", csr);
+ print("lance err #%ux\n", csr);
else {
+ print("lance stopped\n");
l.wedged = 1;
l.misses = 0;
- *l.rap = 0;
- *l.rdp = STOP;
+ lancereset();
wakeup(&l.rr);
wakeup(&l.tr);
return;
@@ 789,7 800,7 @@ isinput(void *arg)
{
Msg *m = arg;
- return l.self.first || ((MPus(m->flags) & LANCEOWNER)==0);
+ return l.wedged || l.self.first || ((MPus(m->flags) & LANCEOWNER)==0);
}
static void
@@ 854,9 865,9 @@ lancekproc(void *arg)
* if the lance is wedged, restart it
*/
if(l.wedged){
- l.wedged = 0;
print("lance wedged, restarting\n");
lancestart(0);
+ l.wedged = 0;
}
/*
M port/page.c => port/page.c +1 -1
@@ 55,7 55,7 @@ pageinit(void)
hw = swapalloc.highwater*BY2PG;
hr = swapalloc.headroom*BY2PG;
-/* print("%lud free pages, %dK bytes, swap %dK, highwater %dK, headroom %dK\n",
+ print("%lud free pages, %dK bytes, swap %dK, highwater %dK, headroom %dK\n",
palloc.user, pmem, vmem, hw/1024, hr/1024);/**/
}
M port/stip.c => port/stip.c +4 -7
@@ 372,7 372,7 @@ ip_reassemble(int offset, Block *bp, Etherhdr *ip)
int ovlap, len, fragsize, pktposn;
int end;
- /* Check lance has handed us a contiguous buffer */
+ /* Check ethrnet has handed us a contiguous buffer */
if(bp->next)
panic("ip: reass ?");
@@ 384,12 384,9 @@ ip_reassemble(int offset, Block *bp, Etherhdr *ip)
* find a reassembly queue for this fragment
*/
qlock(&fraglock);
- for(f = flisthead; f; f = f->next) {
- if(f->src == src)
- if(f->dst == dst)
- if(f->id == id)
+ for(f = flisthead; f; f = f->next)
+ if(f->src == src && f->dst == dst && f->id == id)
break;
- }
qunlock(&fraglock);
/*
@@ 402,7 399,7 @@ ip_reassemble(int offset, Block *bp, Etherhdr *ip)
qlock(f);
ipfragfree(f, 1);
}
- return(bp);
+ return bp;
}
BLKFRAG(bp)->foff = offset<<3;
M port/swap.c => port/swap.c +4 -4
@@ 59,10 59,11 @@ putswap(Page *p)
lock(&swapalloc);
idx = &swapalloc.swmap[((ulong)p)/BY2PG];
- if(--(*idx) == 0)
+ if(--(*idx) == 0) {
swapalloc.free++;
- if(idx < swapalloc.last)
- swapalloc.last = idx;
+ if(idx < swapalloc.last)
+ swapalloc.last = idx;
+ }
unlock(&swapalloc);
}
@@ 293,7 294,6 @@ executeio(void)
for(i = 0; i < ioptr; i++) {
out = iolist[i];
-
k = kmap(out);
kaddr = (char*)VA(k);
M port/taslock.c => port/taslock.c +2 -0
@@ 42,6 42,8 @@ canlock(Lock *l)
void
unlock(Lock *l)
{
+ int s;
+
l->pc = 0;
l->key = 0;
if(u && u->p)
M ss/faultsparc.c => ss/faultsparc.c +1 -3
@@ 33,15 33,13 @@ faultsparc(Ureg *ur)
if(ser&(SE_WRITE|SE_PROT))
read = 0;
}
-/*if(u && strcmp(u->p->text, "rc") == 0)
-print("fault pc=%lux addr=%lux %d\n", ur->pc, addr, read);/**/
+
spllo();
if(u == 0){
dumpregs(ur);
panic("fault u==0 pc=%lux addr=%lux", ur->pc, addr);
}
-/* addr &= VAMASK; /**/
badvaddr = addr;
addr &= ~(BY2PG-1);
user = !(ur->psr&PSRPSUPER);
M ss/l.s => ss/l.s +30 -0
@@ 82,6 82,36 @@ TEXT tas(SB), $0 /* it seems we must be splhi */
NOOP
RETURN
+TEXT softtas(SB), $0 /* all software; avoid LDSTUB */
+
+ MOVW PSR, R8
+ MOVW $SYSPSR, R9
+ MOVW R9, PSR
+ NOOP
+ MOVB (R7), R10
+ CMP R10, R0
+ BE gotit
+#ifdef asdf
+ ANDN $31, R7 /* flush cache line */
+ MOVW $0, (R7, 0xD)
+#endif
+ MOVW $0xFF, R7
+ MOVW R8, PSR
+ NOOP
+ RETURN
+
+gotit:
+ MOVW $0xFF, R10
+ MOVB R10, (R7)
+#ifdef asdf
+ ANDN $31, R7 /* flush cache line */
+ MOVW $0, (R7, 0xD)
+#endif
+ MOVW $0, R7
+ MOVW R8, PSR
+ NOOP
+ RETURN
+
TEXT spllo(SB), $0
MOVW PSR, R7
M ss/main.c => ss/main.c +2 -2
@@ 415,8 415,8 @@ confinit(void)
conf.upages = (conf.npage*70)/100;
if(cpuserver){
i = conf.npage-conf.upages;
- if(i > (6*MB)/BY2PG)
- conf.upages += i - ((6*MB)/BY2PG);
+ if(i > (12*MB)/BY2PG)
+ conf.upages += i - ((12*MB)/BY2PG);
}
romputcxsegm = *(ulong*)(rom+260);
M ss/mmu.c => ss/mmu.c +60 -6
@@ 239,9 239,8 @@ allocctx(Proc *proc)
c = (Ctx*)m->clist;
putctx(c);
- if(c->proc){
+ if(c->proc)
freectx(c, 1);
- }
if(c->pmeg)
panic("allocctx c->pmeg %lux\n", c->pmeg);
@@ 377,9 376,9 @@ mmuinit(void)
compile();
/*
- * map all of kernel region 0.
+ * map all of text image
*/
- ktop = PGROUND(conf.npage0);
+ ktop = PGROUND((ulong)end);
i = 0;
for(c = 0; c < conf.ncontext; c++){
i = 0;
@@ 389,7 388,7 @@ mmuinit(void)
fp = i;
/*
- * Make sure cache is turned on for kernel region 0
+ * Make sure cache is turned on for program and data
*/
pme = PTEVALID|PTEWRITE|PTEKERNEL|PTEMAINMEM;
i = 0;
@@ 412,6 411,33 @@ mmuinit(void)
putpmegspace(INVALIDSEGM+va, INVALIDPTE);
}
+ if(conf.base0 < conf.npage0){
+ /*
+ * map kernel region 0, this may overlap kernel text image
+ */
+ ktop1 = PGROUND(conf.npage0);
+ kbot1 = conf.base0 & ~(BY2SEGM - 1);
+ if(kbot1 < ktop)
+ kbot1 = ktop;
+ for(c = 0; c < conf.ncontext; c++){
+ i = fp;
+ putcontext(c);
+ for(va = kbot1; va < ktop1; va += BY2SEGM)
+ putsegspace(va, i++);
+ }
+ fp = i;
+
+ /*
+ * Make sure cache is turned on for kernel region 0
+ */
+ kbot1 = conf.base0 & ~(BY2PG - 1);
+ pme = PTEVALID|PTEWRITE|PTEKERNEL|PTEMAINMEM;
+ i = PPN(kbot1 & ~KZERO);
+ for(va = kbot1; va < ktop1; va += BY2PG, i++)
+ putpme(va, pme+i, 1);
+ ktop = ktop1;
+ }
+
if(conf.base1 < conf.npage1){
/*
* map kernel region 1, this may overlap kernel region 0's
@@ 437,6 463,7 @@ mmuinit(void)
i = PPN(kbot1 & ~KZERO);
for(va = kbot1; va < ktop1; va += BY2PG, i++)
putpme(va, pme+i, 1);
+ ktop = ktop1;
}
/*
@@ 626,11 653,15 @@ kmappa(ulong pa, ulong flag)
void
kunmap(KMap *k)
{
+ ulong pa;
+
+ pa = k->pa;
k->pa = 0;
lock(&kmapalloc);
k->next = kmapalloc.free;
kmapalloc.free = k;
- putpme(k->va, INVALIDPTE, 1);
+ if(pa != k->pa)
+ putpme(k->va, INVALIDPTE, 1);
unlock(&kmapalloc);
}
@@ 658,6 689,29 @@ kmapregion(ulong pa, ulong n, ulong flag)
KMap*
kmap(Page *pg)
{
+ ulong va;
+ KMap *k;
+
+ /*
+ * avoid an alias: if part of kernel memory, just return map
+ */
+ va = pg->pa|KZERO;
+ if((KZERO<=va && va<(ulong)end) ||
+ (conf.base0<=va && va<conf.npage0) ||
+ (conf.base1<=va && va<conf.npage1)){
+ lock(&kmapalloc);
+ k = kmapalloc.free;
+ if(k == 0){
+ dumpstack();
+ panic("kmap");
+ }
+ kmapalloc.free = k->next;
+ unlock(&kmapalloc);
+ k->va = va;
+ k->pa = va;
+ return k;
+ }
+
/*
* Cache is virtual and a pain to deal with.
* Must avoid having the same entry in the cache twice, so