~kris/9p

9hist

5f83734fd0adabf73b14c0c38fc361decb59fde4 — David du Colombier 35 years ago 6e3179b
Plan 9 from Bell Labs 1991-07-16
10 files changed, 172 insertions(+), 316 deletions(-)

M pc/clock.c
M pc/dat.h
M pc/fault386.c
M pc/fns.h
M pc/kbd.c
M pc/l.s
M pc/main.c
M pc/mem.h
M pc/mmu.c
M pc/trap.c
M pc/clock.c => pc/clock.c +1 -1
@@ 29,7 29,7 @@ clockinit(void)
	/*
	 *  set vector for clock interrupts
	 */
	setvec(Clockvec, clock, SEGIG);
	setvec(Clockvec, clock);

	/*
	 *  make clock output a square wave with a 1/HZ period

M pc/dat.h => pc/dat.h +3 -3
@@ 33,7 33,7 @@ struct Label


/*
 * FPsave.fpstatus
 * FPsave.status
 */
enum
{


@@ 44,8 44,8 @@ enum

struct	FPsave	/* ??? needs to be fixed ??? */
{
	long	fpreg[32];
	long	fpstatus;
	long	status;
	char	reg[66];
};

struct Conf

M pc/fault386.c => pc/fault386.c +1 -1
@@ 9,7 9,7 @@
void
faultinit(void)
{
	setvec(Faultvec, fault386, SEGTG);
	setvec(Faultvec, fault386);
}

void

M pc/fns.h => pc/fns.h +3 -4
@@ 11,6 11,8 @@ void	floppyintr(Ureg*);
long	floppyseek(int, long);
long	floppyread(int, void*, long);
#define	flushvirt();
void	fpsave(FPsave*);
void	fprestore(FPsave*);
void	idle(void);
int	inb(int);
void	intr0(void);


@@ 46,13 48,10 @@ void	lidt(Segdesc*, int);
void	mmuinit(void);
void	outb(int, int);
void	prhex(ulong);
#define	procrestore(x,y)
#define	procsave(x,y)
#define	procsetup(p)	((p)->fpstate = FPinit)
void	screeninit(void);
void	screenputc(int);
void	screenputs(char*, int);
void	setvec(int, void (*)(Ureg*), int);
void	setvec(int, void (*)(Ureg*));
void	systrap(void);
void	touser(void);
void	trapinit(void);

M pc/kbd.c => pc/kbd.c +1 -1
@@ 238,7 238,7 @@ void
kbdinit(void)
{
	initq(&kbdq);
	setvec(Kbdvec, kbdintr, SEGIG);
	setvec(Kbdvec, kbdintr);
}

/*

M pc/l.s => pc/l.s +21 -9
@@ 342,7 342,7 @@ intrcommon:
	POPL	DS
	ADDL	$8,SP	/* error code and trap type */
	IRETL
	RET
	RET		/* this has to be here because of ken */

intrscommon:
	PUSHL	DS


@@ 355,10 355,10 @@ intrscommon:
	POPL	DS
	ADDL	$8,SP	/* error code and trap type */
	IRETL
	RET
	RET		/* this has to be here because of ken */

/*
 *  turn interrupts and traps on
 *  interrupt level is interrupts on or off
 */
TEXT	spllo(SB),$0
	PUSHFL


@@ 366,18 366,12 @@ TEXT	spllo(SB),$0
	STI
	RET

/*
 *  turn interrupts and traps off
 */
TEXT	splhi(SB),$0
	PUSHFL
	POPL	AX
	CLI
	RET

/*
 *  set interrupt level
 */
TEXT	splx(SB),$0
	MOVL	s+0(FP),AX
	PUSHL	AX


@@ 409,4 403,22 @@ TEXT	setlabel(SB),$0
	RET

TEXT	touser(SB),$0
	MOVL	$(USERADDR+BY2PG-5*BY2WD),AX
	MOVL	$(UTZERO+32),0(AX)	/* header is in text */
	MOVL	$(UESEL),4(AX)
	MOVL	$(IFLAG|2),8(AX)
	MOVL	$(USTKTOP-4*BY2WD),12(AX)
	MOVL	$(UDSEL),16(AX)
	MOVL	AX,SP
	IRETL

/*
 *  save/restore floating point
 *	- to be filled in at some future time
 */
TEXT	fpsave(SB),$0
	RET

TEXT	fprestore(SB),$0
	RET


M pc/main.c => pc/main.c +124 -290
@@ 4,232 4,142 @@
#include	"dat.h"
#include	"fns.h"
#include	"io.h"
#include	"ureg.h"
#include	"init.h"

char	user[NAMELEN] = "bootes";
extern long edata;

extern ulong edata;

/*
 *  predeclared
 */
int	fdboot(void);
int	hdboot(void);
int	duartboot(void);
int	parse(char*);
int	getline(int);
int	getstr(char*, char*, int, char*, int);
int	menu(void);

char	file[2*NAMELEN];
char	server[NAMELEN];
char	sysname[NAMELEN];
char	user[NAMELEN] = "none";
char	linebuf[256];
Conf	conf;


typedef	struct Booter	Booter;
struct Booter
{
	char	*name;
	char	*srv;
	int	(*func)(void);
};
Booter	booter[] = {
	{ "fd",		0,	fdboot },
	{ "hd",		0,	hdboot },
	{ "2400",	0,	duartboot },
	{ "1200",	0,	duartboot },
};

int	bootdev;
char	*bootchars = "fh21";
int	usecache;

void
main(void)
{
	char	*path;			/* file path */
	char	element[2*NAMELEN];	/* next element in a file path */
	char	def[2*NAMELEN];

	machinit();
	confinit();
	screeninit();
	printinit();
	print("%d pages in bank0, %d pages in bank1\n", conf.npage0, conf.npage1);
	print("edata == %lux, end == %lux\n", &edata, &end);
	trapinit();
	mmuinit();
	clockinit();
	procinit0();
	initseg();
	grpinit();
	chaninit();
	alarminit();
	kbdinit();
	clockinit();
	floppyinit();
	spllo();
	chandevreset();
	streaminit();
	trapinit();
	swapinit();
	pageinit();
	userinit();

	for(;;){
		sprint(def, "%s!%s!/%s", booter[bootdev].name, booter[bootdev].srv,
			usecache ? "9.cache" : "9.com");
		if(getstr("server", element, sizeof element, def, 0)<0)
			continue;
		if(parse(element) < 0)
			continue;
		if(getstr("user", user, sizeof user, 0, 0)<0)
			continue;
		if(*user==0)
			continue;
		if((*booter[bootdev].func)() < 0)
			continue;
		print("success\n");
	}
	schedinit();
}

/*
 *  parse the server line.  return 0 if OK, -1 if bullshit
 *	BUG -- needs floating point support
 */
int
parse(char *line)
void
machinit(void)
{
	char *def[3];
	char **d;
	char *s;
	int i;

	def[0] = booter[bootdev].name;
	def[1] = booter[bootdev].srv;
	def[2] = "/9.com";

	d = &def[2];
	s = line + strlen(line);
	while((*d = s) > line)
		if(*--s == '!'){
			if(d-- == def)
				return -1;
			*s = '\0';
		}

	for(i = 0; i < strlen(bootchars); i++){
		if(strcmp(def[0], booter[i].name)==0){
			strcpy(server, def[1]);
			strcpy(file, def[2]);
			bootdev = i;
			return 0;
		}
	}
	int n;

	return -1;
	n = m->machno;
	memset(m, 0, sizeof(Mach));
	m->machno = n;
	m->mmask = 1<<m->machno;
	m->fpstate = FPinit;
	active.machs = 1;
}

/*
 *  read a line from the keyboard.
 */
int
getline(int quiet)
void
init0(void)
{
	int c, i=0;
	long start;

	for (start=m->ticks;;) {
	    	do{
			if(TK2SEC(m->ticks - start) > 60)
				return -2;
			c = getc(&kbdq);
		} while(c==-1);
		if(c == '\r')
			c = '\n'; /* turn carriage return into newline */
		if(c == '\177')
			c = '\010';	/* turn delete into backspace */
		if(!quiet){
			if(c == '\033'){
				menu();
				return -1;
			}
			if(c == '\025')
				screenputc('\n');	/* echo ^U as a newline */
			else
				screenputc(c);
		}
		if(c == '\010'){
			if(i > 0)
				i--; /* bs deletes last character */
			continue;
		}
		/* a newline ends a line */
		if (c == '\n')
			break;
		/* ^U wipes out the line */
		if (c =='\025')
			return -1;
		linebuf[i++] = c;
	}
	linebuf[i] = 0;
	return i;
}
	Chan *c;

/*
 *  prompt for a string from the keyboard.  <cr> returns the default.
 */
int
getstr(char *prompt, char *buf, int size, char *def, int quiet)
{
	int len;
	char *cp;

	for (;;) {
		if(def)
			print("%s[default==%s]: ", prompt, def);
		else
			print("%s: ", prompt);
		len = getline(quiet);
		switch(len){
		case -1:
			/* ^U typed */
			continue;
		case -2:
			/* timeout */
			return -1;
		default:
			break;
		}
		if(len >= size){
			print("line too long\n");
			continue;
		}
		break;
	}
	if(*linebuf==0 && def)
		strcpy(buf, def);
	else
		strcpy(buf, linebuf);
	return 0;
}
	u->nerrlab = 0;
	m->proc = u->p;
	u->p->state = Running;
	u->p->mach = m;

int
menu(void)
{
	spllo();

	/*
	 * These are o.k. because rootinit is null.
	 * Then early kproc's will have a root and dot.
	 */
	u->slash = (*devtab[0].attach)(0);
	u->dot = clone(u->slash, 0);

	chandevinit();

/*	kickpager();	/* BUG */
	touser();
}

void
machinit(void)
userinit(void)
{
	int n;
	Proc *p;
	Segment *s;
	User *up;
	KMap *k;

	n = m->machno;
	memset(m, 0, sizeof(Mach));
	m->machno = n;
	m->mmask = 1<<m->machno;
	active.machs = 1;
	p = newproc();
	p->pgrp = newpgrp();
	p->egrp = newegrp();
	p->fgrp = newfgrp();

	strcpy(p->text, "*init*");
	p->fpstate = FPinit;

	/*
	 * Kernel Stack
	 */
	p->sched.pc = (ulong)init0;
	p->sched.sp = USERADDR + BY2PG - 24;
	p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));

	/*
	 * User
	 */
	k = kmap(p->upage);
	up = (User*)VA(k);
	up->p = p;
	kunmap(k);

	/*
	 * User Stack
	 */
	s = newseg(SG_STACK, USTKTOP-BY2PG, 1);
	p->seg[SSEG] = s;

	/*
	 * Text
	 */
	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);

	ready(p);
}

