/*
 * 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 Floating point resource sharing routines
 *
 * This module allows multiple tasks and fibers to safely share the system's
 * floating point resources, by allowing the system to save FPU state
 * information in a task or fiber's stack region when a pre-emptive context
 * switch occurs.
 *
 * The floating point resource sharing mechanism is designed for minimal
 * intrusiveness.  Floating point thread saving is only performed for tasks and
 * fibers that explicitly enable FP resource sharing, to avoid impacting the
 * stack size requirements of all other tasks and fibers.  For those tasks and
 * fibers that do require FP resource sharing, a "lazy save/restore" mechanism
 * is employed so that the FPU's register sets are only switched in and out
 * when absolutely necessary; this avoids wasting effort preserving them when
 * there is no risk that they will be altered, or when there is no need to
 * preserve their contents.
 *
 * The following APIs are provided to allow floating point resource sharing to
 * be enabled or disabled at run-time:
 *
 * void fiber_float_enable  (nano_thread_id_t thread_id, unsigned int options)
 * void task_float_enable   (nano_thread_id_t thread_id, unsigned int options)
 * void fiber_float_disable (nano_thread_id_t thread_id)
 * void task_float_disable  (nano_thread_id_t thread_id)
 *
 * The 'options' parameter is used to specify what non-integer capabilities are
 * being used.  The same options accepted by fiber_fiber_start() are used in the
 * aforementioned APIs, namely USE_FP and USE_SSE.
 *
 * If the nanokernel has been built without SSE instruction support
 * (CONFIG_SSE), the system treats USE_SSE as if it was USE_FP.
 *
 * If the nanokernel has been built without floating point resource sharing
 * support (CONFIG_FP_SHARING), the aforementioned APIs and capabilities do not
 * exist.
 *
 * NOTE
 * It is possible for a single task or fiber to utilize floating instructions
 * _without_ enabling the FP resource sharing feature.  Since no other task or
 * fiber uses the FPU the FP registers won't change when the FP-capable task or
 * fiber isn't executing, meaning there is no need to save the registers.
 *
 * WARNING
 * The use of floating point instructions by ISRs is not supported by the
 * kernel.
 *
 * INTERNAL
 * If automatic enabling of floating point resource sharing _is not_ configured
 * the system leaves CR0[TS] = 0 for all tasks and fibers.  This means that any
 * task or fiber can perform floating point operations at any time without
 * causing an exception, and the system won't stop a task or fiber that
 * shouldn't be doing FP stuff from doing it.
 *
 * If automatic enabling of floating point resource sharing _is_ configured
 * the system leaves CR0[TS] = 0 only for tasks and fibers that are allowed to
 * perform FP operations.  All other tasks and fibers have CR0[TS] = 1 so that
 * an attempt to perform an FP operation will cause an exception, allowing the
 * system to enable FP resource sharing on its behalf.
 */

#ifdef CONFIG_MICROKERNEL
#include <microkernel.h>
#include <micro_private_types.h>
#endif /* CONFIG_MICROKERNEL */

#include <nano_private.h>
#include <toolchain.h>
#include <asm_inline.h>

/* the entire library vanishes without the FP_SHARING option enabled */

#ifdef CONFIG_FP_SHARING

#if defined(CONFIG_SSE)
extern uint32_t _sse_mxcsr_default_value; /* SSE control/status register default value */
#endif			/* CONFIG_SSE */

/**
 *
 * @brief Save non-integer context information
 *
 * This routine saves the system's "live" non-integer context into the
 * specified TCS.  If the specified task or fiber supports SSE then
 * x87/MMX/SSEx thread info is saved, otherwise only x87/MMX thread is saved.
 *
 * @param tcs TBD
 *
 * @return N/A
 */
static void _FpCtxSave(struct tcs *tcs)
{
	_do_fp_ctx_save(tcs->flags & USE_SSE, &tcs->preempFloatReg);
}

/**
 *
 * @brief Initialize non-integer context information
 *
 * This routine initializes the system's "live" non-integer context.
 *
 * @param tcs TBD
 *
 * @return N/A
 */
static inline void _FpCtxInit(struct tcs *tcs)
{
	_do_fp_ctx_init(tcs->flags & USE_SSE);
}

