/*
 * \file        efuse_usr_space_api.c
 * \brief       support read/write user space using keyname mode
 *              mapping keyname to offset by looking /efusekey in dtb
 *
 * \version     1.0.0
 * \date        15/07/14
 * \author      Sam.Wu <yihui.wu@amlgic.com>
 *
 * Copyright (c) 2015 Amlogic. All Rights Reserved.
 *
 */
#include <config.h>
#include <common.h>
#include <command.h>
#include <malloc.h>
#include <linux/ctype.h>
#include <asm/arch/efuse.h>

#define EFUSE_DBG(fmt...)   //printf("[EFUSE_DBG]"fmt)
#define EFUSE_MSG(fmt...)   printf("[EFUSE_MSG]"fmt)
#define EFUSE_ERR(fmt...)   printf("[EFUSE_ERR]f(%s)L%d:", __func__, __LINE__),printf(fmt)

struct efusekey_info{
	char keyname[32];
	unsigned offset;
	unsigned size;
};

static struct _efuseCfgInf{
    unsigned                initMaigc;//magic to indicate whether inited
    unsigned                totalCfgKeyNums;
    struct efusekey_info *  pKeyInf;
}
_efuseKeyInfos = {.totalCfgKeyNums = 0, .pKeyInf = NULL};

int efuse_usr_api_init_dtb(const char*  dt_addr)
{
	int nodeoffset, poffset = 0;
	char propname[32];
	const void* phandle;
	int ret;
	int index;
	uint32_t max_size;
    unsigned efusekeynum = 0;
    struct efusekey_info * efusekey_infos = NULL;

	ret = fdt_check_header(dt_addr);
	if (ret < 0) {
		EFUSE_ERR("fdt check failed [%s]\n", fdt_strerror(ret));
        return __LINE__;
    }
    _efuseKeyInfos.initMaigc = 0;

	nodeoffset = fdt_path_offset(dt_addr, "/efusekey");
	if (nodeoffset < 0) {
		EFUSE_ERR("not find /efusekey node [%s].\n", fdt_strerror(nodeoffset));
        return __LINE__;
    }

	phandle = fdt_getprop(dt_addr, nodeoffset, "keynum", NULL);
	efusekeynum = be32_to_cpup((u32 *)phandle);
	EFUSE_MSG("keynum is %x\n", efusekeynum);

    if (efusekey_infos) free(efusekey_infos) ;
    efusekey_infos = (struct efusekey_info *)malloc(sizeof (struct efusekey_info) *efusekeynum);
    if (!efusekey_infos) {
        EFUSE_ERR("malloc err\n");
        return __LINE__;
    }

	max_size = efuse_get_max();

	for (index = 0; index < efusekeynum; index++)
    {
        struct efusekey_info* theKeyInf = efusekey_infos + index;
		sprintf(propname, "key%d", index);
		/* printf("%s: propname: %s\n",__func__,propname); */
		phandle = fdt_getprop(dt_addr, nodeoffset, propname, NULL);
		if (!phandle) {
			EFUSE_ERR("don't find  match %s\n", propname);
			goto err;
		}
        poffset = fdt_node_offset_by_phandle(dt_addr,
                be32_to_cpup((u32 *)phandle));
        if (!poffset) {
            EFUSE_ERR("can't find device node for key[%s]\n", propname);
            goto err;
        }


		phandle = fdt_getprop(dt_addr, poffset, "keyname", NULL);
        if (!phandle) {
            EFUSE_ERR("Can't find keyname for key[%d]\n", index);
            goto err;
        }
		strcpy(theKeyInf->keyname, phandle);

		phandle = fdt_getprop(dt_addr, poffset, "offset", NULL);
        if (!phandle) {
            EFUSE_ERR("Can't find offset for key[%s]\n", theKeyInf->keyname);
            goto err;
        }
		theKeyInf->offset = be32_to_cpup((u32 *)phandle);

		phandle = fdt_getprop(dt_addr, poffset, "size", NULL);
        if (!phandle) {
            EFUSE_ERR("Can't find size for key[%s]\n", theKeyInf->keyname);
            goto err;
        }
		theKeyInf->size = be32_to_cpup((u32 *)phandle);

		EFUSE_DBG("key[%02d] name=%12s, offset=0x%04x, size=0x%04x\n",
                index, theKeyInf->keyname, theKeyInf->offset, theKeyInf->size);
        if (theKeyInf->offset + theKeyInf->size > max_size) {
            EFUSE_ERR("\n offset (0x%x) + size (0x%x) > max [0x%x]!\n", theKeyInf->offset, theKeyInf->size, max_size);
            return __LINE__;
        }
	}

    _efuseKeyInfos.totalCfgKeyNums = efusekeynum;
    _efuseKeyInfos.pKeyInf         = efusekey_infos;
    EFUSE_DBG("%s success!\n", __func__);
    _efuseKeyInfos.initMaigc = 0xee;
	return 0;

err:
	free(efusekey_infos);
	EFUSE_ERR("%s error!\n", __func__);
	return -1;
}

