// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2019 Amlogic, Inc. 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;

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

    extern int fdt_path_offset(const void *fdt, const char *path);
	nodeoffset = fdt_path_offset(dt_addr, "/efusekey");
	if (nodeoffset < 0) {
		EFUSE_ERR("not find /efusekey node [%s].\n", fdt_strerror(nodeoffset));
        return __LINE__;
    }

    extern const void *fdt_getprop(const void *fdt, int nodeoffset,
            const char *name, int *lenp);
	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;
		}

	extern int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
        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");
                free(tmpBuf);
                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"
);

