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

#include <config.h>
#include <common.h>
#include <command.h>
#include <malloc.h>
#include <linux/ctype.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)

extern uint32_t efuse_get_max(void);
extern int efuse_read_usr(char *buf, size_t count, loff_t *ppos);
extern int efuse_write_usr(char *buf, size_t count, loff_t *ppos);

struct efusekey_info{
	char keyname[32];
	loff_t 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;

	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);

	struct efusekey_info * 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;
        }
        memset(theKeyInf->keyname, 0, sizeof theKeyInf->keyname);
        strncpy(theKeyInf->keyname, phandle, (sizeof theKeyInf->keyname) - 1);

		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%llx) + size (0x%x) > max [0x%x]!\n", theKeyInf->offset, theKeyInf->size, max_size);
            goto err;
        }
	}

    _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, 0, cfgCnt);
    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 = getenv("dtb_mem_addr");
            if (!dtbLoadAddr) {
                setenv("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);
            if (!tmpBuf) {
                EFUSE_ERR("Fail alloc buf 0x%x bytes\n", bufSz);
                return CMD_RET_FAILURE;
            }

            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"
);