static int _get_cfg_key_inf_byname(const char* keyname, const struct efusekey_info ** pKeyInf)
{
    int index = 0;
    struct efusekey_info* theKeyInf = _efuseKeyInfos.pKeyInf;
    int ret = 0;

    if (0xee != _efuseKeyInfos.initMaigc) {
        EFUSE_ERR("Pls init first.\n");
        return __LINE__;
    }
    for (; index < _efuseKeyInfos.totalCfgKeyNums; ++index, ++theKeyInf)
    {
        const char* theKeyname = theKeyInf->keyname;
        ret = strcmp(theKeyname, keyname);
        if (ret) continue;

        *pKeyInf = theKeyInf;
        return 0;
    }

    EFUSE_ERR("efuse keyname(%s) not configured\n", keyname);
    return __LINE__;//Not found the matched name
}

int efuse_usr_api_get_cfg_key_size(const char* keyname, unsigned* pSz)
{
    int ret = 0;
    const struct efusekey_info* theCfgKeyInf = NULL;

    ret = _get_cfg_key_inf_byname(keyname, &theCfgKeyInf);
    if (ret) {
        EFUSE_ERR("not name cfg in dts.\n");
        return __LINE__;
    }

    *pSz = theCfgKeyInf->size;
    return 0;
}

int efuse_usr_api_write_key(const char* keyname, const void* keydata, const unsigned dataSz)
{
    int ret = 0;
    const struct efusekey_info* theCfgKeyInf = NULL;

    ret = _get_cfg_key_inf_byname(keyname, &theCfgKeyInf);
    if (ret) {
        EFUSE_ERR("not name cfg in dts.\n");
        return __LINE__;
    }
    if (dataSz != theCfgKeyInf->size) {
        EFUSE_ERR("dataSz 0x%x != cfg size 0x%x\n", dataSz, theCfgKeyInf->size);
        return __LINE__;
    }

    ret = efuse_write_usr((char*)keydata, theCfgKeyInf->size, (loff_t*)&theCfgKeyInf->offset);
    if (ret < 0) {
        EFUSE_ERR("error: efuse write fail.\n");
        return __LINE__;
    }

    return 0;
}

//usrefuse read mac $loadaddr (size)
int efuse_usr_api_read_key(const char* keyname, void* databuf, const unsigned bufSz)
{
    int ret = 0;
    const struct efusekey_info* theCfgKeyInf = NULL;
    loff_t offset = 0;

    ret = _get_cfg_key_inf_byname(keyname, &theCfgKeyInf);
    if (ret) {
        EFUSE_ERR("not name cfg in dts.\n");
        return __LINE__;
    }
    const unsigned cfgCnt = theCfgKeyInf->size;
    if (cfgCnt > bufSz && bufSz) {
        EFUSE_ERR("cfg size 0x%x > bufsz 0x%x\n", cfgCnt, bufSz);
        return __LINE__;
    }
    EFUSE_DBG("keyname=%s, databuf=%p, bufSz=%d, cfgCnt=%u\n", keyname, databuf, bufSz, cfgCnt);

    offset = theCfgKeyInf->offset;
    memset(databuf, cfgCnt, 0);
    ret = efuse_read_usr((char*)databuf, cfgCnt, &offset);
    if (ret == -1) {
        EFUSE_ERR("ERROR: efuse read user data fail!, size=%u, offset=%llu\n", cfgCnt, offset);
        return __LINE__;
    }

    if (ret != cfgCnt) {
        EFUSE_ERR("ERROR: read %d byte(s) not wanted %d byte(s) data\n", ret, cfgCnt);
        return __LINE__;
    }

    return 0;
}

