/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <linux/fs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#include <netinet/in.h>

#include "vboot_common.h"
#include "vboot_nvstorage.h"
#include "host_common.h"
#include "crossystem.h"
#include "crossystem_arch.h"

#define MOSYS_PATH "/usr/sbin/mosys"

/* Base name for firmware FDT files */
#define FDT_BASE_PATH "/proc/device-tree/firmware/chromeos"
/* Path to compatible FDT entry */
#define FDT_COMPATIBLE_PATH "/proc/device-tree/compatible"
/* Path to the chromeos_arm platform device */
#define PLATFORM_DEV_PATH "/sys/devices/platform/chromeos_arm"
/* Device for NVCTX write */
#define NVCTX_PATH "/dev/mmcblk%d"
/* Base name for GPIO files */
#define GPIO_BASE_PATH "/sys/class/gpio"
#define GPIO_EXPORT_PATH GPIO_BASE_PATH "/export"
/* Name of NvStorage type property */
#define FDT_NVSTORAGE_TYPE_PROP "nonvolatile-context-storage"
/* Errors */
#define E_FAIL      -1
#define E_FILEOP    -2
#define E_MEM       -3
/* Common constants */
#define FNAME_SIZE  80
#define SECTOR_SIZE 512
#define MAX_NMMCBLK 9

typedef struct PlatformFamily {
  const char* compatible_string; /* Last string in FDT compatible entry */
  const char* platform_string;   /* String to return */
} PlatformFamily;

/* Array of platform family names, terminated with a NULL entry */
const PlatformFamily platform_family_array[] = {
  {"nvidia,tegra250", "Tegra2"},
  {"nvidia,tegra20", "Tegra2"},
  {"ti,omap4", "OMAP4"},
  {"ti,omap3", "OMAP3"},
  {"samsung,exynos4210", "EXYNOS4"},
  {"samsung,exynos5250", "EXYNOS5"},
  /* Terminate with NULL entry */
  {NULL, NULL}
};

static int FindEmmcDev(void) {
  int mmcblk;
  char filename[FNAME_SIZE];
  for (mmcblk = 0; mmcblk < MAX_NMMCBLK; mmcblk++) {
    /* Get first non-removable mmc block device */
    snprintf(filename, sizeof(filename), "/sys/block/mmcblk%d/removable",
              mmcblk);
    if (ReadFileInt(filename) == 0)
      return mmcblk;
  }
  /* eMMC not found */
  return E_FAIL;
}

static int ReadFdtValue(const char *property, int *value) {
  char filename[FNAME_SIZE];
  FILE *file;
  int data = 0;

  snprintf(filename, sizeof(filename), FDT_BASE_PATH "/%s", property);
  file = fopen(filename, "rb");
  if (!file) {
    fprintf(stderr, "Unable to open FDT property %s\n", property);
    return E_FILEOP;
  }

  fread(&data, 1, sizeof(data), file);
  fclose(file);

  if (value)
    *value = ntohl(data); /* FDT is network byte order */

  return 0;
}

static int ReadFdtInt(const char *property) {
  int value;
  if (ReadFdtValue(property, &value))
    return E_FAIL;
  return value;
}

static void GetFdtPropertyPath(const char *property, char *path, size_t size) {
  if (property[0] == '/')
    StrCopy(path, property, size);
  else
    snprintf(path, size, FDT_BASE_PATH "/%s", property);
}

static int FdtPropertyExist(const char *property) {
  char filename[FNAME_SIZE];
  struct stat file_status;

  GetFdtPropertyPath(property, filename, sizeof(filename));
  if (!stat(filename, &file_status))
    return 1; // It exists!
  else
    return 0; // It does not exist or some error happened.
}

static int ReadFdtBlock(const char *property, void **block, size_t *size) {
  char filename[FNAME_SIZE];
  FILE *file;
  size_t property_size;
  char *data;

  if (!block)
    return E_FAIL;

  GetFdtPropertyPath(property, filename, sizeof(filename));
  file = fopen(filename, "rb");
  if (!file) {
    fprintf(stderr, "Unable to open FDT property %s\n", property);
    return E_FILEOP;
  }

  fseek(file, 0, SEEK_END);
  property_size = ftell(file);
  rewind(file);

  data = malloc(property_size +1);
  if (!data) {
    fclose(file);
    return E_MEM;
  }
  data[property_size] = 0;

  if (1 != fread(data, property_size, 1, file)) {
    fprintf(stderr, "Unable to read from property %s\n", property);
    fclose(file);
    free(data);
    return E_FILEOP;
  }

  fclose(file);
  *block = data;
  if (size)
    *size = property_size;

  return 0;
}

static char * ReadFdtString(const char *property) {
  void *str = NULL;
  /* Do not need property size */
  ReadFdtBlock(property, &str, 0);
  return (char *)str;
}

