/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
 * common/aml_tlv.c
 *
 * Copyright (C) 2020 Amlogic, Inc. All rights reserved.
 *
 */

#if 0 //bl2
#include <platform_def.h>
#include <aml_tlv.h>
#include <string.h>
#include <sha2.h>
#include <secure_apb.h> //AML_BL2_TMASTER_CFG_REG: AO_SEC_GP_CFG6
#include <acs.h>

#ifdef CONFIG_AML_TLV_BL2_VER_INFO
#include <soc_version.h>
extern const char build_message[];
#endif

#else
#include <config.h>
#include <amlogic/aml_tlv.h>
#include <asm/arch/secure_apb.h>
#include <linux/string.h>
#include <u-boot/sha256.h>

#ifndef AML_BL2_TMASTER_DDR_ADDR
#error ERROR! Please define DDR address for TLV!
#endif

#endif

#ifdef CONFIG_AML_SUPPORT_TLV

//internal use only, to fetch the transfer object from AML_BL2_TMASTER_CFG_REG
//only BL2 can set the AML_BL2_TMASTER_CFG_REG
//all others BL3X just use the obj from AML_BL2_TMASTER_CFG_REG
static s_bl2_to_bl3x_send_t * aml_get_t_master(void)
{

#ifdef BL2_ACS_OFFSET
	if (p_acs)
		*(unsigned int *)AML_BL2_TMASTER_CFG_REG = p_acs->p_plls->nCFGTAddr;
	else
		*(unsigned int *)AML_BL2_TMASTER_CFG_REG = 0;
#endif

	return (s_bl2_to_bl3x_send_t*)(unsigned long)(*(unsigned int *)AML_BL2_TMASTER_CFG_REG);

}


//IMPORTANT: BECAUSE THIS FUNCTION WILL USE DDR AS STORAGE(DEFAULT) THEN
//                    ALL THE APIS MSUT BE USED AFTER DDR INIT DONE

//feature : append item to the list
//para list:
//               nType[IN]       :   unique ID for item
//               nLength[IN]    :   byte data length for data pData
//               pData[IN]       :   data buffer to be processed
//
//return   :  e_err_not_support : BL33 not support valid address for TLV
//               e_ok_ret  : append OK to the list
//               e_err_in_data : invalid input pData
//               e_err_in_size  : invalid data length
//               e_err_over_size : total size exceed the max
//               e_err_item_exit  : item already exist with nType

e_ret_type aml_append_item(unsigned int nType, unsigned int nLength, unsigned char *pData)
{
	e_ret_type eReturn = e_err_not_support;

	#ifdef CONFIG_AML_TLV_BL2_VER_INFO
	int nIndex;
	#endif

	s_bl2_to_bl3x_send_t *pSndMaster = aml_get_t_master();

	if ( !pSndMaster )
		goto exit;

	if ( AML_BL2_TMASTER_MAGIC != pSndMaster->hdr.nMagic)
	{
		//first run which need initialize
		memset(pSndMaster,0,sizeof(*pSndMaster));

		pSndMaster->hdr.nMagic    = AML_BL2_TMASTER_MAGIC;       //magic @BL2
		pSndMaster->hdr.nVersion  = AML_BL2_TMASTER_VERSION;     //version: major | minor
		pSndMaster->hdr.nHeadSize = sizeof(s_bl2_to_bl3x_hdr_t); //size of hdr
		pSndMaster->hdr.pNextBlob = pSndMaster->blob;            //active item
		pSndMaster->hdr.pNextBlob->pNextItem = 0;                //next item is NULL

		//copy BL2 info one by one and limit to sizeof(szBL2Info)
		#ifdef CONFIG_AML_TLV_BL2_VER_INFO
		for ( nIndex = 0;build_message[nIndex] && nIndex < sizeof(pSndMaster->hdr.szBL2Info); ++nIndex)
			pSndMaster->hdr.szBL2Info[nIndex] = build_message[nIndex];
		#endif
	}

	eReturn = e_err_in_data;
	//check input data
	if (!pData )
		goto exit;

	//check input length
	eReturn = e_err_in_size;
	if (!nLength)
		goto exit;

	unsigned int nStoreLength = AML_BL2_TMASTER_ITEM_ALIGN_LEN(nLength);

	eReturn = e_err_over_size;

	//check whether the transfer buffer is overflow or not with this new input
	if (AML_BL2_TMASTER_DDR_MLEN <= (pSndMaster->hdr.nTotalSize + nStoreLength))
		goto exit;

	eReturn = e_err_item_exit;
	s_bl2_tlv_item_t *pItem = 0;
	if ( e_ok_ret == aml_fetch_item(nType, &pItem))
		goto exit;

	//total counter +1
	pSndMaster->hdr.nTLVCount +=1;

	//set item data & info
	pSndMaster->hdr.pNextBlob->nType = nType;
	pSndMaster->hdr.pNextBlob->nLength = nLength;
	pSndMaster->hdr.pNextBlob->nStoreLength = nStoreLength;
	memcpy(pSndMaster->hdr.pNextBlob->szContent,pData,nLength);

	//clean the padding buffer
	if ( nStoreLength > nLength )
			memset(pSndMaster->hdr.pNextBlob->szContent + nLength,0,(nStoreLength - nLength));

	//update total size
	pSndMaster->hdr.nTotalSize += (sizeof(s_bl2_tlv_item_t) - 4 + nStoreLength);

	//shift the next active item
	pSndMaster->hdr.pNextBlob->pNextItem = (s_bl2_tlv_item_t*)(pSndMaster->hdr.pNextBlob->szContent + nStoreLength);

  //update next active item
	pSndMaster->hdr.pNextBlob = pSndMaster->hdr.pNextBlob->pNextItem;

	//init active item
	memset(pSndMaster->hdr.pNextBlob,0,sizeof(s_bl2_tlv_item_t));

#ifdef BL2_ACS_OFFSET
	//update sha2 of TLVs
	sha2((void*)pSndMaster->blob,pSndMaster->hdr.nTotalSize,pSndMaster->hdr.szSHA2TLV,0);

	//update sha2 of head which include sha2 of TLVs
	sha2((void*)pSndMaster,pSndMaster->hdr.nHeadSize ,pSndMaster->szSHA2Head,0);
#else
	sha256_csum_wd((void*)pSndMaster->blob,pSndMaster->hdr.nTotalSize,
		pSndMaster->hdr.szSHA2TLV,pSndMaster->hdr.nHeadSize);
	sha256_csum_wd((void*)pSndMaster,pSndMaster->hdr.nHeadSize ,
		pSndMaster->szSHA2Head,pSndMaster->hdr.nHeadSize);
#endif
	//success
	eReturn = e_ok_ret;

exit:

	return eReturn;
}

