/*
 * Copyright (c) 2015 Intel Corporation
 *
 * 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 common dynamic irq/exception-relation functions for IA-32 arch
 */

#include <nanokernel.h>
#include <arch/cpu.h>
#include <nano_private.h>

#if ALL_DYN_STUBS > 0

/**
 * @brief Allocate dynamic interrupt stub
 *
 * @param sp Pointer to integer tracking stub allocation
 * @param limit Max number of stubs to allow
 * @return index of the first available element of the STUB array or -1
 *          if all elements are used
 */
int _stub_alloc(unsigned int *sp, unsigned int limit)
{
	int rv, key;

	key = irq_lock();
	if (*sp == limit) {
		rv = -1;
	} else {
		rv = (*sp)++;
	}
	irq_unlock(key);

	return rv;
}

/**
 * @brief Get the memory address of an unused dynamic IRQ or exception stub
 *
 * We generate at build time a set of dynamic stubs which push
 * a stub index onto the stack for use as an argument by
 * common handling code. These don't each have individual labels,
 * but it's possible to compute an offset to any particular one
 *
 * @param stub_idx Stub number to fetch the corresponding stub function
 * @param base_ptr Memory location in ROM where stubs begin
 * @return Pointer to the stub code to install into the IDT
 */
void *_get_dynamic_stub(int stub_idx, void *base_ptr)
{
	uint32_t offset;

	/*
	 * Because we want the sizes of the stubs to be consisent and minimized,
	 * stubs are grouped into blocks, each containing a push and subsequent
	 * 2-byte jump instruction to the end of the block, which then contains
	 * a larger jump instruction to common dynamic IRQ handling code
	 */
	offset = (stub_idx * DYN_STUB_SIZE) + ((stub_idx / DYN_STUB_PER_BLOCK) *
					       DYN_STUB_LONG_JMP_EXTRA_SIZE);

	return (void *)((uint32_t)base_ptr + offset);
}


/**
 * @brief Map an IRQ/exception vector back to the corresponding stub index
 *
 * This is used to fetch a reference to a stub when all we have is the IRQ
 * vector.
 *
 * @param IRQ vector as installed in the IDT
 * @return stub index
 */
uint8_t _stub_idx_from_vector(int vector)
{
	IDT_ENTRY *idt_entry;
	uint8_t *stub_addr;

	/*
	 * We need to do a reverse map from the vector number to the stub
	 * index. Look in the IDT for the provided vector and find the memory
	 * address of the handler function, which should be one of
	 * the dynamic stubs
	 */
	idt_entry = (IDT_ENTRY *)(_idt_base_address + (vector << 3));
	stub_addr = (uint8_t *)((uint32_t)idt_entry->offset_low +
		     ((uint32_t)idt_entry->offset_high << 16));

	/*
	 * Return the specific byte in the handler code which contains
	 * the stub index, the argument to the initial push operation
	 */
	return stub_addr[DYN_STUB_IDX_OFFSET];
}

#endif /* ALL_DYN_STUBS */

