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

#include "sw/device/lib/crypto/otbn_util.h"

#include <assert.h>
#include <stddef.h>
#include <stdint.h>

#include "sw/device/lib/crypto/drivers/otbn.h"

void otbn_init(otbn_t *ctx) {
  *ctx = (otbn_t){
      .app = {0},
      .app_is_loaded = false,
      .error_bits = kOtbnErrBitsNoError,
  };
}

otbn_error_t otbn_busy_wait_for_done(otbn_t *ctx) {
  while (otbn_is_busy()) {
  }

  otbn_err_bits_t err_bits;
  otbn_get_err_bits(&err_bits);
  if (err_bits != kOtbnErrBitsNoError) {
    ctx->error_bits = err_bits;
    return kOtbnErrorExecutionFailed;
  }
  return kOtbnErrorOk;
}

/**
 * Checks if the OTBN application's IMEM and DMEM address parameters are valid.
 *
 * IMEM and DMEM ranges must not be "backwards" in memory, with the end address
 * coming before the start address, and the IMEM range must additionally be
 * non-empty. Finally, separate sections in DMEM must not overlap each other
 * when converted to DMEM address space.
 *
 * @param app the OTBN application to check
 * @return true if the addresses are valid, otherwise false.
 */
bool check_app_address_ranges(const otbn_app_t *app) {
  // IMEM must have a strictly positive range (cannot be backwards or empty)
  if (app->imem_end <= app->imem_start) {
    return false;
  }
  // DMEM data section must not be backwards
  if (app->dmem_data_end < app->dmem_data_start) {
    return false;
  }
  return true;
}

otbn_error_t otbn_load_app(otbn_t *ctx, const otbn_app_t app) {
  if (!check_app_address_ranges(&app)) {
    return kOtbnErrorInvalidArgument;
  }

  const size_t imem_num_words = app.imem_end - app.imem_start;
  const size_t data_num_words = app.dmem_data_end - app.dmem_data_start;

  ctx->app_is_loaded = false;

  OTBN_RETURN_IF_ERROR(otbn_imem_write(0, app.imem_start, imem_num_words));

  otbn_zero_dmem();
  if (data_num_words > 0) {
    OTBN_RETURN_IF_ERROR(
        otbn_dmem_write(0, app.dmem_data_start, data_num_words));
  }

  ctx->app = app;
  ctx->app_is_loaded = true;
  return kOtbnErrorOk;
}

otbn_error_t otbn_execute_app(otbn_t *ctx) {
  if (!ctx->app_is_loaded) {
    return kOtbnErrorInvalidArgument;
  }

  otbn_execute();
  return kOtbnErrorOk;
}

otbn_error_t otbn_copy_data_to_otbn(otbn_t *ctx, size_t len,
                                    const uint32_t *src, otbn_addr_t dest) {
  OTBN_RETURN_IF_ERROR(otbn_dmem_write(dest, src, len));

  return kOtbnErrorOk;
}

otbn_error_t otbn_copy_data_from_otbn(otbn_t *ctx, size_t len_bytes,
                                      otbn_addr_t src, uint32_t *dest) {
  OTBN_RETURN_IF_ERROR(otbn_dmem_read(src, dest, len_bytes));

  return kOtbnErrorOk;
}
