// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "sw/device/boot_rom/bootstrap.h"

#include "sw/device/lib/common.h"
#include "sw/device/lib/flash_ctrl.h"
#include "sw/device/lib/gpio.h"
#include "sw/device/lib/hw_sha256.h"
#include "sw/device/lib/spi_device.h"
#include "sw/device/lib/uart.h"  // TODO: Wrap uart in DEBUG macros.

/* Checks if flash is blank to determine if bootstrap is needed. */
/* TODO: Update this to check bootstrap pin instead in Verilator. */
static int bootstrap_requested(void) {
// The following flash empty-sniff-check is done this way due to the lack of
// clear eflash reset in SIM environments.
#if defined(SIMULATION)
  return !!(REG32(FLASH_MEM_BASE_ADDR) == 0 ||
            REG32(FLASH_MEM_BASE_ADDR) == 0xFFFFFFFF);
#else
  return !!(gpio_read() & GPIO_BOOTSTRAP_BIT_MASK);
#endif
}

/* Erase all flash, and verify blank. */
static int erase_flash(void) {
  if (flash_bank_erase(FLASH_BANK_0)) {
    return E_BS_ERASE;
  }
  if (flash_bank_erase(FLASH_BANK_1)) {
    return E_BS_ERASE;
  }
  if (!flash_check_empty()) {
    return E_BS_NOTEMPTY;
  }
  return 0;
}

/* Calculates SHA256 hash of received data and compares it against recieved
 * hash. Returns 0 if both hashes are identical. */
static int check_frame_hash(const frame_t *f) {
  static uint32_t hash[8];
  uint32_t result = 0;
  hw_SHA256_hash((uint8_t *)&f->hdr.frame_num, RAW_BUFFER_SIZE - 32,
                 (uint8_t *)hash);
  for (int i = 0; i < 8; ++i) {
    result |= hash[i] ^ f->hdr.hash[i];
  }
  return result;
}

/* Processes frames received via spid interface and writes them to flash. */
static int bootstrap_flash(void) {
  static frame_t f;
  static uint8_t ack[32] = {0};
  uint32_t expected_frame_no = 0;
  for (;;) {
    if (spid_bytes_available() >= sizeof(f)) {
      spid_read_nb(&f, sizeof(f));
      uart_send_str("Processing frame no: ");
      uart_send_uint(f.hdr.frame_num, 32);
      uart_send_str(" exp no: ");
      uart_send_uint(expected_frame_no, 32);
      uart_send_str("\r\n");

      if (FRAME_NO(f.hdr.frame_num) == expected_frame_no) {
        if (check_frame_hash(&f)) {
          uart_send_str("Error: detected hash mismatch on frame: ");
          uart_send_uint(f.hdr.frame_num, 32);
          uart_send_str("\r\n");
          spid_send(ack, sizeof(ack));
          continue;
        }

        hw_SHA256_hash(&f, sizeof(f), ack);
        spid_send(ack, sizeof(ack));

        if (expected_frame_no == 0) {
          flash_default_region_access(/*rd_en=*/1, /*prog_en=*/1,
                                      /*erase_en=*/1);
          int rv = erase_flash();
          if (rv) {
            return rv;
          }
        }
        if (flash_write(f.hdr.flash_offset, f.data, ARRAYSIZE(f.data))) {
          return E_BS_WRITE;
        }

        ++expected_frame_no;
        if (f.hdr.frame_num & FRAME_EOF_MARKER) {
          break;
        }
      } else {
        // Send previous ack if unable to verify current frame.
        spid_send(ack, sizeof(ack));
      }
    }
  }
  uart_send_str("bootstrap: DONE!\r\n");
  return 0;
}

int bootstrap(void) {
  if (!bootstrap_requested()) {
    return 0;
  }
  // SPI device is only initialized in bootstrap mode.
  spid_init();
  flash_init_block();

  int rv = bootstrap_flash();
  if (rv) {
    rv |= erase_flash();
  }

  // Always make sure to revert flash_ctrl access to default settings.
  // bootstrap_flash enables access to flash to perform update.
  flash_default_region_access(/*rd_en=*/0, /*prog_en=*/0, /*erase_en=*/0);
  return rv;
}
