exception_t decodeIRQControlInvocation(word_t invLabel, word_t length, cte_t *srcSlot, extra_caps_t excaps, word_t *buffer) { if (invLabel == IRQIssueIRQHandler) { word_t index, depth, irq_w; irq_t irq; cte_t *destSlot; cap_t cnodeCap; lookupSlot_ret_t lu_ret; exception_t status; if (length < 3 || excaps.excaprefs[0] == NULL) { current_syscall_error.type = seL4_TruncatedMessage; return EXCEPTION_SYSCALL_ERROR; } irq_w = getSyscallArg(0, buffer); irq = (irq_t) irq_w; index = getSyscallArg(1, buffer); depth = getSyscallArg(2, buffer); cnodeCap = excaps.excaprefs[0]->cap; status = Arch_checkIRQ(irq); if (status != EXCEPTION_NONE) { return status; } if (isIRQActive(irq)) { current_syscall_error.type = seL4_RevokeFirst; userError("Rejecting request for IRQ %u. Already active.", (int)irq); return EXCEPTION_SYSCALL_ERROR; } lu_ret = lookupTargetSlot(cnodeCap, index, depth); if (lu_ret.status != EXCEPTION_NONE) { userError("Target slot for new IRQ Handler cap invalid: cap %lu, IRQ %u.", getExtraCPtr(buffer, 0), (int)irq); return lu_ret.status; } destSlot = lu_ret.slot; status = ensureEmptySlot(destSlot); if (status != EXCEPTION_NONE) { userError("Target slot for new IRQ Handler cap not empty: cap %lu, IRQ %u.", getExtraCPtr(buffer, 0), (int)irq); return status; } setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart); return invokeIRQControl(irq, destSlot, srcSlot); } else { return Arch_decodeIRQControlInvocation(invLabel, length, srcSlot, excaps, buffer); } }
static exception_t Arch_invokeIRQControl(irq_t irq, cte_t *handlerSlot, cte_t *controlSlot, x86_irq_state_t irqState) { updateIRQState(irq, irqState); return invokeIRQControl(irq, handlerSlot, controlSlot); }