~kris/9p

9hist

2f75edee410b6b9874fa5cd36888742a9bcab658 — David du Colombier 35 years ago fcf9586
Plan 9 from Bell Labs 1991-07-19
M gnot/fault68020.c => gnot/fault68020.c +6 -3
@@ 47,6 47,7 @@ fault68020(Ureg *ur, FFrame *f)
{
	ulong addr, badvaddr;
	int user, read, insyscall;
	char buf[ERRLEN];

	if(u == 0){
		dumpregs(ur);


@@ 88,9 89,11 @@ fault68020(Ureg *ur, FFrame *f)

	if(fault(addr, read) < 0){
		if(user){
			pprint("user %s error addr=0x%lux\n", read? "read" : "write", badvaddr);
			pprint("status=0x%lux pc=0x%lux sp=0x%lux\n", ur->sr, ur->pc, ur->usp);
			pexit("Suicide", 0);
			sprint(buf, "sys: fault %s pc=0x%lux addr=0x%lux",
				read? "read" : "write", ur->pc, badvaddr);
			postnote(u->p, 1, buf, NDebug);
			notify(ur);
			return;
		}
		u->p->state = MMUing;
		dumpregs(ur);

M gnot/l.s => gnot/l.s +4 -3
@@ 29,16 29,17 @@ dead:
	BRA	dead

/*
 * Take first processor into user mode
 * Take first processor into user mode.  Leave enough room on the stack
 * for a full-sized Ureg (including long bus error format) to fit
 */

TEXT	touser(SB), $-4

	MOVL	$(USERADDR+BY2PG), A7
	MOVL	$(USERADDR+BY2PG-UREGVARSZ), A7
	MOVW	$0, -(A7)
	MOVL	$(UTZERO+32), -(A7)	/* header is in text */
	MOVW	$0, -(A7)
	MOVL	$(USTKTOP-4*BY2WD), A0
	MOVL	$(USTKTOP-6*BY2WD), A0	/* MAXSYSARG=6 */
	MOVL	A0, USP
	MOVW	$(SUPER|SPL(0)), SR
	MOVL	$8, R0

M gnot/main.c => gnot/main.c +1 -1
@@ 157,7 157,7 @@ userinit(void)
	 * Kernel Stack
	 */
	p->sched.pc = (ulong)init0;
	p->sched.sp = USERADDR+BY2PG-MAXSYSARG*BY2WD;
	p->sched.sp = USERADDR+BY2PG-5*BY2WD;
	p->sched.sr = SUPER|SPL(0);
	p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));


M gnot/mem.h => gnot/mem.h +3 -1
@@ 50,7 50,9 @@
 */

#define	USERADDR	0x80000000
#define	UREGADDR	(USERADDR+BY2PG-(2+4+2+(8+8+1+1)*BY2WD))
/* assuming we're in a syscall, this is the address of the Ureg structure */
#define	UREGVARSZ	(23*BY2WD)	/* size of variable part of Ureg */
#define	UREGADDR	(USERADDR+BY2PG-(UREGVARSZ+2+4+2+(8+8+1+1)*BY2WD))

/*
 * Devices poked during bootstrap

M gnot/trap.c => gnot/trap.c +1 -0
@@ 172,6 172,7 @@ notify(Ureg *ur)
		*(ulong*)(sp+0*BY2WD) = 0;		/* arg 0 is pc */
		ur->usp = sp;
		ur->pc = (ulong)u->notify;
		ur->vo = 0x0080;	/* pretend we're returning from syscall */
		u->notified = 1;
		u->nnote--;
		memmove(&u->lastnote, &u->note[0], sizeof(Note));

M gnot/ureg.h => gnot/ureg.h +2 -1
@@ 17,8 17,9 @@ struct Ureg
	ulong	a6;
	ulong	sp;
	ulong	usp;
	ulong	magic;	/* for db to find bottom of ureg */
	ulong	magic;		/* for db to find bottom of ureg */
	ushort	sr;
	ulong	pc;
	ushort	vo;
	uchar	microstate[UREGVARSZ];	/* variable-sized portion */
};

