/*
 * Copyright (c) 2010-2014 Wind River Systems, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file
 * @brief Interrupt management support for IA-32 arch
 *
 * This module provides routines to manage asynchronous interrupts
 * on the IA-32 architecture.
 *
 * INTERNAL
 * The _idt_base_address symbol is used to determine the base address of the IDT.
 * (It is generated by the linker script, and doesn't correspond to an actual
 * global variable.)
 *
 * Dynamic interrupts are handled by a set of dynamic interrupt stubs defined
 * in intstub.S. Each one pushes a "stub id" onto the stack and calls
 * common_dynamic_handler, which uses the stub id to pull the details
 * about what to do with the dynamic IRQ out of the dyn_irq_list array.
 * This array is populated by calls to irq_connect_dynamic(), which also
 * installs the associated dynamic stub in the IDT.
 */


#include <nanokernel.h>
#include <arch/cpu.h>
#include <nano_private.h>
#include <misc/__assert.h>
#include <idtEnt.h>
#include <misc/printk.h>
#include <irq.h>

extern void _SpuriousIntHandler(void *);
extern void _SpuriousIntNoErrCodeHandler(void *);

/*
 * These 'dummy' variables are used in nanoArchInit() to force the inclusion of
 * the spurious interrupt handlers. They *must* be declared in a module other
 * than the one they are used in to get around garbage collection issues and
 * warnings issued some compilers that they aren't used. Therefore care must
 * be taken if they are to be moved. See nano_private.h for more information.
 */
void *_dummy_spurious_interrupt;
void *_dummy_exception_vector_stub;

/*
 * Place the addresses of the spurious interrupt handlers into the intList
 * section. The genIdt tool can then populate any unused vectors with
 * these routines.
 */
void *__attribute__((section(".spurIsr"))) MK_ISR_NAME(_SpuriousIntHandler) =
	&_SpuriousIntHandler;
void *__attribute__((section(".spurNoErrIsr")))
	MK_ISR_NAME(_SpuriousIntNoErrCodeHandler) =
		&_SpuriousIntNoErrCodeHandler;

#if CONFIG_DEBUG_IRQS
/**
 *
 * @brief Dump out the IDT for debugging purposes
 *
 * The IDT has a strange structure which confounds direct examination in
 * a debugger. This function will print out its contents in human-readable
 * form. If unused, gc-sections will strip this function from the binary.
 */
void irq_debug_dump_idt(void)
{
	int i;
	IDT_ENTRY *idt = (IDT_ENTRY *)_idt_base_address;

	printk("Installed interrupt handlers (spurious omitted):\n");
	for (i = 0; i < CONFIG_IDT_NUM_VECTORS; i++) {
		uint32_t addr = idt[i].offset_low + (idt[i].offset_high << 16);

		if ((void *)addr == &_SpuriousIntNoErrCodeHandler ||
		    (void *)addr == &_SpuriousIntHandler) {
			continue;
		}

		printk("IDT 0x%x: CS=0x%x ADDR=0x%x DPL=0x%x ",
			 i, idt[i].segment_selector, addr,
			 idt[i].dpl);
		if (idt[i].present) {
			printk("present ");
		}

		if (idt[i].gate_size) {
			printk("32-bit ");
		} else {
			printk("16-bit ");
		}

		switch (idt[i].type) {
		case 0x5:
			printk("task gate");
			break;
		case 0x6:
			printk("IRQ gate");
			break;
		case 0x7:
			printk("trap gate");
			break;
		default:
			printk("Garbage type (0x%x)", idt[i].type);
			break;
		}
		printk("\n");
	}
}
#endif

/**
 *
 * @brief Connect a routine to an interrupt vector
 *
 * @param vector interrupt vector: 0 to 255 on IA-32
 * @param routine a function pointer to the interrupt routine
 * @param dpl priv level for interrupt-gate descriptor
 *
 * This routine "connects" the specified <routine> to the specified interrupt
 * <vector>.  On the IA-32 architecture, an interrupt vector is a value from
 * 0 to 255.  This routine merely fills in the appropriate interrupt
 * descriptor table (IDT) with an interrupt-gate descriptor such that <routine>
 * is invoked when interrupt <vector> is asserted.  The <dpl> argument specifies
 * the privilege level for the interrupt-gate descriptor; (hardware) interrupts
 * and exceptions should specify a level of 0, whereas handlers for user-mode
 * software generated interrupts should specify 3.
 *
 * @return N/A
 *
 * INTERNAL
 * Unlike nanoCpuExcConnect() and irq_connect_dynamic(), the _IntVecSet() routine
 * is a very basic API that simply updates the appropriate entry in Interrupt
 * Descriptor Table (IDT) such that the specified routine is invoked when the
 * specified interrupt vector is asserted.
 *
 */

