// Copyright 2016 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.
//
// This is a implementation of IAP firmware updater for STM32-based touchpads.

#include <cstdio>
#include <iomanip>
#include <map>
#include <string>
#include <vector>

#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <unistd.h>

#include <base/logging.h>
#include <base/command_line.h>
#include <base/files/file_util.h>
#include <base/strings/string_number_conversions.h>
#include <brillo/flag_helper.h>

#define GPIO_SYS "/sys/class/gpio/"
#define PULSE_WIDTH 100000  // 100ms reset pulse width, we need at least 300ns.

constexpr int kMaxI2CDevicePathLen = 150;

// Per-board specific configurations.
struct BoardConfig {
  uint8_t i2cBusMin;
  uint8_t i2cBusMax;
  uint8_t i2cSlaveAddress;
  uint32_t flash_size;
  uint32_t flash_address;
  uint32_t fwInfoAddress;
  int32_t bootGPIO;
  int32_t resetGPIO;
};

// Board specific configurations.
static std::map<std::string, struct BoardConfig> boardConfigs = {
    {
        "eve",
        {
            .i2cBusMin = 7,
            .i2cBusMax = 8,
            .i2cSlaveAddress = 0x46,
            .flash_size = 512 * 1024,
            .flash_address = 0x08000000,
            .fwInfoAddress = 0x80001c4,
            .bootGPIO = 432,
            .resetGPIO = 433,
        },
    },
};

// Global config instance.
static struct BoardConfig config;

enum StatusCode {
  ACK = 0x79,
  NACK = 0x1f,
  BUSY = 0x76,
};

class IAPFirmwareUpdater {
 public:
  IAPFirmwareUpdater(uint8_t i2cBusMin,
                     uint8_t u2cBusMax,
                     uint8_t slaveAddress);

  void Flash(uint32_t address, std::string path, bool verify);
  void ReadFirmware(std::string filename);
  void GetFirmwareVersion();
  bool EnterBootloader();
  void LeaveBootLoader();

 private:
  int i2c_fd_;

  // High level functions.
  void WriteFlash(uint32_t address, std::vector<uint8_t> data);
  std::vector<uint8_t> ReadFlash(uint32_t address, uint32_t length);

  // IAP I2C command wrapper functions.
  bool PollForAck(uint32_t timeoutMs = 5000);
  uint8_t GetVersion();
  int GetId();
  void Erase();
  bool WriteFlashChunk(uint32_t address, uint8_t length, uint8_t* data);
  bool ReadFlashChunk(uint32_t address, uint8_t length, uint8_t* data);

  // Helper functions.
  std::vector<uint8_t> LoadFirmware(std::string path);
  bool WriteCommand(uint8_t command);
  uint8_t ReadOneByte();

  bool WriteToFile(std::string path, std::string value);
};

IAPFirmwareUpdater::IAPFirmwareUpdater(uint8_t i2cBusMin,
                                       uint8_t i2cBusMax,
                                       uint8_t slaveAddress) {
  char dev_path[kMaxI2CDevicePathLen];

  for (uint8_t i = i2cBusMax; i >= i2cBusMin; i--) {
    snprintf(dev_path, kMaxI2CDevicePathLen, "/dev/i2c-%d", i);
    LOG(INFO) << "Attempting to probe <" << dev_path << "> for a touchpad";
    i2c_fd_ = open(dev_path, O_RDWR);
    if (i2c_fd_ < 0) {
      PLOG(INFO) << "Failed to open device";
      continue;
    } else {
      LOG(INFO) << "Successfully opened device, attempting to communicate";
    }

    if (ioctl(i2c_fd_, I2C_SLAVE_FORCE, slaveAddress)) {
      PLOG(INFO) << "Failed to set slave address 0x" << std::hex
                 << static_cast<int>(slaveAddress);
      close(i2c_fd_);
      continue;
    }

    if (!EnterBootloader()) {
      close(i2c_fd_);
    } else {
      LOG(INFO) << "Successfully entered bootloader mode, this is the one!";
      return;
    }
  }
}