static int hex_ascii_to_buf(const char* input, uint8_t* buf, const unsigned bufSz)
{
    int ret = 0;
    const char* tmpStr = input;
    const unsigned inputLen = strlen(input);
    int i = 0;

    if (!inputLen) {
        EFUSE_ERR("err input len 0\n");
        return __LINE__;
    }
    if ( ((inputLen>>1)<<1) != inputLen ) {
        EFUSE_ERR("inputLen %d not even\n", inputLen);
        return __LINE__;
    }
    if (bufSz * 2 > inputLen) {
        EFUSE_ERR("bufSz %d not enough\n", bufSz);
        return __LINE__;
    }
    for (tmpStr = input; *tmpStr; ++tmpStr)
    {
        char c = *tmpStr;
        ret = isxdigit(c);
        if (!ret) {
            EFUSE_ERR("input(%s) contain non xdigit, c=%c\n", input, c);
            return __LINE__;
        }
    }

    for (i = 0; i < inputLen; i += 2)
    {
        char tmpByte[8];
        tmpByte[2] = '\0';
        tmpByte[0] = input[i];
        tmpByte[1] = input[i + 1];

        const unsigned val = simple_strtoul(tmpByte, NULL, 16);
        if (val > 0xff) {
            EFUSE_ERR("Exception: val 0x%x > 0xff\n", val);
            return __LINE__;
        }
        buf[i>>1] = val;
    }

    return 0;
}

static int do_usr_efuse_api(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
    int ret = 0;
    const char* subcmd = argv[1];
    if (argc < 2) return CMD_RET_USAGE;

    if (!strcmp("init", subcmd))
    {
        const char* dtbLoadAddr = NULL;
        if (argc > 2)
        {
            dtbLoadAddr = (char*)simple_strtoul(argv[2], NULL, 0);
        }
        else
        {
            dtbLoadAddr = env_get("dtb_mem_addr");
            if (!dtbLoadAddr) {
                env_set("dtb_mem_addr", simple_itoa(CONFIG_SYS_SDRAM_BASE + (16U<<20)));
            }
            dtbLoadAddr = (char*)simple_strtoul(dtbLoadAddr, NULL, 0);
        }
        ret = efuse_usr_api_init_dtb(dtbLoadAddr);
    }
    else if(!strcmp("size", subcmd))
    {
        const char* keyname = argv[2];
        unsigned keysize = argc > 3 ? simple_strtoul(argv[3], NULL, 0) : 0;

        ret = efuse_usr_api_get_cfg_key_size(keyname, &keysize);
        EFUSE_MSG("keysize=%d\n", keysize);
    }
    else if(!strcmp("read", subcmd))
    {
        if (argc < 4) return CMD_RET_USAGE;
        const char* keyname = argv[2];
        char* databuf = (char*)simple_strtoul(argv[3], NULL, 16);
        unsigned bufSz = argc > 4 ? simple_strtoul(argv[4], NULL, 0) : 0;

        if (!bufSz)
        {
            ret =  efuse_usr_api_get_cfg_key_size(keyname, &bufSz);
            if (ret) {
                EFUSE_ERR("Fail in get sz for key[%s]\n", keyname);
                return __LINE__;
            }
        }

        ret = efuse_usr_api_read_key(keyname, databuf, bufSz);
        if (!ret)
        {
            int i = 0;
            printf("efuse read data");
            for (i = 0; i < bufSz; i++) {
                if (i%8 == 0) printf("\n[0x%02x]:", i);
                printf("%02x ", databuf[i]);
            }
            printf("\n");
        }
    }
    else if(!strcmp("write", subcmd))
    {
        if (argc < 4) return CMD_RET_USAGE;
        const char* keyname = argv[2];
        char* keydata = (char*)simple_strtoul(argv[3], NULL, 16);
        unsigned bufSz = argc > 4 ? simple_strtoul(argv[4], NULL, 0) : 0;
        uint8_t* tmpBuf = NULL;

        if (!bufSz)
        {
            const char* input = argv[3];
            bufSz = ( strlen(input) >> 1 );
            tmpBuf = malloc(bufSz);

            ret = hex_ascii_to_buf(input, tmpBuf, bufSz);
            if (ret) {
                EFUSE_ERR("Failed in change hex ascii to buf\n");
                return __LINE__;
            }
            keydata = (char*)tmpBuf;
        }
        ret = efuse_usr_api_write_key(keyname, keydata, bufSz);
        if (tmpBuf) free(tmpBuf) ;
    }

    return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
}

U_BOOT_CMD(
	efuse_user,
    5,  //max argc
    1,	//repeatable
    do_usr_efuse_api,
	"efuse user space read write ops",
	"init <dtbAddr>  --- init efuse user space\n"
	"size keyname <addr>  --- get key size configured in dts\n"
	"read keyname addr <size> --- read key value to mem addr \n"
	"write --- write key value\n"
	"       efuse_user write keyname hexstring --- write key value in hex string\n"
	"       efuse_user write keyname addr size --- write key value, U need load you key value into mem addr first\n"
);

