From 810ca0fa3a0cc3e9ec2ae16430ad1b73b3a9e24d Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 1 Oct 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-10-01 --- bitsy/io.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ bitsy/l.s | 28 +++++++++--------- bitsy/mem.h | 1 + bitsy/trap.c | 80 +++++++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 158 insertions(+), 25 deletions(-) diff --git a/bitsy/io.h b/bitsy/io.h index 021404fb26c8e3f264c9a04a65d8650cfead873d..a86877ea95e72d9eb1492e6deccb6ab65f852f69 100644 --- a/bitsy/io.h +++ b/bitsy/io.h @@ -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 */ +}; diff --git a/bitsy/l.s b/bitsy/l.s index d05c03906fde423e07f2ce3ad845aa0f0755076c..c31fdc7c9917acfff905b6c786e4e764af685bde 100644 --- a/bitsy/l.s +++ b/bitsy/l.s @@ -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] */ diff --git a/bitsy/mem.h b/bitsy/mem.h index 9f6158297476dea12856c357b83efa9a05b36884..169a4a762aff1d61370914ce8a8075bdaf8fa065 100644 --- a/bitsy/mem.h +++ b/bitsy/mem.h @@ -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 diff --git a/bitsy/trap.c b/bitsy/trap.c index bc92a93c67ce5ad334c5b5d217b845b9e30e547e..ce68f19aa574acbd52f909e4ad7fdda6cbda11ec 100644 --- a/bitsy/trap.c +++ b/bitsy/trap.c @@ -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