M pc/clock.c => pc/clock.c +14 -0
@@ 23,6 23,20 @@ enum
	Freq=		1193182,	/* Real clock frequency */
};

/*
 *  delay for l milliseconds
 */
void
delay(int l)
{
	int i;

	while(--l){
		for(i=0; i < 404; i++)
			;
	}
}

void
clockinit(void)
{

M pc/fault386.c => pc/fault386.c +15 -4
@@ 6,20 6,30 @@
#include	"ureg.h"
#include	"io.h"

int faulting;

void
fault386(Ureg *ur)
{
	ulong addr;
	int read;
	int user;
	int n;
	static int times;

print("fault386\n");
dumpregs(ur);
for(;;);
	addr = getcr2();
print("fault386 %lux ur %lux\n", addr, ur);
dumpregs(ur);
if(++times==3)
	panic("3rd time");
	if(faulting)
		panic("double fault\n");
	faulting = 1;
	read = !(ur->ecode & 2);
	user = (ur->ecode & 4);
	if(fault(addr, read) < 0){
	n = fault(addr, read);
print("fault returns %d\n", n);
	if(n < 0){
		if(user){
			pprint("user %s error addr=0x%lux\n", read? "read" : "write", addr);
			pprint("status=0x%lux pc=0x%lux sp=0x%lux\n", ur->flags, ur->pc, ur->usp);


@@ 29,6 39,7 @@ for(;;);
		dumpregs(ur);
		panic("fault: 0x%lux", addr);
	}
	faulting = 0;
}

void

M pc/fns.h => pc/fns.h +1 -0
@@ 1,5 1,6 @@
#include "../port/portfns.h"

void	a20enable(void);
#define	clearmmucache()		/* 386 doesn't have one */
void	clock(Ureg*);
void	clockinit(void);

A pc/headland.c => pc/headland.c +41 -0
@@ 0,0 1,41 @@
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"

/*
 *  headland hip set for the safari.
 *  
 *  serious magic!!!
 */

enum
{
	Head=		0x92,		/* control port */
	 Reset=		(1<<0),		/* reset the 386 */
	 A20ena=	(1<<1),		/* enable address line 20 */
};

/*
 *  enable address bit 20
 */
void
a20enable(void)
{
	outb(Head, A20ena);
}

/*
 *  reset the chip
 */
void
exit(void)
{
	int i;

	u = 0;
	print("exiting\n");
	delay(5000);
	outb(Head, Reset);
}

M pc/kbd.c => pc/kbd.c +1 -1
@@ 257,7 257,7 @@ kbdintr(Ureg *ur)
	int keyup;

	/*
	 *  get a character to be there
	 *  get a character
	 */
	c = inb(Data);


M pc/l.s => pc/l.s +3 -2
@@ 432,12 432,13 @@ TEXT	setlabel(SB),$0
 */
TEXT	touser(SB),$0
	PUSHL	$(UDSEL)			/* old ss */
	PUSHL	$(USTKTOP-4*BY2WD)		/* old sp */
	PUSHL	$(USTKTOP-16)			/* old sp */
	PUSHFL					/* old flags */
	PUSHL	$(UESEL)			/* old cs */
	PUSHL	$(UTZERO+32)			/* old pc */
	MOVL	$(UDSEL),AX		/* set up user's data segment */
	MOVL	$(UDSEL),AX
	MOVW	AX,DS
	MOVW	AX,ES
	IRETL

/*

M pc/main.c => pc/main.c +18 -14
@@ 13,12 13,14 @@ extern long edata;
void
main(void)
{
	a20enable();
	machinit();
	confinit();
	screeninit();
	printinit();
	mmuinit();
	trapinit();
	kbdinit();
	clockinit();
	faultinit();
	procinit0();


@@ 31,7 33,6 @@ main(void)
	swapinit();
	pageinit();
	userinit();
print("user inited\n");

	schedinit();
}


@@ 52,7 53,7 @@ machinit(void)
	active.machs = 1;
}

long useless;
ulong garbage;

void
init0(void)


@@ 64,9 65,6 @@ init0(void)
	u->p->state = Running;
	u->p->mach = m;

	spllo();
print("interrupts on\n");

	/*
	 * These are o.k. because rootinit is null.
	 * Then early kproc's will have a root and dot.


@@ 75,12 73,18 @@ print("interrupts on\n");
	u->dot = clone(u->slash, 0);

	chandevinit();
print("going to user\n");

	/*
	 *  fault in the first executable page
	 *  fault in the first executable page and user stack
	 */
	print("text is %lux\n", *((ulong *)(UTZERO+32)));

	/*  fault in the first stack page
	 */
	useless = *((ulong *)UTZERO);
	print("stack is %lux\n", *((ulong *)(USTKTOP-4)));
	*((ulong *)(USTKTOP-4)) = 0xdeadbeef;
	print("stack is %lux\n", *((ulong *)(USTKTOP-4)));
	delay(5000);

	touser();
}


@@ 104,11 108,12 @@ userinit(void)
	/*
	 * Kernel Stack
	 *
	 * N.B. The -4 for the stack pointer is important.  Gotolabel
	 *	uses the bottom 4 bytes of stack to store it's return pc.
	 * N.B. The -12 for the stack pointer is important.
	 *	4 bytes for gotolabel's return PC
	 *	8 bytes for optional sp and ss pushed during interrupts
	 */
	p->sched.pc = (ulong)init0;
	p->sched.sp = USERADDR + BY2PG - 4;
	p->sched.sp = USERADDR + BY2PG - 12;
	p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));

	/*


@@ 182,13 187,13 @@ confinit(void)
	 *  the last 128k belongs to the roms
	 */
	conf.npage1 = (i)*1024/4;
	conf.base1 = 1024/4;
	conf.base1 = 1024*1024;

	conf.npage = conf.npage0 + conf.npage1;
	conf.maxialloc = (conf.npage0*BY2PG-PGROUND((ulong)&end));

	mul = 1;
	conf.nproc = 20 + 50*mul;
	conf.nproc = 20 + 20*mul;
	conf.npgrp = conf.nproc/2;
	conf.nseg = conf.nproc*3;
	conf.npagetab = (conf.nseg*14)/10;


