/*
 * Copyright 2023 Google LLC
 * Copyright lowRISC contributors
 *
 * 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 "hw/top_matcha/sw/autogen/top_matcha.h"
#include "sw/device/lib/base/memory.h"
#include "sw/device/lib/dif/dif_sensor_ctrl.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/aon_timer_testutils.h"
#include "sw/device/lib/testing/clkmgr_testutils.h"
#include "sw/device/lib/testing/rstmgr_testutils.h"
#include "sw/device/lib/testing/sensor_ctrl_testutils.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "sw/device/lib/testing/test_framework/ottf_main.h"

OTTF_DEFINE_TEST_CONFIG();

/**
 * This test measure clock counts with clkmgr frequency measurements, performing
 * 100 measurements per round. Measurement errors (fast or slow clocks) are
 * recorded as recoverable error in clkmgr.
 *
 * This test configures the clock thresholds so it generates errors, after 100
 * measurements it checks that some errors are found, then a reset is triggered,
 * and it checks the measurements should be disabled, and no errors should be
 * reported.
 *
 * Notice the test overrides the hardware behavior so it comes out with
 * calibrated USB clock, otherwise the USB clock frequency will be incorrect.
 * USB calibration should be a separate test, and may be vendor-specific.
 */
const unsigned int kMeasurementsPerRound = 100;

bool test_main(void) {
  dif_clkmgr_t clkmgr;
  dif_rstmgr_t rstmgr;
  dif_sensor_ctrl_t sensor_ctrl;

  const uint32_t kMeasurementDelayMicros =
      aon_timer_testutils_get_us_from_aon_cycles(kMeasurementsPerRound);

  CHECK_DIF_OK(dif_clkmgr_init(
      mmio_region_from_addr(TOP_MATCHA_CLKMGR_AON_BASE_ADDR), &clkmgr));
  CHECK_DIF_OK(dif_sensor_ctrl_init(
      mmio_region_from_addr(TOP_MATCHA_SENSOR_CTRL_BASE_ADDR), &sensor_ctrl));
  CHECK_DIF_OK(dif_rstmgr_init(
      mmio_region_from_addr(TOP_MATCHA_RSTMGR_AON_BASE_ADDR), &rstmgr));

  LOG_INFO("TEST: wait for ast init");
  IBEX_SPIN_FOR(sensor_ctrl_ast_init_done(&sensor_ctrl),
                1000);  // Time out at 1000us
  LOG_INFO("TEST: done ast init");

  if (rstmgr_testutils_reset_info_any(&rstmgr, kDifRstmgrResetInfoPor)) {
    LOG_INFO("POR reset");

    // Configure the counters to trigger an error by setting them for external
    // clocks.
    clkmgr_testutils_enable_clock_counts_with_expected_thresholds(
        &clkmgr, /*jitter_enabled=*/false, /*external_clk=*/true,
        /*low_speed=*/true);
    busy_spin_micros(kMeasurementDelayMicros);

    // Check we get errors, but let the counters keep going.
    dif_clkmgr_recov_err_codes_t err_codes;
    CHECK_DIF_OK(dif_clkmgr_recov_err_code_get_codes(&clkmgr, &err_codes));
    CHECK(err_codes != 0);

    // Trigger a rstmgr SW reset.
    CHECK_DIF_OK(dif_rstmgr_software_device_reset(&rstmgr));

    // Add delay such that the software reset can take effect
    busy_spin_micros(100);

    // This should not be reached.
    LOG_ERROR("This is unreachable since a reset should have been triggered");
    return false;
  } else if (rstmgr_testutils_reset_info_any(&rstmgr, kDifRstmgrResetInfoSw)) {
    LOG_INFO("Back from rstmgr SW reset");
    CHECK(clkmgr_testutils_check_measurement_enables(&clkmgr,
                                                     kDifToggleDisabled));
    CHECK(clkmgr_testutils_check_measurement_counts(&clkmgr));
    return true;
  } else {
    dif_rstmgr_reset_info_bitfield_t rst_info;
    CHECK_DIF_OK(dif_rstmgr_reset_info_get(&rstmgr, &rst_info));
    LOG_ERROR("Unexpected rst_info 0x%x", rst_info);
    return false;
  }
  return true;
}
