~kris/9p

9hist

bafa3d1142a79204c6d87517de002db6137d0ddf — David du Colombier 25 years ago a9cc49e
Plan 9 from Bell Labs 2000-11-21
M bitsy/clock.c => bitsy/clock.c +9 -0
@@ 24,6 24,8 @@ static void	clockintr(Ureg*, void*);
void
clockinit(void)
{
	ulong x;

	/* map the clock registers */
	timerregs = mapspecial(OSTIMERREGS, 32);



@@ 32,6 34,13 @@ clockinit(void)
	intrenable(IRQtimer0, clockintr, nil, "clock");
	timerregs->oier = 1<<0;

	/* figure out processor frequency */
	x = powerregs->ppcr & 0x1f;
	conf.hz = ClockFreq*(x*4+16);
	conf.mhz = (conf.hz+499999)/1000000;

	print("%lud MHZ WeakARM\n", conf.mhz);

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


M bitsy/dat.h => bitsy/dat.h +190 -18
@@ 1,19 1,25 @@
typedef struct Conf	Conf;
typedef struct FPU	FPU;
typedef struct FPenv	FPenv;
typedef struct FPsave	FPsave;
typedef struct Label	Label;
typedef struct Lock	Lock;
typedef struct MMU	MMU;
typedef struct Mach	Mach;
typedef struct Notsave	Notsave;
typedef struct Page	Page;
typedef struct PMMU	PMMU;
typedef struct Proc	Proc;
typedef struct Ureg	Ureg;
typedef struct Vctl	Vctl;
typedef struct PhysUart	PhysUart;
typedef struct Uart	Uart;
typedef struct Cisdat 		Cisdat;
typedef struct Conf		Conf;
typedef struct Cycintr		Cycintr;
typedef struct FPU		FPU;
typedef struct FPenv		FPenv;
typedef struct FPsave		FPsave;
typedef struct Label		Label;
typedef struct Lock		Lock;
typedef struct MMU		MMU;
typedef struct Mach		Mach;
typedef struct Notsave		Notsave;
typedef struct Page		Page;
typedef struct PCMmap		PCMmap;
typedef struct PCMslot		PCMslot;
typedef struct PCMconftab	PCMconftab;
typedef struct PhysUart		PhysUart;
typedef struct PMMU		PMMU;
typedef struct Proc		Proc;
typedef struct Uart		Uart;
typedef struct Ureg		Ureg;
typedef struct Vctl		Vctl;
typedef struct Uart		Uart;

/*
 *  parameters for sysproc.c


@@ 68,6 74,8 @@ struct Conf
	int	monitor;
	ulong	ialloc;		/* bytes available for interrupt time allocation */
	ulong	pipeqsize;	/* size in bytes of pipe queues */
	ulong	hz;		/* processor cycle freq */
	ulong	mhz;
};

/*


@@ 141,8 149,6 @@ struct Mach
	int	stack[1];
};

typedef struct Cycintr	Cycintr;

/*
 * fasttick timer interrupts
 */


@@ 179,3 185,169 @@ enum
{
	OneMeg=	1024*1024,
};

/*
 *  routines to access UART hardware
 */
struct PhysUart
{
	void	(*enable)(Uart*, int);
	void	(*disable)(Uart*);
	void	(*kick)(Uart*);
	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);
};

enum {
	Stagesize=	1024
};

/*
 *  software UART
 */
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;

	uchar	istage[Stagesize];
	uchar	*iw;
	uchar	*ir;
	uchar	*ie;

	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;
};

/*
 * PCMCIA structures known by both port/cis.c and the pcmcia driver
 */

/*
 * Map between ISA memory space and PCMCIA card memory space.
 */
struct PCMmap {
	ulong	ca;			/* card address */
	ulong	cea;			/* card end address */
	ulong	isa;			/* local virtual address */
	int	len;			/* length of the ISA area */
	int	attr;			/* attribute memory */
};

/*
 *  a PCMCIA configuration entry
 */