/**
 *
 * @brief Enable preservation of non-integer context information
 *
 * This routine allows the specified task/fiber (which may be the active
 * task/fiber) to safely share the system's floating point registers with
 * other tasks/fibers.  The <options> parameter indicates which floating point
 * register sets will be used by the specified task/fiber:
 *
 *  a) USE_FP  indicates x87 FPU and MMX registers only
 *  b) USE_SSE indicates x87 FPU and MMX and SSEx registers
 *
 * Invoking this routine creates a floating point thread for the task/fiber
 * that corresponds to an FPU that has been reset.  The system will thereafter
 * protect the task/fiber's FP context so that it is not altered during
 * a pre-emptive context switch.
 *
 * WARNING
 * This routine should only be used to enable floating point support for a
 * task/fiber that does not currently have such support enabled already.
 *
 * @param tcs  TDB
 * @param options set to either USE_FP or USE_SSE
 *
 * @return N/A
 *
 * INTERNAL
 * Since the transition from "non-FP supporting" to "FP supporting" must be done
 * atomically to avoid confusing the floating point logic used by _Swap(),
 * this routine locks interrupts to ensure that a context switch does not occur,
 * The locking isn't really needed when the routine is called by a fiber
 * (since context switching can't occur), but it is harmless and allows a single
 * routine to be called by both tasks and fibers (thus saving code space).
 *
 * If necessary, the interrupt latency impact of calling this routine from a
 * fiber could be lessened by re-designing things so that only task-type callers
 * locked interrupts (i.e. move the locking to task_float_enable()). However,
 * all calls to fiber_float_enable() would need to be reviewed to ensure they
 * are only used from a fiber, rather than from "generic" code used by both
 * tasks and fibers.
 */
void _FpEnable(struct tcs *tcs, unsigned int options)
{
	unsigned int imask;
	struct tcs *fp_owner;

	/* Lock interrupts to prevent a pre-emptive context switch from occuring
	 */

	imask = irq_lock();

	/* Indicate task/fiber requires non-integer context saving */

	tcs->flags |= options | USE_FP; /* USE_FP is treated as a "dirty bit" */

	/*
	 * Current task/fiber might not allow FP instructions, so clear CR0[TS]
	 * so we can use them. (CR0[TS] gets restored later on, if necessary.)
	 */

	__asm__ volatile("clts\n\t");

	/*
	 * Save the existing non-integer context (since it is about to change),
	 * but only if the FPU is "owned" by an FP-capable task that is
	 * currently
	 * handling an interrupt or exception (meaning it's FP context must be
	 * preserved).
	 */

	fp_owner = _nanokernel.current_fp;
	if (fp_owner) {
		if (fp_owner->flags & INT_OR_EXC_MASK) {
			_FpCtxSave(fp_owner);
		}
	}

	/* Now create a virgin FP context */

	_FpCtxInit(tcs);

	/* Associate the new FP context with the specified task/fiber */

	if (tcs == _nanokernel.current) {
		/*
		 * When enabling FP support for self, just claim ownership of
		 *the FPU
		 * and leave CR0[TS] unset.
		 *
		 * (Note: the FP context is "live" in hardware, not saved in TCS.)
		 */

		_nanokernel.current_fp = tcs;
	} else {
		/*
		 * When enabling FP support for someone else, assign ownership
		 * of the FPU to them (unless we need it ourselves).
		 */

		if ((_nanokernel.current->flags & USE_FP) != USE_FP) {
			/*
			 * We are not FP-capable, so mark FPU as owned by the
			 * thread
			 * we've just enabled FP support for, then disable our
			 * own
			 * FP access by setting CR0[TS] to its original state.
			 */

			_nanokernel.current_fp = tcs;
			_FpAccessDisable();
		} else {
			/*
			 * We are FP-capable (and thus had FPU ownership on
			 *entry), so save
			 * the new FP context in their TCS, leave FPU ownership
			 *with self,
			 * and leave CR0[TS] unset.
			 *
			 * Note: The saved FP context is needed in case the task
			 *or fiber
			 * we enabled FP support for is currently pre-empted,
			 *since _Swap()
			 * uses it to restore FP context when the task/fiber
			 *re-activates.
			 *
			 * Note: Saving the FP context reinits the FPU, and thus
			 *our own
			 * FP context, but that's OK since it didn't need to be
			 *preserved.
			 * (i.e. We aren't currently handling an interrupt or
			 *exception.)
			 */

			_FpCtxSave(tcs);
		}
	}

	irq_unlock(imask);
}

/**
 *
 * @brief Enable preservation of non-integer context information
 *
 * This routine allows a fiber to permit a task/fiber (including itself) to
 * safely share the system's floating point registers with other tasks/fibers.
 *
 * See the description of _FpEnable() for further details.
 *
 * @return N/A
 */