void _IntVecSet(unsigned int vector, void (*routine)(void *), unsigned int dpl)
{
	unsigned long long *pIdtEntry;
	unsigned int key;

	/*
	 * The <vector> parameter must be less than the value of the
	 * CONFIG_IDT_NUM_VECTORS configuration parameter, however,
	 * explicit validation will not be performed in this primitive.
	 */

	pIdtEntry = (unsigned long long *)(_idt_base_address + (vector << 3));

	/*
	 * Lock interrupts to protect the IDT entry to which _IdtEntryCreate()
	 * will write.  They must be locked here because the _IdtEntryCreate()
	 * code is shared with the 'gen_idt' host tool.
	 */

	key = irq_lock();
	_IdtEntCreate(pIdtEntry, routine, dpl);

#ifdef CONFIG_MVIC
	/* Some nonstandard interrupt controllers may be doing some IDT
	 * caching for performance reasons and need the IDT reloaded if
	 * any changes are made to it
	 */
	__asm__ volatile ("lidt _Idt");
#endif

	irq_unlock(key);
}

#if ALL_DYN_IRQ_STUBS > 0
/*
 * _interrupt_vectors_allocated[] is generated by the 'gen_idt' tool. It is
 * initialized to identify which interrupts have been statically connected
 * and which interrupts are available to be dynamically connected at run time.
 * The variable itself is defined in the linker file.
 */
extern unsigned int _interrupt_vectors_allocated[];

/*
 * Guard against situations when ALL_DYN_IRQ_STUBS is left equal to 0,
 * but irq_connect_dynamic is still used, which causes system failure.
 * If ALL_DYN_IRQ_STUBS is left 0, but irq_connect_dynamic is used, linker
 * generates an error
 */
struct dyn_irq_info {
	/** IRQ handler */
	void (*handler)(void *param);
	/** Parameter to pass to the handler */
	void *param;
};

/*
 * Instead of creating a large sparse table mapping all possible IDT vectors
 * to dyn_irq_info, the dynamic stubs push a "stub id" onto the stack
 * which is used by common_dynamic_handler() to fetch the appropriate
 * information out of this much smaller table
 */
static struct dyn_irq_info dyn_irq_list[ALL_DYN_IRQ_STUBS];
static unsigned int next_irq_stub;

/* Memory address pointing to where in ROM the code for the dynamic stubs are */
extern void *_DynIntStubsBegin;

/**
 *
 * @brief Connect a C routine to a hardware interrupt
 *
 * @param irq virtualized IRQ to connect to
 * @param priority requested priority of interrupt
 * @param routine the C interrupt handler
 * @param parameter parameter passed to C routine
 * @param flags IRQ flags
 *
 * This routine connects an interrupt service routine (ISR) coded in C to
 * the specified hardware <irq>.  An interrupt vector will be allocated to
 * satisfy the specified <priority>.
 *
 * The specified <irq> represents a virtualized IRQ, i.e. it does not
 * necessarily represent a specific IRQ line on a given interrupt controller
 * device.  The platform presents a virtualized set of IRQs from 0 to N, where
 * N is the total number of IRQs supported by all the interrupt controller
 * devices on the board.  See the platform's documentation for the mapping of
 * virtualized IRQ to physical IRQ.
 *
 * When the device asserts an interrupt on the specified <irq>, a switch to
 * the interrupt stack is performed (if not already executing on the interrupt
 * stack), followed by saving the integer (i.e. non-floating point) thread of
 * the currently executing task, fiber, or ISR.  The ISR specified by <routine>
 * will then be invoked with the single <parameter>.  When the ISR returns, a
 * context switch may occur.
 *
 * On some platforms <flags> parameter needs to be specified to indicate if
 * the irq is triggered by low or high level or by rising or falling edge.
 *
 * The routine searches for the first available element in the dynamic_stubs
 * array and uses it for the stub.
 *
 * @return the allocated interrupt vector
 *
 * WARNINGS
 * This routine does not perform range checking on the requested <priority>
 * and thus, depending on the underlying interrupt controller, may result
 * in the assignment of an interrupt vector located in the reserved range of
 * the processor.
 *
 * INTERNAL
 * For debug kernels, this routine shall return -1 when there are no
 * vectors remaining in the specified <priority> level.
 */

int _arch_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;
}


/**
 * @brief Common dynamic IRQ handler function
 *
 * This gets called by _DynStubCommon with the stub index supplied as
 * an argument. Look up the required information in dyn_irq_list and
 * execute it.
 *
 * @param stub_idx Index into the dyn_irq_list array
 */
void _common_dynamic_irq_handler(uint32_t stub_idx)
{
	dyn_irq_list[stub_idx].handler(dyn_irq_list[stub_idx].param);
}

/**
 * @internal
 *
 * @brief Set the handler in an already connected stub
 *
 * This routine is used to modify an already fully constructed interrupt stub
 * to specify a new <routine> and/or <parameter>. This only works with
 * dynamic interrupt stubs.
 */
