~kris/9p

9hist

810ca0fa3a0cc3e9ec2ae16430ad1b73b3a9e24d — David du Colombier 25 years ago 206dacd
Plan 9 from Bell Labs 2000-10-01
4 files changed, 158 insertions(+), 25 deletions(-)

M bitsy/io.h
M bitsy/l.s
M bitsy/mem.h
M bitsy/trap.c
M bitsy/io.h => bitsy/io.h +74 -0
@@ 3,3 3,77 @@
 */
typedef struct Uartregs Uartregs;
Uartregs *uart3regs;

/*
 *  IRQ's defined by SA1100
 */
enum
{
	IRQgpio0=	0,
	IRQgpio1=	1,
	IRQgpio2=	2,
	IRQgpio3=	3,
	IRQgpio4=	4,
	IRQgpio5=	5,
	IRQgpio6=	6,
	IRQgpio7=	7,
	IRQgpio8=	8,
	IRQgpio9=	9,
	IRQgpio10=	10,
	IRQgpiohi=	11,
	IRQlcd=		12,
	IRQudc=		13,
	IRQuart1b=	15,
	IRQuart2=	16,
	IRQuart3=	17,
	IRQmcp=		18,
	IRQssp=		19,
	IRQdma0=	20,
	IRQdma1=	21,
	IRQdma2=	22,
	IRQdma3=	23,
	IRQdma4=	24,
	IRQdma5=	25,
	IRQtimer0=	26,
	IRQtimer1=	27,
	IRQtimer2=	28,
	IRQtimer3=	29,
	IRQsecond=	30,
	IRQrtc=		31,
};

/*
 *  GPIO lines (signal names from compaq document).  _i indicates input
 *  and _o output.
 */
enum
{
	PWR_ON_i=	1<<0,	/* power button */
	UP_IRQ_i=	1<<1,	/* microcontroller interrupts */
	LDD8_o=		1<<2,	/* LCD data 8-15 */
	LDD9_o=		1<<3,
	LDD10_o=	1<<4,
	LDD11_o=	1<<5,
	LDD12_o=	1<<6,
	LDD13_o=	1<<7,
	LDD14_o=	1<<8,
	LDD15_o=	1<<9,
	CARD_IND1_i=	1<<10,	/* card inserted in PCMCIA socket 1 */
	CARD_IRQ1_i=	1<<11,	/* PCMCIA socket 1 interrupt */
	CLK_SET0_o=	1<<12,	/* clock selects for audio codec */
	CLK_SET1_o=	1<<13,
	L3_SDA_io=	1<<14,	/* UDA1341 interface */
	L3_MODE_o=	1<<15,
	L3_SCLK_o=	1<<16,
	CARD_IND0_i=	1<<17,	/* card inserted in PCMCIA socket 0 */
	KEY_ACT_i=	1<<18,	/* hot key from cradle */
	SYS_CLK_i=	1<<19,	/* clock from codec */
	BAT_FAULT_i=	1<<20,	/* battery fault */
	CARD_IRQ0_i=	1<<21,	/* PCMCIA socket 0 interrupt */
	LOCK_i=		1<<22,	/* expansion pack lock/unlock */
	COM_DCD_i=	1<<23,	/* DCD from UART3 */
	OPT_IRQ_i=	1<<24,	/* expansion pack IRQ */
	COM_CTS_i=	1<<25,	/* CTS from UART3 */
	COM_RTS_oi=	1<<26,	/* RTS to UART3 */
	OPT_IND_i=	1<<27,	/* expansion pack inserted */
};

M bitsy/l.s => bitsy/l.s +13 -15
@@ 143,16 143,19 @@ TEXT exceptionvectors(SB), $-4
	MOVW	0x18(R15), R15		/* reserved */
	MOVW	0x18(R15), R15		/* IRQ */
	MOVW	0x18(R15), R15		/* FIQ */
	WORD	$_vsvc(SB)		/* reset, in svc mode already */
	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	$_vpab(SB)		/* prefetch abort, switch to svc mode */
	WORD	$_vdab(SB)		/* data abort, switch to svc mode */
	WORD	$_vsvc(SB)		/* reserved */
	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 _vsvc(SB), $-4			/* reset or SWI or reserved */
TEXT _vrst(SB), $-4
	BL	reset

TEXT _vsvc(SB), $-4			/* SWI */
	SUB	$12, R13		/* make room for pc, psr, & type */
	MOVW	R14, 8(R13)		/* ureg->pc = interupted PC */
	MOVW	SPSR, R14		/* ureg->psr = SPSR */


@@ 167,16 170,11 @@ TEXT _vund(SB), $-4			/* undefined */
	MOVW	$PsrMund, R0
	B	_vswitch

TEXT _vpab(SB), $-4			/* prefetch abort */
TEXT _vabt(SB), $-4			/* prefetch abort */
	MOVM.IA	[R0-R3], (R13)		/* free some working space */
	MOVW	$PsrMabt, R0		/* r0 = type */
	B	_vswitch

