~kris/9p

9hist

d2a38bfd2e8dedc6bfb69153bc5f7d6f39acf746 — David du Colombier 25 years ago 31adbde
Plan 9 from Bell Labs 2000-10-07
11 files changed, 271 insertions(+), 348 deletions(-)

M bitsy/clock.c
M bitsy/dat.h
M bitsy/devuart.c
M bitsy/fns.h
M bitsy/io.h
M bitsy/l.s
M bitsy/main.c
M bitsy/mem.h
M bitsy/mmu.c
M bitsy/trap.c
M pc/devi82365.c
M bitsy/clock.c => bitsy/clock.c +5 -15
@@ 18,12 18,6 @@ typedef struct OSTimer

static OSTimer *timerregs = (OSTimer*)OSTIMERREGS;

enum
{
	/* hardware counter frequency */
	ClockFreq=	3686400,
};

static void	clockintr(Ureg*, void*);

typedef struct Clock0link Clock0link;


@@ 58,8 52,9 @@ clockinit(void)
	timerregs = mapspecial(OSTIMERREGS, 32);

	/* enable interrupts on match register 0, turn off all others */
	timerregs->oier = 1<<0;
	timerregs->ossr |= 1<<0;
	intrenable(IRQtimer0, clockintr, nil, "clock");
	timerregs->oier = 1<<0;

	/* post interrupt 1/HZ secs from now */
	timerregs->osmr[0] = timerregs->oscr + ClockFreq/HZ;


@@ 91,15 86,10 @@ clockintr(Ureg*, void*)
void
delay(int ms)
{
	ulong cnt, old;
	ulong start;

	while(ms-- > 0){
		cnt = ClockFreq/1000;
		while(cnt-- > 0){
			old = timerregs->oscr;
			while(old == timerregs->oscr)
				;
		}
		start = timerregs->oscr;
		while(timerregs->oscr-start < ClockFreq/1000);
	}
		
}

M bitsy/dat.h => bitsy/dat.h +8 -0
@@ 10,6 10,8 @@ typedef struct PMMU	PMMU;
typedef struct Proc	Proc;
typedef struct Ureg	Ureg;
typedef struct Vctl	Vctl;
typedef struct PhysUart	PhysUart;
typedef struct Uart	Uart;

/*
 *  parameters for sysproc.c


@@ 134,6 136,12 @@ struct Mach
	vlong	mtrrfix[11];
	vlong	mtrrvar[32];		/* 256 max. */

	/* save areas for exceptions */
	ulong	sfiq[5];
	ulong	sirq[5];
	ulong	sund[5];
	ulong	sabt[5];

	int	stack[1];
};


M bitsy/devuart.c => bitsy/devuart.c +50 -275
@@ 8,119 8,7 @@

#include	"../port/netif.h"

enum
{
	Nuart = 1,
	Stagesize= 1024,
};

/* hardware registers */
struct Uartregs
{
	ulong	ctl[4];
	ulong	dummya;
	ulong	data;
	ulong	dummyb;
	ulong	status0;
	ulong	status1;
};

enum
{
	/* ctl[0] bits */
	Parity=		1<<0,
	Even=		1<<1,
	Stop1=		0<<2,
	Stop2=		1<<2,
	Bits7=		0<<3,
	Bits8=		1<<3,
	SCE=		1<<4,	/* synchronous clock enable */
	RCE=		1<<5,	/* rx on falling edge of clock */
	TCE=		1<<6,	/* tx on falling edge of clock */

	/* ctl[3] bits */
	Rena=		1<<0,	/* receiver enable */
	Tena=		1<<1,	/* transmitter enable */
	Break=		1<<2,	/* force TXD3 low */
	Rintena=	1<<3,	/* enable receive interrupt */
	Tintena=	1<<4,	/* enable transmitter interrupt */
	Loopback=	1<<5,	/* loop back data */

	/* data bits */
	DEparity=	1<<8,	/* parity error */
	DEframe=		1<<9,	/* framing error */
	DEoverrun=	1<<10,	/* overrun error */

