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 } }
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); } }