Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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;
}