	/* status0 bits */
	Tint=		1<<0,	/* transmit fifo half full interrupt */
	Rint0=		1<<1,	/* receiver fifo 1/3-2/3 full */
	Rint1=		1<<2,	/* receiver fifo not empty and receiver idle */
	Breakstart=	1<<3,
	Breakend=	1<<4,
	Fifoerror=	1<<5,	/* fifo error */

	/* status1 bits */
	Tbusy=		1<<0,	/* transmitting */
	Rnotempty=	1<<1,	/* receive fifo not empty */
	Tnotfull=	1<<2,	/* transmit fifo not full */
	ParityError=	1<<3,
	FrameError=	1<<4,
	Overrun=	1<<5,
};

Uartregs *uart3regs = UART3REGS;

/* software representation */
typedef struct Uart Uart;
struct Uart
{
	QLock;
	int	dev;
	int	opens;
	Uartregs	*regs;

	int	enabled;
	Uart	*elist;			/* next enabled interface */
	char	name[NAMELEN];

	uchar	sticky[4];		/* sticky write register values */
	ulong	freq;			/* clock frequency */
	uchar	mask;			/* bits/char */
	int	baud;			/* baud rate */

	int	parity;			/* parity errors */
	int	frame;			/* framing errors */
	int	overrun;		/* rcvr overruns */

	/* buffers */
	int	(*putc)(Queue*, int);
	Queue	*iq;
	Queue	*oq;

	Lock	rlock;			/* receive */
	uchar	istage[Stagesize];
	uchar	*ip;
	uchar	*ie;

	int	haveinput;

	Lock	tlock;			/* transmit */
	uchar	ostage[Stagesize];
	uchar	*op;
	uchar	*oe;

	int	modem;			/* hardware flow control on */
	int	xonoff;			/* software flow control on */
	int	blocked;
	int	cts, dsr, dcd, dcdts;		/* keep track of modem status */ 
	int	ctsbackoff;
	int	hup_dsr, hup_dcd;	/* send hangup upstream? */
	int	dohup;

	int	kinuse;		/* device in use by kernel */

	Rendez	r;
};
static	Uart*	uart[Nuart];
static	int	nuart;



@@ 132,23 20,20 @@ static int uartndir;
 */
static char	Ekinuse[] = "device in use by kernel";

static void	uartsetbaud(Uart *p, int rate);
static void	uartflow(void *v);
static void	uartkick0(void *v);
static void	uartkick(void *v);
static void	uartrts(Uart *p, int on);
static void	uartintr(Ureg*, void*);
static void	uartdcdhup(Uart*, int);
static void	uartdcdts(Uart*, int);
static void	uartdsrhup(Uart*, int);

/*
 *  define a Uart.
 *  define a Uart
 */
static void
uartsetup0(Uartregs *regs, ulong freq, char *name)
Uart*
uartsetup(PhysUart *phys, void *regs, ulong freq, char *name)
{
	Uart *p;

	if(nuart >= Nuart)
		return;
		return nil;

	p = xalloc(sizeof(Uart));
	uart[nuart] = p;


@@ 156,23 41,21 @@ uartsetup0(Uartregs *regs, ulong freq, char *name)
	p->dev = nuart++;
	p->freq = freq;
	p->regs = regs;

	memset(p->sticky, 0, sizeof(p->sticky));
	p->phys = phys;

	/*
	 *  set rate to 115200 baud.
	 *  8 bits/character.
	 *  1 stop bit.
	 *  interrupts disabled.
	 *  enabled with interrupts disabled.
	 */
	p->sticky[0] = Bits8;
	p->regs->ctl[0] = p->sticky[0];
	p->sticky[3] = Rena|Tena;
	p->regs->ctl[3] = p->sticky[3];
	uartsetbaud(p, 115200);

	p->iq = qopen(4*1024, 0, uartflow, p);
	p->oq = qopen(4*1024, 0, uartkick, p);
	(*p->phys->bits)(p, 8);
	(*p->phys->stop)(p, 1);
	(*p->phys->baud)(p, 115200);
	(*p->phys->enable)(p, 0);

	p->iq = qopen(4*1024, 0, p->phys->flow, p);
	p->oq = qopen(4*1024, 0, p->phys->kick, p);
	if(p->iq == nil || p->oq == nil)
		panic("uartsetup");



@@ 180,47 63,7 @@ uartsetup0(Uartregs *regs, ulong freq, char *name)
	p->ie = &p->istage[Stagesize];
	p->op = p->ostage;
	p->oe = p->ostage;
}