bool IAPFirmwareUpdater::PollForAck(uint32_t timeoutMs) {
  struct timespec delay = {.tv_sec = 0, .tv_nsec = 250000000};
  uint8_t byte;
  uint32_t elapseMs = 0;
  struct timeval start, current;
  gettimeofday(&start, NULL);

  while (true) {
    switch ((byte = ReadOneByte())) {
      case ACK:
        return true;
      case NACK:
        return false;
      case BUSY:
        nanosleep(&delay, NULL);
        break;
      default:
        LOG(FATAL) << "PollForAck: unexpected byte 0x" << std::hex
                   << static_cast<int>(byte);
    }

    gettimeofday(&current, NULL);
    elapseMs = ((current.tv_sec - start.tv_sec) * 1000 +
                (current.tv_usec - start.tv_usec) / 1000);
    if (elapseMs > timeoutMs) {
      LOG(ERROR) << "PollForAck: timed out waiting for ACK";
      return false;
    }
  }
}

void IAPFirmwareUpdater::Flash(uint32_t address,
                               std::string path,
                               bool verify) {
  int id = GetId();
  LOG(INFO) << "BootLoader version: 0x" << std::hex
            << static_cast<int>(GetVersion());
  LOG(INFO) << "Chip ID: 0x" << std::hex << id;

  // Begin flashing
  std::vector<uint8_t> firmware = LoadFirmware(path);
  Erase();
  WriteFlash(address, firmware);
  std::vector<uint8_t> readFirmware = ReadFlash(address, firmware.size());

  if (verify) {
    LOG(INFO) << "Verifing firmware ...";
    for (unsigned i = 0; i < firmware.size(); i++) {
      if (firmware[i] != readFirmware[i]) {
        LOG(FATAL) << "Verification failed at 0x" << std::setfill('0')
                   << std::setw(8) << address + i;
      }
    }
    LOG(INFO) << "Firmware verified.";
  }

  LeaveBootLoader();
}

void IAPFirmwareUpdater::GetFirmwareVersion() {
  std::vector<uint8_t> version_bytes(4, 0);
  ReadFlashChunk(config.fwInfoAddress, version_bytes.size(),
                 version_bytes.data());
  uint32_t version = *reinterpret_cast<uint32_t*>(version_bytes.data());
  printf("0x%x\n", version);

  LeaveBootLoader();
}

void IAPFirmwareUpdater::ReadFirmware(std::string filename) {
  std::vector<uint8_t> firmware =
      ReadFlash(config.flash_address, config.flash_size);
  WriteToFile(filename, std::string(firmware.begin(), firmware.end()));
  LOG(INFO) << "Firmware saved to " << filename;

  LeaveBootLoader();
}

bool IAPFirmwareUpdater::EnterBootloader() {
  // Bootloader (IAP mode) can be entered by first asserting the BOOT pin
  // then toggle the reset pin.
  const std::string bootGPIO = base::NumberToString(config.bootGPIO);
  const std::string resetGPIO = base::NumberToString(config.resetGPIO);

  CHECK(WriteToFile(GPIO_SYS "export", bootGPIO));
  CHECK(WriteToFile(GPIO_SYS "export", resetGPIO));
  CHECK(WriteToFile(GPIO_SYS "gpio" + bootGPIO + "/direction", "out"));
  CHECK(WriteToFile(GPIO_SYS "gpio" + resetGPIO + "/direction", "out"));
  CHECK(WriteToFile(GPIO_SYS "gpio" + bootGPIO + "/value", "1"));
  CHECK(WriteToFile(GPIO_SYS "gpio" + resetGPIO + "/value", "1"));
  usleep(PULSE_WIDTH);
  CHECK(WriteToFile(GPIO_SYS "gpio" + resetGPIO + "/value", "0"));
  usleep(PULSE_WIDTH);
  CHECK(WriteToFile(GPIO_SYS "gpio" + bootGPIO + "/value", "0"));
  CHECK(WriteToFile(GPIO_SYS "unexport", bootGPIO));
  CHECK(WriteToFile(GPIO_SYS "unexport", resetGPIO));

  int id = GetId();
  if (id == -1) {
    LOG(INFO) << "Failed to enter bootloader mode.";
    return false;
  }
  return true;
}

