M gnot/dat.h => gnot/dat.h +1 -0
@@ 101,6 101,7 @@ struct Conf
int npipe; /* number of pipes */
int nservice; /* number of services */
int nfsyschan; /* number of filsys open channels */
+ int nlapd; /* number of dragnet protocol modules */
ulong maxialloc; /* maximum bytes used by ialloc */
int copymode; /* 0 is copy on write, 1 is copy on reference */
int portispaged; /* ??? */
M gnot/screen.c => gnot/screen.c +50 -0
@@ 83,3 83,53 @@ screenputs(char *s, int n)
while(n-- > 0)
screenputc(*s++);
}
+
+int
+screenbits(void)
+{
+ if(*(uchar*)MOUSE & (1<<4))
+ return 2;
+ else
+ return 1;
+}
+
+void
+getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb)
+{
+ ulong ans;
+
+ /*
+ * The gnot says 0 is white (max intensity)
+ */
+ if(gscreen.ldepth == 0){
+ if(p == 0)
+ ans = ~0;
+ else
+ ans = 0;
+ }else{
+ switch(p){
+ case 0: ans = ~0; break;
+ case 1: ans = 0xAAAAAAAA; break;
+ case 2: ans = 0x55555555; break;
+ default: ans = 0; break;
+ }
+ *pr = *pg = *pb = ans;
+}
+
+int
+setcolor(ulong p, ulong r, ulong g, ulong b)
+{
+ return 0; /* can't change mono screen colormap */
+}
+
+int
+hwcursset(uchar *s, uchar *c, int ox, int oy)
+{
+ return 0;
+}
+
+int
+hwcursmove(int x, int y)
+{
+ return 0;
+}
M pc/clock.c => pc/clock.c +15 -4
@@ 4,6 4,7 @@
#include "dat.h"
#include "fns.h"
#include "io.h"
+#include "ureg.h"
/*
* 8253 timer
@@ 24,10 25,20 @@ clockinit(void)
}
void
-clock(void *arg)
+clock(Ureg *ur)
{
+ Proc *p;
+
m->ticks++;
- if((m->ticks%185)==0)
- print("%d secs\n", TK2SEC(m->ticks));
- INT0ENABLE;
+ p = m->proc;
+ if(p){
+ p->pc = ur->eip;
+ if (p->state==Running)
+ p->time[p->insyscall]++;
+ }
+
+ if((m->ticks%185) == 92)
+ floppystart();
+ else if((m->ticks%185) == 0)
+ floppystop();
}
M pc/dat.h => pc/dat.h +0 -3
@@ 126,7 126,6 @@ typedef void KMap;
#define NERR 15
#define NNOTE 5
-#define NFD 100
struct User
{
Proc *p;
@@ 137,8 136,6 @@ struct User
char elem[NAMELEN]; /* last name element from namec */
Chan *slash;
Chan *dot;
- Chan *fd[NFD];
- int maxfd; /* highest fd in use */
/*
* Rest of structure controlled by devproc.c and friends.
* lock(&p->debug) to modify.
M pc/fns.h => pc/fns.h +16 -4
@@ 1,8 1,13 @@
#include "../port/portfns.h"
-void clock(void*);
+void clock(Ureg*);
void clockinit(void);
void delay(int);
+void floppyinit(void);
+void floppyintr(Ureg*);
+void floppystart(void);
+void floppystop(void);
+void idle(void);
int inb(int);
void intr0(void);
void intr1(void);
@@ 21,18 26,25 @@ void intr13(void);
void intr14(void);
void intr15(void);
void intr16(void);
+void intr17(void);
+void intr18(void);
+void intr19(void);
+void intr20(void);
+void intr21(void);
+void intr22(void);
+void intr23(void);
void intrbad(void);
-int kbdc(void);
void kbdinit(void);
-void kbdintr(void*);
+void kbdintr(Ureg*);
void lgdt(Segdesc*, int);
void lidt(Segdesc*, int);
+void mmuinit(void);
void outb(int, int);
void prhex(ulong);
void screeninit(void);
void screenputc(int);
void screenputs(char*, int);
-void setvec(int, void (*)(void*), int);
+void setvec(int, void (*)(Ureg*), int);
void systrap(void);
void trapinit(void);
int tas(Lock*);
M pc/io.h => pc/io.h +1 -1
@@ 10,7 10,7 @@ enum
Intena= 0x20, /* written to Intctlport, enables next int */
- Int0vec= 17, /* first interrupt vector used by the 8259 */
+ Int0vec= 16, /* first interrupt vector used by the 8259 */
Clockvec= Int0vec+0, /* clock interrupts */
Kbdvec= Int0vec+1, /* keyboard interrupts */
};
M pc/kbd.c => pc/kbd.c +14 -33
@@ 1,9 1,9 @@
#include "u.h"
#include "lib.h"
+#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
-#include "mem.h"
enum {
Data= 0x60, /* data port */
@@ 241,28 241,11 @@ kbdinit(void)
setvec(Kbdvec, kbdintr, SEGIG);
}
-/*
- * get a byte from the keyboard
- */
-int
-kbdc(void)
-{
- int c;
-
- for(;;){
- while((inb(Status)&Inready)==0)
- ;
- kbdintr(&c);
- c = getc(&kbdq);
- if(c != -1)
- return c;
- }
-}
-
int
kbdputc(IOQ* q, int c)
{
- screenputc(c);
+ if(c==0x10)
+ panic("^p");
putc(q, c);
}
@@ 270,7 253,7 @@ kbdputc(IOQ* q, int c)
* keyboard interrupt
*/
void
-kbdintr(void *a)
+kbdintr(Ureg *ur)
{
int c, nc;
static int esc1, esc2;
@@ 291,7 274,7 @@ kbdintr(void *a)
if(c > sizeof kbtab){
print("unknown key %ux\n", c|keyup);
kbdputc(&kbdq, k1);
- goto out;
+ return;
}
/*
@@ 299,10 282,10 @@ kbdintr(void *a)
*/
if(c == 0xe0){
esc1 = 1;
- goto out;
+ return;
} else if(c == 0xe1){
esc2 = 2;
- goto out;
+ return;
}
if(esc1){
@@ 310,7 293,7 @@ kbdintr(void *a)
esc1 = 0;
} else if(esc2){
esc2--;
- goto out;
+ return;
} else if(shift)
c = kbtabshift[c];
else
@@ 331,7 314,7 @@ kbdintr(void *a)
ctl = 0;
break;
}
- goto out;
+ return;
}
/*
@@ 361,23 344,21 @@ kbdintr(void *a)
switch(c){
case Caps:
caps ^= 1;
- goto out;
+ return;
case Num:
num ^= 1;
- goto out;
+ return;
case Shift:
shift = 1;
- goto out;
+ return;
case Latin:
lstate = 1;
- goto out;
+ return;
case Ctrl:
ctl = 1;
- goto out;
+ return;
}
}
kbdputc(&kbdq, c);
-out:
- INT0ENABLE; /* reenable interrupt */
return;
}
M pc/l.s => pc/l.s +35 -1
@@ 80,7 80,7 @@ flush:
MOVW AX,SS
MOVW AX,ES
-/* JMPFAR* SELECTOR(2, SELGDT, 0):$protected(SB) /**/
+/* JMPFAR SELECTOR(2, SELGDT, 0):$mode32bit(SB) /**/
BYTE $0xEA
WORD $mode32bit(SB)
WORD $SELECTOR(2, SELGDT, 0)
@@ 261,6 261,34 @@ TEXT intr16(SB),$0
PUSHL $0
PUSHL $16
JMP intrcommon
+TEXT intr17(SB),$0
+ PUSHL $0
+ PUSHL $17
+ JMP intrcommon
+TEXT intr18(SB),$0
+ PUSHL $0
+ PUSHL $18
+ JMP intrcommon
+TEXT intr19(SB),$0
+ PUSHL $0
+ PUSHL $19
+ JMP intrcommon
+TEXT intr20(SB),$0
+ PUSHL $0
+ PUSHL $20
+ JMP intrcommon
+TEXT intr21(SB),$0
+ PUSHL $0
+ PUSHL $21
+ JMP intrcommon
+TEXT intr22(SB),$0
+ PUSHL $0
+ PUSHL $22
+ JMP intrcommon
+TEXT intr23(SB),$0
+ PUSHL $0
+ PUSHL $23
+ JMP intrcommon
TEXT intrbad(SB),$0
PUSHL $0
PUSHL $0x1ff
@@ 311,3 339,9 @@ TEXT splhi(SB),$0
*/
TEXT splx(SB),$0
RET
+
+/*
+ *
+ */
+TEXT idle(SB),$0
+ HLT
M pc/main.c => pc/main.c +19 -6
@@ 1,18 1,27 @@
#include "u.h"
#include "lib.h"
+#include "mem.h"
#include "dat.h"
#include "fns.h"
+#include "io.h"
main(void)
{
screeninit();
- print("screen inited\n");
trapinit();
- print("traps inited\n");
kbdinit();
- print("kbd inited\n");
+ clockinit();
+ mmuinit();
+ floppyinit();
spllo();
- for(;;);
+ for(;;){
+ int c;
+
+ c = getc(&kbdq);
+ if(c!=-1)
+ screenputc(c);
+ idle();
+ }
}
void
@@ 21,7 30,7 @@ delay(int l)
int i;
while(--l){
- for(i=0; i < 10000; i++)
+ for(i=0; i < 100; i++)
;
}
}
@@ 52,7 61,11 @@ panic(char *fmt, ...)
screenputs("panic: ", 7);
n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
screenputs(buf, n);
- for(;;);
+ screenputs("\n", 1);
+ INT0ENABLE;
+ spllo();
+ for(;;)
+ idle();
}
void
M pc/mem.h => pc/mem.h +12 -6
@@ 5,7 5,6 @@
/*
* Sizes
*/
-
#define BI2BY 8 /* bits per byte */
#define BI2WD 32 /* bits per word */
#define BY2WD 4 /* bytes per word */
@@ 20,7 19,6 @@
* Time
* Clock frequency is ??? HZ
*/
-
#define HZ (18) /* clock frequency */
#define MS2HZ (54) /* millisec per clock tick */
#define TK2SEC(t) ((t)*10/185) /* ticks to seconds */
@@ 30,7 28,6 @@
/*
* Fundamental addresses
*/
-
#define USERADDR 0xC0000000
#define UREGADDR (USERADDR+BY2PG-4*16)
@@ 40,7 37,6 @@
* User is at 0-2GB
* Kernel is at 2GB-4GB
*/
-
#define UZERO 0 /* base of user address space */
#define UTZERO (UZERO+BY2PG) /* first address in user text */
#define TSTKTOP USERADDR /* end of new stack in sysexec */
@@ 55,15 51,16 @@
#define isphys(x) ((x)&KZERO)
/*
- * known segments (in GDT) and their selectors
+ * known 80386 segments (in GDT) and their selectors
*/
-
#define NULLSEG 0 /* null segment */
#define KDSEG 1 /* kernel data/stack */
#define KESEG 2 /* kernel executable */
#define UDSEG 3 /* user data/stack */
#define UESEG 4 /* user executable */
#define SYSGATE 5 /* system call gate */
+#define RDSEG 6 /* reboot data/stack */
+#define RESEG 7 /* reboot executable */
#define SELGDT (0<<3) /* selector is in gdt */
#define SELLDT (1<<3) /* selector is in ldt */
@@ 77,6 74,8 @@
#define UESEL SELECTOR(UESEG, SELGDT, 3)
#define UDSEL SELECTOR(UDSEG, SELGDT, 3)
#define USSEL SELECTOR(UDSEG, SELGDT, 3)
+#define RDSEL SELECTOR(RDSEG, SELGDT, 0)
+#define RESEL SELECTOR(RESEG, SELGDT, 0)
/*
* fields in segment descriptors
@@ 96,3 95,10 @@
#define SEGW (1<<9) /* writable (for data/stack) */
#define SEGR (1<<9) /* readable (for code) */
#define SEGD (1<<22) /* default 1==32bit (for code) */
+
+/*
+ * virtual MMU entries
+ */
+#define PTEMAPMEM (1024*1024) /* ??? */
+#define SEGMAPSIZE 16 /* ??? */
+#define PTEPERTAB (PTEMAPMEM/BY2PG) /* ??? */
M pc/mmu.c => pc/mmu.c +5 -1
@@ 49,11 49,13 @@ struct Tss
#define DATASEG(p) { 0xFFFF, SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW }
#define EXECSEG(p) { 0xFFFF, SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR }
#define CALLGATE(s,o,p) { (o)&0xFFFF|((s)<<16), (o)&0xFFFF0000|SEGP|SEGPL(p)|SEGCG }
+#define D16SEG(p) { 0xFFFF, (0x0<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW }
+#define E16SEG(p) { 0xFFFF, (0x0<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR }
/*
* global descriptor table describing all segments
*/
-Segdesc gdt[6] =
+Segdesc gdt[] =
{
[NULLSEG] { 0, 0}, /* null descriptor */
[KDSEG] DATASEG(0), /* kernel data/stack */
@@ 61,6 63,8 @@ Segdesc gdt[6] =
[UDSEG] DATASEG(3), /* user data/stack */
[UESEG] EXECSEG(3), /* user code */
[SYSGATE] CALLGATE(KESEL,0,3), /* call gate for system calls */
+[RDSEG] D16SEG(0), /* reboot data/stack */
+[RESEG] E16SEG(0), /* reboot code */
};
void
M pc/trap.c => pc/trap.c +10 -20
@@ 20,7 20,7 @@ sethvec(int v, void (*r)(void), int type)
}
void
-setvec(int v, void (*r)(void*), int type)
+setvec(int v, void (*r)(Ureg*), int type)
{
ilt[v].d1 &= ~SEGTYPE;
ilt[v].d1 |= type;
@@ 55,11 55,18 @@ trapinit(void)
sethvec(14, intr14, SEGTG);
sethvec(15, intr15, SEGTG);
sethvec(16, intr16, SEGTG);
+ sethvec(17, intr17, SEGTG);
+ sethvec(18, intr18, SEGTG);
+ sethvec(19, intr19, SEGTG);
+ sethvec(20, intr20, SEGTG);
+ sethvec(21, intr21, SEGTG);
+ sethvec(22, intr22, SEGTG);
+ sethvec(23, intr23, SEGTG);
/*
* set all others to unknown
*/
- for(i = 17; i < 256; i++)
+ for(i = 24; i < 256; i++)
sethvec(i, intrbad, SEGIG);
/*
@@ 88,26 95,9 @@ trapinit(void)
*/
trap(Ureg *ur)
{
- print("trap %lux\n", ur->trap);
- print(" edi %lux\n", ur->edi);
- print(" esi %lux\n", ur->esi);
- print(" ebp %lux\n", ur->ebp);
- print(" esp %lux\n", ur->esp);
- print(" ebx %lux\n", ur->ebx);
- print(" edx %lux\n", ur->edx);
- print(" ecx %lux\n", ur->ecx);
- print(" eax %lux\n", ur->eax);
- print(" ds %lux\n", ur->ds);
- print(" trap %lux\n", ur->trap);
- print(" ecode %lux\n", ur->ecode);
- print(" eip %lux\n", ur->eip);
- print(" cs %lux\n", ur->cs);
- print(" eflags %lux\n", ur->eflags);
- print(" oesp %lux\n", ur->oesp);
- print(" ss %lux\n", ur->ss);
- delay(500);
if(ur->trap>=256 || ivec[ur->trap] == 0)
panic("bad trap type %d\n", ur->trap);
(*ivec[ur->trap])(ur);
+ INT0ENABLE;
}
M port/devbit.c => port/devbit.c +223 -97
@@ 6,7 6,6 @@
#include "errno.h"
#include "devtab.h"
-#include "ureg.h"
#include <libg.h>
#include <gnot.h>
@@ 14,6 13,25 @@
extern GFont *defont;
/*
+ * Some monochrome screens are reversed from what we like:
+ * We want 0's bright and 1s dark.
+ * Indexed by an Fcode, these compensate for the source bitmap being wrong
+ * (exchange S rows) and destination (exchange D columns and invert result)
+ */
+int flipS[] = {
+ 0x0, 0x4, 0x8, 0xC, 0x1, 0x5, 0x9, 0xD,
+ 0x2, 0x6, 0xA, 0xE, 0x3, 0x7, 0xB, 0xF
+};
+
+int flipD[] = {
+ 0xF, 0xD, 0xE, 0xC, 0x7, 0x5, 0x6, 0x4,
+ 0xB, 0x9, 0xA, 0x8, 0x3, 0x1, 0x2, 0x0,
+};
+
+int flipping; /* are flip tables being used to transform Fcodes? */
+int hwcursor; /* is there a hardware cursor? */
+
+/*
* Device (#b/bitblt) is exclusive use on open, so no locks are necessary
* for i/o
*/
@@ 41,26 59,25 @@ struct
int rid; /* read bitmap id */
int rminy; /* read miny */
int rmaxy; /* read maxy */
+ int mid; /* colormap read bitmap id */
}bit;
#define FREE 0x80000000
void bitcompact(void);
void bitfree(GBitmap*);
-void mouseupdate(int);
extern GBitmap gscreen;
struct{
/*
- * First three fields are known in l.s
+ * First four fields are known in screen.c
*/
int dx; /* interrupt-time delta */
int dy;
int track; /* update cursor on screen */
- int clock; /* check mouse.track on RTE */
Mouse;
int changed; /* mouse structure changed since last read */
- int newbuttons; /* interrupt time access only */
Rendez r;
+ int newbuttons; /* interrupt time access only */
}mouse;
Cursor arrow =
@@ 105,7 122,7 @@ GBitmap clr =
{0, 0, 16, 16}
};
-ulong cursorbackbits[16];
+ulong cursorbackbits[16*4];
GBitmap cursorback =
{
cursorbackbits,
@@ 141,6 158,7 @@ bitreset(void)
{
int i;
GBitmap *bp;
+ ulong r;
bit.map = ialloc(conf.nbitmap * sizeof(GBitmap), 0);
for(i=0,bp=bit.map; i<conf.nbitmap; i++,bp++){
@@ 150,6 168,9 @@ bitreset(void)
bp--;
bp->base = 0;
bit.map[0] = gscreen; /* bitmap 0 is screen */
+ getcolor(0, &r, &r, &r);
+ if(r == 0)
+ flipping = 1;
bit.free = bit.map+1;
bit.lastid = -1;
bit.lastfid = -1;
@@ 168,9 189,12 @@ bitinit(void)
{
lock(&bit);
unlock(&bit);
- if(gscreen.ldepth > 1)
- panic("bitinit ldepth>1");
- cursorback.ldepth = gscreen.ldepth;
+ if(gscreen.ldepth > 3)
+ cursorback.ldepth = 0;
+ else {
+ cursorback.ldepth = gscreen.ldepth;
+ cursorback.width = ((16 << gscreen.ldepth) + 31) >> 5;
+ }
cursoron(1);
}
@@ 186,6 210,7 @@ bitclone(Chan *c, Chan *nc)
nc = devclone(c, nc);
if(c->qid.path != CHDIR)
incref(&bit);
+ return nc;
}
int
@@ 215,6 240,7 @@ bitopen(Chan *c, int omode)
bit.lastid = -1;
bit.lastfid = -1;
bit.rid = -1;
+ bit.mid = -1;
bit.init = 0;
bit.ref = 1;
Cursortocursor(&arrow);
@@ 272,7 298,8 @@ bitclose(Chan *c)
/*
* These macros turn user-level (high bit at left) into internal (whatever)
- * bit order. On the gnot they're trivial.
+ * bit order. So far all machines have the same (good) order; when
+ * that changes, these should switch on a variable set at init time.
*/
#define U2K(x) (x)
#define K2U(x) (x)
@@ 282,7 309,7 @@ bitread(Chan *c, void *va, long n, ulong offset)
{
uchar *p, *q;
long miny, maxy, t, x, y;
- ulong l, nw, ws;
+ ulong l, nw, ws, rv, gv, bv;
int off, j;
Fontchar *i;
GBitmap *src;
@@ 387,9 414,36 @@ bitread(Chan *c, void *va, long n, ulong offset)
n = 3;
break;
}
+ if(bit.mid >= 0){
+ /*
+ * read colormap:
+ * data 12*(2**bitmapdepth)
+ */
+ l = (1<<bit.map[bit.mid].ldepth);
+ nw = 1 << l;
+ if(n < 12*nw)
+ error(Ebadblt);
+ for(j = 0; j < nw; j++){
+ if(bit.mid == 0){
+ getcolor(flipping? ~j : j, &rv, &gv, &bv);
+ }else{
+ rv = j;
+ for(off = 32-l; off > 0; off -= l)
+ rv = (rv << l) | j;
+ gv = bv = rv;
+ }
+ PLONG(p, rv);
+ PLONG(p+4, gv);
+ PLONG(p+8, bv);
+ p += 12;
+ }
+ bit.mid = -1;
+ n = 12*nw;
+ break;
+ }
if(bit.rid >= 0){
/*
- * read
+ * read bitmap:
* data bytewidth*(maxy-miny)
*/
src = &bit.map[bit.rid];
@@ 420,8 474,12 @@ bitread(Chan *c, void *va, long n, ulong offset)
for(y=miny; y<maxy; y++){
q = (uchar*)gaddr(src, Pt(src->r.min.x, y));
q += (src->r.min.x&((sizeof(ulong))*ws-1))/ws;
- for(x=0; x<l; x++)
- *p++ = K2U(*q++);
+ if(bit.rid == 0 && flipping) /* flip bits */
+ for(x=0; x<l; x++)
+ *p++ = ~K2U(*q++);
+ else
+ for(x=0; x<l; x++)
+ *p++ = K2U(*q++);
n += l;
}
if(off)
@@ 473,12 531,13 @@ long
bitwrite(Chan *c, void *va, long n, ulong offset)
{
uchar *p, *q;
- long m, v, miny, maxy, minx, maxx, t, x, y, tw, th;
- ulong l, nw, ws;
- int off, isoff, i;
+ long m, v, miny, maxy, minx, maxx, t, x, y;
+ ulong l, nw, ws, rv;
+ int off, isoff, i, ok;
Point pt, pt1, pt2;
Rectangle rect;
Cursor curs;
+ Fcode fc;
Fontchar *fcp;
GBitmap *bp, *src, *dst;
GFont *f;
@@ 514,7 573,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(m < 18)
error(Ebadblt);
v = *(p+1);
- if(v!=0 && v!=1) /* BUG */
+ if(v>3) /* BUG */
error(Ebadblt);
ws = 1<<(5-v); /* pixels per word */
if(bit.free == 0)
@@ 572,31 631,37 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
*/
if(m < 31)
error(Ebadblt);
+ fc = GSHORT(p+29) & 0xF;
+ v = GSHORT(p+11);
+ src = &bit.map[v];
+ if(v<0 || v>=conf.nbitmap || src->ldepth < 0)
+ error(Ebadbitmap);
+ off = 0;
+ if(v == 0){
+ if(flipping)
+ fc = flipS[fc];
+ off = 1;
+ }
v = GSHORT(p+1);
dst = &bit.map[v];
if(v<0 || v>=conf.nbitmap || dst->ldepth < 0)
error(Ebadbitmap);
- off = 0;
- if(v == 0)
+ if(v == 0){
+ if(flipping)
+ fc = flipD[fc];
off = 1;
+ }
pt.x = GLONG(p+3);
pt.y = GLONG(p+7);
- v = GSHORT(p+11);
- src = &bit.map[v];
- if(v<0 || v>=conf.nbitmap || src->ldepth < 0)
- error(Ebadbitmap);
- if(v == 0)
- off = 1;
rect.min.x = GLONG(p+13);
rect.min.y = GLONG(p+17);
rect.max.x = GLONG(p+21);
rect.max.y = GLONG(p+25);
- v = GSHORT(p+29);
if(off && !isoff){
cursoroff(1);
isoff = 1;
}
- balubitblt(dst, pt, src, rect, v);
+ gbitblt(dst, pt, src, rect, fc);
m -= 31;
p += 31;
break;
@@ 744,23 809,44 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
error(Ebadbitmap);
off = 0;
- if(v == 0)
+ fc = GSHORT(p+20) & 0xF;
+ if(v == 0){
+ if(flipping)
+ fc = flipD[fc];
off = 1;
+ }
pt1.x = GLONG(p+3);
pt1.y = GLONG(p+7);
pt2.x = GLONG(p+11);
pt2.y = GLONG(p+15);
t = p[19];
- v = GSHORT(p+20);
if(off && !isoff){
cursoroff(1);
isoff = 1;
}
- gsegment(dst, pt1, pt2, t, v);
+ gsegment(dst, pt1, pt2, t, fc);
m -= 22;
p += 22;
break;
+ case 'm':
+ /*
+ * read colormap
+ *
+ * 'm' 1
+ * id 2
+ */
+ if(m < 3)
+ error(Ebadblt);
+ v = GSHORT(p+1);
+ dst = &bit.map[v];
+ if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
+ error(Ebadbitmap);
+ bit.mid = v;
+ m -= 3;
+ p += 3;
+ break;
+
case 'p':
/*
* point
@@ 778,17 864,20 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
error(Ebadbitmap);
off = 0;
- if(v == 0)
+ fc = GSHORT(p+12) & 0xF;
+ if(v == 0){
+ if(flipping)
+ fc = flipD[fc];
off = 1;
+ }
pt1.x = GLONG(p+3);
pt1.y = GLONG(p+7);
t = p[11];
- v = GSHORT(p+12);
if(off && !isoff){
cursoroff(1);
isoff = 1;
}
- gpoint(dst, pt1, t, v);
+ gpoint(dst, pt1, t, fc);
m -= 14;
p += 14;
break;
@@ 835,15 924,18 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
error(Ebadbitmap);
off = 0;
- if(v == 0)
+ fc = GSHORT(p+13) & 0xF;
+ if(v == 0){
+ if(flipping)
+ fc = flipD[fc];
off = 1;
+ }
pt.x = GLONG(p+3);
pt.y = GLONG(p+7);
v = GSHORT(p+11);
f = &bit.font[v];
if(v<0 || v>=conf.nfont || f->bits==0 || f->bits->ldepth<0)
error(Ebadblt);
- v = GSHORT(p+13);
p += 15;
m -= 15;
q = memchr(p, 0, m);
@@ 853,7 945,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
cursoroff(1);
isoff = 1;
}
- gstring(dst, pt, f, (char*)p, v);
+ gstring(dst, pt, f, (char*)p, fc);
q++;
m -= q-p;
p = q;
@@ 875,8 967,12 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
error(Ebadbitmap);
off = 0;
- if(v == 0)
+ fc = GSHORT(p+21) & 0xF;
+ if(v == 0){
+ if(flipping)
+ fc = flipD[fc];
off = 1;
+ }
rect.min.x = GLONG(p+3);
rect.min.y = GLONG(p+7);
rect.max.x = GLONG(p+11);
@@ 885,12 981,11 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
src = &bit.map[v];
if(v<0 || v>=conf.nbitmap || src->ldepth<0)
error(Ebadbitmap);
- v = GSHORT(p+21);
if(off && !isoff){
cursoroff(1);
isoff = 1;
}
- gtexture(dst, rect, src, v);
+ gtexture(dst, rect, src, fc);
m -= 23;
p += 23;
break;
@@ 937,8 1032,12 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
for(y=miny; y<maxy; y++){
q = (uchar*)gaddr(dst, Pt(dst->r.min.x, y));
q += (dst->r.min.x&((sizeof(ulong))*ws-1))/ws;
- for(x=0; x<l; x++)
- *q++ = U2K(*p++);
+ if(v == 0 && flipping) /* flip bits */
+ for(x=0; x<l; x++)
+ *q++ = ~U2K(*p++);
+ else
+ for(x=0; x<l; x++)
+ *q++ = U2K(*p++);
m -= l;
}
break;
@@ 954,7 1053,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
error(Ebadblt);
pt1.x = GLONG(p+1);
pt1.y = GLONG(p+5);
- if(!eqpt(mouse.xy, pt1)){
+/* if(!eqpt(mouse.xy, pt1))*/{
mouse.xy = pt1;
mouse.track = 1;
mouseclock();
@@ 962,6 1061,38 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
m -= 9;
p += 9;
break;
+
+ case 'z':
+ /*
+ * write the colormap
+ *
+ * 'z' 1
+ * id 2
+ * map 12*(2**bitmapdepth)
+ */
+ if(m < 3)
+ error(Ebadblt);
+ v = GSHORT(p+1);
+ if(v != 0)
+ error(Ebadbitmap);
+ m -= 3;
+ p += 3;
+ nw = 1 << (1 << bit.map[v].ldepth);
+ if(m < 12*nw)
+ error(Ebadblt);
+ ok = 1;
+ for(i = 0; i < nw; i++){
+ ok &= setcolor(i, GLONG(p), GLONG(p+4), GLONG(p+8));
+ p += 12;
+ m -= 12;
+ }
+ if(!ok){
+ /* assume monochrome: possibly change flipping */
+ l = GLONG(p-12);
+ getcolor(nw-1, &rv, &rv, &rv);
+ flipping = (l != rv);
+ }
+ break;
}
poperror();
@@ 1011,8 1142,6 @@ bitcompact(void)
p1 += 2 + p1[0];
}
bit.wfree = p1;
- if(p1<bit.words || p1>=bit.words+bit.nwords)
- panic("bitcompact");
qunlock(&bitlock);
}
@@ 1041,9 1170,9 @@ cursoron(int dolock)
cursor.r = raddp(cursor.r, cursor.offset);
gbitblt(&cursorback, Pt(0, 0), &gscreen, cursor.r, S);
gbitblt(&gscreen, add(mouse.xy, cursor.offset),
- &clr, Rect(0, 0, 16, 16), D&~S);
+ &clr, Rect(0, 0, 16, 16), flipping? flipD[D&~S] : D&~S);
gbitblt(&gscreen, add(mouse.xy, cursor.offset),
- &set, Rect(0, 0, 16, 16), S|D);
+ &set, Rect(0, 0, 16, 16), flipping? flipD[S|D] : S|D);
}
if(dolock)
unlock(&cursor);
@@ 1061,7 1190,16 @@ cursoroff(int dolock)
}
void
-mousebuttons(int b) /* called spl5 */
+mousedelta(int b, int dx, int dy) /* called at higher priority */
+{
+ mouse.dx += dx;
+ mouse.dy += dy;
+ mouse.newbuttons = b;
+ mouse.track = 1;
+}
+
+void
+mousebuttons(int b) /* called at higher priority */
{
/*
* It is possible if you click very fast and get bad luck
@@ 1074,20 1212,28 @@ mousebuttons(int b) /* called spl5 */
}
void
-mouseclock(void) /* called spl6 */
-{
- ++mouse.clock;
-}
-
-void
-mousetry(Ureg *ur)
+mouseclock(void) /* called splhi */
{
- int s;
-
- if(mouse.clock && mouse.track && (ur->sr&SPL(7)) == 0 && canlock(&cursor)){
- s = spl1();
- mouseupdate(0);
- splx(s);
+ int x, y;
+ if(mouse.track && canlock(&cursor)){
+ x = mouse.xy.x + mouse.dx;
+ if(x < gscreen.r.min.x)
+ x = gscreen.r.min.x;
+ if(x >= gscreen.r.max.x)
+ x = gscreen.r.max.x;
+ y = mouse.xy.y + mouse.dy;
+ if(y < gscreen.r.min.y)
+ y = gscreen.r.min.y;
+ if(y >= gscreen.r.max.y)
+ y = gscreen.r.max.y;
+ cursoroff(0);
+ mouse.xy = Pt(x, y);
+ cursoron(0);
+ mouse.dx = 0;
+ mouse.dy = 0;
+ mouse.track = 0;
+ mouse.buttons = mouse.newbuttons;
+ mouse.changed = 1;
unlock(&cursor);
wakeup(&mouse.r);
}
@@ 1096,42 1242,22 @@ mousetry(Ureg *ur)
int
mouseputc(IOQ *q, int c)
{
- /*
- * put your favorite serial mouse code here
- */
-}
-
-void
-mouseupdate(int dolock)
-{
- int x, y;
-
- if(dolock && !canlock(&cursor))
- return;
-
- x = mouse.xy.x + mouse.dx;
- if(x < gscreen.r.min.x)
- x = gscreen.r.min.x;
- if(x >= gscreen.r.max.x)
- x = gscreen.r.max.x;
- y = mouse.xy.y + mouse.dy;
- if(y < gscreen.r.min.y)
- y = gscreen.r.min.y;
- if(y >= gscreen.r.max.y)
- y = gscreen.r.max.y;
- cursoroff(0);
- mouse.xy = Pt(x, y);
- cursoron(0);
- mouse.dx = 0;
- mouse.dy = 0;
- mouse.clock = 0;
- mouse.track = 0;
- mouse.buttons = mouse.newbuttons;
- mouse.changed = 1;
-
- if(dolock){
- unlock(&cursor);
- wakeup(&mouse.r);
+ static short msg[5];
+ static int nb;
+ static uchar b[] = {0, 4, 2, 6, 1, 5, 3, 7};
+
+ if((c&0xF0) == 0x80)
+ nb=0;
+ msg[nb] = c;
+ if(c & 0x80)
+ msg[nb] |= 0xFF00; /* sign extend */
+ if(++nb == 5){
+ mouse.newbuttons = b[(msg[0]&7)^7];
+ mouse.dx = msg[1]+msg[3];
+ mouse.dy = -(msg[2]+msg[4]);
+ mouse.track = 1;
+ mouseclock();
+ nb = 0;
}
}
M port/devdk.c => port/devdk.c +3 -2
@@ 767,7 767,7 @@ dkstat(Chan *c, char *dp)
/*
* opening a dk device allocates a Line. Opening the `clone'
* device is a ``macro'' for finding a free Line and opening
- * it's ctl file.
+ * its ctl file.
*
* opening the `listen' sub device is a macro for listening for
* a new call. Lile `clone' the ctl file of the new channel is
@@ 1473,7 1473,8 @@ dkcsckproc(void *a)
break;
default:
- DPRINT("unrecognized csc message %o(%o)\n", d.type, line);
+ print("unrecognized csc message %o.%o(%o)\n",
+ d.type, d.srv, line);
break;
}
}
M port/devscsi.c => port/devscsi.c +5 -1
@@ 104,7 104,7 @@ scsiwalk(Chan *c, char *name)
void
scsistat(Chan *c, char *db)
{
- devstat(c, db, 0, 0, scsigen);
+ devstat(c, db, 0, 0, scsigeno);
}
Chan *
@@ 579,5 579,9 @@ scsictrlintr(void)
default:
panic("scsi status 0x%2.2ux", status);
}
+ kprint("resetting...");
+ PUT(Own_id, ownid);
+ PUT(Cmd, Reset);
+ break;
}
}
M port/devwren.c => port/devwren.c +1 -1
@@ 150,7 150,7 @@ wrenattach(char *param)
d = &wren[dev];
d->blocksize = BGLONG(&buf[4]);
- plen = BGLONG(&buf[0]);
+ plen = BGLONG(&buf[0])+1;
d->p[Npart].firstblock = 0;
d->p[Npart].maxblock = plen;
plen = plen/Npart;
M port/fault.c => port/fault.c +4 -3
@@ 165,9 165,6 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
if(ask < BY2PG)
memset(kaddr+ask, 0, BY2PG-ask);
- if((s->type&SG_TYPE) == SG_TEXT)
- memset(new->cachectl, PG_TXTFLUSH, sizeof(new->cachectl));
-
poperror();
kunmap(k);
qunlock(&c->rdl);
@@ 176,6 173,8 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
new->daddr = daddr;
cachepage(new, s->image);
*p = new;
+ if(s->flushme)
+ memset(new->cachectl, PG_TXTFLUSH, sizeof(new->cachectl));
}
else
putpage(new);
@@ 207,6 206,8 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
cachepage(new, &swapimage);
putswap(*p);
*p = new;
+ if(s->flushme)
+ memset(new->cachectl, PG_TXTFLUSH, sizeof(new->cachectl));
}
else
putpage(new);
M port/portdat.h => port/portdat.h +1 -0
@@ 348,6 348,7 @@ struct Segment
ulong size; /* size in pages */
ulong fstart; /* start address in file for demand load */
ulong flen; /* length of segment in file */
+ int flushme; /* maintain consistent icache for this segment */
Image *image; /* image in file system attached to this segment */
Page *(*pgalloc)(ulong addr);/* SG_PHYSICAL page allocator */
void (*pgfree)(Page *); /* SG_PHYSICAL page free */
M port/portfns.h => port/portfns.h +40 -35
@@ 2,12 2,12 @@
#define SET(x) x = 0
#define USED(x) if(x)
-void alarminit(void);
Alarm* alarm(int, void (*)(Alarm*), void*);
+void alarminit(void);
Block* allocb(ulong);
-Image* attachimage(int, Chan*, ulong, ulong);
int anyready(void);
void append(List**, List*);
+Image* attachimage(int, Chan*, ulong, ulong);
int blen(Block *);
int bround(Block *, int);
void buzz(int, int);
@@ 15,9 15,9 @@ void cachepage(Page*, Image*);
void cancel(Alarm*);
int cangetc(void*);
int canlock(Lock*);
-int canqlock(QLock*);
int canpage(Proc*);
int canputc(void*);
+int canqlock(QLock*);
void chandevinit(void);
void chandevreset(void);
void chaninit(void);
@@ 25,10 25,10 @@ void checkalarms(void);
void clock(Ureg*);
Chan* clone(Chan*, Chan*);
void close(Chan*);
-void closemount(Mount*);
-void closepgrp(Pgrp*);
void closeegrp(Egrp*);
void closefgrp(Fgrp*);
+void closemount(Mount*);
+void closepgrp(Pgrp*);
long clrfpintr(void);
void confinit(void);
int consactive(void);
@@ 36,8 36,8 @@ Env* copyenv(Env*, int);
void copypage(Page*, Page*);
int decref(Ref*);
void delay(int);
-void delete0(List**, List*);
void delete(List**, List*, List*);
+void delete0(List**, List*);
Chan* devattach(int, char*);
Chan* devclone(Chan*, Chan*);
void devdir(Chan*, Qid, char*, long, long, Dir*);
@@ 52,11 52,11 @@ void dumpqueues(void);
void dumpregs(Ureg*);
void dumpstack(void);
Fgrp* dupfgrp(Fgrp*);
-void dupswap(Page*);
-void envpgclose(Env *);
void duppage(Page*);
-Segment* dupseg(Segment*);
+Segment* dupseg(Segment*);
+void dupswap(Page*);
void envcpy(Egrp*, Egrp*);
+void envpgclose(Env *);
int eqchan(Chan*, Chan*, long);
int eqqid(Qid, Qid);
void error(int);
@@ 77,10 77,14 @@ void freepte(Segment*, Pte*);
void freesegs(int);
Block* getb(Blist*);
int getc(IOQ*);
-int gets(IOQ*, void*, int);
+void getcolor(ulong, ulong*, ulong*, ulong*);
int getfields(char*, char**, int, char);
Block* getq(Queue*);
+int gets(IOQ*, void*, int);
void gotolabel(Label*);
+void grpinit(void);
+int hwcursset(uchar*, uchar*, int, int);
+int hwcursmove(int, int);
void* ialloc(ulong, int);
long ibrk(ulong, int);
int incref(Ref*);
@@ 91,23 95,23 @@ void invalidateu(void);
void isdir(Chan*);
int ispages(void*);
void kbdclock(void);
-void kbdrepeat(int);
int kbdputc(IOQ*, int);
+void kbdrepeat(int);
+void kickpager(void);
int kprint(char*, ...);
void kproc(char*, void(*)(void*), void*);
-void kickpager(void);
void lights(int);
void lock(Lock*);
-void lockpage(Page*);
void lockinit(void);
+void lockpage(Page*);
Page* lookpage(Image*, ulong);
void machinit(void);
void mapstack(Proc*);
void mfreeseg(Segment*, ulong, int);
-void mntdump(void);
void mmurelease(Proc*);
-int mouseputc(IOQ*, int);
+void mntdump(void);
int mount(Chan*, Chan*, int);
+int mouseputc(IOQ*, int);
Chan* namec(char*, int, int, ulong);
Alarm* newalarm(void);
Chan* newchan(void);
@@ 118,7 122,7 @@ Page* newpage(int, Segment **, ulong);
Pgrp* newpgrp(void);
Proc* newproc(void);
void newqinfo(Qinfo*);
-Segment* newseg(int, ulong, ulong);
+Segment* newseg(int, ulong, ulong);
char* nextelem(char*, char*);
void nexterror(void);
void notify(Ureg*);
@@ 130,36 134,35 @@ int pagemeis0(void*);
void panic(char*, ...);
void pexit(char*, int);
void pgrpcpy(Pgrp*, Pgrp*);
-void pio(Segment *, ulong, ulong, Page **);
-Pte* ptecpy(Pte*);
-void putseg(Segment*);
-void putswap(Page*);
-void grpinit(void);
void pgrpnote(Pgrp*, char*, long, int);
Pgrp* pgrptab(int);
+void pio(Segment *, ulong, ulong, Page **);
#define poperror() u->nerrlab--
int postnote(Proc*, int, char*, int);
int pprint(char*, ...);
void printinit(void);
-void procctl(Proc *p);
-void putimage(Image*);
-void putpage(Page*);
-void putstr(char*);
-int putc(IOQ*, int);
-void putstr(char*);
-void putstrn(char*, long);
-void puts(IOQ*, void*, int);
-ulong procalarm(ulong);
+ulong procalarm(ulong);
+void procctl(Proc*);
void procdump(void);
void procinit0(void);
Proc* proctab(int);
Pte* ptealloc(void);
+Pte* ptecpy(Pte*);
Block* pullup(Block *, int);
Queue* pushq(Stream*, Qinfo*);
int putb(Blist*, Block*);
void putbq(Blist*, Block*);
+int putc(IOQ*, int);
+void putimage(Image*);
void putmmu(ulong, ulong, Page*);
+void putpage(Page*);
int putq(Queue*, Block*);
+void puts(IOQ*, void*, int);
+void putseg(Segment*);
+void putstr(char*);
+void putstr(char*);
+void putstrn(char*, long);
+void putswap(Page*);
ulong pwait(Waitmsg*);
void qlock(QLock*);
void qunlock(QLock*);
@@ 174,12 177,14 @@ void savefpregs(FPsave*);
void sccintr(void);
void sccsetup(void*);
void sccspecial(int, IOQ*, IOQ*, int);
-void schedinit(void);
void sched(void);
+void schedinit(void);
+int screenbits(void);
long seconds(void);
-Segment* seg(Proc*, ulong, int);
-void segpage(Segment*, Page*);
+Segment* seg(Proc*, ulong, int);
ulong segattach(Proc*, ulong, char *, ulong, ulong);
+void segpage(Segment*, Page*);
+int setcolor(ulong, ulong, ulong, ulong);
int setlabel(Label*);
void setswapchan(Chan*);
char* skipslash(char*);
@@ 187,13 192,13 @@ void sleep(Rendez*, int(*)(void*), void*);
int splhi(void);
int spllo(void);
void splx(int);
-int streamclose1(Stream*);
int streamclose(Chan*);
+int streamclose1(Stream*);
int streamenter(Stream*);
int streamexit(Stream*, int);
Devgen streamgen;
-void streaminit0(void);
void streaminit(void);
+void streaminit0(void);
Stream* streamnew(ushort, ushort, ushort, Qinfo*, int);
void streamopen(Chan*, Qinfo*);
int streamparse(char*, Block*);
M port/queue.c => port/queue.c +0 -1
@@ 4,7 4,6 @@
#include "dat.h"
#include "fns.h"
#include "io.h"
-#include "errno.h"
void
initq(IOQ *q)
M port/segment.c => port/segment.c +48 -10
@@ 11,6 11,7 @@
Page *lkpage(ulong addr);
Page *snewpage(ulong addr);
void lkpgfree(Page*);
+void imagereclaim(void);
/* System specific segattach devices */
#include "segment.h"
@@ 30,6 31,8 @@ struct segalloc
Segment *free;
}segalloc;
+static QLock ireclaim;
+
void
initseg(void)
{
@@ 75,6 78,7 @@ newseg(int type, ulong base, ulong size)
s->flen = 0;
s->pgalloc = 0;
s->pgfree = 0;
+ s->flushme = 0;
memset(s->map, 0, sizeof(s->map));
return s;
@@ 135,13 139,20 @@ dupseg(Segment *s)
int i;
switch(s->type&SG_TYPE) {
- case SG_TEXT: /* new segment shares pte set */
+ case SG_TEXT: /* New segment shares pte set */
case SG_SHARED:
case SG_PHYSICAL:
incref(s);
return s;
- case SG_DATA: /* copy on write both old and new plus demand load info */
- lock(s);
+
+ case SG_BSS: /* Just copy on write */
+ case SG_STACK:
+ qlock(&s->lk);
+ n = newseg(s->type, s->base, s->size);
+ goto copypte;
+
+ case SG_DATA: /* Copy on write plus demand load info */
+ qlock(&s->lk);
n = newseg(s->type, s->base, s->size);
incref(s->image);
@@ 152,13 163,10 @@ dupseg(Segment *s)
for(i = 0; i < SEGMAPSIZE; i++)
if(pte = s->map[i])
n->map[i] = ptecpy(pte);
- unlock(s);
+
+ n->flushme = s->flushme;
+ qunlock(&s->lk);
return n;
- case SG_BSS: /* Just copy on write */
- case SG_STACK:
- lock(s);
- n = newseg(s->type, s->base, s->size);
- goto copypte;
}
panic("dupseg");
@@ 188,6 196,7 @@ attachimage(int type, Chan *c, ulong base, ulong len)
lock(&imagealloc);
+ /* Search the image cache for remains of the text from a previous incarnation */
for(i = ihash(c->qid.path); i; i = i->hash) {
if(c->qid.path == i->qid.path) {
lock(i);
@@ 204,6 213,7 @@ attachimage(int type, Chan *c, ulong base, ulong len)
while(!(i = imagealloc.free)) {
unlock(&imagealloc);
+ imagereclaim();
resrcwait("no images");
lock(&imagealloc);
}
@@ 236,6 246,32 @@ found:
}
void
+imagereclaim(void)
+{
+ Page *p;
+
+ if(!canqlock(&ireclaim)) /* Somebody is already cleaning the page cache */
+ return;
+
+ lock(&palloc);
+ for(p = palloc.head; p; p = p->next) {
+ if(p->image == 0)
+ continue;
+
+ unlock(&palloc);
+ lockpage(p);
+ if(p->ref == 0 && p->image != &swapimage)
+ uncachepage(p);
+ unlockpage(p);
+ lock(&palloc);
+ }
+
+ unlock(&palloc);
+
+ qunlock(&ireclaim);
+}
+
+void
putimage(Image *i)
{
Image *f, **l;
@@ 271,7 307,7 @@ putimage(Image *i)
}
long
-ibrk(ulong addr, int seg) /* Called with a locked segment */
+ibrk(ulong addr, int seg)
{
Segment *s, *ns;
ulong newtop, newsize;
@@ 428,6 464,8 @@ syssegflush(ulong *arg)
if(s == 0)
errors("bad segment address");
+ s->flushme = 1;
+
soff = arg[0]-s->base;
j = (soff&(PTEMAPMEM-1))/BY2PG;
pages = ((arg[0]+arg[1]+(BY2PG-1))&~(BY2PG-1))-(arg[0]&~(BY2PG-1));
M port/swap.c => port/swap.c +2 -3
@@ 9,7 9,6 @@
/* Predeclaration */
void pageout(Proc *p, Segment*);
int pagepte(int, Segment*, Page**);
-void openswap(void);
int needpages(void*);
void pager(void*);
void executeio(void);
@@ 17,7 16,7 @@ int canflush(Proc *p, Segment*);
enum
{
- Maxpages = 500, /* Max number of pageouts per process pass */
+ Maxpages = 500, /* Max number of pageouts per segment pass */
};
Image swapimage;
@@ 196,7 195,7 @@ canflush(Proc *p, Segment *s)
unlock(s);
/* Now we must do hardwork to ensure all processes which have tlb
- * entries for this segment are flushed
+ * entries for this segment will be flushed if we suceed in pageing it out
*/
p = proctab(0);
ep = &p[conf.nproc];
M port/sysfile.c => port/sysfile.c +2 -2
@@ 124,7 124,7 @@ sysdup(ulong *arg)
unlock(f);
if(oc)
close(oc);
- }else {
+ }else{
if(waserror()) {
close(c);
nexterror();
@@ 144,7 144,7 @@ sysopen(ulong *arg)
Chan *c = 0;
openmode(arg[1]); /* error check only */
- if(waserror()) {
+ if(waserror()){
if(c)
close(c);
nexterror();
M port/sysproc.c => port/sysproc.c +6 -6
@@ 129,6 129,7 @@ sysexec(ulong *arg)
}
if(!indir)
strcpy(elem, u->elem);
+
n = (*devtab[tc->type].read)(tc, &exec, sizeof(Exec), 0);
if(n < 2)
Err:
@@ 257,6 258,7 @@ sysexec(ulong *arg)
img = attachimage(SG_TEXT|SG_RONLY, tc, UTZERO, (t-UTZERO)>>PGSHIFT);
ts = img->s;
p->seg[TSEG] = ts;
+ ts->flushme = 1;
ts->fstart = 0;
ts->flen = sizeof(Exec)+exec.text;
@@ 270,12 272,9 @@ sysexec(ulong *arg)
s->fstart = ts->fstart+ts->flen;
s->flen = exec.data;
-
/* BSS. Zero fill on demand */
p->seg[BSEG] = newseg(SG_BSS, d, (b-d)>>PGSHIFT);
- close(tc);
-
/*
* Move the stack
*/
@@ 286,6 285,7 @@ sysexec(ulong *arg)
relocateseg(s, TSTKTOP-USTKTOP);
p->seg[ESEG] = 0;
+ close(tc);
poperror();
/*
@@ 525,12 525,12 @@ syssegfree(ulong *arg)
Segment *s;
ulong from, len;
- s = seg(u->p, arg[0], 1);
+ from = PGROUND(arg[0]);
+ s = seg(u->p, from, 1);
if(s == 0)
errors("not in address space");
- from = PGROUND(arg[1]);
- len = arg[2];
+ len = arg[1];
if(from+len > s->top) {
qunlock(&s->lk);
M ss/dat.h => ss/dat.h +4 -6
@@ 64,9 64,10 @@ struct Conf
ulong base0; /* base of bank 0 */
ulong base1; /* base of bank 1 */
ulong npage; /* total physical pages of memory */
- ulong norig; /* origins */
- ulong npte; /* contiguous page table entries */
- ulong nmod; /* single (modifying) page table entries */
+ ulong nseg; /* number of segments */
+ ulong nimage; /* number of page cache image headers */
+ ulong npagetab; /* number of pte tables */
+ ulong nswap; /* number of swap blocks */
int nalarm; /* alarms */
int nchan; /* channels */
int nenv; /* distinct environment values */
@@ 147,7 148,6 @@ struct Mach
#define NERR 15
#define NNOTE 5
-#define NFD 100
struct User
{
Proc *p;
@@ 158,8 158,6 @@ struct User
char elem[NAMELEN]; /* last name element from namec */
Chan *slash;
Chan *dot;
- Chan *fd[NFD];
- int maxfd; /* highest fd in use */
/*
* Rest of structure controlled by devproc.c and friends.
* lock(&p->debug) to modify.
M ss/main.c => ss/main.c +17 -18
@@ 34,7 34,8 @@ main(void)
cacheinit();
intrinit();
procinit0();
- pgrpinit();
+ initseg();
+ grpinit();
chaninit();
alarminit();
chandevreset();
@@ 109,6 110,7 @@ init0(void)
u->slash = (*devtab[0].attach)(0);
u->dot = clone(u->slash, 0);
+ kickpager();
touser(USTKTOP-5*BY2WD);
}
@@ 118,12 120,15 @@ void
userinit(void)
{
Proc *p;
- Seg *s;
+ Segment *s;
User *up;
KMap *k;
p = newproc();
p->pgrp = newpgrp();
+ p->egrp = newegrp();
+ p->fgrp = newfgrp();
+
strcpy(p->text, "*init*");
savefpregs(&initfp);
p->fpstate = FPinit;
@@ 146,25 151,18 @@ userinit(void)
/*
* User Stack
*/
- s = &p->seg[SSEG];
- s->proc = p;
- s->o = neworig(USTKTOP-BY2PG, 1, OWRPERM, 0);
- s->minva = USTKTOP-BY2PG;
- s->maxva = USTKTOP;
+ s = newseg(SG_STACK, USTKTOP-BY2PG, 1);
+ p->seg[SSEG] = s;
/*
* Text
*/
- s = &p->seg[TSEG];
- s->proc = p;
- s->o = neworig(UTZERO, 1, 0, 0);
- s->o->pte[0].page = newpage(0, 0, UTZERO);
- s->o->npage = 1;
- k = kmap(s->o->pte[0].page);
+ s = newseg(SG_TEXT, UTZERO, 1);
+ p->seg[TSEG] = s;
+ segpage(s, newpage(1, 0, UTZERO));
+ k = kmap(s->map[0]->pages[0]);
memmove((ulong*)VA(k), initcode, sizeof initcode);
kunmap(k);
- s->minva = UTZERO;
- s->maxva = UTZERO+BY2PG;
ready(p);
}
@@ 271,10 269,11 @@ confinit(void)
mul = 2;
conf.nproc = 50*mul;
conf.npgrp = 12*mul;
- conf.npte = 1400*mul;
- conf.nmod = 800*mul;
+ conf.nseg = conf.nproc*4;
+ conf.npagetab = conf.nseg*2;
+ conf.nswap = 4096;
+ conf.nimage = 50;
conf.nalarm = 1000;
- conf.norig = 150*mul;
conf.nchan = 200*mul;
conf.nenv = 100*mul;
conf.nenvchar = 8000*mul;
M ss/mem.h => ss/mem.h +3 -0
@@ 93,6 93,9 @@
#define PTEACCESS (1<<25)
#define PTEMODIFY (1<<24)
#define PTEUNCACHED 0
+#define PTEMAPMEM (1024*1024)
+#define PTEPERTAB (PTEMAPMEM/BY2PG)
+#define SEGMAPSIZE 16
#define INVALIDPTE 0
#define PPN(pa) ((pa>>12)&0xFFFF)
M ss/mmu.c => ss/mmu.c +13 -1
@@ 22,6 22,8 @@ struct
int newpid(Proc*);
void purgepid(int);
+void flushcontext(void);
+
int pidtime[NTLBPID]; /* should be per m */
/*
@@ 33,6 35,16 @@ mapstack(Proc *p)
short tp;
ulong tlbphys;
+ if(p->newtlb) {
+ flushcontext();
+ tp = u->p->pidonmach[m->machno];
+ if(tp)
+ pidtime[tp] = 0;
+ /* easiest is to forget what pid we had.... */
+ memset(u->p->pidonmach, 0, sizeof u->p->pidonmach);
+ p->newtlb = 0;
+ }
+
tp = p->pidonmach[m->machno];
if(tp == 0){
tp = newpid(p);
@@ 194,7 206,7 @@ mmuinit(void)
}
void
-putmmu(ulong tlbvirt, ulong tlbphys)
+putmmu(ulong tlbvirt, ulong tlbphys, Page *pg)
{
short tp;
Proc *p;
A ss/segment.h => ss/segment.h +19 -0
@@ 0,0 1,19 @@
+/*
+ * Attach segment types
+ */
+
+typedef struct Physseg Physseg;
+struct Physseg
+{
+ ulong attr; /* Segment attributes */
+ char *name; /* Attach name */
+ ulong pa; /* Physical address */
+ ulong size; /* Maximum segment size in pages */
+ Page *(*pgalloc)(ulong); /* Allocation if we need it */
+ void (*pgfree)(Page*);
+}physseg[] = {
+ { SG_SHARED, "shared", 0, SEGMAXSIZE, 0, 0 },
+ { SG_PHYSICAL, "kmem", KZERO, SEGMAXSIZE, 0, 0 },
+ { SG_BSS, "memory", 0, SEGMAXSIZE, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 },
+};