From ffea75c01c9521c8b21cfcb1c846b757df55e39c Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 5 Sep 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-09-05 --- bitsy/clock.c | 4 +- bitsy/dat.h | 4 +- bitsy/devuart.c | 13 +-- bitsy/fns.h | 2 + bitsy/l.s | 19 +++-- bitsy/main.c | 118 +++++++++++++++++++++++++- bitsy/mmu.c | 5 ++ ip/ip.c | 2 +- pc/vga3dfx.c | 216 +++++++++++++++++++++++++++++++++++++++++++++--- 9 files changed, 350 insertions(+), 33 deletions(-) diff --git a/bitsy/clock.c b/bitsy/clock.c index 87ffe715924cad950e0704c28f2ce90d14456e94..7c6942cac21f673a0a87010a4766403635951217 100644 --- a/bitsy/clock.c +++ b/bitsy/clock.c @@ -49,5 +49,7 @@ clockintr(Ureg*, void*) void delay(int ms) { - USED(ms); + ms *= 1000; + while(ms-->0) + ; } diff --git a/bitsy/dat.h b/bitsy/dat.h index e0ff4eaf4738b26891393fc822a8f76a627b3b3a..0e0ce30918bec4be8df32b374cf7a3f364f90ed0 100644 --- a/bitsy/dat.h +++ b/bitsy/dat.h @@ -52,7 +52,6 @@ struct Conf { ulong nmach; /* processors */ ulong nproc; /* processes */ - ulong monitor; /* has monitor? */ ulong npage0; /* total physical pages of memory */ ulong npage1; /* total physical pages of memory */ ulong npage; /* total physical pages of memory */ @@ -63,7 +62,8 @@ struct Conf ulong base0; /* base of bank 0 */ ulong base1; /* base of bank 1 */ ulong copymode; /* 0 is copy on write, 1 is copy on reference */ - ulong ialloc; /* max interrupt time allocation in bytes */ + int monitor; + ulong ialloc; /* bytes available for interrupt time allocation */ ulong pipeqsize; /* size in bytes of pipe queues */ }; diff --git a/bitsy/devuart.c b/bitsy/devuart.c index a65382823473625b0ea4efdacf5b669d7ca00a95..efcff9fda892b8c1a9b8a004c345d9bf94e02940 100644 --- a/bitsy/devuart.c +++ b/bitsy/devuart.c @@ -22,9 +22,9 @@ struct Uartregs ulong ctl1; ulong ctl2; ulong ctl3; - uchar dummyd[4]; + ulong dummya; ulong data; - uchar dummyf[4]; + ulong dummyb; ulong status0; ulong status1; }; @@ -33,6 +33,8 @@ struct Uartregs /* ctl0 bits */ enum { + /* status register 1 bits */ + XmitBusy = (1 << 0), XmitNotFull = (1 << 2), }; @@ -491,16 +493,15 @@ Dev uartdevtab = { }; void -putuartstr(char *str) +serialputs(char *str, int n) { Uartregs *ur; ur = UART3REGS; - while(*str){ + while(n-- > 0){ /* wait for output ready */ - while(ur->status1 & XmitNotFull) + while((ur->status1 & XmitNotFull) == 0) ; ur->data = *str++; - } } diff --git a/bitsy/fns.h b/bitsy/fns.h index bf63b7404d2f40985fb57ecbd5ce9d47717ffe63..6c78164d4ad0006202f9cd7763408d4b49074012 100644 --- a/bitsy/fns.h +++ b/bitsy/fns.h @@ -12,6 +12,8 @@ void evenaddr(ulong); void idle(void); #define idlehands() /* nothing to do in the runproc */ int iprint(char*, ...); +void meminit(void); +void mmuinit(void); #define procrestore(p) void procsave(Proc*); void procsetup(Proc*); diff --git a/bitsy/l.s b/bitsy/l.s index 7fbd027a66c0099693d593adda6fa1f58a74f79e..a505fbb64e94b96b40c32f0a949e96a6e6082857 100644 --- a/bitsy/l.s +++ b/bitsy/l.s @@ -12,13 +12,20 @@ _main: MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1 MOVW R1, CPSR - /* turn on caches and write buffer */ - MRC CpMMU, 0, R1, C(CpControl), C(0x0) - ORR $(CpCdcache|CpCwb), R1 - MCR CpMMU, 0, R1, C(CpControl), C(0x0) + /* flush TLB's */ + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x0) + /* drain prefetch */ + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 - /* turn off interrupts */ - BL splhi(SB) + /* drain write buffer */ + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x0), 4 + + /* disable the MMU */ + MOVW $0x130, R1 + MCR CpMMU, 0, R1, C(CpControl), C(0x0) MOVW $(MACHADDR+BY2PG), R13 /* stack */ SUB $4, R13 /* link */ diff --git a/bitsy/main.c b/bitsy/main.c index 9306df8beea9a38d33b9971f68d1f37298c430bc..0135a1d23013aacfc9239105966c9ad5c52f60b4 100644 --- a/bitsy/main.c +++ b/bitsy/main.c @@ -8,13 +8,17 @@ #include "init.h" #include "pool.h" +#include "sa1110.h" + Mach *m; Conf conf; void main(void) { - putuartstr("hello ken"); + iprint("bitsy kernel\n"); + confinit(); + mmuinit(); } /* @@ -25,6 +29,9 @@ exit(int ispanic) { void (*f)(); + USED(ispanic); + delay(1000); + f = nil; (*f)(); } @@ -48,15 +55,118 @@ procsave(Proc *p) } /* place holder */ +/* + * dummy since rdb is not included + */ void -serialputs(char*, int) +rdb(void) { } +enum +{ + OneMeg= 1024*1024, +}; + /* - * dummy since rdb is not included + * probe the last location in a meg of memory, make sure it's not + * reflected into something else we've already found. + */ +int +probemem(ulong addr) +{ + ulong *p; + ulong a; + + addr += OneMeg - sizeof(ulong); + p = (ulong*)addr; + *p = addr; + for(a = conf.base0+OneMeg-sizeof(ulong); a < conf.npage0; a += OneMeg){ + p = (ulong*)a; + *p = 0; + } + for(a = conf.base1+OneMeg-sizeof(ulong); a < conf.npage1; a += OneMeg){ + p = (ulong*)a; + *p = 0; + } + p = (ulong*)addr; + iprint("%lux @ %lux\n", *p, addr); + if(*p != addr) + return -1; + return 0; +} + +/* + * we assume that the kernel is at the beginning of one of the + * contiguous chunks of memory. */ void -rdb(void) +confinit(void) { + int i; + ulong addr; + ulong ktop; + + /* find first two contiguous sections of available memory */ + addr = PHYSDRAM0; + conf.base0 = conf.npage0 = addr; + conf.base1 = conf.npage1 = addr; + for(i = 0; i < 512; i++){ + if(probemem(addr) == 0) + break; + addr += OneMeg; + } + for(; i < 512; i++){ + if(probemem(addr) < 0) + break; + addr += OneMeg; + conf.npage0 = addr; + } + + conf.base1 = conf.npage1 = addr; + for(; i < 512; i++){ + if(probemem(addr) == 0) + break; + addr += OneMeg; + } + for(; i < 512; i++){ + if(probemem(addr) < 0) + break; + addr += OneMeg; + conf.npage1 = addr; + } + + /* take kernel out of allocatable space */ + ktop = PGROUND((ulong)end); + if(ktop >= conf.base0 && ktop <= conf.npage0) + conf.base0 = ktop; + else if(ktop >= conf.base1 && ktop <= conf.npage1) + conf.base1 = ktop; + else + iprint("kernel not in allocatable space\n"); + iprint("%lux-%lux %lux-%lux\n", conf.base0, conf.npage0, conf.base1, conf.npage1); + + /* make npages the right thing */ + conf.npage0 = (conf.npage0 - conf.base0)/BY2PG; + conf.npage1 = (conf.npage1 - conf.base1)/BY2PG; + conf.npage = conf.npage0+conf.npage1; + + if(conf.npage > 16*MB/BY2PG){ + conf.upages = (conf.npage*60)/100; + imagmem->minarena = 4*1024*1024; + }else + conf.upages = (conf.npage*40)/100; + conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG; + + conf.nmach = 1; + + /* set up other configuration parameters */ + conf.nproc = 100; + conf.nswap = conf.npage*3; + conf.nswppo = 4096; + conf.nimage = 200; + + conf.monitor = 1; + + conf.copymode = 0; /* copy on write */ } diff --git a/bitsy/mmu.c b/bitsy/mmu.c index 2d9e8b37d1937c0c34adb7154ee271247fc1825c..0b29eb3f5f3bfad63955d04d66f77e2129d41da7 100644 --- a/bitsy/mmu.c +++ b/bitsy/mmu.c @@ -7,6 +7,11 @@ #include "ureg.h" #include "../port/error.h" +void +mmuinit(void) +{ +} + void putmmu(ulong va, ulong pa, Page*) { diff --git a/ip/ip.c b/ip/ip.c index 097c8b04576107f1518314fe7f2a55e72afb1ebe..2631f752a891e24fd7726a2a8f764ae71a01ff24 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -15,7 +15,7 @@ enum { IPHDR = 20, /* sizeof(Iphdr) */ IP_VER = 0x40, /* Using IP version 4 */ - IP_HLEN = 0x05, /* Header length in characters */ + IP_HLEN = 0x05, /* Header length in words */ IP_DF = 0x4000, /* Don't fragment */ IP_MF = 0x2000, /* More fragments */ IP_MAX = (32*1024), /* Maximum Internet packet size */ diff --git a/pc/vga3dfx.c b/pc/vga3dfx.c index 2169abf03c81de0fc5e937ecf603e579dfe6d5ab..e6a397d61d4ccb8acfd78f6eda042d41ec1fc187 100644 --- a/pc/vga3dfx.c +++ b/pc/vga3dfx.c @@ -12,12 +12,27 @@ #include #include "screen.h" +typedef struct { + int vidProcCfg; + int hwCurPatAddr; + int hwCurLoc; + int hwCurC0; + int hwCurC1; +} Cursor3dfx; + +enum { + dramInit0 = 0x18, + dramInit1 = 0x1C, + + hwCur = 0x5C, +}; + static ulong tdfxlinear(VGAscr* scr, int* size, int* align) { - ulong aperture, oaperture; - int oapsize, wasupamem; Pcidev *p; + int oapsize, wasupamem; + ulong aperture, oaperture; oaperture = scr->aperture; oapsize = scr->apsize; @@ -26,7 +41,7 @@ tdfxlinear(VGAscr* scr, int* size, int* align) aperture = 0; if(p = pcimatch(nil, 0x121A, 0)){ switch(p->did){ - case 0x0005: /* Voodoo 3 3000 */ + case 0x0005: /* Avenger (a.k.a. Voodoo3) */ aperture = p->mem[1].bar & ~0x0F; *size = p->mem[1].size; break; @@ -57,22 +72,197 @@ tdfxlinear(VGAscr* scr, int* size, int* align) return aperture; } +static void +tdfxenable(VGAscr* scr) +{ + Pcidev *p; + Physseg seg; + ulong aperture; + int align, i, *mmio, size; + + /* + * Only once, can't be disabled for now. + * scr->io holds the physical address of + * the MMIO registers. + */ + if(scr->io) + return; + if(p = pcimatch(nil, 0x121A, 0)){ + switch(p->did){ + case 0x0005: /* Avenger (a.k.a. Voodoo3) */ + break; + default: + return; + } + } + else + return; + scr->io = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0); + if(scr->io == 0) + return; + + memset(&seg, 0, sizeof(seg)); + seg.attr = SG_PHYSICAL; + seg.name = smalloc(NAMELEN); + snprint(seg.name, NAMELEN, "3dfxmmio"); + seg.pa = scr->io; + seg.size = p->mem[0].size; + addphysseg(&seg); + + size = p->mem[1].size; + align = 0; + aperture = tdfxlinear(scr, &size, &align); + if(aperture) { + scr->aperture = aperture; + scr->apsize = size; + memset(&seg, 0, sizeof(seg)); + seg.attr = SG_PHYSICAL; + seg.name = smalloc(NAMELEN); + snprint(seg.name, NAMELEN, "3dfxscreen"); + seg.pa = aperture; + seg.size = size; + addphysseg(&seg); + } + + /* + * Find a place for the cursor data in display memory. + * If SDRAM then there's 16MB memory else it's SGRAM + * and can count it based on the power-on straps - + * chip size can be 8Mb or 16Mb, and there can be 4 or + * 8 of them. + * Use the last 1KB of the framebuffer. + */ + mmio = KADDR(scr->io + dramInit0); + if(*(mmio+1) & 0x40000000) + i = 16*1024*1024; + else{ + if(*mmio & 0x08000000) + i = 16*1024*1024/8; + else + i = 8*1024*1024/8; + if(*mmio & 0x04000000) + i *= 8; + else + i *= 4; + } + scr->storage = i - 1024; +} + +static void +tdfxcurdisable(VGAscr* scr) +{ + Cursor3dfx *cursor3dfx; + + if(scr->io == 0) + return; + cursor3dfx = KADDR(scr->io+hwCur); + cursor3dfx->vidProcCfg &= ~0x08000000; +} + +static void +tdfxcurload(VGAscr* scr, Cursor* curs) +{ + int y; + uchar *p; + Cursor3dfx *cursor3dfx; + + if(scr->io == 0) + return; + cursor3dfx = KADDR(scr->io+hwCur); + + /* + * Disable the cursor then load the new image in + * the top-left of the 64x64 array. + * The cursor data is stored in memory as 128-bit + * words consisting of plane 0 in the least significant 64-bits + * and plane 1 in the most significant. + * The X11 cursor truth table is: + * p0 p1 colour + * 0 0 transparent + * 0 1 transparent + * 1 0 hwCurC0 + * 1 1 hwCurC1 + * Unused portions of the image have been initialised to be + * transparent. + */ + cursor3dfx->vidProcCfg &= ~0x08000000; + p = KADDR(scr->aperture + scr->storage); + for(y = 0; y < 16; y++){ + *p++ = curs->clr[2*y]|curs->set[2*y]; + *p++ = curs->clr[2*y+1]|curs->set[2*y+1]; + p += 6; + *p++ = curs->set[2*y]; + *p++ = curs->set[2*y+1]; + p += 6; + } + + /* + * Save the cursor hotpoint and enable the cursor. + * The 0,0 cursor point is bottom-right. + */ + scr->offset.x = 63+curs->offset.x; + scr->offset.y = 63+curs->offset.y; + cursor3dfx->vidProcCfg |= 0x08000000; +} + +static int +tdfxcurmove(VGAscr* scr, Point p) +{ + Cursor3dfx *cursor3dfx; + + if(scr->io == 0) + return 1; + cursor3dfx = KADDR(scr->io+hwCur); + + cursor3dfx->hwCurLoc = ((p.y+scr->offset.y)<<16)|(p.x+scr->offset.x); + + return 0; +} + +static void +tdfxcurenable(VGAscr* scr) +{ + Cursor3dfx *cursor3dfx; + + tdfxenable(scr); + if(scr->io == 0) + return; + cursor3dfx = KADDR(scr->io+hwCur); + + /* + * Cursor colours. + */ + cursor3dfx->hwCurC0 = 0xFFFFFFFF; + cursor3dfx->hwCurC1 = 0x00000000; + + /* + * Initialise the 64x64 cursor to be transparent (X11 mode). + */ + cursor3dfx->hwCurPatAddr = scr->storage; + memset(KADDR(scr->aperture + scr->storage), 0, 64*16); + + /* + * Load, locate and enable the 64x64 cursor in X11 mode. + */ + tdfxcurload(scr, &arrow); + tdfxcurmove(scr, ZP); + cursor3dfx->vidProcCfg |= 0x08000002; +} + VGAdev vga3dfxdev = { "3dfx", - nil, /* enable */ - nil, /* disable */ - nil, /* page */ - tdfxlinear, /* linear */ - nil, /* drawinit */ - nil, /* fill */ + tdfxenable, + nil, + nil, + tdfxlinear, }; VGAcur vga3dfxcur = { "3dfxhwgc", - nil, /* enable */ - nil, /* disable */ - nil, /* load */ - nil, /* move */ + tdfxcurenable, + tdfxcurdisable, + tdfxcurload, + tdfxcurmove, };