/* 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 <stddef.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,tegra124", "Tegra5"},
  {"nvidia,tegra250", "Tegra2"},
  {"nvidia,tegra20", "Tegra2"},
  {"ti,omap4", "OMAP4"},
  {"ti,omap3", "OMAP3"},
  {"samsung,exynos4210", "EXYNOS4"},
  {"samsung,exynos5250", "EXYNOS5"},
  {"samsung,exynos5420", "EXYNOS5"},
  {"qcom,ipq8064", "IPQ8064"},
  /* Terminate with NULL entry */
  {NULL, NULL}
};

static int FindEmmcDev(void) {
  int mmcblk;
  unsigned value;
  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, &value) < 0)
      continue;
    if (value == 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;
  }

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

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

  return 0;
}

static int ReadFdtInt(const char *property) {
  int value = 0;
  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];
  unsigned value;

  snprintf(gpio_name, sizeof(gpio_name), "%s/%s/value",
           PLATFORM_DEV_PATH, name);
  if (ReadFileInt(gpio_name, &value) < 0)
    return -1;

  return (int)value;
}

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

  snprintf(gpio_name, sizeof(gpio_name), "%s/gpio%d/value",
           GPIO_BASE_PATH, gpio_number);
  if (ReadFileInt(gpio_name, &value) < 0) {
    /* 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 */
    if (ReadFileInt(gpio_name, &value) < 0)
      return -1;
  }

  return (int)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_mosys(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_mosys(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") || !strcmp(media, "flash"))
    return VbReadNvStorage_mosys(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") || !strcmp(media, "flash"))
    return VbWriteNvStorage_mosys(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")) {
    int value;
    value = VbGetPlatformGpioStatus("recovery");
    if (value != -1)
      return value;

    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,
                                    size_t 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;
}