static char * ReadFdtPlatformFamily(void) {
  char *compat = NULL;
  char *s;
  const PlatformFamily* p;
  size_t size = 0;
  int slen;

  if(ReadFdtBlock(FDT_COMPATIBLE_PATH, (void **)&compat, &size))
    return NULL;

  if (size > 0)
    compat[size-1] = 0;

  /* Check each null separated string in compatible against the family array */
  s = compat;
  while ((s-compat) < size) {
    slen = strlen(s);
    for (p = platform_family_array; p->compatible_string; p++) {
      if (!strcmp(s, p->compatible_string)) {
        free(compat);
        return strdup(p->platform_string);
      }
    }
    s += slen + 1;
  }

  /* No recognized 'compatible' entry found */
  free(compat);
  return NULL;
}

static int VbGetPlatformGpioStatus(const char* name) {
  char gpio_name[FNAME_SIZE];
  int value;

  snprintf(gpio_name, sizeof(gpio_name), "%s/%s/value",
           PLATFORM_DEV_PATH, name);
  value = ReadFileInt(gpio_name);

  return value;
}

static int VbGetGpioStatus(unsigned gpio_number) {
  char gpio_name[FNAME_SIZE];
  int value;

  snprintf(gpio_name, sizeof(gpio_name), "%s/gpio%d/value",
           GPIO_BASE_PATH, gpio_number);
  value = ReadFileInt(gpio_name);

  if (value == -1) {
    /* Try exporting the GPIO */
    FILE* f = fopen(GPIO_EXPORT_PATH, "wt");
    if (!f)
      return -1;
    fprintf(f, "%d", gpio_number);
    fclose(f);

    /* Try re-reading the GPIO value */
    value = ReadFileInt(gpio_name);
  }

  return value;
}

static int VbGetVarGpio(const char* name) {
  int gpio_num;
  void *pp = NULL;
  int *prop;
  size_t proplen = 0;
  int ret = 0;

  /* TODO: This should at some point in the future use the phandle
   * to find the gpio chip and thus the base number. Assume 0 now,
   * which isn't 100% future-proof (i.e. if one of the switches gets
   * moved to an offchip gpio controller.
   */

  ret = ReadFdtBlock(name, &pp, &proplen);
  if (ret || !pp || proplen != 12) {
    ret = 2;
    goto out;
  }
  prop = pp;
  gpio_num = ntohl(prop[1]);

  /*
   * TODO(chrome-os-partner:11296): Use gpio_num == 0 to denote non-exist
   * GPIO for now, at the risk that one day we might actually want to read
   * from a GPIO port 0.  We should figure out how to represent "non-exist"
   * properly.
   */
  if (gpio_num)
    ret = VbGetGpioStatus(gpio_num);
  else
    ret = -1;
out:
  if (pp)
    free(pp);

  return ret;
}

static int ExecuteMosys(char * const argv[], char *buf, size_t bufsize) {
  int status, mosys_to_crossystem[2];
  pid_t pid;
  ssize_t n;

  if (pipe(mosys_to_crossystem) < 0) {
    VBDEBUG(("pipe() error\n"));
    return -1;
  }

  if ((pid = fork()) < 0) {
    VBDEBUG(("fork() error\n"));
    close(mosys_to_crossystem[0]);
    close(mosys_to_crossystem[1]);
    return -1;
  } else if (!pid) {  /* Child */
    close(mosys_to_crossystem[0]);
    /* Redirect pipe's write-end to mosys' stdout */
    if (STDOUT_FILENO != mosys_to_crossystem[1]) {
      if (dup2(mosys_to_crossystem[1], STDOUT_FILENO) != STDOUT_FILENO) {
        VBDEBUG(("stdout dup2() failed (mosys)\n"));
        close(mosys_to_crossystem[1]);
        exit(1);
      }
    }
    /* Execute mosys */
    execv(MOSYS_PATH, argv);
    /* We shouldn't be here; exit now! */
    VBDEBUG(("execv() of mosys failed\n"));
    close(mosys_to_crossystem[1]);
    exit(1);
  } else {  /* Parent */
    close(mosys_to_crossystem[1]);
    if (bufsize) {
      bufsize--;  /* Reserve 1 byte for '\0' */
      while ((n = read(mosys_to_crossystem[0], buf, bufsize)) > 0) {
        buf += n;
        bufsize -= n;
      }
      *buf = '\0';
    } else {
      n = 0;
    }
    close(mosys_to_crossystem[0]);
    if (n < 0)
      VBDEBUG(("read() error while reading output from mosys\n"));
    if (waitpid(pid, &status, 0) < 0 || status) {
      VBDEBUG(("waitpid() or mosys error\n"));
      fprintf(stderr, "waitpid() or mosys error\n");
      return -1;
    }
    if (n < 0)
      return -1;
  }
  return 0;
}