void IAPFirmwareUpdater::LeaveBootLoader() {
  const std::string bootGPIO = base::NumberToString(config.bootGPIO);
  const std::string resetGPIO = base::NumberToString(config.resetGPIO);

  CHECK(WriteToFile(GPIO_SYS "export", bootGPIO));
  CHECK(WriteToFile(GPIO_SYS "export", resetGPIO));
  CHECK(WriteToFile(GPIO_SYS "gpio" + bootGPIO + "/direction", "out"));
  CHECK(WriteToFile(GPIO_SYS "gpio" + resetGPIO + "/direction", "out"));
  CHECK(WriteToFile(GPIO_SYS "gpio" + bootGPIO + "/value", "0"));
  CHECK(WriteToFile(GPIO_SYS "gpio" + resetGPIO + "/value", "1"));
  usleep(PULSE_WIDTH);
  CHECK(WriteToFile(GPIO_SYS "gpio" + resetGPIO + "/value", "0"));
  CHECK(WriteToFile(GPIO_SYS "unexport", bootGPIO));
  CHECK(WriteToFile(GPIO_SYS "unexport", resetGPIO));
}

void IAPFirmwareUpdater::WriteFlash(uint32_t address,
                                    std::vector<uint8_t> data) {
  const uint32_t chunkSize = 200;
  uint32_t length = data.size();
  uint32_t sent = 0, to_send = 0;
  uint8_t* buffer = data.data();

  LOG(INFO) << "Writing flash ";
  while (sent < length) {
    printf(".");
    fflush(stdout);
    to_send = std::min(chunkSize, length - sent);
    if (!WriteFlashChunk(address + sent, to_send, buffer + sent)) {
      LOG(FATAL) << "WriteFlashChunk failed at 0x" << std::hex
                 << std::setfill('0') << std::setw(8) << sent;
    }
    sent += to_send;
  }
  printf("\n");
}

std::vector<uint8_t> IAPFirmwareUpdater::ReadFlash(uint32_t address,
                                                   uint32_t length) {
  const uint32_t chunkSize = 200;
  std::vector<uint8_t> data(length, 0);
  uint8_t* buffer = data.data();
  uint32_t read = 0, to_read = 0;

  LOG(INFO) << "Reading flash ";
  while (read < length) {
    printf(".");
    fflush(stdout);
    to_read = std::min(chunkSize, length - read);
    if (!ReadFlashChunk(address + read, to_read, buffer + read)) {
      LOG(FATAL) << "ReadFlashChunk failed at 0x" << std::hex
                 << std::setfill('0') << std::setw(8) << read;
    }
    read += to_read;
  }
  printf("\n");
  return data;
}

uint8_t IAPFirmwareUpdater::GetVersion() {
  CHECK(WriteCommand(0x01));
  CHECK(PollForAck());
  uint8_t version = ReadOneByte();
  CHECK(PollForAck());
  return version;
}

int IAPFirmwareUpdater::GetId() {
  uint8_t idBuf[3];
  if (!WriteCommand(0x02)) {
    return -1;
  }
  if (!PollForAck()) {
    return -1;
  }
  if (read(i2c_fd_, idBuf, 3) != 3) {
    return -1;
  }
  if (!PollForAck()) {
    return -1;
  }
  return idBuf[1] << 8 | idBuf[2];
}

void IAPFirmwareUpdater::Erase() {
  LOG(INFO) << "Starting full erase ... ";
  fflush(stdout);

  CHECK(WriteCommand(0x45));
  CHECK(PollForAck());
  uint8_t idBuf[3] = {0xff, 0xff, 0x00};
  CHECK_EQ(write(i2c_fd_, idBuf, 3), 3);
  CHECK(PollForAck(60000));
  LOG(INFO) << "done";
}