struct PCMconftab
{
	int	index;
	ushort	irqs;		/* legal irqs */
	uchar	irqtype;
	uchar	bit16;		/* true for 16 bit access */
	struct {
		ulong	start;
		ulong	len;
	} io[16];
	int	nio;
	uchar	vpp1;
	uchar	vpp2;
	uchar	memwait;
	ulong	maxwait;
	ulong	readywait;
	ulong	otherwait;
};

/*
 *  For walking a PCMCIA card's information structure
 */
struct Cisdat
{
	uchar	*cisbase;
	int	cispos;
	int	cisskip;
	int	cislen;
};

/*
 *  PCMCIA card slot
 */
struct PCMslot
{
	Ref;

	long	memlen;		/* memory length */
	uchar	slotno;		/* slot number */
	void	*regs;		/* i/o registers */
	void	*mem;		/* memory */
	void	*attr;		/* attribute memory */

	/* status */
	uchar	special;	/* in use for a special device */
	uchar	already;	/* already inited */
	uchar	occupied;
	uchar	battery;
	uchar	wrprot;
	uchar	powered;
	uchar	configed;
	uchar	enabled;
	uchar	busy;

	/* cis info */
	ulong	msec;		/* time of last slotinfo call */
	char	verstr[512];	/* version string */
	uchar	cpresent;	/* config registers present */
	ulong	caddr;		/* relative address of config registers */
	int	nctab;		/* number of config table entries */
	PCMconftab	ctab[8];
	PCMconftab	*def;		/* default conftab */

	/* for walking through cis */
	Cisdat;

	/* maps are fixed */
	PCMmap memmap;
	PCMmap attrmap;
};

M bitsy/devpcmcia.c => bitsy/devpcmcia.c +142 -83
@@ 27,6 27,11 @@ enum
#define TYPE(c)		(c->qid.path&0xff)
#define QID(s,t)	(((s)<<8)|(t))

static void increfp(PCMslot*);
static void decrefp(PCMslot*);
static void slotmap(int, ulong, ulong, ulong);
static void slottiming(int, int, int, int, int);

static int
pcmgen(Chan *c, Dirtab *, int , int i, Dir *dp)
{


@@ 68,94 73,19 @@ pcmgen(Chan *c, Dirtab *, int , int i, Dir *dp)
	return 1;
}

static void
slotinfo(void)
{
	ulong x = gpioregs->level;

	if(x & GPIO_OPT_IND_i){
		/* no expansion pack */
		slot[0].occupied = 0;
		slot[1].occupied = 0;
	} else {
		slot[0].occupied = (x & GPIO_CARD_IND0_i) == 0;
		slot[1].occupied = (x & GPIO_CARD_IND1_i) == 0;
	}
}

static void
increfp(PCMslot *pp)
{
	if(incref(&pcmcia) == 1)
		exppackpower(1);
	lock(pp);
	if(pp->ref++ == 0)
		;
	unlock(pp);
	slotinfo();
}
static void
decrefp(PCMslot *pp)
{
	slotinfo();
	lock(pp);
	if(pp->ref-- == 1)
		;
	unlock(pp);
	if(decref(&pcmcia) == 0)
		exppackpower(0);
}

/*
 *  get a map for pc card region, return corrected len
 */
PCMmap*
pcmmap(int slotno, ulong, int, int attr)
{
	if(slotno > nslot)
		panic("pcmmap");
	if(attr)
		return &slot[slotno].attrmap;
	else
		return &slot[slotno].memmap;
}
void
pcmunmap(int, PCMmap*)
{
}

/*
 *  map in the space for the cards
 *  set up the cards, default timing is 300 ns
 */