/*
 *  setup all uarts (called early by main() to allow debugging output to
 *  a serial port)
 */
void
uartsetup(void)
{
	uart3regs = mapspecial(UART3REGS, 64);
	uartsetup0(uart3regs, 36864000, "serialport3");
}

/*
 *  enable a port's interrupts.  set DTR and RTS
 */
static void
uartenable(Uart *p)
{
	p->sticky[3] |= Rintena|Tintena;
	p->regs->ctl[3] = p->sticky[3];
	intrenable(IRQuart3, uartintr, p, p->name);
}

/*
 *  disable interrupts. clear DTR, and RTS
 */
static void
uartdisable(Uart *p)
{
	p->sticky[3] &= ~(Rintena|Tintena);
	p->regs->ctl[3] = p->sticky[3];
}

static long
uartstatus(Chan*, Uart *p, void *buf, long n, long offset)
{
	USED(p);
//		"b%d c%d d%d e%d l%d m%d p%c r%d s%d i%d\n"
//		"dev(%d) type(%d) framing(%d) overruns(%d)%s%s%s%s\n",
	return readstr(offset, buf, n, "");
	return p;
}

static void


@@ 304,7 147,7 @@ uartopen(Chan *c, int omode)
			error(Ekinuse);
		qlock(p);
		if(p->opens++ == 0){
			uartenable(p);
			(*p->phys->enable)(p, 1);
			qreopen(p->iq);
			qreopen(p->oq);
		}


@@ 332,7 175,7 @@ uartclose(Chan *c)
			error(Ekinuse);
		qlock(p);
		if(--(p->opens) == 0){
			uartdisable(p);
			(*p->phys->disable)(p);
			qclose(p->iq);
			qclose(p->oq);
			p->ip = p->istage;


@@ 363,7 206,7 @@ uartread(Chan *c, void *buf, long n, vlong off)
	case Nctlqid:
		return readnum(offset, buf, n, NETID(c->qid.path), NUMSIZE);
	case Nstatqid:
		return uartstatus(c, p, buf, n, offset);
		return (*p->phys->status)(p, buf, n, offset);
	}

	return 0;


