~kris/9p

9hist

a53ddff3f0482baaacc14a7500bba281c167c99e — David du Colombier 26 years ago 478cb3e
Plan 9 from Bell Labs 2000-09-02
A bitsy/clock.c => bitsy/clock.c +53 -0
@@ 0,0 1,53 @@
#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"io.h"
#include	"ureg.h"
#include	"../port/error.h"

typedef struct Clock0link Clock0link;
typedef struct Clock0link {
	void		(*clock)(void);
	Clock0link*	link;
} Clock0link;

static Clock0link *clock0link;
static Lock clock0lock;

void
addclock0link(void (*clock)(void))
{
	Clock0link *lp;

	if((lp = malloc(sizeof(Clock0link))) == 0){
		print("addclock0link: too many links\n");
		return;
	}
	ilock(&clock0lock);
	lp->clock = clock;
	lp->link = clock0link;
	clock0link = lp;
	iunlock(&clock0lock);
}


vlong
fastticks(uvlong *hz)
{
	USED(hz);

	return m->ticks;
}

void
clockintr(Ureg*, void*)
{
}

void
delay(int ms)
{
	USED(ms);
}

M bitsy/dat.h => bitsy/dat.h +9 -0
@@ 34,6 34,15 @@ struct Label
/*
 *  no floating point, hence nothing to save
 */

/*
 * FPsave.status
 */
enum
{
	FPinit,
	FPinactive,
};
struct	FPsave
{
	int	dummy;

M bitsy/fns.h => bitsy/fns.h +3 -0
@@ 7,8 7,11 @@ void	clockintr(Ureg*, void*);
void	clockintrsched(void);
void	(*coherence)(void);
void	delay(int);
void	evenaddr(ulong);
#define	getpgcolor(a)	0
void	idle(void);
#define	idlehands()			/* nothing to do in the runproc */
int	iprint(char*, ...);
#define	procrestore(p)
void	procsave(Proc*);
void	procsetup(Proc*);

M bitsy/l.s => bitsy/l.s +14 -3
@@ 17,11 17,15 @@ _main:
	ORR	$(CpCdcache|CpCwb), R1
	MCR     CpMMU, 0, R1, C(CpControl), C(0x0)

	/* turn off interrupts */
	BL	splhi(SB)

	MOVW	$(MACHADDR+BY2PG), R13		/* stack */
	SUB	$4, R13				/* link */
	BL	main(SB)
	BL	exit(SB)
	/* we shouldn't get here */
	BL	_div(SB)			/* hack to get _div etc loaded */
_mainloop:
	B	_mainloop



@@ 162,12 166,13 @@ _vswitch:				/* switch to svc, type in R0 */
	MOVM.IA	  (R3), [R0-R3]		/* restore [R0-R3] */
	B	_vsaveu

	/* push the registers as in ureg */
_vsaveu:
	SUB	$4, R13			/* save link */
	MOVW	R14, (R13)
	MOVM.DB.W [R0-R14], (R13)	/* save svc registers */
	MOVM.DB.W.S [R0-R14], (R13)	/* save svc registers */