@@ 275,4 280,3 @@ mouseputc(IOQ *q, int c)
{
	return c;
}


M pc/mem.h => pc/mem.h +2 -6
@@ 48,7 48,7 @@
#define TSTKSIZ 10
#define	USTKTOP		(TSTKTOP-TSTKSIZ*BY2PG)	/* byte just beyond user stack */
#define	USTKSIZE	(4*1024*1024 - TSTKSIZ*BY2PG)	/* size of user stack */
#define USTKBTM		USTKTOP - USTKSIZE
#define USTKBTM		(USTKTOP - USTKSIZE)

#define	MACHSIZE	4096



@@ 63,9 63,7 @@
#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 TSSSEG	8	/* task segment */
#define TSSSEG	6	/* task segment */

#define SELGDT	(0<<3)	/* selector is in gdt */
#define	SELLDT	(1<<3)	/* selector is in ldt */


@@ 77,8 75,6 @@
#define KDSEL	SELECTOR(KDSEG, SELGDT, 0)
#define UESEL	SELECTOR(UESEG, SELGDT, 3)
#define UDSEL	SELECTOR(UDSEG, SELGDT, 3)
#define RDSEL	SELECTOR(RDSEG, SELGDT, 0)
#define RESEL	SELECTOR(RESEG, SELGDT, 0)
#define TSSSEL	SELECTOR(TSSSEG, SELGDT, 0)

