/*
 * cmd_hnvram.c -- makes hnvram contents available in u-boot.
 *      Loads contents of hnvram from spi flash and saves it
 *      to environment variables named HNV_<name>.
 *
 * Copyright (C) 2015 Google Inc.
 * Author: Chris Gibson <cgibson@google.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <command.h>
#include <common.h>
#include <malloc.h>
#include <spi_flash.h>

/* local debug macro */
#undef HNVRAM_DEBUG

#ifdef HNVRAM_DEBUG
#define DEBUG(fmt, args...)  printf(fmt, ##args)
#else
#define DEBUG(fmt, args...)
#endif  /* HNVRAM_DEBUG */

#define CONFIG_SF_DEFAULT_MODE SPI_MODE_3


// Flash erase block size
#define HNVRAM_BLOCKSIZE 0x00010000

// Location in DRAM where hnvram variables are stored during boot
// DRAM is 128 MB [0x80000000 - 0x88000000]
// Store hnvram at 120 - 122 MB
#define HNVRAM_DRAM_OFFSET 0x87800000

// Where in flash does hnvram partition start
#define HNVRAM_MTD_OFFSET 0x00200000

// Total hnvram is 2MB with 4 partitions
#define MAX_HNVRAM_SIZE     0x00200000

#define HNVRAM_RO_SIZE      0x00100000
#define HNVRAM_RW_SIZE      0x00040000
#define HNVRAM_RWB_SIZE     0x00020000
#define HNVRAM_RAW_FS_SIZE  0x00020000

// B1 and B2 corresponding to RW_OFFSET and RWB_OFFSET
#define HNVRAM_B1_OFFSET  (HNVRAM_RO_SIZE)
#define HNVRAM_B2_OFFSET  (HNVRAM_RO_SIZE + HNVRAM_RW_SIZE)

#define CMD_RET_SUCCESS 0
#define CMD_RET_FAILURE 1
#define CMD_RET_USAGE -1

// These keys are stored in binary format for historical reasons
const char *hnvram_binary_keys[] = {
        "LOADER_VERSION",
        "HDCP_KEY",
        "DTCP_KEY",
};

static void *xmalloc(size_t size)
{
        void *p = NULL;
        if (!(p = malloc(size))) {
                printf("error: memory not allocated\n");
                return 0;
        }
        memset(p, 0, size);
        return p;
}

int read_u8(const char **p)
{
        int v = *(const unsigned char *)(*p);
        *p += 1;
        return v;
}

int read_s32_be(const char **p)
{
        const unsigned char *vp = (const unsigned char *)*p;
        *p += 4;
        return (vp[0]<<24) + (vp[1]<<16) + (vp[2]<<8) + vp[3];
}

int read_u16_le(const char **p)
{
        const unsigned char *up = (const unsigned char *)(*p);
        *p += 2;
        return up[0] + (up[1] << 8);
}

int is_hnvram_binary(const char *name, int namelen)
{
        int i;
        for (i = 0; i < ARRAY_SIZE(hnvram_binary_keys); i++) {
                const char *k = hnvram_binary_keys[i];
                if ((int)strlen(k) == namelen && strncmp(k, name, namelen) == 0) {
                        return 1;
                }
        }
        return 0;
}

char *encode_hex(const char *s, int len)
{
        char *optr, *out = xmalloc(len * 2 + 1);
        for (optr = out; len > 0; len--) {
                sprintf(optr, "%02x", read_u8(&s));
                optr += 2;
        }
        return out;
}

char *encode_macaddr(const char *mac)
{
        int i;
        char *out = xmalloc(6 * 2 + 5 + 2);
        for (i = 0; i < 6; i++) {
                sprintf(out + i * 3, "%02X:", read_u8(&mac));
        }
        out[6*2 + 5] = '\0';
        return out;
}

static void _copy_setenv(const char *name, int namelen,
                const char *val, int vallen)
{
        char *n, *v;
        if (namelen + vallen < 128) {
                n = xmalloc(4 + namelen + 1);
                v = xmalloc(vallen + 1);
                memcpy(n, "HNV_", 4);
                memcpy(n + 4, name, namelen);
                memcpy(v, val, vallen);
                n[namelen+4] = 0;
                v[vallen] = 0;
                setenv(n, v);
                free(n);
                free(v);
        } else {
                DEBUG("ignoring oversized val: %.15s, vallen: %d\n", val, vallen);
        }
}

