/******************************************************************************
*
* Copyright (C) 2015 - 2016 Xilinx, Inc.  All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/****************************************************************************/
/**
*
* @file xipipsu.c
* @addtogroup ipipsu_v1_0
* @{
*
* This file contains the implementation of the interface functions for XIpiPsu
* driver. Refer to the header file xipipsu.h for more detailed information.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver	Who	Date	Changes
* ----- ------ -------- ----------------------------------------------
* 1.00	mjr	03/15/15	First Release
* 2.0	mjr	01/22/16	Fixed response buffer address
*                               calculation. CR# 932582.
* 2.1	kvn	05/05/16	Modified code for MISRA-C:2012 Compliance
* </pre>
*
*****************************************************************************/

/***************************** Include Files ********************************/
#include "xipipsu.h"
#include "xipipsu_hw.h"

/****************************************************************************/
/**
 * Initialize the Instance pointer based on a given Config Pointer
 *
 * @param	InstancePtr is a pointer to the instance to be worked on
 * @param	CfgPtr is the device configuration structure containing required
 *		  	hardware build data
 * @param	EffectiveAddress is the base address of the device. If address
 *        	translation is not utilized, this parameter can be passed in using
 *        	CfgPtr->Config.BaseAddress to specify the physical base address.
 * @return	XST_SUCCESS if initialization was successful
 * 			XST_FAILURE in case of failure
 *
 */

XStatus XIpiPsu_CfgInitialize(XIpiPsu *InstancePtr, XIpiPsu_Config * CfgPtr,
		UINTPTR EffectiveAddress)
{
	u32 Index;
	/* Verify arguments */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(CfgPtr != NULL);
	/* Set device base address and ID */
	InstancePtr->Config.DeviceId = CfgPtr->DeviceId;
	InstancePtr->Config.BaseAddress = EffectiveAddress;
	InstancePtr->Config.BitMask = CfgPtr->BitMask;
	InstancePtr->Config.IntId = CfgPtr->IntId;

	InstancePtr->Config.TargetCount = CfgPtr->TargetCount;

	for (Index = 0U; Index < CfgPtr->TargetCount; Index++) {
		InstancePtr->Config.TargetList[Index].Mask =
				CfgPtr->TargetList[Index].Mask;
		InstancePtr->Config.TargetList[Index].BufferIndex =
				CfgPtr->TargetList[Index].BufferIndex;
	}

	/* Mark the component as Ready */
	InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
	return (XST_SUCCESS);
}

/**
 * @brief	Reset the given IPI register set.
 *        	This function can be called to disable the IPIs from all
 *        	the sources and clear any pending IPIs in status register
 *
 * @param 	InstancePtr is the pointer to current IPI instance
 *
 */

void XIpiPsu_Reset(XIpiPsu *InstancePtr)
{

	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/**************Disable***************/

	XIpiPsu_WriteReg(InstancePtr->Config.BaseAddress, XIPIPSU_IDR_OFFSET,
			XIPIPSU_ALL_MASK);

	/**************Clear***************/
	XIpiPsu_WriteReg(InstancePtr->Config.BaseAddress, XIPIPSU_ISR_OFFSET,
			XIPIPSU_ALL_MASK);

}

/**
 * @brief	Trigger an IPI to a Destination CPU
 *
 * @param	InstancePtr is the pointer to current IPI instance
 * @param	DestCpuMask is the Mask of the CPU to which IPI is to be triggered
 *
 *
 * @return	XST_SUCCESS if successful
 * 			XST_FAILURE if an error occurred
 */

XStatus XIpiPsu_TriggerIpi(XIpiPsu *InstancePtr, u32 DestCpuMask)
{

	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/* Trigger an IPI to the Target */
	XIpiPsu_WriteReg(InstancePtr->Config.BaseAddress, XIPIPSU_TRIG_OFFSET,
			DestCpuMask);
	return XST_SUCCESS;

}

