/*
 * \file        km_efuse_key.c
 * \brief       efuse key ops for key manage
 *
 * \version     1.0.0
 * \date        15/06/30
 * \author      Sam.Wu <yihui.wu@amlgic.com>
 *
 * Copyright (c) 2015 Amlogic. All Rights Reserved.
 *
 */
#include "key_manage_i.h"
#include <asm/arch/secure_apb.h>
#include <asm/io.h>
#include <common.h>

#include <amlogic/aml_efuse.h>

#define SECURE_BOOT_KEY_NAME    "secure_boot_set"

extern int efuse_usr_api_init_dtb(const char*  dt_addr);
extern int efuse_usr_api_get_cfg_key_size(const char* keyname, unsigned* pSz);
extern int efuse_usr_api_write_key(const char* keyname, const void* keydata, const unsigned dataSz);
extern int efuse_usr_api_read_key(const char* keyname, void* databuf, const unsigned bufSz);

int keymanage_efuse_init(const char *buf, int len)
{
    char ver;
    int ret = 0;

    const char* 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);
    if (ret) {
        KM_ERR("efuse init failed\n");
        return __LINE__;
    }

    ver = unifykey_get_efuse_version();
    if (ver == 0) {
        KM_DBG("efuse version not cfg\n");
        return 0;
    }

    //TODO: program the efuse version

    return ret;
}

int keymange_efuse_exit(void)
{
    return 0;
}

//must be hexdata if stored in efuse
int keymanage_efuse_write(const char *keyname, const void* keydata, unsigned int datalen)
{
    int ret = 0;

    if (!strcmp(SECURE_BOOT_KEY_NAME, keyname))
    {
            char _cmdbuf[96];
            sprintf(_cmdbuf, "efuse %s %p", keyname, keydata);
            ret = run_command(_cmdbuf, 0);;
    }
    else
    {
            ret = efuse_usr_api_write_key(keyname,  keydata, datalen);
    }

    return ret;
}

ssize_t keymanage_efuse_size(const char* keyname)
{
    int ret = 0;
    unsigned cfgSz = 0;

    ret = efuse_usr_api_get_cfg_key_size(keyname, &cfgSz);
    if (ret || !cfgSz) {
        KM_ERR("Fail at get cfg size for efuse key[%s]\n", keyname);
        return 0;
    }

    return cfgSz;
}

int keymanage_efuse_exist(const char* keyname)
{

        if (!strcmp(SECURE_BOOT_KEY_NAME, keyname))
        {
                const unsigned long cfg10 = IS_FEAT_BOOT_VERIFY();
                KM_MSG("cfg10=0x%lX\n", cfg10);
                return ( cfg10 );
        }
        else
        {
                int ret = 0;
                const ssize_t cfgSz = keymanage_efuse_size(keyname);
                char* databuf = NULL;
                int isEmpty = 1;
                int i = 0;

                databuf = (char*)malloc(cfgSz);
                if (!databuf) {
                        KM_ERR("Fail to alloc bufsz 0x%x for key %s\n", (unsigned)cfgSz, keyname);
                        return 0;
                }
                ret = keymanage_efuse_read(keyname, databuf, cfgSz);
                if (ret) {
                        KM_ERR("Fail at read key[%s]\n", keyname);
                        goto _exit;
                }
                for (i = 0; i < cfgSz && isEmpty; ++i) {
                        isEmpty = !databuf[i];
                }

_exit:
                free(databuf);
                return !isEmpty;
        }

        return __LINE__;
}

int keymanage_efuse_query_can_read(const char* keyname)
{
        if (!strcmp(SECURE_BOOT_KEY_NAME, keyname))
        {
                return 0;
        }
        else
        {
                return 1;//user space always can be read
        }
}

//data format is hexdata
int keymanage_efuse_read(const char *keyname, void* databuf, const unsigned bufSz)
{
    int ret = 0;
    unsigned cfgSz = 0;

    cfgSz = keymanage_efuse_size(keyname);
    if (cfgSz > bufSz) {
        KM_ERR("buf sz 0x%x < dts cfg sz 0x%x\n", bufSz, cfgSz);
        return __LINE__;
    }

    ret = efuse_usr_api_read_key(keyname, databuf, cfgSz);

    return ret;
}

