diff --git a/sys/arm/sa11x0/sa11x0.c b/sys/arm/sa11x0/sa11x0.c index b9f53eb98fb7..57fc7192bdf3 100644 --- a/sys/arm/sa11x0/sa11x0.c +++ b/sys/arm/sa11x0/sa11x0.c @@ -85,8 +85,7 @@ __FBSDID("$FreeBSD$"); #include #include -extern struct intrhand *irqhandlers[]; -extern u_int levels[]; +extern void sa11x0_activateirqs(void); static struct resource *sa1110_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); @@ -96,10 +95,8 @@ static int sa1110_activate_resource(device_t, device_t, int, int, static int sa1110_setup_intr(device_t, device_t, struct resource *, int, driver_intr_t *, void *, void **); -extern u_int irqmasks[]; +struct sa11x0_softc *sa11x0_softc; /* There can be only one. */ -void irq_setmasks(void); -void intr_calculatemasks(void); static int sa1110_setup_intr(device_t dev, device_t child, struct resource *ires, int flags, driver_intr_t *intr, void *arg, @@ -107,23 +104,16 @@ sa1110_setup_intr(device_t dev, device_t child, { int saved_cpsr; - if (flags & INTR_TYPE_TTY) { + if (flags & INTR_TYPE_TTY) ires->r_start = 15; - irqmasks[IPL_SERIAL] |= 1 << ires->r_start; - } else if (flags & INTR_TYPE_CLK) { + else if (flags & INTR_TYPE_CLK) { if (ires->r_start == 0) ires->r_start = 26; else ires->r_start = 27; - irqmasks[IPL_SERIAL] |= 1 << ires->r_start; } -#if 0 - intr_calculatemasks(); -#endif saved_cpsr = SetCPSR(I32_bit, I32_bit); - set_splmasks(); - irq_setmasks(); SetCPSR(I32_bit, saved_cpsr & I32_bit); BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, intr, arg, cookiep); @@ -173,9 +163,10 @@ sa11x0_attach(device_t dev) int unit = device_get_unit(dev); sc->sc_iot = &sa11x0_bs_tag; + sa11x0_softc = sc; + /* Map the SAIP */ - bzero(irqhandlers, 0x20 * sizeof(void*)); if (bus_space_map(sc->sc_iot, SAIPIC_BASE, SAIPIC_NPORTS, 0, &sc->sc_ioh)) panic("saip%d: Cannot map registers", unit); @@ -240,6 +231,7 @@ sa11x0_attach(device_t dev) device_add_child(dev, "saost", 0); bus_generic_probe(dev); bus_generic_attach(dev); + sa11x0_activateirqs(); return (0); } diff --git a/sys/arm/sa11x0/sa11x0_irq.S b/sys/arm/sa11x0/sa11x0_irq.S index cabeb4065ba5..8f85012c595e 100644 --- a/sys/arm/sa11x0/sa11x0_irq.S +++ b/sys/arm/sa11x0/sa11x0_irq.S @@ -44,13 +44,9 @@ #include #include __FBSDID("$FreeBSD$"); -Lcurrent_spl_level: - .word _C_LABEL(current_spl_level) Lcurrent_intr_depth: .word _C_LABEL(current_intr_depth) -Lspl_masks: - .word _C_LABEL(spl_masks) .globl _C_LABEL(saipic_base) _C_LABEL(saipic_base): .word 0x00000000 @@ -60,7 +56,7 @@ Ldbg_str: .asciz "irq_entry %x %x\n" #endif -AST_ALIGNMENT_FAULT_LOCALS +AST_LOCALS /* * Regsister usage * @@ -71,12 +67,10 @@ AST_ALIGNMENT_FAULT_LOCALS * r10 - Base address of SAIP */ -#define _SPL_LEVELS 13 /* XXX */ ASENTRY_NP(irq_entry) sub lr, lr, #0x00000004 /* Adjust the lr */ PUSHFRAMEINSVC /* Push an interrupt frame */ - ENABLE_ALIGNMENT_FAULTS /* Load r8 with the SAIPIC interrupt requests */ @@ -101,64 +95,10 @@ ASENTRY_NP(irq_entry) add r1, r1, #1 str r1, [r0] - /* - * Need to block all interrupts at the IPL or lower for - * all asserted interrupts. - * This basically emulates hardware interrupt priority levels. - * Means we need to go through the interrupt mask and for - * every asserted interrupt we need to mask out all other - * interrupts at the same or lower IPL. - * If only we could wait until the main loop but we need to sort - * this out first so interrupts can be re-enabled. - * - * This would benefit from a special ffs type routine - */ - - mov r9, #(_SPL_LEVELS - 1) - ldr r7, Lspl_masks -Lfind_highest_ipl: - ldr r2, [r7, r9, lsl #2] - tst r8, r2 - subeq r9, r9, #1 - beq Lfind_highest_ipl - - /* r9 = SPL level of highest priority interrupt */ - add r9, r9, #1 - ldr r2, [r7, r9, lsl #2] - mvn r2, r2 - - ldr r0, Lcurrent_spl_level - ldr r1, [r0] - str r9, [r0] - stmfd sp!, {r1} - - /* Update the SAIP irq masks */ - bl _C_LABEL(irq_setmasks) -#ifdef INTR_DEBUG - stmfd sp!, {r0,r1,r2} - adr r0, Ldbg_str - mov r2, r9 - bl _C_LABEL(printf) - ldmia sp!, {r0,r1,r2} -#endif - mrs r0, cpsr_all /* Enable IRQ's */ - bic r0, r0, #I32_bit - msr cpsr_all, r0 - mov r0, r8 + mov r0, sp + mov r1, r8 bl _C_LABEL(arm_handler_execute) - ldmfd sp!, {r2} - ldr r1, Lcurrent_spl_level - str r2, [r1] - /* Restore previous disabled mask */ - bl _C_LABEL(irq_setmasks) - bl _C_LABEL(dosoftints) /* Handle the soft interrupts */ - - /* Kill IRQ's in preparation for exit */ - mrs r0, cpsr_all - orr r0, r0, #(I32_bit) - msr cpsr_all, r0 - #ifdef INTR_DEBUG adr r0, Ldbg_str mov r1, #3 @@ -172,42 +112,24 @@ Lfind_highest_ipl: sub r1, r1, #1 str r1, [r0] - DO_AST_AND_RESTORE_ALIGNMENT_FAULTS + DO_AST PULLFRAMEFROMSVCANDEXIT /* NOT REACHED */ b . - 8 -ENTRY(irq_setmasks) - /* Disable interrupts */ - mrs r3, cpsr_all - orr r1, r3, #(I32_bit) - msr cpsr_all, r1 - - /* Calculate interrupt mask */ - ldr r0, Lspl_masks - ldr r2, Lcurrent_spl_level - ldr r2, [r2] - ldr r2, [r0, r2, lsl #2] - ldr r0, _C_LABEL(saipic_base) - str r2, [r0, #(SAIPIC_MR)] /* Set mask register */ - - /* Restore old cpsr and exit */ - /* msr cpsr_all, r3 XXX: not now.*/ - mov pc, lr Lcnt: .word _C_LABEL(cnt) +ENTRY(sa11x0_activateirqs) + ldr r0, _C_LABEL(saipic_base) + mov r1, #0xffffffff + str r1, [r0, #(SAIPIC_MR)] + mov pc, lr #ifdef IRQSTATS Lintrcnt: .word _C_LABEL(intrcnt) #endif -Lirqhandlers: - .word _C_LABEL(irqhandlers) /* Pointer to array of irqhandlers */ - - - - .global _C_LABEL(intrnames), _C_LABEL(eintrnames) .global _C_LABEL(eintrcnt) _C_LABEL(intrnames): diff --git a/sys/arm/sa11x0/sa11x0_irqhandler.c b/sys/arm/sa11x0/sa11x0_irqhandler.c index 5b7e430ee1da..c7e4030864ab 100644 --- a/sys/arm/sa11x0/sa11x0_irqhandler.c +++ b/sys/arm/sa11x0/sa11x0_irqhandler.c @@ -93,141 +93,48 @@ __FBSDID("$FreeBSD$"); #include #include +#include #define NIRQS 0x20 struct intrhand *irqhandlers[NIRQS]; int current_intr_depth; -u_int actual_mask; -#define IPL_LEVELS 13 -#ifdef hpcarm -#define IPL_LEVELS (NIPL+1) -u_int imask[NIPL]; -#else -u_int spl_mask; -u_int irqmasks[IPL_LEVELS]; -#endif -u_int irqblock[NIRQS]; -u_int levels[IPL_LEVELS]; +extern struct sa11x0_softc *sa11x0_softc; -extern void set_spl_masks(void); -#if 0 -static int fakeintr(void *); -#endif -#ifdef DEBUG -static int dumpirqhandlers(void); -#endif - /* Recalculate the interrupt masks from scratch. * We could code special registry and deregistry versions of this function that * would be faster, but the code would be nastier, and we don't expect this to * happen very much anyway. */ -void intr_calculatemasks(void); -void -intr_calculatemasks(void) -{ - int irq; - int intrlevel[ICU_LEN]; - int level; +int +arm_get_irqnb(void *frame) +{ + struct sa11x0_softc *sc = sa11x0_softc; - /* First, figure out which levels each IRQ uses. */ - for (irq = 0; irq < ICU_LEN; irq++) { - intrlevel[irq] = levels[irq]; - } - /* Then figure out which IRQs use each level. */ -#ifdef hpcarm - for (level = 0; level < NIPL; level++) { -#else - for (level = 0; level <= IPL_LEVELS; level++) { -#endif - int irqs = 0; - for (irq = 0; irq < ICU_LEN; irq++) { - if (intrlevel[irq] & (1 << level)) { - irqs |= 1 << irq; - } - } -#ifdef hpcarm - - imask[level] = irqs; -#else - irqmasks[level] = irqs; - printf("level %d set to %x\n", level, irqs); -#endif - } - /* - * Enforce a hierarchy that gives slow devices a better chance at not - * dropping data. - */ -#ifdef hpcarm - for (level = NIPL - 1; level > 0; level--) - imask[level - 1] |= imask[level]; -#else - for (level = IPL_LEVELS; level > 0; level--) - irqmasks[level - 1] |= irqmasks[level]; -#endif - /* - * Calculate irqblock[], which emulates hardware interrupt levels. - */ -#if 0 - for (irq = 0; irq < ICU_LEN; irq++) { - int irqs = 1 << irq; - for (q = irqhandlers[irq]; q; q = q->ih_next) -#ifdef hpcarm - irqs |= ~imask[q->ih_level]; -#else - irqs |= ~irqmasks[q->ih_level]; -#endif - irqblock[irq] = irqs; - } -#endif + return(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SAIPIC_IP)); } - -const struct evcnt *sa11x0_intr_evcnt(sa11x0_chipset_tag_t, int); + +void +arm_mask_irqs(int irq) +{ + /* XXX */ +} + +void +arm_unmask_irqs(int irq) +{ + /* XXX */ +} + void stray_irqhandler(void *); -const struct evcnt * -sa11x0_intr_evcnt(sa11x0_chipset_tag_t ic, int irq) -{ - - /* XXX for now, no evcnt parent reported */ - return NULL; -} - void stray_irqhandler(void *p) { printf("stray interrupt %p\n", p); - printf("bla\n"); } - -#if 0 -int -fakeintr(void *p) -{ - - return 0; -} -#endif -#ifdef DEBUG -int -dumpirqhandlers() -{ - int irq; - struct irqhandler *p; - - for (irq = 0; irq < ICU_LEN; irq++) { - printf("irq %d:", irq); - p = irqhandlers[irq]; - for (; p; p = p->ih_next) - printf("ih_func: 0x%lx, ", (unsigned long)p->ih_func); - printf("\n"); - } - return 0; -} -#endif /* End of irqhandler.c */ diff --git a/sys/arm/sa11x0/std.sa11x0 b/sys/arm/sa11x0/std.sa11x0 index f95a815df476..3cf84655c97d 100644 --- a/sys/arm/sa11x0/std.sa11x0 +++ b/sys/arm/sa11x0/std.sa11x0 @@ -3,3 +3,5 @@ files "../sa11x0/files.sa11x0" cpu CPU_SA1100 cpu CPU_SA1110 +makeoptions KERNPHYSADDR=0xc0000000 +makeoptions KERNVIRTADDR=0xc0000000