	MOVW	$setR12(SB), R12	/* safety */
	MOVW	$setR12(SB), R12	/* the SB from user mode is different */
	MOVW	R13, R0			/* argument is &ureg */
	SUB	$8, R13			/* space for argument+link */
	BL	exception(SB)


@@ 177,7 182,7 @@ _vrfe:
	MOVW	(R13), R14		/* restore link */
	MOVW	8(R13), R0		/* restore SPSR */
	MOVW	R0, SPSR
	MOVM.DB (R13), [R0-R14]	/* restore registers */
	MOVM.DB.S (R13), [R0-R14]		/* restore registers */
	ADD	$12, R13		/* skip saved link+type+SPSR */
	RFE				/* MOVM.IA.S.W (R13), [R15] */



@@ 199,6 204,12 @@ TEXT splx(SB), $-4
	MOVW	R1, CPSR
	RET

TEXT splxpc(SB), $0				/* for iunlock */
	MOVW	R0, R1
	MOVW	CPSR, R0
	MOVW	R1, CPSR
	RET

TEXT islo(SB), $-4
	MOVW	CPSR, R0
	AND	$(PsrDfiq|PsrDirq), R0

M bitsy/main.c => bitsy/main.c +39 -1
@@ 9,13 9,51 @@
#include	"pool.h"

Mach *m;
Conf conf;

void
main(void)
{

}

/*
 *  exit kernel either on a panic or user request
 */
void
exit(int ispanic)
{
	USED(ispanic);
}

/*
 *  set mach dependent process state for a new process
 */
void
procsetup(Proc *p)
{
	p->fpstate = FPinit;
}

/*
 *  Save the mach dependent part of the process state.
 */
void
procsave(Proc *p)
{
	USED(p);
}

/* place holder */
void
serialputs(char*, int)
{
}

/*
 *  dummy since rdb is not included 
 */
void
exit(int)
rdb(void)
{
}

M bitsy/mem.h => bitsy/mem.h +19 -2
@@ 14,6 14,7 @@
#define	PGSHIFT		12			/* log(BY2PG) */
#define ROUND(s, sz)	(((s)+(sz-1))&~(sz-1))
#define PGROUND(s)	ROUND(s, BY2PG)
#define	BLOCKALIGN	8

#define	MAXMACH		1			/* max # cpus system can run */



@@ 27,11 28,22 @@
#define	MS2TK(t)	((((ulong)(t))*HZ)/1000)	/* milliseconds to ticks */

/*
 *  Address spaces
 * Fundamental addresses
 */
#define KZERO		0xC0000000
#define MACHADDR	(KZERO+0x00001000)

/*
 *  Address spaces
 */
#define	UZERO		0			/* base of user address space */
#define	UTZERO		(UZERO+BY2PG)		/* first address in user text */
#define	KZERO		0xC0000000		/* base of kernel address space */
#define	KTZERO		0xC0008000		/* first address in kernel text */
#define	USTKTOP		(KZERO-BY2PG)		/* byte just beyond user stack */
#define	USTKSIZE	(16*1024*1024)		/* size of user stack */
#define	TSTKTOP		(USTKTOP-USTKSIZE)	/* end of new stack in sysexec */
#define TSTKSIZ 	100

#define KSTACK		(16*1024)		/* Size of kernel stack */

/*


@@ 46,3 58,8 @@
/*
 *  physical MMU
 */
#define	PTEVALID	0
#define	PTERONLY	0
#define	PTEWRITE	0
#define	PTEUNCACHED	0


A bitsy/mmu.c => bitsy/mmu.c +26 -0
@@ 0,0 1,26 @@
#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"io.h"
#include	"ureg.h"
#include	"../port/error.h"

void
putmmu(ulong va, ulong pa, Page*)
{
	USED(va, pa);
}

void
mmurelease(Proc* proc)
{
	USED(proc);
}

void
mmuswitch(Proc* proc)
{
	USED(proc);
}

A bitsy/random.c => bitsy/random.c +138 -0
@@ 0,0 1,138 @@
#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"../port/error.h"


struct Rb
{
	QLock;
	Rendez	producer;
	Rendez	consumer;
	ulong	randomcount;
	uchar	buf[1024];
	uchar	*ep;
	uchar	*rp;
	uchar	*wp;
	uchar	next;
	uchar	wakeme;
	ushort	bits;
	ulong	randn;
} rb;

static int
rbnotfull(void*)
{
	int i;

	i = rb.rp - rb.wp;
	return i != 1 && i != (1 - sizeof(rb.buf));
}

static int
rbnotempty(void*)
{
	return rb.wp != rb.rp;
}

static void
genrandom(void*)
{
	up->basepri = PriNormal;
	up->priority = up->basepri;

	for(;;){
		for(;;)
			if(++rb.randomcount > 100000)
				break;
		if(anyhigher())
			sched();
		if(!rbnotfull(0))
			sleep(&rb.producer, rbnotfull, 0);
	}
}

/*
 *  produce random bits in a circular buffer
 */
static void
randomclock(void)
{
	if(rb.randomcount == 0 || !rbnotfull(0))
		return;

	rb.bits = (rb.bits<<2) ^ rb.randomcount;
	rb.randomcount = 0;

	rb.next++;
	if(rb.next != 8/2)
		return;
	rb.next = 0;

	*rb.wp ^= rb.bits;
	if(rb.wp+1 == rb.ep)
		rb.wp = rb.buf;
	else
		rb.wp = rb.wp+1;

	if(rb.wakeme)
		wakeup(&rb.consumer);
}

void
randominit(void)
{
	addclock0link(randomclock);
	rb.ep = rb.buf + sizeof(rb.buf);
	rb.rp = rb.wp = rb.buf;
	kproc("genrandom", genrandom, 0);
}

/*
 *  consume random bytes from a circular buffer
 */
ulong
randomread(void *xp, ulong n)
{
	uchar *e, *p;
	ulong x;

	p = xp;

	if(waserror()){
		qunlock(&rb);
		nexterror();
	}

	qlock(&rb);
	for(e = p + n; p < e; ){
		if(rb.wp == rb.rp){
			rb.wakeme = 1;
			wakeup(&rb.producer);
			sleep(&rb.consumer, rbnotempty, 0);
			rb.wakeme = 0;
			continue;
		}

		/*
		 *  beating clocks will be precictable if
		 *  they are synchronized.  Use a cheap pseudo
		 *  random number generator to obscure any cycles.
		 */
		x = rb.randn*1103515245 ^ *rb.rp;
		*p++ = rb.randn = x;

		if(rb.rp+1 == rb.ep)
			rb.rp = rb.buf;
		else
			rb.rp = rb.rp+1;
	}
	qunlock(&rb);
	poperror();

	wakeup(&rb.producer);

	return n;
}

A bitsy/screen.c => bitsy/screen.c +44 -0
@@ 0,0 1,44 @@
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "ureg.h"
#include "../port/error.h"

#define	Image	IMAGE
#include <draw.h>
#include <memdraw.h>
#include <cursor.h>
#include "screen.h"

void
flushmemscreen(Rectangle)
{
}

uchar*
attachscreen(Rectangle*, ulong*, int*, int*, int*)
{
	return nil;
}

void
getcolor(ulong p, ulong* pr, ulong* pg, ulong* pb)
{
	USED(p, pr, pg, pb);
}

int
setcolor(ulong p, ulong r, ulong g, ulong b)
{
	USED(p,r,g,b);
	return 0;
}

void
blankscreen(int blank)
{
	USED(blank);
}

A bitsy/screen.h => bitsy/screen.h +2 -0
@@ 0,0 1,2 @@
extern void	blankscreen(int);
extern void	flushmemscreen(Rectangle);

A bitsy/segment.h => bitsy/segment.h +8 -0
@@ 0,0 1,8 @@
/*
 * Attach segment types
 */
static Physseg physseg[10] = {
	{ SG_SHARED,	"shared",	0,	SEGMAXSIZE,	0, 	0 },
	{ SG_BSS,	"memory",	0,	SEGMAXSIZE,	0,	0 },
	{ 0,		0,		0,	0,		0,	0 },
};

A bitsy/trap.c => bitsy/trap.c +123 -0
@@ 0,0 1,123 @@
#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"io.h"
#include	"ureg.h"
#include	"../port/error.h"

/*
 * called in sysfile.c
 */
void
evenaddr(ulong addr)
{
	if(addr & 3){
		postnote(up, 1, "sys: odd address", NDebug);
		error(Ebadarg);
	}
}

void
exception(void)
{
}

/* Give enough context in the ureg to produce a kernel stack for
 * a sleeping process
 */
void
setkernur(Ureg *ureg, Proc *p)
{
	USED(ureg, p);
}

/*
 *  return the userpc the last exception happened at
 */
ulong
userpc(void)
{
	return 0;
}

/* This routine must save the values of registers the user is not permitted
 * to write from devproc and then restore the saved values before returning.
 */
void
setregisters(Ureg* ureg, char* pureg, char* uva, int n)
{
	USED(ureg, pureg, uva, n);
}

/*
 *  this is the body for all kproc's
 */
static
void
linkproc(void)
{
	spllo();
	up->kpfun(up->kparg);
}

/*
 *  setup stack and initial PC for a new kernel proc.  This is architecture
 *  dependent because of the starting stack location
 */
void
kprocchild(Proc *p, void (*func)(void*), void *arg)
{
	p->sched.pc = (ulong)linkproc;
	p->sched.sp = (ulong)p->kstack+KSTACK;

	p->kpfun = func;
	p->kparg = arg;
}


/* 
 *  Craft a return frame which will cause the child to pop out of
 *  the scheduler in user mode with the return register zero.  Set
 *  pc to point to a l.s return function.
 */
void
forkchild(Proc *p, Ureg *ureg)
{
	USED(p, ureg);
}

/*
 *  setup stack, initial PC, and any arch dependent regs for an execing user proc.
 */
long
execregs(ulong entry, ulong ssize, ulong nargs)
{
	ulong *sp;
	Ureg *ureg;

	sp = (ulong*)(USTKTOP - ssize);
	*--sp = nargs;

	ureg = up->dbgreg;
	ureg->r13 = (ulong)sp;
	ureg->pc = entry;
	return USTKTOP-BY2WD;		/* address of user-level clock */
}

/*
 *  dump the processor stack for this process
 */
void
dumpstack(void)
{
}


ulong
dbgpc(Proc *p)
{
	USED(p);
	return 0;
}

M pc/trap.c => pc/trap.c +3 -0
@@ 712,6 712,9 @@ execregs(ulong entry, ulong ssize, ulong nargs)
	return USTKTOP-BY2WD;		/* address of user-level clock */
}

/*
 *  return the userpc the last exception happened at
 */
ulong
userpc(void)
{