/*

M pc/mmu.c => pc/mmu.c +22 -24
@@ 66,8 66,6 @@ Segdesc gdt[] =
[UDSEG]		DATASEGM(3),		/* user data/stack */
[UESEG]		EXECSEGM(3),		/* user code */
[SYSGATE]	CALLGATE(KESEL,0,3),	/* call gate for system calls */
[RDSEG]		D16SEGM(0),		/* reboot data/stack */
[RESEG]		E16SEGM(0),		/* reboot code */
[TSSSEG]	TSSSEGM(0,0),		/* tss segment */
};



@@ 86,7 84,20 @@ static ulong	*upt;		/* page table for struct User */
 *  offset of virtual address into
 *  bottom level page table
 */
#define BTMOFF(v)	(((v)>>(PGSHIFT))&(BY2PG-1))
#define BTMOFF(v)	(((v)>>(PGSHIFT))&(WD2PG-1))

void
mmudump(void)
{
	int i;
	ulong *z;
	z = (ulong*)gdt;
	for(i = 0; i < sizeof(gdt)/4; i+=2)
		print("%8.8lux %8.8lux\n", *z++, *z++);
	print("UESEL %lux UDSEL %lux\n", UESEL, UDSEL);
	print("KESEL %lux KDSEL %lux\n", KESEL, KDSEL);
	panic("done");
}

void
mmuinit(void)


@@ 112,12 123,11 @@ mmuinit(void)
	 *  leave a map for a user area.
	 */

	/*  allocate and fill low level page tables for physical mem */
	nkpt = ROUNDUP(conf.npage0+conf.npage1, 4*1024*1024);
	nkpt = nkpt/(4*1024*1024);
	/*  allocate and fill low level page tables for kernel mem */
	nkpt = ROUNDUP(conf.npage, 4*1024);
	nkpt = nkpt/(4*1024);
	kpt = ialloc(nkpt*BY2PG, 1);
	n = ROUNDUP(conf.npage0+conf.npage1, 1*1024*1024);
	n = n/(4*1024);
	n = ROUNDUP(conf.npage, 1024);
	for(i = 0; i < n; i++)
		kpt[i] = (i<<PGSHIFT) | PTEVALID | PTEKERNEL | PTEWRITE;



@@ 150,8 160,6 @@ mapstack(Proc *p)
	ulong tlbphys;
	int i;

print("mapstack\n");

	if(p->upage->va != (USERADDR|(p->pid&0xFFFF)))
		panic("mapstack %d 0x%lux 0x%lux", p->pid, p->upage->pa, p->upage->va);



@@ 210,7 218,7 @@ putmmu(ulong va, ulong pa, Page *pg)
	Proc *p;
	int i;

print("putmmu %lux %lux USTKTOP %lux\n", va, pa, USTKTOP); /**/
print("putmmu %lux %lux\n", va, pa); /**/
	if(u==0)
		panic("putmmu");
	p = u->p;


@@ 232,8 240,9 @@ print("putmmu %lux %lux USTKTOP %lux\n", va, pa, USTKTOP); /**/
	pg = p->mmu[i];
	if(pg == 0){
		pg = p->mmu[i] = newpage(1, 0, 0);
		p->mmue[i] = PPN(pg->pa) | PTEVALID | PTEKERNEL | PTEWRITE;
		p->mmue[i] = PPN(pg->pa) | PTEVALID | PTEUSER | PTEWRITE;
		toppt[topoff] = p->mmue[i];
print("toppt[%d] = %lux\n", topoff, p->mmue[i]);
	}

	/*


@@ 241,6 250,7 @@ print("putmmu %lux %lux USTKTOP %lux\n", va, pa, USTKTOP); /**/
	 */
	pt = (ulong*)(p->mmu[i]->pa|KZERO);
	pt[BTMOFF(va)] = pa | PTEUSER;
print("%lux[%d] = %lux\n", pt, BTMOFF(va), pa | PTEUSER);

	/* flush cached mmu entries */
	putcr3(((ulong)toppt)&~KZERO);