void _irq_handler_set(unsigned int vector, void (*routine)(void *parameter),
		      void *parameter)
{
	int key;
	uint8_t stub_idx;

	/*
	 * Disable IRQs so we can ensure that the associated interrupt
	 * doesn't run in an inconsistent state while we're doing this
	 */
	key = irq_lock();

	stub_idx = _stub_idx_from_vector(vector);

	__ASSERT(stub_idx < ALL_DYN_IRQ_STUBS, "Bad stub index");

	dyn_irq_list[stub_idx].handler = routine;
	dyn_irq_list[stub_idx].param = parameter;
	irq_unlock(key);
}


/**
 *
 * @brief Allocate a free interrupt vector given <priority>
 *
 * This routine scans the _interrupt_vectors_allocated[] array for a free vector
 * that satisfies the specified <priority>.  It is a utility function for use
 * only by the interrupt controller's _SysIntVecAlloc() routine.
 *
 * This routine assumes that the relationship between interrupt priority and
 * interrupt vector is :
 *
 *      priority = (vector / 16) - 2;
 *
 * Vectors 0 to 31 are reserved for CPU exceptions and do NOT fall under
 * the priority scheme. The first vector used for priority level 0 will be 32.
 *
 * Each interrupt priority level  contains 16 vectors, and the prioritization
 * of interrupts within a priority  level is determined by the vector number;
 * the higher the vector number, the higher the priority within that priority
 * level.
 *
 * It is also assumed that the interrupt controllers are capable of managing
 * interrupt requests on a per-vector level as opposed to a per-priority level.
 * For example, the local APIC on Pentium4 and later processors, the in-service
 * register (ISR) and the interrupt request register (IRR) are 256 bits wide.
 *
 * @return allocated interrupt vector
 *
 * INTERNAL
 * For debug kernels, this routine shall return -1 when there are no
 * vectors remaining in the specified <priority> level.
 */

int _IntVecAlloc(unsigned int requested_priority)
{
	unsigned int key;
	unsigned int entryToScan;
	unsigned int fsb; /* first set bit in entry */
	unsigned int search_set;
	int vector_block;
	int vector;

	static unsigned int mask[2] = {0x0000ffff, 0xffff0000};

	vector_block = requested_priority + 2;

	__ASSERT(((vector_block << 4) + 15) <= CONFIG_IDT_NUM_VECTORS,
		 "IDT too small (%d entries) to use priority %d",
		 CONFIG_IDT_NUM_VECTORS, requested_priority);

	/*
	 * Atomically allocate a vector from the _interrupt_vectors_allocated[]
	 * array to prevent race conditions with other tasks/fibers attempting
	 * to allocate an interrupt vector.
	 *
	 * Note: As _interrupt_vectors_allocated[] is initialized by the 'gen_idt'
	 * tool, it is critical that this routine use the same algorithm as the
	 * 'gen_idt' tool for allocating interrupt vectors.
	 */

	entryToScan = vector_block >> 1;

	/*
	 * The _interrupt_vectors_allocated[] entry indexed by 'entryToScan' is a
	 * 32-bit quantity and thus represents the vectors for a pair of priority
	 * levels. Mask out the unwanted priority level and then use find_lsb_set()
	 * to scan for an available vector of the requested priority.
	 *
	 * Note that find_lsb_set() returns bit position from 1 to 32,
	 * or 0 if the argument is zero.
	 */

	key = irq_lock();

	search_set = mask[vector_block & 1] & _interrupt_vectors_allocated[entryToScan];
	fsb = find_lsb_set(search_set);

	__ASSERT(fsb != 0, "No remaning vectors for priority level %d",
		 requested_priority);

	/*
	 * An available vector of the requested priority was found.
	 * Mark it as allocated.
	 */

	--fsb;
	_interrupt_vectors_allocated[entryToScan] &= ~(1 << fsb);

	irq_unlock(key);

	/* compute vector given allocated bit within the priority level */

	vector = (entryToScan << 5) + fsb;

	return vector;
}

/**
 *
 * @brief Mark interrupt vector as allocated
 *
 * This routine is used to "reserve" an interrupt vector that is allocated
 * or assigned by any means other than _IntVecAllocate().  This marks the vector
 * as allocated so that any future invocations of _IntVecAllocate() will not
 * return that vector.
 *
 * @return N/A
 *
 */

void _IntVecMarkAllocated(unsigned int vector)
{
	unsigned int entryToSet = vector / 32;
	unsigned int bitToSet = vector % 32;
	unsigned int imask;

	imask = irq_lock();
	_interrupt_vectors_allocated[entryToSet] &= ~(1 << bitToSet);
	irq_unlock(imask);
}

/**
 *
 * @brief Mark interrupt vector as free
 *
 * This routine is used to "free" an interrupt vector that is allocated
 * or assigned using _IntVecAllocate() or _IntVecMarkAllocated(). This marks the
 * vector as available so that any future allocations can return that vector.
 *
 */

void _IntVecMarkFree(unsigned int vector)
{
	unsigned int entryToSet = vector / 32;
	unsigned int bitToSet = vector % 32;
	unsigned int imask;

	imask = irq_lock();
	_interrupt_vectors_allocated[entryToSet] |= (1 << bitToSet);
	irq_unlock(imask);
}
#endif /* ALL_DYN_IRQ_STUBS > 0 */
