From a8c811ed5a239cd9dabcbab14ff1c0657923fc70 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 6 Apr 1995 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1995-04-06 --- pc/devvga.c | 262 +++++++++++++++++++++------------------------------- pc/fns.h | 1 + pc/mmu.c | 40 ++++++++ 3 files changed, 144 insertions(+), 159 deletions(-) diff --git a/pc/devvga.c b/pc/devvga.c index 43492ad0d753cad55f8a4d9ed65201d8cb919775..4e21f7190ce03f4deb770655d63cf2fceff72ba0 100644 --- a/pc/devvga.c +++ b/pc/devvga.c @@ -12,9 +12,24 @@ enum { + /* default footprint is 64k */ Footshift= 16, Footprint= 1<name); + port += sprint(cbuf+port, "%s\n", hwgc->name); else - sprint(cbuf+port, "off\n"); + port += sprint(cbuf+port, "off\n"); + sprint(cbuf+port, "addr: 0x%lux\n", screenmem&~KZERO); return readstr(offset, buf, n, cbuf); case Qvgaiob: port = offset; @@ -231,15 +235,25 @@ vgabread(Chan *c, long n, ulong offset) static void vgactl(char *arg) { - int x, y, z; - char *cp, *field[3]; + int n; + ulong x, y, z; + char *cp, *field[4]; Hwgc *hwgcp; Vgac *vgacp; - if(getfields(arg, field, 3, " ") != 2) + n = getfields(arg, field, 4, " "); + if(n < 2) error(Ebadarg); - if(strcmp(field[0], "hwgc") == 0){ + if(strcmp(field[0], "disable") == 0){ + screendisabled = 1; + } + else if(strcmp(field[0], "enable") == 0){ + screendisabled = 0; + } + else if(strcmp(field[0], "hwgc") == 0){ + if(n < 2) + error(Ebadarg); if(strcmp(field[1], "off") == 0){ if(hwgc){ (*hwgc->disable)(); @@ -264,6 +278,8 @@ vgactl(char *arg) } } else if(strcmp(field[0], "type") == 0){ + if(n < 2) + error(Ebadarg); for(vgacp = vgactlr; vgacp; vgacp = vgacp->link){ if(strcmp(field[1], vgacp->name) == 0){ vgac = vgacp; @@ -272,6 +288,8 @@ vgactl(char *arg) } } else if(strcmp(field[0], "size") == 0){ + if(n < 2) + error(Ebadarg); x = strtoul(field[1], &cp, 0); if(x == 0 || x > 2048) error(Ebadarg); @@ -300,6 +318,47 @@ vgactl(char *arg) cursoron(1); return; } + else if(strcmp(field[0], "linear") == 0){ + if(n < 2) + error(Ebadarg); + x = strtoul(field[1], 0, 0); + if(n < 3) + y = 0; + else + y = strtoul(field[2], 0, 0); + + /* see if it fits in the usual place */ + if(x <= 2*Footprint){ + screenmem = SCREENMEM; + if(x == 0) + footprint = Footprint; + else + footprint = x; + gscreen.base = (void*)screenmem; + return; + } + + /* grab new space */ + if(y == 0){ + if(footprint >= x) + return; + } else { + int s, e; + + s = screenmem & ~KZERO; + e = s + footprint; + s = ROUND(s, y); + if(e > s + x) + return; + } + y = getspace(x, y); + if(y == 0) + error("not enough free address space"); + screenmem = y; + gscreen.base = (void*)y; + footprint = x; + return; + } error(Ebadarg); } @@ -476,109 +535,6 @@ screeninit(void) memset(CGASCREEN, 0, CGAWIDTH*CGAHEIGHT); } -/* - * a few well known VGA modes and the code to set them - */ -typedef struct VGAmode VGAmode; -struct VGAmode -{ - uchar misc; - uchar sequencer[5]; - uchar crt[0x19]; - uchar graphics[9]; - uchar attribute[0x15]; -}; - -/* - * 640x480 display, 1, 2, or 4 bit color. - */ -VGAmode mode12 = -{ - /* general */ - 0xe7, - /* sequence */ - 0x03, 0x01, 0x0f, 0x00, 0x06, - /* crt */ - 0x65, 0x4f, 0x50, 0x88, 0x55, 0x9a, 0x09, 0x3e, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe8, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, - 0xff, - /* graphics */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, - 0xff, - /* attribute */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x01, 0x10, 0x0f, 0x00, 0x00, -}; - -/* - * 320x200 display, 8 bit color. - */ -VGAmode mode13 = -{ - /* general */ - 0x63, - /* sequence */ - 0x03, 0x01, 0x0f, 0x00, 0x0e, - /* crt */ - 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, - 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, - 0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3, - 0xff, - /* graphics */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, - 0xff, - /* attribute */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x41, 0x10, 0x0f, 0x00, 0x00, -}; - -static void -setmode(VGAmode *vga) -{ - uchar seq00, seq01; - int i; - - /* - * Turn off the screen and - * reset the sequencer and leave it off. - * Load the generic VGA registers: - * misc; - * sequencer; - * restore the sequencer reset state; - * take off write-protect on crt[0x00-0x07]; - * crt; - * graphics; - * attribute; - * Restore the screen state. - */ - seq00 = vgaxi(Seqx, 0x00); - vgaxo(Seqx, 0x00, 0x00); - - seq01 = vgaxi(Seqx, 0x01)|0x01; - vgaxo(Seqx, 0x01, seq01|0x20); - - vgao(MiscW, vga->misc); - - for(i = 2; i < sizeof(vga->sequencer); i++) - vgaxo(Seqx, i, vga->sequencer[i]); - vgaxo(Seqx, 0x00, seq00); - - vgaxo(Crtx, 0x11, vga->crt[0x11] & ~0x80); - for(i = 0; i < sizeof(vga->crt); i++) - vgaxo(Crtx, i, vga->crt[i]); - - for(i = 0; i < sizeof(vga->graphics); i++) - vgaxo(Grx, i, vga->graphics[i]); - - for(i = 0; i < sizeof(vga->attribute); i++) - vgaxo(Attrx, i, vga->attribute[i]); - - vgaxo(Seqx, 0x01, seq01); -} - static ulong xnto32(uchar x, int n) { @@ -610,28 +566,16 @@ setscreen(int maxx, int maxy, int ldepth) } lock(&screenlock); - /* set default mode, a user program sets more complicated ones */ - switch(ldepth){ - case 0: - setmode(&mode12); - break; - case 3: - setmode(&mode13); - break; - default: - error(Ebadarg); - } - /* setup a bitmap for the new size */ gscreen.ldepth = ldepth; gscreen.width = (maxx*(1<page(i>>Footshift); - memset(gscreen.base, 0xff, Footprint); + for(i = 0; i < gscreen.width*BY2WD*maxy; i += footprint){ + vgac->page(i>>footshift); + memset(gscreen.base, 0xff, footprint); } /* get size for a system window */ @@ -717,8 +661,8 @@ byteload(uchar *q, uchar *data, int m, int *page, uchar *e) if(q >= e){ pg = ++*page; vgac->page(pg); - q -= Footprint; - diff -= Footprint; + q -= footprint; + diff -= footprint; } *q ^= (*data^*q) & m; return diff; @@ -738,8 +682,8 @@ lineload(uchar *q, uchar *data, int len, int *page, uchar *e) if(q >= e){ pg = ++*page; vgac->page(pg); - q -= Footprint; - diff -= Footprint; + q -= footprint; + diff -= footprint; } rem = e - q; @@ -748,8 +692,8 @@ lineload(uchar *q, uchar *data, int len, int *page, uchar *e) memmove(q, data, rem); pg = ++*page; vgac->page(pg); - q -= Footprint; - diff -= Footprint; + q -= footprint; + diff -= footprint; memmove(q+rem, data+rem, len-rem); } else memmove(q, data, len); @@ -769,7 +713,7 @@ screenload(Rectangle r, uchar *data, int tl, int l, int dolock) ulong off; uchar *q, *e; - if(cga || !rectclip(&r, gscreen.r) || tl<=0) + if(screendisabled || cga || !rectclip(&r, gscreen.r) || tl<=0) return; if(dolock && hwgc == 0) @@ -784,12 +728,12 @@ screenload(Rectangle r, uchar *data, int tl, int l, int dolock) mr = 0xFF ^ (0xFF >> rpart); off = q - (uchar*)gscreen.base; - page = off>>Footshift; + page = off>>footshift; vgac->page(page); - q = ((uchar*)gscreen.base) + (off&(Footprint-1)); + q = ((uchar*)gscreen.base) + (off&(footprint-1)); sw = gscreen.width*sizeof(ulong); - e = ((uchar*)gscreen.base) + Footprint; + e = ((uchar*)gscreen.base) + footprint; /* may need to do bit insertion on edges */ if(tl <= 0){ @@ -873,8 +817,8 @@ byteunload(uchar *q, uchar *data, int m, int *page, uchar *e) if(q >= e){ pg = ++*page; vgac->page(pg); - q -= Footprint; - diff -= Footprint; + q -= footprint; + diff -= footprint; } *data ^= (*q^*data) & m; return diff; @@ -894,8 +838,8 @@ lineunload(uchar *q, uchar *data, int len, int *page, uchar *e) if(q >= e){ pg = ++*page; vgac->page(pg); - q -= Footprint; - diff -= Footprint; + q -= footprint; + diff -= footprint; } rem = e - q; @@ -904,8 +848,8 @@ lineunload(uchar *q, uchar *data, int len, int *page, uchar *e) memmove(data, q, rem); pg = ++*page; vgac->page(pg); - q -= Footprint; - diff -= Footprint; + q -= footprint; + diff -= footprint; memmove(data+rem, q+rem, len-rem); } else memmove(data, q, len); @@ -926,7 +870,7 @@ screenunload(Rectangle r, uchar *data, int tl, int l, int dolock) ulong off; uchar *q, *e; - if(cga || !rectclip(&r, gscreen.r) || tl<=0) + if(screendisabled || cga || !rectclip(&r, gscreen.r) || tl<=0) return; if(dolock && hwgc == 0) @@ -941,12 +885,12 @@ screenunload(Rectangle r, uchar *data, int tl, int l, int dolock) mr = 0xFF ^ (0xFF >> rpart); off = q - (uchar*)gscreen.base; - page = off>>Footshift; + page = off>>footshift; vgac->page(page); - q = ((uchar*)gscreen.base) + (off&(Footprint-1)); + q = ((uchar*)gscreen.base) + (off&(footprint-1)); sw = gscreen.width*sizeof(ulong); - e = ((uchar*)gscreen.base) + Footprint; + e = ((uchar*)gscreen.base) + footprint; /* may need to do bit insertion on edges */ if(tl <= 0){ diff --git a/pc/fns.h b/pc/fns.h index e3663aa0792c82acf28941719a32dc1c6de380a3..03d6e8f389c3903722c6ca6dfed2a085ce966921 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -45,6 +45,7 @@ int iprint(char*, ...); int isaconfig(char*, int, ISAConf*); ulong getisa(ulong, int, int); void putisa(ulong, int); +ulong getspace(int, int); void kbdinit(void); long* mapaddr(ulong); void mathinit(void); diff --git a/pc/mmu.c b/pc/mmu.c index fca2fa7e534cbd4db1d117a71aed62218999361a..49f2bcd6752df84fb0c59e5fa72a24e1a29448d0 100644 --- a/pc/mmu.c +++ b/pc/mmu.c @@ -88,6 +88,7 @@ static ulong *kpt; /* 2nd level page tables for kernel mem */ #define MAXUMEG 64 /* maximum memory per user process in megabytes */ #define ONEMEG (1024*1024) +/* unallocated ISA space */ enum { Nisa= 256, }; @@ -98,6 +99,14 @@ struct ulong e[Nisa]; } isaalloc; +/* unallocated space */ +struct +{ + Lock; + ulong s; + ulong e; +} msalloc; + /* * Change current page table and the stack to use for exceptions * (traps & interrupts). The exception stack comes from the tss. @@ -170,6 +179,15 @@ mmuinit(void) memset(&tss, 0, sizeof(tss)); taskswitch(ktoppg.pa, BY2PG + (ulong)m); puttr(TSSSEL);/**/ + + /* + * allocatable, non ISA memory + */ + if(conf.topofmem > 16*1024*1024) + msalloc.s = conf.topofmem; + else + msalloc.s = 16*1024*1024; + msalloc.e = 128*1024*1024; } /* @@ -441,3 +459,25 @@ mapaddr(ulong addr) return (long*)(KZERO | 4*1024*1024-BY2PG | off); } + +/* + * get non-ISA memory space + */ +ulong +getspace(int len, int span) +{ + ulong x; + + lock(&msalloc); + x = msalloc.s; + if(span) + x = ROUND(x, span); + if(len > msalloc.e - x){ + unlock(&msalloc); + return 0; + } + msalloc.s = x + len; + unlock(&msalloc); + + return x | KZERO; +}