@@ 261,15 271,3 @@ systrap(void)
{
	panic("system trap from user");
}

void
exit(void)
{
	int i;

	u = 0;
	print("exiting\n");
	for(i = 0; i < WD2PG; i++)
		toppt[i] = 0;
	putcr3(((ulong)toppt)&~KZERO);
}

M pc/trap.c => pc/trap.c +24 -24
@@ 60,30 60,30 @@ trapinit(void)
	/*
	 *  set the standard traps
	 */
	sethvec(0, intr0, SEGTG, 0);
	sethvec(1, intr1, SEGTG, 0);
	sethvec(2, intr2, SEGTG, 0);
	sethvec(3, intr3, SEGTG, 0);
	sethvec(4, intr4, SEGTG, 0);
	sethvec(5, intr5, SEGTG, 0);
	sethvec(6, intr6, SEGTG, 0);
	sethvec(7, intr7, SEGTG, 0);
	sethvec(8, intr8, SEGTG, 0);
	sethvec(9, intr9, SEGTG, 0);
	sethvec(10, intr10, SEGTG, 0);
	sethvec(11, intr11, SEGTG, 0);
	sethvec(12, intr12, SEGTG, 0);
	sethvec(13, intr13, SEGTG, 0);
	sethvec(14, intr14, SEGTG, 0);
	sethvec(15, intr15, SEGTG, 0);
	sethvec(16, intr16, SEGTG, 0);
	sethvec(17, intr17, SEGTG, 0);
	sethvec(18, intr18, SEGTG, 0);
	sethvec(19, intr19, SEGTG, 0);
	sethvec(20, intr20, SEGTG, 0);
	sethvec(21, intr21, SEGTG, 0);
	sethvec(22, intr22, SEGTG, 0);
	sethvec(23, intr23, SEGTG, 0);
	sethvec(0, intr0, SEGIG, 0);
	sethvec(1, intr1, SEGIG, 0);
	sethvec(2, intr2, SEGIG, 0);
	sethvec(3, intr3, SEGIG, 0);
	sethvec(4, intr4, SEGIG, 0);
	sethvec(5, intr5, SEGIG, 0);
	sethvec(6, intr6, SEGIG, 0);
	sethvec(7, intr7, SEGIG, 0);
	sethvec(8, intr8, SEGIG, 0);
	sethvec(9, intr9, SEGIG, 0);
	sethvec(10, intr10, SEGIG, 0);
	sethvec(11, intr11, SEGIG, 0);
	sethvec(12, intr12, SEGIG, 0);
	sethvec(13, intr13, SEGIG, 0);
	sethvec(14, intr14, SEGIG, 0);
	sethvec(15, intr15, SEGIG, 0);
	sethvec(16, intr16, SEGIG, 0);
	sethvec(17, intr17, SEGIG, 0);
	sethvec(18, intr18, SEGIG, 0);
	sethvec(19, intr19, SEGIG, 0);
	sethvec(20, intr20, SEGIG, 0);
	sethvec(21, intr21, SEGIG, 0);
	sethvec(22, intr22, SEGIG, 0);
	sethvec(23, intr23, SEGIG, 0);

	/*
	 *  set all others to unknown interrupts

M port/fault.c => port/fault.c +7 -2
@@ 103,8 103,13 @@ again:
	}

	qunlock(&s->lk);
	if(new)				/* A race may provide a page we never used when
		putpage(new);		 * a fault is fixed while process slept in newpage */

	/*
	 * A race may provide a page we never used when	
	 * a fault is fixed while process slept in newpage
	 */
	if(new)
		putpage(new);

	putmmu(addr, mmuphys, *pg);
	return 0;

M power/boot.c => power/boot.c +1 -2
@@ 369,9 369,8 @@ boot(int ask)
	Dir dir;
	char dirbuf[DIRLEN];

	if(ask){
	if(ask)
		outin("server", sys, sizeof(sys));
	}

	for(tries = 0; tries < 5; tries++){
		fd = -1;