/**
 * @brief Poll for an acknowledgement using Observation Register
 *
 * @param	InstancePtr is the pointer to current IPI instance
 * @param	DestCpuMask is the Mask of the destination CPU from which ACK is expected
 * @param	TimeOutCount is the Count after which the routines returns failure
 *
 * @return	XST_SUCCESS if successful
 * 			XST_FAILURE if a timeout occurred
 */

XStatus XIpiPsu_PollForAck(XIpiPsu *InstancePtr, u32 DestCpuMask,
		u32 TimeOutCount)
{
	u32 Flag, PollCount;
	XStatus Status;

	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	PollCount = 0U;
	/* Poll the OBS register until the corresponding DestCpu bit is cleared */
	do {
		Flag = (XIpiPsu_ReadReg(InstancePtr->Config.BaseAddress,
				XIPIPSU_OBS_OFFSET)) & (DestCpuMask);
		PollCount++;
		/* Check if the IPI was Acknowledged by the Target or we Timed Out*/
	} while ((0x00000000U != Flag) && (PollCount < TimeOutCount));

	if (PollCount >= TimeOutCount) {
		Status = XST_FAILURE;
	} else {
		Status = XST_SUCCESS;
	}

	return Status;
}

/**
 * @brief	Get the Buffer Index for a CPU specified by Mask
 *
 * @param	InstancePtr is the pointer to current IPI instance
 * @param	CpuMask is the Mask of the CPU form which Index is required
 *
 * @return	Buffer Index value if CPU Mask is valid
 * 			XIPIPSU_MAX_BUFF_INDEX+1 if not valid
 *
 * @note	Static function used only by XIpiPsu_GetBufferAddress
 *
 */
static u32 XIpiPsu_GetBufferIndex(XIpiPsu *InstancePtr, u32 CpuMask)
{
	u32 BufferIndex;
	u32 Index;
	/* Init Index with an invalid value */
	BufferIndex = XIPIPSU_MAX_BUFF_INDEX + 1U;

	/*Search for CPU in the List */
	for (Index = 0U; Index < InstancePtr->Config.TargetCount; Index++) {
		/*If we find the CPU , then set the Index and break the loop*/
		if (InstancePtr->Config.TargetList[Index].Mask == CpuMask) {
			BufferIndex = InstancePtr->Config.TargetList[Index].BufferIndex;
			break;
		}
	}

	/* Return the Index */
	return BufferIndex;
}

/**
 * @brief	Get the Buffer Address for a given pair of CPUs
 *
 * @param	InstancePtr is the pointer to current IPI instance
 * @param	SrcCpuMask is the Mask for Source CPU
 * @param	DestCpuMask is the Mask for Destination CPU
 * @param	BufferType is either XIPIPSU_BUF_TYPE_MSG or XIPIPSU_BUF_TYPE_RESP
 *
 * @return	Valid Buffer Address if no error
 * 			NULL if an error occurred in calculating Address
 *
 */

static u32* XIpiPsu_GetBufferAddress(XIpiPsu *InstancePtr, u32 SrcCpuMask,
		u32 DestCpuMask, u32 BufferType)
{
#ifdef __aarch64__
	u64 BufferAddr;
#else
	u32 BufferAddr;
#endif

	u32 SrcIndex;
	u32 DestIndex;
	/* Get the buffer indices */
	SrcIndex = XIpiPsu_GetBufferIndex(InstancePtr, SrcCpuMask);
	DestIndex = XIpiPsu_GetBufferIndex(InstancePtr, DestCpuMask);

	/* If we got an invalid buffer index, then return NULL pointer, else valid address */
	if ((SrcIndex > XIPIPSU_MAX_BUFF_INDEX)
			|| (DestIndex > XIPIPSU_MAX_BUFF_INDEX)) {
		BufferAddr = 0U;
	} else {

		if (XIPIPSU_BUF_TYPE_MSG == BufferType) {
			BufferAddr = XIPIPSU_MSG_RAM_BASE
					+ (SrcIndex * XIPIPSU_BUFFER_OFFSET_GROUP)
					+ (DestIndex * XIPIPSU_BUFFER_OFFSET_TARGET);
		} else if (XIPIPSU_BUF_TYPE_RESP == BufferType) {
			BufferAddr = XIPIPSU_MSG_RAM_BASE
					+ (DestIndex * XIPIPSU_BUFFER_OFFSET_GROUP)
					+ (SrcIndex * XIPIPSU_BUFFER_OFFSET_TARGET)
					+ (XIPIPSU_BUFFER_OFFSET_RESPONSE);
		} else {
			BufferAddr = 0U;
		}

	}

	return (u32 *) BufferAddr;
}