@@ 385,7 228,7 @@ uartctl(Uart *p, char *cmd)
	for(i = 0; i < nf; i++){

		if(strncmp(f[i], "break", 5) == 0){
//			uartbreak(p, 0);
			(*p->phys->dobreak)(p, 0);
			continue;
		}



@@ 393,19 236,19 @@ uartctl(Uart *p, char *cmd)
		switch(*f[i]){
		case 'B':
		case 'b':
//			uartsetbaud(p, n);
			(*p->phys->baud)(p, n);
			break;
		case 'C':
		case 'c':
//			uartdcdhup(p, n);
			uartdcdhup(p, n);
			break;
		case 'D':
		case 'd':
//			uartdtr(p, n);
			(*p->phys->dtr)(p, n);
			break;
		case 'E':
		case 'e':
//			uartdsrhup(p, n);
			uartdsrhup(p, n);
			break;
		case 'f':
		case 'F':


@@ 418,17 261,14 @@ uartctl(Uart *p, char *cmd)
			break;
		case 'i':
		case 'I':
//			lock(&p->flock);
//			uartfifo(p, n);
//			unlock(&p->flock);
			break;
		case 'L':
		case 'l':
//			uartbits(p, n);
			(*p->phys->bits)(p, n);
			break;
		case 'm':
		case 'M':
//			uartmflow(p, n);
			(*p->phys->modemctl)(p, n);
			break;
		case 'n':
		case 'N':


@@ 436,15 276,15 @@ uartctl(Uart *p, char *cmd)
			break;
		case 'P':
		case 'p':
//			uartparity(p, *(cmd+1));
			(*p->phys->parity)(p, *(cmd+1));
			break;
		case 'K':
		case 'k':
//			uartbreak(p, n);
			(*p->phys->dobreak)(p, n);
			break;
		case 'R':
		case 'r':
//			uartrts(p, n);
			(*p->phys->rts)(p, n);
			break;
		case 'Q':
		case 'q':


@@ 453,7 293,7 @@ uartctl(Uart *p, char *cmd)
			break;
		case 'T':
		case 't':
//			uartdcdts(p, n);
			uartdcdts(p, n);
			break;
		case 'W':
		case 'w':


@@ 536,107 376,42 @@ Dev uartdevtab = {
};

/*
 *  set the buad rate
 * decide if we should hangup when dsr or dcd drops.
 */
static void
uartsetbaud(Uart *p, int rate)
uartdsrhup(Uart *p, int n)
{
	ulong brconst;

	if(rate <= 0)
		return;

	brconst = (p->freq+8*rate-1)/(16*rate) - 1;
	p->regs->ctl[1] = (brconst>>8) & 0xf;
	p->regs->ctl[2] = brconst;

	p->baud = rate;
	p->hup_dsr = n;
}

/*
 *  turn on/off rts
 */
static void
uartrts(Uart*, int)
uartdcdhup(Uart *p, int n)
{
	p->hup_dcd = n;
}

/*
 *  restart input if it's off
 *  save dcd timestamps for gps clock
 */
static void
uartflow(void *v)
uartdcdts(Uart *p, int n)
{
	Uart *p;

	p = v;
	if(p->modem){
		uartrts(p, 1);
		ilock(&p->rlock);
		p->haveinput = 1;
		iunlock(&p->rlock);
	}
	p->dcdts = n;
}

/*
 *  restart output if not blocked and OK to send
 *  put some bytes into the local queue to avoid calling
 *  qconsume for every character
 */
static void
uartkick0(void *v)
int
uartstageoutput(Uart *p)
{
	int i;
	Uart *p;
	int n;

	p = v;
	if(p->cts == 0 || p->blocked)
		return;

	/*
	 *  128 here is an arbitrary limit to make sure
	 *  we don't stay in this loop too long.  If the
	 *  chips output queue is longer than 128, too
	 *  bad -- presotto
	 */
	for(i = 0; i < 128; i++){
//		if(!(uartrdreg(p, Lstat) & Outready))
//			break;
//		if(p->op >= p->oe && stageoutput(p) == 0)
//			break;
//		outb(p->port + Data, *(p->op++));
	}
}

static void
uartkick(void *v)
{
	Uart *p;

	p = v;
	ilock(&p->tlock);
	uartkick0(p);
	iunlock(&p->tlock);
}

static void
uartintr(Ureg*, void *x)
{
	Uart *p;

	p = x;
}

void
serialputs(char *str, int n)
{
	Uartregs *ur;

	ur = uart3regs;
	while(n-- > 0){
		/* wait for output ready */
		while((ur->status1 & Tnotfull) == 0)
			;
		ur->data = *str++;
	}
	while((ur->status1 & Tbusy))
		;
	n = qconsume(p->oq, p->ostage, Stagesize);
	if(n <= 0)
		return 0;
	p->op = p->ostage;
	p->oe = p->ostage + n;
	return n;
}

M bitsy/fns.h => bitsy/fns.h +12 -2
@@ 7,14 7,18 @@ void	clockinit(void);
#define	coherence()
void	delay(int);
void	evenaddr(ulong);
void	exceptionvectors(void);
void	flushcache(void);
void	flushmmu(void);
ulong	getfar(void);
ulong	getfsr(void);
#define	getpgcolor(a)	0
void	h3650uartsetup(void);
void	idle(void);
#define	idlehands()			/* nothing to do in the runproc */
void	intrenable(int, void (*)(Ureg*, void*), void*, char*);
int	iprint(char*, ...);
void	mappedIvecEnable(void);
void	mappedIvecDisable(void);
void*	mapspecial(ulong, int);
void	meminit(void);
void	mmuinit(void);


@@ 29,13 33,19 @@ void	putdac(ulong);
void	putttb(ulong);
void	putpid(ulong);
void	reset(void);
Uart*	uartsetup(PhysUart*, void*, ulong, char*);
void	sa1100_uartsetup(void);
void	screeninit(void);
int	screenprint(char*, ...);			/* debugging */
void	(*screenputs)(char*, int);
void	setr13(int, ulong*);
void	touser(void*);
void	trapdump(char *tag);
void	trapinit(void);
int	tas(void*);
void	uartsetup(void);
int	uartstageoutput(Uart*);
void	vectors(void);
void	vtable(void);
void	wbflush(void);

#define	waserror()	(up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))

M bitsy/io.h => bitsy/io.h +87 -0
@@ 77,3 77,90 @@ enum
	COM_RTS_oi=	1<<26,	/* RTS to UART3 */
	OPT_IND_i=	1<<27,	/* expansion pack inserted */
};

enum
{
	/* hardware counter frequency */
	ClockFreq=	3686400,
	Stagesize=	1024,
	Nuart = 4,

	/* soft flow control chars */
	CTLS= 023,
	CTLQ= 021,
};

typedef struct PhysUart PhysUart;
typedef struct Uart Uart;

/* link twixt hardware and software */
struct PhysUart
{
	void	(*enable)(Uart*, int);
	void	(*disable)(Uart*);
	void	(*kick)(void*);
	void	(*flow)(void*);
	void	(*intr)(Ureg*, void*);
	void	(*dobreak)(Uart*, int);
	void	(*baud)(Uart*, int);
	void	(*bits)(Uart*, int);
	void	(*stop)(Uart*, int);
	void	(*parity)(Uart*, int);
	void	(*modemctl)(Uart*, int);
	void	(*rts)(Uart*, int);
	void	(*dtr)(Uart*, int);
	long	(*status)(Uart*, void*, long, long);
};

/* software representation */
struct Uart
{
	QLock;
	int	type;
	int	dev;
	int	opens;
	void	*regs;
	PhysUart	*phys;

	int	enabled;
	Uart	*elist;			/* next enabled interface */
	char	name[NAMELEN];

	uchar	sticky[4];		/* sticky write register values */
	ulong	freq;			/* clock frequency */
	uchar	mask;			/* bits/char */
	int	baud;			/* baud rate */

	int	parity;			/* parity errors */
	int	frame;			/* framing errors */
	int	overrun;		/* rcvr overruns */

	/* buffers */
	int	(*putc)(Queue*, int);
	Queue	*iq;
	Queue	*oq;

	Lock	rlock;			/* receive */
	uchar	istage[Stagesize];
	uchar	*ip;
	uchar	*ie;

	int	haveinput;

	Lock	tlock;			/* transmit */
	uchar	ostage[Stagesize];
	uchar	*op;
	uchar	*oe;

	int	modem;			/* hardware flow control on */
	int	xonoff;			/* software flow control on */
	int	blocked;
	int	cts, dsr, dcd, dcdts;		/* keep track of modem status */ 
	int	ctsbackoff;
	int	hup_dsr, hup_dcd;	/* send hangup upstream? */
	int	dohup;

	int	kinuse;		/* device in use by kernel */

	Rendez	r;
};

M bitsy/l.s => bitsy/l.s +48 -31
@@ 10,8 10,12 @@ _main:
	MOVW	$(PsrDirq|PsrDfiq|PsrMsvc), R1
	MOVW	R1, CPSR

	/* flush TLB's */
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x0)
	/* disable the MMU */
	MOVW	$0x130, R1
	MCR     CpMMU, 0, R1, C(CpControl), C(0x0)

	/* flush caches */
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0
	/* drain prefetch */
	MOVW	R0,R0						
	MOVW	R0,R0


