M bitsy/clock.c => bitsy/clock.c +3 -1
@@ 49,5 49,7 @@ clockintr(Ureg*, void*)
void
delay(int ms)
{
- USED(ms);
+ ms *= 1000;
+ while(ms-->0)
+ ;
}
M bitsy/dat.h => bitsy/dat.h +2 -2
@@ 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 */
};
M bitsy/devuart.c => bitsy/devuart.c +7 -6
@@ 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++;
-
}
}
M bitsy/fns.h => bitsy/fns.h +2 -0
@@ 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*);
M bitsy/l.s => bitsy/l.s +13 -6
@@ 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 */
M bitsy/main.c => bitsy/main.c +114 -4
@@ 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 */
}
M bitsy/mmu.c => bitsy/mmu.c +5 -0
@@ 8,6 8,11 @@
#include "../port/error.h"
void
+mmuinit(void)
+{
+}
+
+void
putmmu(ulong va, ulong pa, Page*)
{
USED(va, pa);
M ip/ip.c => ip/ip.c +1 -1
@@ 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 */
M pc/vga3dfx.c => pc/vga3dfx.c +203 -13
@@ 12,12 12,27 @@
#include <cursor.h>
#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,
};