static void
pcmciareset(void)
{
	int j;
	PCMslot *pp;
	/* staticly map the whole area */
	slotmap(0, PHYSPCM0REGS, PYHSPCM0ATTR, PYHSPCM0MEM);
	slotmap(1, PHYSPCM1REGS, PYHSPCM1ATTR, PYHSPCM1MEM);

	for(j = 0; j < nslot; j++){
		pp = &slot[j];
		pp->slotno = j;
		pp->memlen = 64*OneMeg;
		pp->msec = ~0;
		pp->verstr[0] = 0;

		pp->mem = mapmem(j == 0 ? PYHSPCM0MEM : PYHSPCM1MEM, 64*OneMeg);
		pp->memmap.ca = 0;
		pp->memmap.cea = 64*MB;
		pp->memmap.isa = (ulong)pp->mem;
		pp->memmap.len = 64*OneMeg;
		pp->memmap.attr = 0;

		pp->attr = mapmem(j == 0 ? PYHSPCM0ATTR : PYHSPCM1ATTR, OneMeg);
		pp->attrmap.ca = 0;
		pp->attrmap.cea = 64*MB;
		pp->attrmap.isa = (ulong)pp->attr;
		pp->attrmap.len = OneMeg;
		pp->attrmap.attr = 1;

		pp->regs = mapspecial(j == 0 ? PHYSPCM0REGS : PHYSPCM1REGS, 32*1024);
	}
	/* set timing to the default, 300 */
	slottiming(0, 300, 300, 300, 0);
	slottiming(1, 300, 300, 300, 0);
}

static Chan*


@@ 231,7 161,7 @@ pcmread(void *a, long n, ulong off, uchar *start, ulong len)
		return 0;
	if(off + n > len)
		n = len - off;
	memmoves(a, start+off, n);
	memmoveb(a, start+off, n);
	return n;
}



@@ 353,3 283,132 @@ Dev pcmciadevtab = {
	devremove,
	devwstat,
};

/* see what's there */
static void
slotinfo(void)
{
	ulong x = gpioregs->level;

	if(x & GPIO_OPT_IND_i){
		/* no expansion pack */
		slot[0].occupied = 0;
		slot[1].occupied = 0;
	} else {
		slot[0].occupied = (x & GPIO_CARD_IND0_i) == 0;
		slot[1].occupied = (x & GPIO_CARD_IND1_i) == 0;
	}
}

/* use reference card to turn cards on and off */
static void
increfp(PCMslot *pp)
{
	if(incref(&pcmcia) == 1){
		egpiobits(EGPIO_exp_nvram_power|EGPIO_exp_full_power, 1);
		egpiobits(EGPIO_pcmcia_reset, 0);
		delay(100);	/* time to power up */
	}

	incref(pp);

	slotinfo();
}

static void
decrefp(PCMslot *pp)
{
	slotinfo();
	decref(pp);
	if(decref(&pcmcia) == 0)
		egpiobits(EGPIO_exp_nvram_power|EGPIO_exp_full_power, 0);
}

/*
 *  the regions are staticly mapped
 */
static void
slotmap(int slotno, ulong regs, ulong attr, ulong mem)
{
	PCMslot *pp;

	pp = &slot[slotno];
	pp->slotno = slotno;
	pp->memlen = 64*OneMeg;
	pp->msec = ~0;
	pp->verstr[0] = 0;

	pp->mem = mapmem(mem, 64*OneMeg, 0);
	pp->memmap.ca = 0;
	pp->memmap.cea = 64*MB;
	pp->memmap.isa = (ulong)pp->mem;
	pp->memmap.len = 64*OneMeg;
	pp->memmap.attr = 0;

	pp->attr = mapmem(attr, OneMeg, 0);
	pp->attrmap.ca = 0;
	pp->attrmap.cea = MB;
	pp->attrmap.isa = (ulong)pp->attr;
	pp->attrmap.len = OneMeg;
	pp->attrmap.attr = 1;

	pp->regs = mapspecial(regs, 32*1024);
}
PCMmap*
pcmmap(int slotno, ulong, int, int attr)
{
	if(slotno > nslot)
		panic("pcmmap");
	if(attr)
		return &slot[slotno].attrmap;
	else
		return &slot[slotno].memmap;
}
void
pcmunmap(int, PCMmap*)
{
}