//IMPORTANT: BECAUSE THIS FUNCTION WILL USE DDR AS STORAGE(DEFAULT) THEN
//           ALL THE APIS MSUT BE USED AFTER DDR INIT DONE


//feature : fetch the item from list with nType
//para list:
//               nType[IN]       :   unique ID for item
//               ppItem[OUT]  :   item found which has the matched type nType
//
//return   :  e_err_not_support : BL33 not support valid address for TLV
//               e_ok_ret  : found the item and return with ppItem
//               e_err_sha_hdr : head sha2 check fail
//               e_err_sha_tlv  : TLV sha2 check fail
//               e_err_no_item : no item match the type nType

e_ret_type aml_fetch_item(unsigned int nType, s_bl2_tlv_item_t **ppItem)
{
	e_ret_type eReturn = e_err_not_support;
	s_bl2_to_bl3x_send_t *pSndMaster = aml_get_t_master();
	s_bl2_tlv_item_t *pItem = 0;
	unsigned char szSHA2[32];

	if ( ppItem )
		*ppItem = 0;

	if ( !pSndMaster )
		goto exit;

	eReturn = e_err_no_item;

    //check TLV's counter
	if (!pSndMaster->hdr.nTLVCount)
		goto exit;

	eReturn = e_err_sha_hdr;

	//check sha2 of header
#ifdef BL2_ACS_OFFSET
	sha2((void*)pSndMaster,pSndMaster->hdr.nHeadSize ,szSHA2,0);
#else
	sha256_csum_wd((void*)pSndMaster,pSndMaster->hdr.nHeadSize,
		szSHA2,pSndMaster->hdr.nHeadSize);
#endif

	if (memcmp(szSHA2,pSndMaster->szSHA2Head,sizeof(szSHA2)))
		goto exit;

	eReturn = e_err_sha_tlv;

	//check sha2 of TLVs
#ifdef BL2_ACS_OFFSET
	sha2((void*)pSndMaster->blob,pSndMaster->hdr.nTotalSize,szSHA2,0);
#else
	sha256_csum_wd((void*)pSndMaster->blob,pSndMaster->hdr.nTotalSize,
		szSHA2,pSndMaster->hdr.nTotalSize);
#endif

	if (memcmp(szSHA2,pSndMaster->hdr.szSHA2TLV,sizeof(szSHA2)))
		goto exit;

  //first item
	pItem = pSndMaster->blob;

  //check the list
	while (pItem->nLength)
	{
		if ( nType == pItem->nType)
			break;

		pItem = pItem->pNextItem;
	}

	//check valid item or not with length
	if (pItem->nLength)
		eReturn = e_ok_ret;
	else
	{
		pItem = 0;
		eReturn = e_err_no_item;
	}

	*ppItem = pItem;

exit:

	return eReturn;
}

#endif //#ifdef CONFIG_AML_SUPPORT_TLV
