Example #1
0
void handle_irq(arch_registers_state_t* save_area, uintptr_t fault_pc,
                uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3)
{
    uint32_t irq = 0;

    /* The assembly stub leaves the first 4 registers, the stack pointer, and
     * the exception PC for us to save, as it's run out of room for the
     * necessary instructions. */
    save_area->named.x0    = x0;
    save_area->named.x1    = x1;
    save_area->named.x2    = x2;
    save_area->named.x3    = x3;
    save_area->named.stack = sysreg_read_sp_el0();
    save_area->named.pc    = fault_pc;

    irq = gic_get_active_irq();

    debug(SUBSYS_DISPATCH, "IRQ %"PRIu32" while %s\n", irq,
          dcb_current ? (dcb_current->disabled ? "disabled": "enabled") :
                        "in kernel");

    if (dcb_current != NULL) {
        dispatcher_handle_t handle = dcb_current->disp;
        if (save_area == dispatcher_get_disabled_save_area(handle)) {
            assert(dispatcher_is_disabled_ip(handle, fault_pc));
            dcb_current->disabled = true;
        } else {
/*            debug(SUBSYS_DISPATCH,
                  "save_area=%p, dispatcher_get_enabled_save_are(handle)=%p\n",
                   save_area, dispatcher_get_enabled_save_area(handle));
*/

            assert(save_area == dispatcher_get_enabled_save_area(handle));
            assert(!dispatcher_is_disabled_ip(handle, fault_pc));
            dcb_current->disabled = false;
        }
    }

    if (pit_handle_irq(irq)) {
        // Timer interrupt, pit_handle_irq acks it at the timer.
        assert(kernel_ticks_enabled);
        kernel_now += kernel_timeslice;
        wakeup_check(kernel_now);
        dispatch(schedule());
    }
    /* This is the (still) unacknowledged startup interrupt sent by the BSP.
     * We just acknowledge it here. */
    else if(irq == 1)
    {
    	gic_ack_irq(irq);
    	dispatch(schedule());
    }
    else {
        gic_ack_irq(irq);
        send_user_interrupt(irq);
        panic("Unhandled IRQ %"PRIu32"\n", irq);
    }

}
/*
 * \brief Mask and handle timer interrupt.
 * There seems no possibility to disable interrupts directly on the timer device, therefore deactivate timer
 * at pic. Clear interrupt if pending.
 */
void pit_mask_irq(bool masked)
{
    if (masked) {
        pic_set_irq_enabled(PIT_IRQ, 0);
        pit_handle_irq(PIT_IRQ);
    }
    else {
        pic_set_irq_enabled(PIT_IRQ, 1); //Enable timer interrupts
    }
}
Example #3
0
void pit_mask_irq(bool masked, uint8_t pit_id)
{
	 sp804_pit_t *pit;
	 if(pit_id == PIT0_ID)
		 pit = &pit0;
	 else if(pit_id == PIT1_ID)
		 pit = &pit1;
	 else
		 panic("Unsupported PIT ID: %"PRIu32, pit_id);

    if (masked) {
        sp804_pit_Timer1Control_int_enable_wrf(pit, 0);
    }
    else {
        sp804_pit_Timer1Control_int_enable_wrf(pit, 1);
    }

    if (masked) {
        // Clear interrupt if pending.
        pit_handle_irq(pit_id ? PIT1_IRQ : PIT0_IRQ);
    }
}