@@ 19,11 23,7 @@ _main:
	MOVW	R0,R0

	/* 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)
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4

	MOVW	$(MACHADDR+BY2PG), R13		/* stack */
	SUB	$4, R13				/* link */


@@ 36,12 36,12 @@ _mainloop:

/* flush tlb's */
TEXT flushmmu(SB), $-4
	MCR	CpMMU, 0, R0, C(CpTLBFlush), C(0x0)
	MCR	CpMMU, 0, R0, C(CpTLBFlush), C(0x7)
	RET

/* flush instruction cache */
TEXT flushicache(SB), $-4
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x0)
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x5), 0
	/* drain prefetch */
	MOVW	R0,R0					
	MOVW	R0,R0


@@ 51,12 51,12 @@ TEXT flushicache(SB), $-4

/* flush data cache */
TEXT flushdcache(SB), $-4
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x0)
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x6), 0
	RET

/* flush i and d caches */
TEXT flushcache(SB), $-4
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x0)
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0
	/* drain prefetch */
	MOVW	R0,R0						
	MOVW	R0,R0


@@ 66,7 66,7 @@ TEXT flushcache(SB), $-4

/* drain write buffer */
TEXT wbflush(SB), $-4
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x0), 4
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4
	RET

/* return cpu id */


@@ 90,11 90,11 @@ TEXT putttb(SB), $-4
	RET