static int VbReadNvStorage_mkbp(VbNvContext* vnc) {
  char hexstring[VBNV_BLOCK_SIZE * 2 + 32];  /* Reserve extra 32 bytes */
  char * const argv[] = {
    MOSYS_PATH, "nvram", "vboot", "read", NULL
  };
  char hexdigit[3];
  int i;

  if (ExecuteMosys(argv, hexstring, sizeof(hexstring)))
    return -1;
  hexdigit[2] = '\0';
  for (i = 0; i < VBNV_BLOCK_SIZE; i++) {
    hexdigit[0] = hexstring[i * 2];
    hexdigit[1] = hexstring[i * 2 + 1];
    vnc->raw[i] = strtol(hexdigit, NULL, 16);
  }
  return 0;
}

static int VbWriteNvStorage_mkbp(VbNvContext* vnc) {
  char hexstring[VBNV_BLOCK_SIZE * 2 + 1];
  char * const argv[] = {
    MOSYS_PATH, "nvram", "vboot", "write", hexstring, NULL
  };
  int i;

  for (i = 0; i < VBNV_BLOCK_SIZE; i++)
    snprintf(hexstring + i * 2, 3, "%02x", vnc->raw[i]);
  hexstring[sizeof(hexstring) - 1] = '\0';
  if (ExecuteMosys(argv, NULL, 0))
    return -1;
  return 0;
}

static int VbReadNvStorage_disk(VbNvContext* vnc) {
  int nvctx_fd = -1;
  uint8_t sector[SECTOR_SIZE];
  int rv = -1;
  char nvctx_path[FNAME_SIZE];
  int emmc_dev;
  int lba = ReadFdtInt("nonvolatile-context-lba");
  int offset = ReadFdtInt("nonvolatile-context-offset");
  int size = ReadFdtInt("nonvolatile-context-size");

  emmc_dev = FindEmmcDev();
  if (emmc_dev < 0)
    return E_FAIL;
  snprintf(nvctx_path, sizeof(nvctx_path), NVCTX_PATH, emmc_dev);

  if (size != sizeof(vnc->raw) || (size + offset > SECTOR_SIZE))
    return E_FAIL;

  nvctx_fd = open(nvctx_path, O_RDONLY);
  if (nvctx_fd == -1) {
    fprintf(stderr, "%s: failed to open %s\n", __FUNCTION__, nvctx_path);
    goto out;
  }
  lseek(nvctx_fd, lba * SECTOR_SIZE, SEEK_SET);

  rv = read(nvctx_fd, sector, SECTOR_SIZE);
  if (size <= 0) {
    fprintf(stderr, "%s: failed to read nvctx from device %s\n",
            __FUNCTION__, nvctx_path);
    goto out;
  }
  Memcpy(vnc->raw, sector+offset, size);
  rv = 0;

out:
  if (nvctx_fd > 0)
    close(nvctx_fd);

  return rv;
}

static int VbWriteNvStorage_disk(VbNvContext* vnc) {
  int nvctx_fd = -1;
  uint8_t sector[SECTOR_SIZE];
  int rv = -1;
  char nvctx_path[FNAME_SIZE];
  int emmc_dev;
  int lba = ReadFdtInt("nonvolatile-context-lba");
  int offset = ReadFdtInt("nonvolatile-context-offset");
  int size = ReadFdtInt("nonvolatile-context-size");

  emmc_dev = FindEmmcDev();
  if (emmc_dev < 0)
    return E_FAIL;
  snprintf(nvctx_path, sizeof(nvctx_path), NVCTX_PATH, emmc_dev);

  if (size != sizeof(vnc->raw) || (size + offset > SECTOR_SIZE))
    return E_FAIL;

  do {
    nvctx_fd = open(nvctx_path, O_RDWR);
    if (nvctx_fd == -1) {
      fprintf(stderr, "%s: failed to open %s\n", __FUNCTION__, nvctx_path);
      break;
    }
    lseek(nvctx_fd, lba * SECTOR_SIZE, SEEK_SET);
    rv = read(nvctx_fd, sector, SECTOR_SIZE);
    if (rv <= 0) {
      fprintf(stderr, "%s: failed to read nvctx from device %s\n",
              __FUNCTION__, nvctx_path);
      break;
    }
    Memcpy(sector+offset, vnc->raw, size);
    lseek(nvctx_fd, lba * SECTOR_SIZE, SEEK_SET);
    rv = write(nvctx_fd, sector, SECTOR_SIZE);
    if (rv <= 0) {
      fprintf(stderr,  "%s: failed to write nvctx to device %s\n",
              __FUNCTION__, nvctx_path);
      break;
    }
    /* Must flush buffer cache here to make sure it goes to disk */
    rv = ioctl(nvctx_fd, BLKFLSBUF, 0);
    if (rv < 0) {
      fprintf(stderr,  "%s: failed to flush nvctx to device %s\n",
              __FUNCTION__, nvctx_path);
      break;
    }
    rv = 0;
  } while (0);

  if (nvctx_fd > 0)
    close(nvctx_fd);

  return rv;
}