/*
 *  setup card timings
 *    times are in ns
 *    count = ceiling[access-time/(2*3*T)] - 1, where T is a processor cycle
 *
 */
static int
ns2count(int ns)
{
	ulong y;

	/* get 100 times cycle time */
	y = 100000000/(conf.hz/1000);

	/* get 10 times ns/(cycle*6) */
	y = (1000*ns)/(6*y);

	/* round up */
	y += 9;
	y /= 10;

	/* subtract 1 */
	return y-1;
}
static void
slottiming(int slotno, int tio, int tattr, int tmem, int fast)
{
	ulong x;

	x = 0;
	if(fast)
		x |= 1<<MECR_fast0;
	x |= ns2count(tio) << MECR_io0;
	x |= ns2count(tattr) << MECR_attr0;
	x |= ns2count(tmem) << MECR_mem0;
	if(slotno == 0){
		x |= memconfregs->mecr & 0xffff0000;
	} else {
		x <<= 16;
		x |= memconfregs->mecr & 0xffff;
	}
	memconfregs->mecr = x;
}

M bitsy/devuart.c => bitsy/devuart.c +8 -0
@@ 8,6 8,14 @@

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

enum
{
	Nuart = 4,

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

static	Uart*	uart[Nuart];
static	int	nuart;

M bitsy/devuda1341.c => bitsy/devuda1341.c +39 -40
@@ 19,7 19,7 @@
#include	"io.h"
#include	"sa1110dma.h"

static int debug = 0;
static int debug = 2;

/*
 * GPIO based L3 bus support.


@@ 417,7 417,7 @@ audioqnotempty(void *x)
{
	IOstate *s = x;

	return dmaidle(s->dma) || s->emptying != s->next;
	return dmaidle(s->dma) || s->emptying != s->current;
}

static int


@@ 428,10 428,17 @@ audioqnotfull(void *x)
	return dmaidle(s->dma) || s->filling != s->current;
}

SSPregs *sspregs;
MCPregs	*mcpregs;

static void
audioinit(void)
{
	/* do nothing */
	/* Turn MCP operations off */
	mcpregs = mapspecial(MCPREGS, 0x34);
	mcpregs->status &= ~(1<<16);

	sspregs = mapspecial(SSPREGS, 32);
}

uchar	status0	= 0x22;


@@ 464,8 471,6 @@ enable(void)

	/* Enable the audio power */
	audiopower(1);
	amplifierpower(1);
	audiomute(0);

	/* external clock configured for 44100 samples/sec */
	gpioregs->set	= GPIO_CLK_SET0_o;