void
delay(int l)
exit(void)
{
	int i;

	while(--l){
		for(i=0; i < 404; i++)
			;
	}
	u = 0;
	splhi();
	print("exiting\n");
	for(;;)
		;
}

Conf	conf;

void
confinit(void)
{


@@ 314,124 224,48 @@ confinit(void)
	conf.cntrlp = 0;
}

int
sprint(char *s, char *fmt, ...)
{
	return doprint(s, s+PRINTSIZE, fmt, (&fmt+1)) - s;
}

int
print(char *fmt, ...)
{
	char buf[PRINTSIZE];
	int n;

	n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
	screenputs(buf, n);
	return n;
}

/*
 *  set up floating point for a new process
 *	BUG -- needs floating point support
 */
void
panic(char *fmt, ...)
procsetup(Proc *p)
{
	char buf[PRINTSIZE];
	int n;

	screenputs("panic: ", 7);
	n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
	screenputs(buf, n);
	screenputs("\n", 1);
	spllo();
	for(;;)
		idle();
}

int
kbdputc(IOQ* q, int c)
{
	if(c==0x10)
		panic("^p");
	putc(q, c);
}

struct Palloc palloc;

void*
ialloc(ulong n, int align)
{
	ulong p;

	if(palloc.active && n!=0)
		print("ialloc bad\n");
	if(palloc.addr == 0)
		palloc.addr = ((ulong)&end)&~KZERO;
	if(align)
		palloc.addr = PGROUND(palloc.addr);

	memset((void*)(palloc.addr|KZERO), 0, n);
	p = palloc.addr;
	palloc.addr += n;
	if(align)
		palloc.addr = PGROUND(palloc.addr);

	if(palloc.addr >= conf.maxialloc)
		panic("keep bill joy away");

	return (void*)(p|KZERO);
	p->fpstate = FPinit;
	m->fpstate = FPinit;
}