/*
 *  enable mmu, i and d caches, and exception vectors at 0xffff0000
 *  enable mmu, i and d caches
 */
TEXT mmuenable(SB), $-4
	MRC	CpMMU, 0, R0, C(CpControl), C(0x0)
	ORR	$(CpCmmuena|CpCdcache|CpCicache|CpCvivec), R0
	ORR	$(CpCmmuena|CpCdcache|CpCicache), R0
	MCR     CpMMU, 0, R0, C(CpControl), C(0x0)
	RET



@@ 104,6 104,20 @@ TEXT mmudisable(SB), $-4
	MCR     CpMMU, 0, R0, C(CpControl), C(0x0)
	RET

/*
 *  use exception vectors at 0xffff0000
 */
TEXT mappedIvecEnable(SB), $-4
	MRC	CpMMU, 0, R0, C(CpControl), C(0x0)
	ORR	$(CpCvivec), R0
	MCR     CpMMU, 0, R0, C(CpControl), C(0x0)
	RET
TEXT mappedIvecDisable(SB), $-4
	MRC	CpMMU, 0, R0, C(CpControl), C(0x0)
	BIC	$(CpCvivec), R0
	MCR     CpMMU, 0, R0, C(CpControl), C(0x0)
	RET

/* set the translation table base */
TEXT putdac(SB), $-4
	MCR	CpMMU, 0, R0, C(CpDAC), C(0x0)


@@ 134,23 148,26 @@ TEXT setr13(SB), $-4
/*
 *  exception vectors, copied by trapinit() to somewhere useful
 */
TEXT exceptionvectors(SB), $-4
	MOVW	0x18(R15), R15		/* reset */
	MOVW	0x18(R15), R15		/* undefined */
	MOVW	0x18(R15), R15		/* SWI */
	MOVW	0x18(R15), R15		/* prefetch abort */
	MOVW	0x18(R15), R15		/* data abort */
	MOVW	0x18(R15), R15		/* reserved */
	MOVW	0x18(R15), R15		/* IRQ */
	MOVW	0x18(R15), R15		/* FIQ */
	WORD	$_vrst(SB)		/* reset, in svc mode already */
	WORD	$_vund(SB)		/* undefined, switch to svc mode */
	WORD	$_vsvc(SB)		/* swi, in svc mode already */
	WORD	$_vabt(SB)		/* prefetch abort, switch to svc mode */
	WORD	$_vabt(SB)		/* data abort, switch to svc mode */
	WORD	$_vrst(SB)		/* reserved, shouldn't happen */
	WORD	$_virq(SB)		/* IRQ, switch to svc mode */
	WORD	$_vfiq(SB)		/* FIQ, switch to svc mode */