@@ 577,6 582,8 @@ mxvolume(void) {
static void
outenable(void) {
	/* turn on DAC, set output gain switch */
	amplifierpower(1);
	audiomute(0);
	status1 |= 0x41;
	L3_write(UDA1341_L3Addr | UDA1341_STATUS, (uchar*)&status1, 1);
	/* set volume */


@@ 591,6 598,8 @@ outenable(void) {
static void
outdisable(void) {
	/* turn off DAC, clear output gain switch */
	audiomute(1);
	amplifierpower(0);
	status1 &= ~0x41;
	L3_write(UDA1341_L3Addr | UDA1341_STATUS, (uchar*)&status1, 1);
	if (debug) {


@@ 683,22 692,15 @@ static void
audiointr(void *x, ulong ndma) {
	IOstate *s = x;

	if (s == &audio.o) {
		/* Only interrupt routine touches s->current */
		if (debug > 1) iprint("#A: audio interrupt @%p\n", s->current);
		s->current++;
		if (s->current == &s->buf[Nbuf])
			s->current = &s->buf[0];
		if (ndma > 0)
	if (debug > 1) iprint("#A: audio interrupt @%p\n", s->current);
	/* Only interrupt routine touches s->current */
	s->current++;
	if (s->current == &s->buf[Nbuf])
		s->current = &s->buf[0];
	if (ndma > 0) {
		if (s == &audio.o)
			sendaudio(s);
	} else if (s == &audio.i) {
		/* Only interrupt routine touches s->current */
		if (debug > 1) iprint("#A: audio interrupt @%p\n", s->current);
		s->current->nbytes = Bufsize;
		s->current++;
		if (s->current == &s->buf[Nbuf])
			s->current = &s->buf[0];
		if (ndma > 0)
		else if (s == &audio.i)
			recvaudio(s);
	}
	wakeup(&s->vous);


@@ 723,9 725,10 @@ audiostat(Chan *c, char *db)
}

static Chan*
audioopen(Chan *c, int omode)
audioopen(Chan *c, int mode)
{
	IOstate *s;
	int omode = mode;

	switch(c->qid.path & ~CHDIR) {
	default:


@@ 741,8 744,7 @@ audioopen(Chan *c, int omode)

	case Qaudio:
		omode = (omode & 0x7) + 1;
//		if (omode & ~(Aread | Awrite))
		if (omode & ~(Awrite))
		if (omode & ~(Aread | Awrite))
			error(Ebadarg);
		qlock(&audio);
		if(audio.amode & omode){


@@ 754,20 756,17 @@ audioopen(Chan *c, int omode)
		if (omode & Aread) {
			inenable();
			s = &audio.i;
			/* read */
			audio.amode |= Aread;
			if(audio.i.bufinit == 0)
			if(s->bufinit == 0)
				bufinit(s);
			setempty(s);
			s->emptying = &s->buf[Nbuf-1];
			s->chan = c;
			s->dma = dmaalloc(0, 0, 4, 2, SSPRecvDMA, Port4SSP, audiointr, (void*)s);
		}
		if (omode & 0x2) {
		if (omode & Awrite) {
			outenable();
			s = &audio.o;
			/* write */
//			amplifierpower(1);
//			audiomute(0);
			audio.amode |= Awrite;
			if(s->bufinit == 0)
				bufinit(s);


@@ 781,8 780,8 @@ audioopen(Chan *c, int omode)
		if (debug) print("#A: open done\n");
		break;
	}
	c = devopen(c, omode, audiodir, nelem(audiodir), devgen);
	c->mode = openmode(omode);
	c = devopen(c, mode, audiodir, nelem(audiodir), devgen);
	c->mode = openmode(mode);
	c->flag |= COPEN;
	c->offset = 0;



@@ 892,15 891,22 @@ audioread(Chan *c, void *v, long n, vlong off)
		if (debug > 1) print("#A: read %ld\n", n);
		if((audio.amode & Aread) == 0)
			error(Emode);
		s = &audio.o;
		s = &audio.i;
		qlock(s);
		if(waserror()){
			qunlock(s);
			nexterror();
		}
		while(n > 0) {
			if(s->emptying->nbytes == 0) {
				if (debug > 1) print("#A: emptied @%p\n", s->emptying);
				recvaudio(s);
				s->emptying++;
				if (s->emptying == &s->buf[Nbuf])
					s->emptying = s->buf;
			}
			/* wait if dma in progress */
			while (!dmaidle(s->dma) && s->emptying == s->next) {
			while (!dmaidle(s->dma) && s->emptying == s->current) {
				if (debug > 1) print("#A: sleep\n");
				sleep(&s->vous, audioqnotempty, s);
			}


@@ 913,13 919,6 @@ audioread(Chan *c, void *v, long n, vlong off)
			s->emptying->nbytes -= m;
			n -= m;
			p += m;
			if(s->emptying->nbytes == 0) {
				if (debug > 1) print("#A: emptied @%p\n", s->emptying);
				s->emptying++;
				if (s->emptying == &s->buf[Nbuf])
					s->emptying = s->buf;
				recvaudio(s);
			}
		}
		poperror();
		qunlock(s);

M bitsy/fns.h => bitsy/fns.h +1 -1
@@ 33,7 33,7 @@ void	intrenable(int, void (*)(Ureg*, void*), void*, char*);
int	iprint(char*, ...);
void	irpower(int);
void	lcdpower(int);
void*	mapmem(ulong, int);
void*	mapmem(ulong, int, int);
void	mappedIvecEnable(void);
void	mappedIvecDisable(void);
void*	mapspecial(ulong, int);

M bitsy/io.h => bitsy/io.h +56 -161
@@ 1,8 1,12 @@
/*
 *  Definitions for IO devices.  Used only in C.
 */
typedef struct Uartregs Uartregs;
Uartregs *uart3regs;

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

/*
 *  IRQ's defined by SA1100


@@ 105,89 109,17 @@ enum
	GPIO_32_768kHz_o=	1<<27,	/* 32.768 kHz clock (O, RTC) */
};

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)(Uart*);
	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
/* hardware registers */
typedef struct Uartregs Uartregs;
struct Uartregs
{
	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;

	uchar	istage[Stagesize];
	uchar	*iw;
	uchar	*ir;
	uchar	*ie;

	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;
	ulong	ctl[4];
	ulong	dummya;
	ulong	data;
	ulong	dummyb;
	ulong	status[2];
};
Uartregs *uart3regs;

/* general purpose I/O lines control registers */
typedef struct GPIOregs GPIOregs;


@@ 266,90 198,53 @@ struct MCPregs {
extern MCPregs *mcpregs;

/*
 * PCMCIA support code.
 */

typedef struct PCMmap		PCMmap;
typedef struct PCMslot		PCMslot;
typedef struct PCMconftab	PCMconftab;
typedef struct Cisdat 		Cisdat;

/*
 * Map between ISA memory space and PCMCIA card memory space.
 *  memory configuration
 */
struct PCMmap {
	ulong	ca;			/* card address */
	ulong	cea;			/* card end address */
	ulong	isa;			/* local virtual address */
	int	len;			/* length of the ISA area */
	int	attr;			/* attribute memory */
};

/* configuration table entry */
struct PCMconftab
enum
{
	int	index;
	ushort	irqs;		/* legal irqs */
	uchar	irqtype;
	uchar	bit16;		/* true for 16 bit access */
	struct {
		ulong	start;
		ulong	len;
	} io[16];
	int	nio;
	uchar	vpp1;
	uchar	vpp2;
	uchar	memwait;
	ulong	maxwait;
	ulong	readywait;
	ulong	otherwait;
	/* bit shifts for pcmcia access time counters */
	MECR_io0=	0,
	MECR_attr0=	5,
	MECR_mem0=	10,
	MECR_fast0=	11,
	MECR_io1=	MECR_io0+16,
	MECR_attr1=	MECR_attr0+16,
	MECR_mem1=	MECR_mem0+16,
	MECR_fast1=	MECR_fast0+16,
};

/* cis memory walking */
struct Cisdat
typedef struct MemConfRegs MemConfRegs;
struct MemConfRegs
{
	uchar	*cisbase;
	int	cispos;
	int	cisskip;
	int	cislen;
	ulong	mdcnfg;		/* dram */
	ulong	mdcas00;	/* dram banks 0/1 */
	ulong	mdcas01;
	ulong	mdcas02;
	ulong	msc0;		/* static */
	ulong	msc1;
	ulong	mecr;		/* pcmcia */
	ulong	mdrefr;		/* dram refresh */
	ulong	mdcas20;	/* dram banks 2/3 */
	ulong	mdcas21;
	ulong	mdcas22;
	ulong	msc2;		/* static */
	ulong	smcnfg;		/* SMROM config */
};
extern MemConfRegs *memconfregs;

/* a card slot */
struct PCMslot
/*
 *  power management
 */
typedef struct PowerRegs PowerRegs;
struct PowerRegs
{
	Lock;
	int	ref;

	long	memlen;		/* memory length */
	uchar	slotno;		/* slot number */
	void	*regs;		/* i/o registers */
	void	*mem;		/* memory */
	void	*attr;		/* attribute memory */

	/* status */
	uchar	special;	/* in use for a special device */
	uchar	already;	/* already inited */
	uchar	occupied;
	uchar	battery;
	uchar	wrprot;
	uchar	powered;
	uchar	configed;
	uchar	enabled;
	uchar	busy;

	/* cis info */
	ulong	msec;		/* time of last slotinfo call */
	char	verstr[512];	/* version string */
	uchar	cpresent;	/* config registers present */
	ulong	caddr;		/* relative address of config registers */
	int	nctab;		/* number of config table entries */
	PCMconftab	ctab[8];
	PCMconftab	*def;		/* default conftab */

	/* for walking through cis */
	Cisdat;

	/* maps are fixed */
	PCMmap memmap;
	PCMmap attrmap;
	ulong	pmcr;
	ulong	pssr;
	ulong	pspr;
	ulong	pwer;
	ulong	pcfr;
	ulong	ppcr;
	ulong	pgsr;
	ulong	posr;
};
extern PowerRegs *powerregs;

M bitsy/main.c => bitsy/main.c +19 -37
@@ 13,11 13,6 @@ Proc	*up;
Conf	conf;
int 	noprint;

static void	gpioinit(void);
static void ppcinit(void);
static void sspinit(void);
static void mcpinit(void);

void
main(void)
{


@@ 38,10 33,7 @@ main(void)
	confinit();
	xinit();
	mmuinit();
	gpioinit();
	ppcinit();
	mcpinit();
	sspinit();
	machinit();
	trapinit();
	sa1100_uartsetup(1);
	rs232power(1);


@@ 361,10 353,17 @@ confinit(void)

GPIOregs *gpioregs;
ulong *egpioreg = (ulong*)EGPIOREGS;
PPCregs *ppcregs;
MemConfRegs *memconfregs;
PowerRegs *powerregs;

static void
gpioinit(void)
/*
 *  configure the machine
 */
void
machinit(void)
{
	/* set direction of SA1110 io pins and select alternate functions for some */
	gpioregs = mapspecial(GPIOREGS, 32);
	gpioregs->direction = 
		GPIO_LDD8_o|GPIO_LDD9_o|GPIO_LDD10_o|GPIO_LDD11_o


@@ 379,32 378,23 @@ gpioinit(void)
		|GPIO_LDD12_o|GPIO_LDD13_o|GPIO_LDD14_o|GPIO_LDD15_o
		|GPIO_SSP_CLK_i;

	/* map in special H3650 io pins */
	egpioreg = mapspecial(EGPIOREGS, 4);
}

PPCregs *ppcregs;

static void
ppcinit(void) {
	/* map in peripheral pin controller (ssp will need it) */
	ppcregs = mapspecial(PPCREGS, 32);
}

MCPregs *mcpregs;
	/* SA1110 power management */
	powerregs = mapspecial(POWERREGS, 32);

static void
mcpinit(void) {
	mcpregs = mapspecial(MCPREGS, 0x34);
	mcpregs->status &= ~(1<<16);
	/* Turn MCP operations off */
	/* memory configuraton */
	memconfregs = mapspecial(MEMCONFREGS, 32);
}

SSPregs *sspregs;

static void
sspinit(void) {
	sspregs = mapspecial(SSPREGS, 32);
}

/*
 *  manage egpio bits
 */
static ulong egpiosticky;

void


@@ 458,11 448,3 @@ flashprogpower(int on)
{
	egpiobits(EGPIO_prog_flash, on);
}

void
exppackpower(int on)
{
	egpiobits(EGPIO_exp_full_power|EGPIO_exp_nvram_power, on);
	if(on)
		delay(100);
}

M bitsy/mem.h => bitsy/mem.h +5 -3
@@ 94,7 94,6 @@
/*
 *  peripheral control module physical addresses
 */
#define LCDREGS		0xB0100000	/* display */
#define USBREGS		0x80000000	/* serial port 0 - USB */
#define UART1REGS	0x80010000	/* serial port 1 - UART */
#define GPCLKREGS	0x80020060	/* serial port 1 - general purpose clock */


@@ 103,10 102,13 @@
#define UART3REGS	0x80050000	/* serial port 3 - RS232 UART */
#define MCPREGS		0x80060000	/* serial port 4 - multimedia comm port */
#define SSPREGS		0x80070060	/* serial port 4 - synchronous serial port */
#define PPCREGS		0x90060000	/* peripheral pin controller */
#define OSTIMERREGS	0x90000000	/* operating system timer registers */
#define POWERREGS	0x90020000	/* power management */
#define GPIOREGS	0x90040000	/* 28 general purpose IO pins */
#define INTRREGS	0x90050000	/* interrupt registers */
#define OSTIMERREGS	0x90000000	/* operating system timer registers */
#define PPCREGS		0x90060000	/* peripheral pin controller */
#define MEMCONFREGS	0xA0000000	/* memory configuration */
#define LCDREGS		0xB0100000	/* display */

/*
 *  PCMCIA addresses

M bitsy/mmu.c => bitsy/mmu.c +11 -3
@@ 211,10 211,18 @@ mapspecial(ulong pa, int len)

/* map add on memory */
void*
mapmem(ulong pa, int len)
mapmem(ulong pa, int len, int cached)
{
	return _map(pa, len, EMEMZERO, EMEMTOP, L1KernelRW|L1Cached|L1Buffered,
			L2KernelRW|L2Cached|L2Buffered);
	ulong l1, l2;

	if(cached){
		l1 = L1KernelRW|L1Cached|L1Buffered;
		l2 = L2KernelRW|L2Cached|L2Buffered;
	} else {
		l1 = L1KernelRW;
		l2 = L2KernelRW;
	}
	return _map(pa, len, EMEMZERO, EMEMTOP, l1, l2);
}

/* map a virtual address to a physical one */

M bitsy/sa1110uart.c => bitsy/sa1110uart.c +0 -11
@@ 10,17 10,6 @@

/* this isn't strictly a sa1100 driver.  The rts/cts stuff is h3650 specific */

/* hardware registers */
typedef struct Uartregs Uartregs;
struct Uartregs
{
	ulong	ctl[4];
	ulong	dummya;
	ulong	data;
	ulong	dummyb;
	ulong	status[2];
};

enum
{
	/* ctl[0] bits */

M bitsy/trap.c => bitsy/trap.c +4 -3
@@ 179,7 179,7 @@ trap(Ureg *ureg)
	int found;
	Vctl *v;
	int user, x, rv;
	ulong va;
	ulong va, fsr;
	char buf[ERRLEN];

	user = (ureg->psr & PsrMask) == PsrMusr;


@@ 217,7 217,8 @@ trap(Ureg *ureg)
	case PsrMabt+1:	/* data fault */
		va = getfar();
		inst = *(ulong*)(ureg->pc);
		switch(getfsr() & 0xf){
		fsr = getfsr() & 0xf;
		switch(fsr){
		case 0x0:
			panic("vector exception at %lux\n", ureg->pc);
			break;


@@ 239,7 240,7 @@ trap(Ureg *ureg)
		case 0xa:
		case 0xc:
		case 0xe:
			panic("external abort at %lux\n", ureg->pc);
			panic("external abort 0x%ux pc 0x%lux addr 0x%lux\n", fsr, ureg->pc, va);
			break;
		case 0x5:
		case 0x7:

M ip/il.c => ip/il.c +1 -1
@@ 58,7 58,7 @@ enum
	AckDelay	= 2*Iltickms,	/* max time twixt message rcvd & ack sent */
	MaxTimeout 	= 30*Seconds,	/* max time between rexmit */
	QueryTime	= 10*Seconds,	/* time between subsequent queries */
	DeathTime	= 5*QueryTime,
	DeathTime	= 30*QueryTime,

	MaxRexmit 	= 16,		/* max retransmissions before hangup */
	Defaultwin	= 20,