int irq_connect_dynamic(unsigned int irq, unsigned int priority, void (*routine)(void *parameter), void *parameter, uint32_t flags) { int vector; int stub_idx; /* * Invoke the interrupt controller routine _SysIntVecAlloc() which will: * a) allocate a vector satisfying the requested priority, * b) create a new entry in the dynamic stub array * c) program the underlying interrupt controller device such that * when <irq> is asserted, the allocated interrupt vector will be * presented to the CPU. * * The _SysIntVecAlloc() routine will use the "utility" routine * _IntVecAlloc() provided in this module to scan the * _interrupt_vectors_allocated[] array for a suitable vector. */ vector = _SysIntVecAlloc(irq, priority, flags); __ASSERT(vector != -1, "Unable to request a vector for irq %d with priority %d", irq, priority); stub_idx = _stub_alloc(&next_irq_stub, ALL_DYN_IRQ_STUBS); __ASSERT(stub_idx != -1, "No available interrupt stubs found"); dyn_irq_list[stub_idx].handler = routine; dyn_irq_list[stub_idx].param = parameter; _IntVecSet(vector, _get_dynamic_stub(stub_idx, &_DynIntStubsBegin), 0); return vector; }
void _NanoCpuExcConnectAtDpl( unsigned int vector, /* interrupt vector: 0 to 255 on IA-32 */ void (*routine)(NANO_ESF * pEsf), unsigned int dpl /* priv level for interrupt-gate descriptor */ ) { int stub_idx, limit, offset; unsigned int *next_p; void *base_ptr; /* * Check to see if this exception type takes an error code, we * have different stubs for that */ if (((1 << vector) & _EXC_ERROR_CODE_FAULTS) == 0) { base_ptr = &_DynExcStubsNoErrBegin; next_p = &next_exc_noerr_stub; limit = CONFIG_NUM_DYNAMIC_EXC_NOERR_STUBS; offset = CONFIG_NUM_DYNAMIC_EXC_STUBS; } else { base_ptr = &_DynExcStubsBegin; next_p = &next_exc_stub; limit = CONFIG_NUM_DYNAMIC_EXC_STUBS; offset = 0; } stub_idx = _stub_alloc(next_p, limit); __ASSERT(stub_idx != -1, "No available execption stubs"); /* * We have the same array for both error code and non error code * exceptions, the second half is reserved for the non error code * handlers */ exc_handlers[stub_idx + offset] = routine; _IntVecSet(vector, _get_dynamic_stub(stub_idx, base_ptr), dpl); }
int irq_connect_dynamic(unsigned int irq, unsigned int priority, void (*routine)(void *parameter), void *parameter, uint32_t flags) { int vector; int stub_idx; /* * Check if the same IRQ was already connected before, in such as case, * simply re-connect the existing stub. */ int i; for (i=0; i<next_irq_stub; ++i) { if (dyn_irq_list[i].irq == irq) { __ASSERT(dyn_irq_list[i].priority == priority, "Non consistent priority"); dyn_irq_list[i].handler = routine; dyn_irq_list[i].param = parameter; _SysIntVecProgram(dyn_irq_list[i].vector, irq, flags); _IntVecSet(dyn_irq_list[i].vector, _get_dynamic_stub(i, &_DynIntStubsBegin), 0); return dyn_irq_list[i].vector; } } /* * Invoke the interrupt controller routine _SysIntVecAlloc() which will: * a) allocate a vector satisfying the requested priority, * b) create a new entry in the dynamic stub array * c) program the underlying interrupt controller device such that * when <irq> is asserted, the allocated interrupt vector will be * presented to the CPU. * * The _SysIntVecAlloc() routine will use the "utility" routine * _IntVecAlloc() provided in this module to scan the * _interrupt_vectors_allocated[] array for a suitable vector. */ vector = _SysIntVecAlloc(irq, priority, flags); #if defined(DEBUG) /* * The return value from _SysIntVecAlloc() will be -1 if an invalid * <irq> or <priority> was specified, or if a vector could not be * allocated to honour the requested priority (for the boards that can * support programming the interrupt vector for each IRQ). */ if (vector == -1) return (-1); #endif /* DEBUG */ stub_idx = _stub_alloc(&next_irq_stub, ALL_DYN_IRQ_STUBS); __ASSERT(stub_idx != -1, "No available interrupt stubs found"); dyn_irq_list[stub_idx].handler = routine; dyn_irq_list[stub_idx].param = parameter; dyn_irq_list[stub_idx].vector = vector; dyn_irq_list[stub_idx].irq = irq; dyn_irq_list[stub_idx].priority = priority; _IntVecSet(vector, _get_dynamic_stub(stub_idx, &_DynIntStubsBegin), 0); return vector; }