/**
 * @brief	Read an Incoming Message from a Source
 *
 * @param 	InstancePtr is the pointer to current IPI instance
 * @param 	SrcCpuMask is the Device Mask for the CPU which has sent the message
 * @param 	MsgPtr is the pointer to Buffer to which the read message needs to be stored
 * @param 	MsgLength is the length of the buffer/message
 * @param 	BufferType is the type of buffer (XIPIPSU_BUF_TYPE_MSG or XIPIPSU_BUF_TYPE_RESP)
 *
 * @return	XST_SUCCESS if successful
 * 			XST_FAILURE if an error occurred
 */

XStatus XIpiPsu_ReadMessage(XIpiPsu *InstancePtr, u32 SrcCpuMask, u32 *MsgPtr,
		u32 MsgLength, u8 BufferType)
{
	u32 *BufferPtr;
	u32 Index;
	XStatus Status;

	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid(MsgPtr != NULL);
	Xil_AssertNonvoid(MsgLength <= XIPIPSU_MAX_MSG_LEN);

	BufferPtr = XIpiPsu_GetBufferAddress(InstancePtr, SrcCpuMask,
			InstancePtr->Config.BitMask, BufferType);
	if (BufferPtr != NULL) {
		/* Copy the IPI Buffer contents into Users's Buffer*/
		for (Index = 0U; Index < MsgLength; Index++) {
			MsgPtr[Index] = BufferPtr[Index];
		}
		Status = XST_SUCCESS;
	} else {
		Status = XST_FAILURE;
	}

	return Status;
}


/**
 * @brief	Send a Message to Destination
 *
 * @param	InstancePtr is the pointer to current IPI instance
 * @param	DestCpuMask is the Device Mask for the destination CPU
 * @param	MsgPtr is the pointer to Buffer which contains the message to be sent
 * @param	MsgLength is the length of the buffer/message
 * @param	BufferType is the type of buffer (XIPIPSU_BUF_TYPE_MSG or XIPIPSU_BUF_TYPE_RESP)
 *
 * @return	XST_SUCCESS if successful
 * 			XST_FAILURE if an error occurred
 */

XStatus XIpiPsu_WriteMessage(XIpiPsu *InstancePtr, u32 DestCpuMask, u32 *MsgPtr,
		u32 MsgLength, u8 BufferType)
{
	u32 *BufferPtr;
	u32 Index;
	XStatus Status;

	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid(MsgPtr != NULL);
	Xil_AssertNonvoid(MsgLength <= XIPIPSU_MAX_MSG_LEN);

	BufferPtr = XIpiPsu_GetBufferAddress(InstancePtr,
			InstancePtr->Config.BitMask, DestCpuMask, BufferType);
	if (BufferPtr != NULL) {
		/* Copy the Message to IPI Buffer */
		for (Index = 0U; Index < MsgLength; Index++) {
			BufferPtr[Index] = MsgPtr[Index];
		}
		Status = XST_SUCCESS;
	} else {
		Status = XST_FAILURE;
	}

	return Status;
}
/** @} */
