From 6bc41a53311561691c0ae0d8db0192e77af6d650 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 6 Jul 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-07-06 --- gnot/dat.h | 1 + gnot/screen.c | 50 ++++++++ pc/clock.c | 19 ++- pc/dat.h | 3 - pc/fns.h | 20 +++- pc/io.h | 2 +- pc/kbd.c | 47 +++----- pc/l.s | 36 +++++- pc/main.c | 25 +++- pc/mem.h | 18 ++- pc/mmu.c | 6 +- pc/trap.c | 30 ++--- port/devbit.c | 320 ++++++++++++++++++++++++++++++++++--------------- port/devdk.c | 5 +- port/devscsi.c | 6 +- port/devwren.c | 2 +- port/fault.c | 7 +- port/portdat.h | 1 + port/portfns.h | 75 ++++++------ port/queue.c | 1 - port/segment.c | 58 +++++++-- port/swap.c | 5 +- port/sysfile.c | 4 +- port/sysproc.c | 12 +- ss/dat.h | 10 +- ss/main.c | 35 +++--- ss/mem.h | 3 + ss/mmu.c | 14 ++- ss/segment.h | 19 +++ 29 files changed, 569 insertions(+), 265 deletions(-) create mode 100644 ss/segment.h diff --git a/gnot/dat.h b/gnot/dat.h index 0fe99a4d1396ce13dca5b656766b1acb2cd94db8..500929f05a444d97f97c97d384227495939444cb 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -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; /* ??? */ diff --git a/gnot/screen.c b/gnot/screen.c index 2945007b296abe8336e3e5907be1b2e0f6c9cde8..80f202d9bdeac10dc007fe1b431b11d68049c766 100644 --- a/gnot/screen.c +++ b/gnot/screen.c @@ -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; +} diff --git a/pc/clock.c b/pc/clock.c index e84ffdb12d2cd9374a6ec9efde54eebb7fa4ec94..5c6facc0a4e491134fb79ac2258ec1491bd8af75 100644 --- a/pc/clock.c +++ b/pc/clock.c @@ -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(); } diff --git a/pc/dat.h b/pc/dat.h index c133d25c5d929dcacfce05d0c81aca0a764145e1..0f37468082dbcca06142088a20f269457238f811 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -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. diff --git a/pc/fns.h b/pc/fns.h index 37b59f207daa93bd05a8f493633773d1f1ccbf35..af6544ce00cbf0379da4813f6d1a8404694f7894 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -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*); diff --git a/pc/io.h b/pc/io.h index d41c219773b988db7fdeb642a1f19bc1d339e205..b9f3cb7c43770d1ac19011dc799ec68de48273ae 100644 --- a/pc/io.h +++ b/pc/io.h @@ -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 */ }; diff --git a/pc/kbd.c b/pc/kbd.c index 41ae2275fb4e2c5c7efa38a69234890faa84be85..85577ec00050b256ceab5a9efb4bdcbbf0f0e04a 100644 --- a/pc/kbd.c +++ b/pc/kbd.c @@ -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; } diff --git a/pc/l.s b/pc/l.s index a153b4343babfc08a68c8a0979e395efd0d32d03..576ce5a743c6530109ba7334fd7aa8ebe4997665 100644 --- a/pc/l.s +++ b/pc/l.s @@ -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 diff --git a/pc/main.c b/pc/main.c index 98cb20bd14a4a7b258f659f8e268c6c529926ca1..d83dd8d4349b14dbc56873cd0330d83570d57d5a 100644 --- a/pc/main.c +++ b/pc/main.c @@ -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 diff --git a/pc/mem.h b/pc/mem.h index de5040c95b1822c5fba0cf31ee25d23c20b679e2..a0791e67b8a32c730aca3128539b665e1403df51 100644 --- a/pc/mem.h +++ b/pc/mem.h @@ -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) /* ??? */ diff --git a/pc/mmu.c b/pc/mmu.c index 10c6898440d354860bc9706d656e12d883068fb7..0f43875fadaea1d45a535c60546009943a86647b 100644 --- a/pc/mmu.c +++ b/pc/mmu.c @@ -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 diff --git a/pc/trap.c b/pc/trap.c index 62b76a385e34a0b8585493c24ac1467505bfe062..bc29fbb69aaac601dca4ac6b11b9e5a22739a12e 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -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; } diff --git a/port/devbit.c b/port/devbit.c index e5014161ca7d62277be3508433f7419a6dea6fc6..fc886a6b5b42a07005a1fa299515fb9d659c9f6d 100644 --- a/port/devbit.c +++ b/port/devbit.c @@ -6,13 +6,31 @@ #include "errno.h" #include "devtab.h" -#include "ureg.h" #include #include 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; ibase = 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< 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; yr.min.x, y)); q += (src->r.min.x&((sizeof(ulong))*ws-1))/ws; - for(x=0; x3) /* 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; yr.min.x, y)); q += (dst->r.min.x&((sizeof(ulong))*ws-1))/ws; - for(x=0; x=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; } } diff --git a/port/devdk.c b/port/devdk.c index b21c1ca4588256688d1d19d2a8de693d34f573e2..9094504b8a82507e39caa72b409a5904dcdc748f 100644 --- a/port/devdk.c +++ b/port/devdk.c @@ -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; } } diff --git a/port/devscsi.c b/port/devscsi.c index 1499e86bb4c8833ab4a5dce894ef6edba0fd1c63..0314ec8cec16b9411f32b60927661c0eb564c03f 100644 --- a/port/devscsi.c +++ b/port/devscsi.c @@ -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; } } diff --git a/port/devwren.c b/port/devwren.c index b0937a0f9c91c30fa3577576362fd7fd82cf9ccb..c313cf352f4b6f912f93a3e761375758229804d0 100644 --- a/port/devwren.c +++ b/port/devwren.c @@ -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; diff --git a/port/fault.c b/port/fault.c index 6780f47e5b1178504231277c19370a1522ef186d..d8ab9d52e4c16a4d7b6d0e8ae22b5a41f4d5729f 100644 --- a/port/fault.c +++ b/port/fault.c @@ -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); diff --git a/port/portdat.h b/port/portdat.h index 44f20d510486c3f7df4fc3f95e93dc5b923cc9d3..ac6229753a46ae4abd38c2c8230c79c9f2f65a93 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -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 */ diff --git a/port/portfns.h b/port/portfns.h index 70f16601071857be6e9e68aef848e2dc451a652d..ead0af9bc824948bcabc70c941f8a30aa18be611 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -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*); diff --git a/port/queue.c b/port/queue.c index db545ac915c32d99d8cae668fbfc9e84aa13c005..d15e29ea5bd937e9514dc404ea9b180406fda362 100644 --- a/port/queue.c +++ b/port/queue.c @@ -4,7 +4,6 @@ #include "dat.h" #include "fns.h" #include "io.h" -#include "errno.h" void initq(IOQ *q) diff --git a/port/segment.c b/port/segment.c index 1f92bfcd7b8ed1883d147c518f52613c7e1f7e01..0a53b6c1c9b3f5c8b58c898e76a603f0c5aaf8f1 100644 --- a/port/segment.c +++ b/port/segment.c @@ -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); } @@ -235,6 +245,32 @@ found: return i; } +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) { @@ -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)); diff --git a/port/swap.c b/port/swap.c index 38e6062a0b4d4b15b2107261f8c8cd8829f4cea5..6fefcc95707a45cf26f378fd07ed6ec98d0d2f23 100644 --- a/port/swap.c +++ b/port/swap.c @@ -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]; diff --git a/port/sysfile.c b/port/sysfile.c index fe65eb9f21a73969c77737842a7b7f0a2d4b9a46..8ee95baf8bb9ed394380a4c34976fbb6501dae70 100644 --- a/port/sysfile.c +++ b/port/sysfile.c @@ -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(); diff --git a/port/sysproc.c b/port/sysproc.c index 4300cbcfe40588d5527e3d2a3cae9476a4dfe6b3..6cc152c3fea37c4148889890c130b646fd7be922 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -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); diff --git a/ss/dat.h b/ss/dat.h index 2c7baa6a773cf23ee594b3c0b2aba2c23844f511..1cceac208a46b8325102f3de9b75ddeea8e2eb4c 100644 --- a/ss/dat.h +++ b/ss/dat.h @@ -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. diff --git a/ss/main.c b/ss/main.c index bb0960e7129eaae45c6ab7af6df7f1a82a2d2547..ae9c544c40d8f473c4da311f49a58fc29377070e 100644 --- a/ss/main.c +++ b/ss/main.c @@ -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; diff --git a/ss/mem.h b/ss/mem.h index 1dc0cb0f2d9769c1694b7ff5b49dd044032aea28..cee5ba43f1efa65979a02447dc7e91125035c9a1 100644 --- a/ss/mem.h +++ b/ss/mem.h @@ -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) diff --git a/ss/mmu.c b/ss/mmu.c index 5e65773ff3f5a72f82eb6aa41afc16be3e0f05af..9788a9cfbbcff987e98d91b3608ccdfd3946cac1 100644 --- a/ss/mmu.c +++ b/ss/mmu.c @@ -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; diff --git a/ss/segment.h b/ss/segment.h new file mode 100644 index 0000000000000000000000000000000000000000..06b7d48889248277c7303519f9eb130d6ba89ab3 --- /dev/null +++ b/ss/segment.h @@ -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 }, +};