/*
 * 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)
{
	uint64_t *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 = (uint64_t *)(_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, (uint32_t)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(uint8_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 */