TEXT _vdab(SB), $-4			/* data abort */
	MOVM.IA	[R0-R3], (R13)		/* free some working space */
	MOVW	$(PsrMabt+1), R0	/* r0 = type */
	B	_vswitch

TEXT _virq(SB), $-4			/* IRQ */
	MOVM.IA	[R0-R3], (R13)		/* free some working space */
	MOVW	$PsrMirq, R0		/* r0 = type */


@@ 204,13 202,13 @@ _vswitch:				/* switch to svc, type in R0 */
	 *  R13 and R14 are no longer accessible.  That's why R3 was left to point to where
	 *  the old [r0-r3] are stored.
	 */
	MOVM.DB.W [R0-R2], (R13)	/* set ureg->{pc, psr, type}; r13 points to ureg->type  */
	MOVM.DB.W [R0-R2], (R13)	/* set ureg->{type, psr, pc}; r13 points to ureg->type  */
	MOVM.IA	  (R3), [R0-R3]		/* restore [R0-R3] from previous mode's stack */
	MOVM.DB.W.S [R0-R14], (R13)	/* save user level registers, at end r13 points to ureg */

	/*
	 *  if the original interrupt happened while executing SVC mode, the User R14 in the Ureg is
	 *  wrong.  We need to save the SVC one there.
	 *  if the original interrupt happened while executing SVC mode,
	 *  the User R14 in the Ureg is wrong.  We need to save the SVC one there.
	 */
	MOVW	0x40(R13), R1
	AND.S	$0xf, R1


@@ 231,7 229,7 @@ _vrfe:
	MOVW	8(R13), R14		/* restore link */
	MOVW	4(R13), R0		/* restore SPSR */
	MOVW	R0, SPSR		/* ... */
	MOVM.DB.S (R13), [R0-R14]	/* restore registers */
	MOVM.DB.W.S (R13), [R0-R14]	/* restore registers */
	ADD	$8, R13			/* pop past ureg->{type+psr} */
	RFE				/* MOVM.IA.S.W (R13), [R15] */


M bitsy/mem.h => bitsy/mem.h +1 -0
@@ 91,6 91,7 @@
#define SSPREGS		0x80070060	/* serial port 4 - synchronous serial port */
#define PPCREGS		0x90060000	/* peripheral pin controller */
#define GPIOREGS	0x90040000	/* 28 general purpose IO pins */
#define INTRREGS	0x90050000	/* interrupt registers */

/*
 *  Program Status Registers

M bitsy/trap.c => bitsy/trap.c +70 -10
@@ 7,17 7,32 @@
#include	"ureg.h"
#include	"../port/error.h"

/*
 * called in sysfile.c
 */
void
evenaddr(ulong addr)
struct Intrregs
{
	if(addr & 3){
		postnote(up, 1, "sys: odd address", NDebug);
		error(Ebadarg);
	}
}
	ulong	icip;	/* pending IRQs */
	ulong	icmr;	/* IRQ mask */
	ulong	iclr;	/* IRQ if bit == 0, FRIQ if 1 */
	ulong	iccr;	/* control register */
	ulong	icfp;	/* pending FIQs */
	ulong	dummy1[3]
	ulong	icpr;	/* pending interrupts */
	
};

struct Intrregs *intrregs;

typedef struct Vctl {
	Vctl*	next;			/* handlers on this vector */

	char	name[NAMELEN];		/* of driver */
	int	irq;

	void	(*f)(Ureg*, void*);	/* handler to call */
	void*	a;			/* argument to call it with */
} Vctl;

static Lock vctllock;
static Vctl *vctl[32];

/*
 *  set up for exceptioons


@@ 35,6 50,35 @@ trapinit(void)
	 */
	memmove((void*)KZERO, exceptionvectors, 2*4*8);
	wbflush();

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

	/* make all interrupts irq and disable all interrupts */
	intrregs->iclr = 0;
	intrregs->icmr = 0;
}

/*
 *  enable an interrupt and attach a function to i
 */
void
intrenable(int irq, void (*f)(Ureg*, void*), void* a, char *name)
{
	int vno;
	Vctl *v;

	v = xalloc(sizeof(Vctl));
	v->irq = irq;
	v->f = f;
	v->a = a;
	strncpy(v->name, name, NAMELEN-1);
	v->name[NAMELEN-1] = 0;

	lock(&vctllock);
	v->next = vctl[irq];
	vctl[irq] = v;
	unlock(&vctllock);
}

/*


@@ 43,6 87,22 @@ trapinit(void)
void
trap(Ureg *ureg)
{
	switch(ureg->type){
	case PsrMfiq:	/* fast interrupt */
		panic("fiq can't happen");
		break;
	case PsrMabt:	/* fault */
	case PsrMabt+1:	/* fault */
		panic("faults not implemented");
		break;
	case PsrMund:	/* undefined instruction */
		panic("undefined instruction");
		break;
	case PsrMirq:	/* device interrupt */
		break;
	case PsrMsvc:	/* system call */
		break;
	}
}

/* Give enough context in the ureg to produce a kernel stack for