/*
 *  some dummy's so we can use kernel code
 * Save the part of the process state.
 *	BUG -- needs floating point support
 */
void
sched(void)
{ }

void
ready(Proc*p)
{ }

int
postnote(Proc*p, int x, char* y, int z)
procsave(uchar *state, int len)
{
	panic("postnote");
}


/*
 *  boot from hard disk
 *  Restore what procsave() saves
 *	BUG -- needs floating point support
 */
int
hdboot(void)
void
procrestore(Proc *p, uchar *state)
{
	print("hdboot unimplemented\n");
	return -1;
}

/*
 *  boot from the duart
 */
int
duartboot(void)
void
firmware(void)
{
	print("duartboot unimplemented\n");
	return -1;
	panic("firmware");
}

#include "dosfs.h"

/*
 *  boot from the floppy
 */
int
fdboot(void)
void
buzz(int f, int d)
{
}

void
lights(int val)
{
	Dosbpb b;
	extern int dosboot(Dosbpb*);

	print("booting from floppy 0\n");
	b.seek = floppyseek;
	b.read = floppyread;
	b.dev = 0;
	return dosboot(&b);
}

M pc/mem.h => pc/mem.h +5 -2
@@ 69,10 69,8 @@
#define NULLSEL	SELECTOR(NULLSEG, SELGDT, 0)
#define KESEL	SELECTOR(KESEG, SELGDT, 0)
#define KDSEL	SELECTOR(KDSEG, SELGDT, 0)
#define KSSEL	SELECTOR(KDSEG, SELGDT, 0)
#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)