FUNC_ALIAS(_FpEnable, fiber_float_enable, void);

/**
 *
 * @brief Enable preservation of non-integer context information
 *
 * This routine allows a task to permit a task/fiber (including itself) to
 * safely share the system's floating point registers with other tasks/fibers.
 *
 * See the description of _FpEnable() for further details.
 *
 * @return N/A
 */
FUNC_ALIAS(_FpEnable, task_float_enable, void);

/**
 *
 * @brief Disable preservation of non-integer context information
 *
 * This routine prevents the specified task/fiber (which may be the active
 * task/fiber) from safely sharing any of the system's floating point registers
 * with other tasks/fibers.
 *
 * WARNING
 * This routine should only be used to disable floating point support for
 * a task/fiber that currently has such support enabled.
 *
 * @param tcs TBD
 *
 * @return N/A
 *
 * INTERNAL
 * Since the transition from "FP supporting" to "non-FP supporting" must be done
 * atomically to avoid confusing the floating point logic used by _Swap(),
 * this routine locks interrupts to ensure that a context switch does not occur,
 * The locking isn't really needed when the routine is called by a fiber
 * (since context switching can't occur), but it is harmless and allows a single
 * routine to be called by both tasks and fibers (thus saving code space).
 *
 * If necessary, the interrupt latency impact of calling this routine from a
 * fiber could be lessened by re-designing things so that only task-type callers
 * locked interrupts (i.e. move the locking to task_float_disable()). However,
 * all calls to fiber_float_disable() would need to be reviewed to ensure they
 * are only used from a fiber, rather than from "generic" code used by both
 * tasks and fibers.
 */
void _FpDisable(struct tcs *tcs)
{
	unsigned int imask;

	/* Lock interrupts to prevent a pre-emptive context switch from occuring
	 */

	imask = irq_lock();

	/*
	 * Disable _all_ floating point capabilities for the task/fiber,
	 * regardless
	 * of the options specified at the time support was enabled.
	 */

	tcs->flags &= ~(USE_FP | USE_SSE);

	if (tcs == _nanokernel.current) {
		_FpAccessDisable();
		_nanokernel.current_fp = (struct tcs *)0;
	} else {
		if (_nanokernel.current_fp == tcs)
			_nanokernel.current_fp = (struct tcs *)0;
	}

	irq_unlock(imask);
}

/**
 *
 * @brief Disable preservation of non-integer context
 *information
 *
 * This routine allows a fiber to disallow a task/fiber (including itself) from
 * safely sharing any of the system's floating point registers with other
 * tasks/fibers.
 *
 * WARNING
 * This routine should only be used to disable floating point support for
 * a task/fiber that currently has such support enabled.
 *
 * @return N/A
 */
FUNC_ALIAS(_FpDisable, fiber_float_disable, void);

/**
 *
 * @brief Disable preservation of non-integer context information
 *
 * This routine allows a task to disallow a task/fiber (including itself) from
 * safely sharing any of the system's floating point registers with other
 * tasks/fibers.
 *
 * WARNING
 * This routine should only be used to disable floating point support for
 * a task/fiber that currently has such support enabled.
 *
 * @return N/A
 */
FUNC_ALIAS(_FpDisable, task_float_disable, void);


/**
 *
 * @brief Handler for "device not available" exception
 *
 * This routine is registered to handle the "device not available" exception
 * (vector = 7)
 *
 * The processor will generate this exception if any x87 FPU, MMX, or SSEx
 * instruction is executed while CR0[TS]=1.  The handler then enables the
 * current task or fiber with the USE_FP option (or the USE_SSE option if the
 * SSE configuration option has been enabled).
 *
 * @param pEsf this value is not used for this architecture
 *
 * @return N/A
 */
void _FpNotAvailableExcHandler(NANO_ESF * pEsf)
{
	unsigned int enableOption;

	ARG_UNUSED(pEsf);

	/*
	 * Assume the exception did not occur in the thread of an ISR.
	 * (In other words, CPU cycles will not be consumed to perform
	 * error checking to ensure the exception was not generated in an ISR.)
	 */

	PRINTK("_FpNotAvailableExcHandler() exception handler has been "
	       "invoked\n");

/* Enable the highest level of FP capability configured into the kernel */

#ifdef CONFIG_SSE
	enableOption = USE_SSE;
#else
	enableOption = USE_FP;
#endif

	_FpEnable(_nanokernel.current, enableOption);
}

#endif /* CONFIG_FP_SHARING */