TEXT vectors(SB), $-4
	MOVW	0x18(R15), R15			/* reset */
	MOVW	0x18(R15), R15			/* undefined */
	MOVW	0x18(R15), R15			/* SWI */
	MOVW	0x18(R15), R15			/* prefetch abort */
	MOVW	0x18(R15), R15			/* data abort */
	MOVW	0x18(R15), R15			/* reserved */
	MOVW	0x18(R15), R15			/* IRQ */
	MOVW	0x18(R15), R15			/* FIQ */

TEXT vtable(SB), $-4
	WORD	$_vsvc(SB)			/* reset, in svc mode already */
	WORD	$_vund(SB)			/* undefined, switch to svc mode */
	WORD	$_vsvc(SB)			/* swi, in svc mode already */
	WORD	$_vabt(SB)			/* prefetch abort, switch to svc mode */
	WORD	$_vabt(SB)			/* data abort, switch to svc mode */
	WORD	$_vsvc(SB)			/* reserved */
	WORD	$_virq(SB)			/* IRQ, switch to svc mode */
	WORD	$_vfiq(SB)			/* FIQ, switch to svc mode */

TEXT _vrst(SB), $-4
	BL	reset(SB)

M bitsy/main.c => bitsy/main.c +10 -4
@@ 17,6 17,9 @@ main(void)
	/* zero out bss */
	memset(edata, 0, end-edata);

	/* point to Mach structure */
	m = (Mach*)MACHADDR;

	iprint("bitsy kernel\n");
	confinit();
	iprint("%d pages %lux(%lud) %lux(%lud)\n", conf.npage, conf.base0, conf.npage0, conf.base1, conf.npage1);


@@ 26,15 29,17 @@ main(void)
	delay(2000);
	iprint("done\n");
	mmuinit();
	uartsetup();
	sa1100_uartsetup();
	iprint("after mmuinit\n");
	clockinit();
	iprint("after clockinit\n");
	trapinit();
	iprint("after trapinit\n");
	clockinit();
	iprint("after clockinit\n");
trapdump("before spllo");
	spllo();
	iprint("after spllo\n");
	delay(1000000);
	delay(10000);
trapdump("after delay");
	exit(1);
}



@@ 181,3 186,4 @@ confinit(void)

	conf.copymode = 0;		/* copy on write */
}


M bitsy/mem.h => bitsy/mem.h +1 -1
@@ 53,7 53,7 @@
#define	TSTKTOP		(USTKTOP-USTKSIZE)	/* end of new stack in sysexec */
#define TSTKSIZ 	100
#define MACHADDR	(KZERO+0x00001000)
#define	EVECTORS	0xFFFF0000		/* base of exception vectors (also mapped to KZERO) */
#define	EVECTORS	0xFFFF0000		/* virt base of exception vectors */

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


M bitsy/mmu.c => bitsy/mmu.c +14 -7
@@ 54,6 54,7 @@ static ulong phystrans[16] =

ulong *l1table;


/*
 *  We map all of memory, flash, and the zeros area with sections.
 *  Special use space is mapped on the fly with regmap.


@@ 65,8 66,8 @@ mmuinit(void)
	ulong *t;

	/* get a prototype level 1 page */
	l1table = xspanalloc(BY2PG, 16*1024, 0);
	memset(l1table, 0, BY2PG);
	l1table = xspanalloc(16*1024, 16*1024, 0);
	memset(l1table, 0, 16*1024);

	/* direct map DRAM */
	e = conf.base1 + BY2PG*conf.npage1;


