/*
 * 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(uintptr_t base_addr, uintptr_t otp_addr) {
  CHECK_DIF_OK(dif_flash_ctrl_init_state(&flash_ctrl, mmio_region_from_addr(base_addr)));
  flash_ctrl_init(base_addr, otp_addr);
  return kDifOk;
}

dif_result_t eflash_chip_erase(uintptr_t base_addr) {
  flash_ctrl_bank_erase_perms_set(base_addr, kHardenedBoolTrue);
  rom_error_t err_0 = flash_ctrl_data_erase(base_addr, 0, kFlashCtrlEraseTypeBank);
  rom_error_t err_1 = flash_ctrl_data_erase(base_addr, FLASH_CTRL_PARAM_BYTES_PER_BANK,
                                            kFlashCtrlEraseTypeBank);
  flash_ctrl_bank_erase_perms_set(base_addr, 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(uintptr_t base_addr, const void* dst, uint8_t* src) {
  uint32_t flash_dst = (uint32_t)dst & ~TOP_MATCHA_EFLASH_BASE_ADDR;
  flash_ctrl_data_default_perms_set(base_addr, (flash_ctrl_perms_t){
      .read = kMultiBitBool4False,
      .write = kMultiBitBool4True,
      .erase = kMultiBitBool4False,
  });
  rom_error_t err = flash_ctrl_data_write(
      base_addr, flash_dst, EFLASH_PAGE_SIZE / sizeof(uint32_t), src);
  if (err != kErrorOk) {
    return kDifError;
  }
  flash_ctrl_data_default_perms_set(base_addr, (flash_ctrl_perms_t){
      .read = kMultiBitBool4True,
      .write = kMultiBitBool4False,
      .erase = kMultiBitBool4False,
  });
  return kDifOk;
}
