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

#include "bootstrap.h"

#include "common.h"
#include "flash_ctrl.h"
#include "gpio.h"
#include "spi_device.h"
#include "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(FlashBank0)) {
    return E_BS_ERASE;
  }
  if (flash_bank_erase(FlashBank1)) {
    return E_BS_ERASE;
  }
  if (!flash_check_empty()) {
    return E_BS_NOTEMPTY;
  }
  return 0;
}

/* 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");

      // TODO: Add hash check.
      if (FRAME_NO(f.hdr.frame_num) == expected_frame_no) {
        // TODO: Add ack computation.
        spid_send(ack, sizeof(ack));

        if (expected_frame_no == 0) {
          // TODO: Add signed header checks.
          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();

  // 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;
}