@@ 83,11 84,14 @@ mmuinit(void)
		l1table[a>>20] = L1Section | L1KernelRW | (a&L1SectBaseMask) |
				L1Cached | L1Buffered;

	/* map first page of DRAM also into 0xFFFF0000 for the interrupt vectors */
	t = xspanalloc(BY2PG, 16*1024, 0);
	/*
	 *  double map start of ram to exception vectors
	 */
	a = EVECTORS;
	t = xspanalloc(BY2PG, 1024, 0);
	memset(t, 0, BY2PG);
	l1table[0xFFFF0000>>20] = L1PageTable | L1Domain0 | (((ulong)t) & L1PTBaseMask);
	t[0xF0000>>PGSHIFT] = L2SmallPage | L2KernelRW | PHYSDRAM0;
	l1table[a>>20] = L1PageTable | L1Domain0 | (((ulong)t) & L1PTBaseMask);
	t[(a&0xfffff)>>PGSHIFT] = L2SmallPage | L2KernelRW | (PHYSDRAM0 & L2PageBaseMask);

	/* set up the domain register to cause all domains to obey pte access bits */
	iprint("setting up domain access\n");


@@ 97,7 101,10 @@ mmuinit(void)
	iprint("setting tlb map %lux\n", (ulong)l1table);
	putttb((ulong)l1table);

	/* enable mmu, and make 0xFFFF0000 the virtual address of the exception vecs */
	/* enable mmu */
	wbflush();
	flushcache();
	flushmmu();
	mmuenable();
}


M bitsy/trap.c => bitsy/trap.c +35 -9
@@ 34,23 34,40 @@ typedef struct Vctl {
static Lock vctllock;
static Vctl *vctl[32];


/*
 *   Layout at virtual address 0.
 */
typedef struct Vpage0 {
	void	(*vectors[8])(void);
	ulong	vtable[8];

	ulong	hole[16];
} Vpage0;
Vpage0 *vpage0;

/*
 *  set up for exceptioons
 */
void
trapinit(void)
{
	/*
	 *  exceptionvectors points to a prototype in l.s of the
	 *  exception vectors that save the regs and then call
	 *  trap().  The actual vectorrs are double mapped
	 *  to 0xffff0000 and to KZERO.  We write them via
	 *  KZERO since a data access to them will cause an
	 *  exception.
	 */
	memmove((void*)KZERO, exceptionvectors, 2*4*8);
	/* set up the exception vectors */
	vpage0 = (Vpage0*)EVECTORS;
	memmove(vpage0->vectors, vectors, sizeof(vpage0->vectors));
	memmove(vpage0->vtable, vtable, sizeof(vpage0->vtable));
	memset(vpage0->hole, 0, sizeof(vpage0->hole));
	wbflush();

	/* use exception vectors at 0xFFFF0000 */
	mappedIvecEnable();

	/* set up the stacks for the interrupt modes */
	setr13(PsrMfiq, m->sfiq);
	setr13(PsrMirq, m->sirq);
	setr13(PsrMabt, m->sabt);
	setr13(PsrMund, m->sund);

	/* map in interrupt registers */
	intrregs = mapspecial(INTRREGS, sizeof(*intrregs));



@@ 59,6 76,15 @@ trapinit(void)
	intrregs->icmr = 0;
}

void
trapdump(char *tag)
{
	iprint("%s: icip %lux icmr %lux iclr %lux iccr %lux icfp %lux\n",
		tag, intrregs->icip, intrregs->icmr, intrregs->iclr,
		intrregs->iccr, intrregs->icfp);
}


/*
 *  enable an interrupt and attach a function to it
 */

M pc/devi82365.c => pc/devi82365.c +1 -4
@@ 440,10 440,7 @@ pcmspecial(char *idstr, ISAConf *isa)
	extern char *strstr(char*, char*);
	static int resetdone;

	if (! resetdone) {
		i82365reset();
		resetdone++;
	}
	i82365reset();
	for(pp = slot; pp < lastslot; pp++){
		if(pp->special)
			continue;	/* already taken */