int VbReadNvStorage(VbNvContext* vnc) {
  /* Default to disk for older firmware which does not provide storage type */
  char *media;
  if (!FdtPropertyExist(FDT_NVSTORAGE_TYPE_PROP))
    return VbReadNvStorage_disk(vnc);
  media = ReadFdtString(FDT_NVSTORAGE_TYPE_PROP);
  if (!strcmp(media, "disk"))
    return VbReadNvStorage_disk(vnc);
  if (!strcmp(media, "mkbp"))
    return VbReadNvStorage_mkbp(vnc);
  return -1;
}

int VbWriteNvStorage(VbNvContext* vnc) {
  /* Default to disk for older firmware which does not provide storage type */
  char *media;
  if (!FdtPropertyExist(FDT_NVSTORAGE_TYPE_PROP))
    return VbWriteNvStorage_disk(vnc);
  media = ReadFdtString(FDT_NVSTORAGE_TYPE_PROP);
  if (!strcmp(media, "disk"))
    return VbWriteNvStorage_disk(vnc);
  if (!strcmp(media, "mkbp"))
    return VbWriteNvStorage_mkbp(vnc);
  return -1;
}

VbSharedDataHeader *VbSharedDataRead(void) {
  void *block = NULL;
  size_t size = 0;
  if (ReadFdtBlock("vboot-shared-data", &block, &size))
    return NULL;
  VbSharedDataHeader *p = (VbSharedDataHeader *)block;
  if (p->magic != VB_SHARED_DATA_MAGIC) {
    fprintf(stderr,  "%s: failed to validate magic in "
            "VbSharedDataHeader (%x != %x)\n",
            __FUNCTION__, p->magic, VB_SHARED_DATA_MAGIC);
    return NULL;
  }
  return (VbSharedDataHeader *)block;
}

int VbGetArchPropertyInt(const char* name) {
  if (!strcasecmp(name, "fmap_base")) {
    return ReadFdtInt("fmap-offset");
  } else if (!strcasecmp(name, "devsw_cur")) {
    /* Systems with virtual developer switches return at-boot value */
    int flags = VbGetSystemPropertyInt("vdat_flags");
    if ((flags != -1) && (flags & VBSD_HONOR_VIRT_DEV_SWITCH))
      return VbGetSystemPropertyInt("devsw_boot");

    return VbGetVarGpio("developer-switch");
  } else if (!strcasecmp(name, "recoverysw_cur")) {
    return VbGetVarGpio("recovery-switch");
  } else if (!strcasecmp(name, "wpsw_cur")) {
    int value;
    /* Try finding the GPIO through the chromeos_arm platform device first. */
    value = VbGetPlatformGpioStatus("write-protect");
    if (value != -1)
      return value;
    return VbGetVarGpio("write-protect-switch");
  } else if (!strcasecmp(name, "recoverysw_ec_boot"))
    /* TODO: read correct value using ectool */
    return 0;
  else
    return -1;
}

const char* VbGetArchPropertyString(const char* name, char* dest, int size) {
  char *str = NULL;
  char *rv = NULL;
  char *prop = NULL;

  if (!strcasecmp(name,"arch"))
    return StrCopy(dest, "arm", size);

  /* Properties from fdt */
  if (!strcasecmp(name, "ro_fwid"))
    prop = "readonly-firmware-version";
  else if (!strcasecmp(name, "hwid"))
    prop = "hardware-id";
  else if (!strcasecmp(name, "fwid"))
    prop = "firmware-version";
  else if (!strcasecmp(name, "mainfw_type"))
    prop = "firmware-type";
  else if (!strcasecmp(name, "ecfw_act"))
    prop = "active-ec-firmware";
  else if (!strcasecmp(name, "ddr_type"))
    prop = "ddr-type";

  if (prop)
    str = ReadFdtString(prop);

  if (!strcasecmp(name, "platform_family"))
    str = ReadFdtPlatformFamily();

  if (str) {
      rv = StrCopy(dest, str, size);
      free(str);
      return rv;
  }
  return NULL;
}

int VbSetArchPropertyInt(const char* name, int value) {
  /* All is handled in arch independent fashion */
  return -1;
}

int VbSetArchPropertyString(const char* name, const char* value) {
  /* All is handled in arch independent fashion */
  return -1;
}

int VbArchInit(void)
{
  return 0;
}
