=================================================================== RCS file: /cvs/funnyos/arch/testarm/dev/tairqc.c,v retrieving revision 1.1 retrieving revision 1.5 diff -u -r1.1 -r1.5 --- funnyos/arch/testarm/dev/tairqc.c 2007/10/29 20:12:18 1.1 +++ funnyos/arch/testarm/dev/tairqc.c 2007/11/02 13:27:42 1.5 @@ -1,23 +1,39 @@ /* - * $Id: tairqc.c,v 1.1 2007/10/29 20:12:18 init Exp $ + * $Id: tairqc.c,v 1.5 2007/11/02 13:27:42 init Exp $ */ #include #include #include +#include #include #include +#include +#define TAIRQC_DEBUG + +#ifdef TAIRQC_DEBUG +#define DPRINTF(x...) do { printf(x); } while (0) +#else +#define DPRINTF(x...) { } +#endif + /* * testarm Interrupt Controller Unit support. */ int tairqc_attach(struct device *self, uint32_t loc, uint8_t flags); +void tairqc_mask_intr(uint8_t intrno); +void tairqc_unmask_intr(uint8_t intrno); +uint32_t tairqc_intrstatus(void); void tairqc_irq(void); +extern void (*irq_trampoline_func)(void); +struct tairqc_dd *irqcdd; /* current irq device */ struct driver tairqc_dr = { sizeof(struct tairqc_dd), tairqc_attach, + NULL, NULL }; @@ -30,17 +46,57 @@ /* leap to parent's bus_handle */ ddp->td_bushandlep = self->dv_parent->dv_aux; - + /* save locator */ + ddp->td_ioaddr = loc ? loc : TAIRQC_REG_BASE; + irqcdd = ddp; + + printf("testarm IRQ Controller (2=cons, 3=ether, 4=rtc, 6=mp)\n"); + + /* override trampoline so core irq jumps to us */ + irq_trampoline_func = tairqc_irq; + + /* XXX unmask rtc intr */ + tairqc_unmask_intr(4); + + return(0); } void +tairqc_mask_intr(uint8_t intrno) +{ + bus_write_1(irqcdd->td_bushandlep, irqcdd->td_ioaddr + TAIRQC_OFF_IRQMASK, intrno); + DPRINTF("tairqc_mask_intr: masked interrupt no. %d (status=0x%x)\n", intrno, tairqc_intrstatus()); +} + + +void +tairqc_unmask_intr(uint8_t intrno) +{ + bus_write_1(irqcdd->td_bushandlep, irqcdd->td_ioaddr + TAIRQC_OFF_IRQUNMASK, intrno); + DPRINTF("tairqc_unmask_intr: unmasked interrupt no. %d (status=0x%x)\n", intrno, tairqc_intrstatus()); +} + + +uint32_t +tairqc_intrstatus(void) +{ + bus_read_4(irqcdd->td_bushandlep, irqcdd->td_ioaddr + TAIRQC_OFF_IRQSTATUS); +} + + +void tairqc_irq(void) { /* - * Process an IRQ + * Process an IRQ. */ + uint32_t irqstatus; + /* read intr status; one bit per intr source */ + irqstatus = tairqc_intrstatus(); + + DPRINTF("tairqc_itq: got interrupt (status=0x%x)\n", irqstatus); }