AT91RM9200 and possibly other ARM targets are broken in 8-current after recent commit

Hans Petter Selasky hselasky at c2i.net
Sun Apr 20 15:01:48 UTC 2008


Hi John,

I'm sorry to say that a recent patch done by you has broken at least the 
AT91RM9200 target in 8-current.

http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/arm/arm/intr.c.diff?r1=1.19;r2=1.20

I spent spent several hours today scratching my head why the platform didn't 
boot. I added a couple of prints into the code:

void
arm_handler_execute(struct trapframe *frame, int irqnb)
{
        struct intr_event *event;
        struct thread *td = curthread;
        int i;
        
        PCPU_INC(cnt.v_intr);
        td->td_intr_nesting_level++;
        while ((i = arm_get_next_irq()) != -1) {
                intrcnt[intrcnt_tab[i]]++;
                event = intr_events[i];
XXX                printf("i%u", i);
                if (intr_event_handle(event, frame) != 0) {
                        /* XXX: Log stray IRQs */
                        arm_mask_irq(i);
                }
        }
        td->td_intr_nesting_level--;
}

void
arm_mask_irq(uintptr_t nb)
{
XXX        printf("m%u\n", (uint8_t *)nb - (uint8_t *)0);
        bus_space_write_4(at91_softc->sc_st,
            at91_softc->sc_sys_sh, IC_IDCR, 1 << nb);
 
}

void
arm_unmask_irq(uintptr_t nb)
{
XXX        printf("u%u\n", (uint8_t *)nb - (uint8_t *)0);
        bus_space_write_4(at91_softc->sc_st,
        at91_softc->sc_sys_sh, IC_IECR, 1 << nb);
        bus_space_write_4(at91_softc->sc_st, at91_softc->sc_sys_sh,
            IC_EOICR, 0);
 
}

All I get during bootup is "i1". Then the platform hangs. By modifying 
the "arm_handler_execute" things work again:

void
arm_handler_execute(struct trapframe *frame, int irqnb)
{
        struct intr_event *event;
        struct thread *td = curthread;
        int i;
                
        PCPU_INC(cnt.v_intr);
        td->td_intr_nesting_level++;
        while ((i = arm_get_next_irq()) != -1) {
                intrcnt[intrcnt_tab[i]]++;
                event = intr_events[i];
XXX                arm_mask_irq(i);
                if (intr_event_handle(event, frame) != 0) {
                        /* XXX: Log stray IRQs */
                }
XXX                arm_unmask_irq(i);
        }
        td->td_intr_nesting_level--;
}

I understand that the mask and unmask functions should be called by the 
factored out code, but they are not called in the same manner like before.

How can we fix this ?

--HPS


More information about the freebsd-arm mailing list