@@ 112,3 110,8 @@
#define	PTERONLY	(0<<1)
#define	PTEKERNEL	(0<<2)
#define	PTEUSER		(1<<2)

/*
 *  flag register bits that we care about
 */
#define IFLAG	0x200

M pc/mmu.c => pc/mmu.c +11 -1
@@ 72,10 72,20 @@ extern ulong tpt[];
void
mmuinit(void)
{

	/*
	 *  set up the global descriptor table
	 */
	gdt[SYSGATE].d0 = ((ulong)systrap)&0xFFFF|(KESEL<<16);
	gdt[SYSGATE].d1 = ((ulong)systrap)&0xFFFF0000|SEGP|SEGPL(3)|SEGCG;
	lgdt(gdt, sizeof gdt);

	/*
	 *  set up system page tables
	 */

	/*
	 *  set up the task segment
	 */
}

void

M pc/trap.c => pc/trap.c +2 -4
@@ 36,10 36,8 @@ sethvec(int v, void (*r)(void), int type, int pri)
}

void
setvec(int v, void (*r)(Ureg*), int type)
setvec(int v, void (*r)(Ureg*))
{
	ilt[v].d1 &= ~SEGTYPE;
	ilt[v].d1 |= type;
	ivec[v] = r;

	/*


@@ 97,7 95,7 @@ trapinit(void)
	 *  system calls
	 */
	sethvec(64, intr64, SEGTG, 3);
/*	setvec(64, syscall, SEGTG);	/**/
	setvec(64, (void (*)(Ureg*))syscall);

	/*
	 *  tell the hardware where the table is (and how long)