bool IAPFirmwareUpdater::WriteFlashChunk(uint32_t address,
                                         uint8_t length,
                                         uint8_t* data) {
  CHECK(WriteCommand(0x31));
  CHECK(PollForAck());
  uint8_t addr[5];
  uint8_t checksum = 0;

  for (int i = 0; i < 4; i++) {
    addr[i] = (address >> (24 - i * 8)) & 0xff;
    checksum ^= addr[i];
  }
  addr[4] = checksum;
  CHECK_EQ(write(i2c_fd_, addr, 5), 5);
  CHECK(PollForAck());

  uint8_t buffer[300] = {0};
  int offset = 0;
  buffer[offset++] = length - 1;

  checksum = length - 1;
  for (int i = 0; i < length; i++) {
    buffer[offset++] = data[i];
    checksum ^= data[i];
  }
  buffer[offset++] = checksum;
  CHECK_EQ(write(i2c_fd_, buffer, offset), offset);
  CHECK(PollForAck());
  return true;
}

bool IAPFirmwareUpdater::ReadFlashChunk(uint32_t address,
                                        uint8_t length,
                                        uint8_t* data) {
  CHECK(WriteCommand(0x11));
  CHECK(PollForAck());
  uint8_t addr[5];
  uint8_t checksum = 0;

  for (int i = 0; i < 4; i++) {
    addr[i] = (address >> (24 - i * 8)) & 0xff;
    checksum ^= addr[i];
  }
  addr[4] = checksum;
  CHECK_EQ(write(i2c_fd_, addr, 5), 5);
  CHECK(PollForAck());

  uint8_t size = length - 1;
  uint8_t len[2] = {size, static_cast<uint8_t>(~size)};
  CHECK_EQ(write(i2c_fd_, len, 2), 2);
  CHECK(PollForAck());

  CHECK_EQ(read(i2c_fd_, data, length), length);
  return true;
}

std::vector<uint8_t> IAPFirmwareUpdater::LoadFirmware(std::string path) {
  std::string buf;
  CHECK(base::ReadFileToString(base::FilePath(path), &buf))
      << "Failed to load firmware: " << path;
  return std::vector<uint8_t>(buf.begin(), buf.end());
}

bool IAPFirmwareUpdater::WriteCommand(uint8_t command) {
  uint8_t buffer[2] = {command, static_cast<uint8_t>(~command)};
  return write(i2c_fd_, buffer, 2) == 2;
}

uint8_t IAPFirmwareUpdater::ReadOneByte() {
  uint8_t byte;
  CHECK_EQ(read(i2c_fd_, &byte, 1), 1);
  return byte;
}

bool IAPFirmwareUpdater::WriteToFile(std::string path, std::string value) {
  return (base::WriteFile(base::FilePath(path), value.c_str(), value.size()) ==
          value.size());
}

int main(int argc, const char* argv[]) {
  DEFINE_string(board, "", "Target board to update");
  DEFINE_string(read, "", "Read current firmware content to file");
  DEFINE_bool(fw_version, false, "Get current firmware version");
  DEFINE_bool(enter_bootloader, false, "Enter bootloader mode");
  DEFINE_bool(leave_bootloader, false, "Leave bootloader mode");
  brillo::FlagHelper::Init(argc, argv, "STM32 IAP firmware updater");

  if (!FLAGS_board.length()) {
    LOG(FATAL) << "No board specified";
  }

  if (boardConfigs.find(FLAGS_board) == boardConfigs.end()) {
    LOG(FATAL) << "Unsupported board " << FLAGS_board;
  }
  config = boardConfigs[FLAGS_board];

  auto updater = IAPFirmwareUpdater(config.i2cBusMin, config.i2cBusMax,
                                    config.i2cSlaveAddress);

  if (FLAGS_fw_version) {
    updater.GetFirmwareVersion();
  } else if (FLAGS_read.length()) {
    updater.ReadFirmware(FLAGS_read);
  } else if (FLAGS_enter_bootloader) {
    // Do nothing as the constructor already enters bootloader
  } else if (FLAGS_leave_bootloader) {
    updater.LeaveBootLoader();
  } else {
    auto commandline = base::CommandLine::ForCurrentProcess();
    auto args = commandline->GetArgs();
    if (args.size() >= 1) {
      updater.Flash(config.flash_address, args[0], true);
    }
  }
  return 0;
}
