/*
 * Copyright 2023 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "sw/device/lib/eflash.h"

#include "flash_ctrl_regs.h"  // Generated.
#include "hw/top_matcha/sw/autogen/top_matcha.h"
#include "sw/device/lib/dif/dif_flash_ctrl.h"
#include "sw/device/lib/testing/flash_ctrl_testutils.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"

static dif_flash_ctrl_state_t flash_ctrl;

dif_result_t eflash_init(mmio_region_t base_addr, mmio_region_t otp_addr) {
  CHECK_DIF_OK(dif_flash_ctrl_init_state(&flash_ctrl, base_addr));
  flash_ctrl_init(base_addr, otp_addr);
  return kDifOk;
}

dif_result_t eflash_chip_erase(void) {
  flash_ctrl_bank_erase_perms_set(kHardenedBoolTrue);
  rom_error_t err_0 = flash_ctrl_data_erase(0, kFlashCtrlEraseTypeBank);
  rom_error_t err_1 = flash_ctrl_data_erase(FLASH_CTRL_PARAM_BYTES_PER_BANK,
                                            kFlashCtrlEraseTypeBank);
  flash_ctrl_bank_erase_perms_set(kHardenedBoolFalse);
  if (err_0 != kErrorOk || err_1 != kErrorOk) {
    return kDifError;
  }
  return kDifOk;
}

// Writes 256-bytes from src to dst.
// Take dst as a memory address, and mask off the top.
dif_result_t eflash_write_page(const void* dst, uint8_t* src) {
  uint32_t flash_dst = (uint32_t)dst & ~TOP_MATCHA_EFLASH_BASE_ADDR;
  flash_ctrl_data_default_perms_set((flash_ctrl_perms_t){
      .read = kMultiBitBool4False,
      .write = kMultiBitBool4True,
      .erase = kMultiBitBool4False,
  });
  rom_error_t err = flash_ctrl_data_write(
      flash_dst, EFLASH_PAGE_SIZE / sizeof(uint32_t), src);
  if (err != kErrorOk) {
    return kDifError;
  }
  flash_ctrl_data_default_perms_set((flash_ctrl_perms_t){
      .read = kMultiBitBool4True,
      .write = kMultiBitBool4False,
      .erase = kMultiBitBool4False,
  });
  return kDifOk;
}