static int _parse_hnvram(const char *buf, int len)
{
        // An hnvram structure. Format is a tag-length-value sequence of:
        //    [1 byte]   type (1 for notdone, 0 for done)
        //    [4 bytes]  record length
        //    [1 byte]   key length
        //    [x bytes]  key
        //    [4 bytes]  value length
        //    [y bytes]  value
        int rectype, reclen, namelen, vallen;
        int done = 0;
        const char *name, *val, *p = buf;
        while (p - buf <= len + 11) {
                rectype = read_u8(&p);
                if (rectype == 0x00) {
                        printf("done processing hnvram block!\n");
                        done = 1;
                        break;
                }
                if (rectype != 0x01) {
                        printf("error: hnvram invalid rectype %x\n", rectype);
                        return -1;
                }

                reclen = read_s32_be(&p);
                if (reclen <= 6 || (p - buf) + reclen >= len) {
                        printf("error: hnvram invalid reclen %d\n", reclen);
                        return -1;
                }
                namelen = read_u8(&p);
                if (namelen < 1 || (p - buf) + namelen >= len) {
                        printf("error: hnvram invalid namelen %d\n", namelen);
                        return -1;
                }
                name = p;
                p += namelen;
                vallen = read_s32_be(&p);
                if (vallen < 0 || (p - buf) + vallen >= len) {
                        printf("error: hnvram invalid vallen %d\n", vallen);
                        return -1;
                }
                val = p;
                p += vallen;
                if (vallen == 6 && namelen >= 8 &&
                                strncmp("MAC_ADDR", name, 8) == 0) {
                        char *macstr = encode_macaddr(val);
                        _copy_setenv(name, namelen, macstr, strlen(macstr));
                        free(macstr);
                } else if (is_hnvram_binary(name, namelen)) {
                        char *hexstr = encode_hex(val, vallen);
                        _copy_setenv(name, namelen, hexstr, strlen(hexstr));
                        free(hexstr);
                } else {
                        _copy_setenv(name, namelen, val, vallen);
                }
        }
        if (!done) {
                printf("error: failed to find final hnvram record?\n");
                return -1;
        }
        return 0;
}

#if defined(CONFIG_CMD_HNVRAM)
int do_hnvram(void) {
        char command[60];
        sprintf(command, "spi_flash read 0x%x 0x%x 0x%x", HNVRAM_MTD_OFFSET, HNVRAM_DRAM_OFFSET, MAX_HNVRAM_SIZE);
        int ret = run_command(command, 0);

        if (ret) {
          printf("failed reading from spi-flash at addr: %d\n", HNVRAM_MTD_OFFSET);
          return ret;
        }

        char *buf = HNVRAM_DRAM_OFFSET;

        // Next step: Seek to different parts of the buffer that contain the
        // first, second, and third sections of hnvram.
        if (_parse_hnvram(buf, HNVRAM_BLOCKSIZE) != 0) {
                printf("failed parsing hnvram at offset: 0x%p\n", buf);
                return -1;
        }
        if (_parse_hnvram(buf+HNVRAM_B1_OFFSET, HNVRAM_BLOCKSIZE) != 0) {
                printf("failed parsing hnvram at offset: 0x%p\n", buf+HNVRAM_B1_OFFSET);
                return -1;
        }
        if (_parse_hnvram(buf+HNVRAM_B2_OFFSET, HNVRAM_BLOCKSIZE) != 0) {
                printf("failed parsing hnvram at offset: 0x%p\n", buf+HNVRAM_B2_OFFSET);
                return -1;
        }

        free(buf);
        return CMD_RET_SUCCESS;
}

static int do_hnvram_cmd(cmd_tbl_t *cmdtp, int flag, int argc,
                char * const argv[]) {
        return do_hnvram();
}

U_BOOT_CMD(
        hnvram, 1, 0, do_hnvram_cmd,
        "load hnvram from flash",
        "\n"
        "load hnvram from flash into environment vars named HNV_<name>\n"
        );
#endif  /* CONFIG_CMD_HNVRAM */
