// Copyright ${helper.date} 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.

// clang-format off

${gencmd}
<%
## list renode unsupported peripherals
unsupported_peripherals = [
  "adc_ctrl", "clkmgr", "edn", "entropy_src", "keymgr", "pattgen",
  "pinmux", "pwm", "rv_core_ibex", "rv_plic", "sensor_ctrl", "spi_device",
  "sram_ctrl", "sysrst_ctrl", "usbdev"
]
unsupported_smc_peripherals = [
  "rv_core_ibex_smc", "rv_plic_smc", "rv_timer_smc", "rv_timer_smc2"
]
alert_peripheral_names = sorted({p.name for p in helper.alert_peripherals if p.inst_name not in unsupported_smc_peripherals})
%>\
#include "sw/device/lib/base/mmio.h"
% for n in sorted(alert_peripheral_names + ["alert_handler"]):
#include "sw/device/lib/dif/dif_${n}.h"
% endfor
#include "sw/device/lib/testing/alert_handler_testutils.h"
#include "sw/device/lib/testing/test_framework/FreeRTOSConfig.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "sw/device/lib/testing/test_framework/ottf_test_config.h"

#include "alert_handler_regs.h"  // Generated.
#include "hw/top_${top["name"]}/sw/autogen/top_${top["name"]}.h"

OTTF_DEFINE_TEST_CONFIG();

static dif_alert_handler_t alert_handler;
% for p in helper.alert_peripherals:
% if p.inst_name not in unsupported_smc_peripherals:
static dif_${p.name}_t ${p.inst_name};
% endif
% endfor

/**
 * Initialize the peripherals used in this test.
 */
static void init_peripherals(void) {
  mmio_region_t base_addr;
  base_addr = mmio_region_from_addr(TOP_${top["name"].upper()}_ALERT_HANDLER_BASE_ADDR);
  CHECK_DIF_OK(dif_alert_handler_init(base_addr, &alert_handler));

  % for p in helper.alert_peripherals:
  % if p.inst_name not in unsupported_smc_peripherals:
  base_addr = mmio_region_from_addr(${p.base_addr_name});
  CHECK_DIF_OK(dif_${p.name}_init(base_addr, &${p.inst_name}));

  % endif
  % endfor
}

/**
 * Configure the alert handler to escalate on alerts upto phase 1 (i.e. wipe
 * secret) but not trigger reset. Then CPU can check if alert_handler triggers the correct
 * alert_cause register.
 */
static void alert_handler_config(void) {
  dif_alert_handler_alert_t alerts[ALERT_HANDLER_PARAM_N_ALERTS];
  dif_alert_handler_class_t alert_classes[ALERT_HANDLER_PARAM_N_ALERTS];

  // Enable all incoming alerts and configure them to classa.
  // This alert should never fire because we do not expect any incoming alerts.
  for (int i = 0; i < ALERT_HANDLER_PARAM_N_ALERTS; ++i) {
    alerts[i] = i;
    alert_classes[i] = kDifAlertHandlerClassA;
  }

  dif_alert_handler_escalation_phase_t esc_phases[] = {
      {.phase = kDifAlertHandlerClassStatePhase0,
       .signal = 0,
       .duration_cycles = 2000}};

  dif_alert_handler_class_config_t class_config = {
      .auto_lock_accumulation_counter = kDifToggleDisabled,
      .accumulator_threshold = 0,
      .irq_deadline_cycles = 10000,
      .escalation_phases = esc_phases,
      .escalation_phases_len = ARRAYSIZE(esc_phases),
      .crashdump_escalation_phase = kDifAlertHandlerClassStatePhase1,
  };

  dif_alert_handler_class_config_t class_configs[] = {class_config,
                                                      class_config};

  dif_alert_handler_class_t classes[] = {kDifAlertHandlerClassA,
                                         kDifAlertHandlerClassB};
  dif_alert_handler_config_t config = {
      .alerts = alerts,
      .alert_classes = alert_classes,
      .alerts_len = ARRAYSIZE(alerts),
      .classes = classes,
      .class_configs = class_configs,
      .classes_len = ARRAYSIZE(class_configs),
      .ping_timeout = 1000,
  };

  alert_handler_testutils_configure_all(&alert_handler, config,
                                        kDifToggleEnabled);
}

// Trigger alert for each module by writing one to `alert_test` register.
// Then check alert_handler's alert_cause register to make sure the correct alert reaches
// alert_handler.
static void trigger_alert_test(void) {
  bool is_cause;
  dif_alert_handler_alert_t exp_alert;
  % for p in helper.alert_peripherals:
  % if p.inst_name not in unsupported_smc_peripherals:

  % if p.name in unsupported_peripherals:
#ifndef DISABLE_RENODE_TEST
  % endif
  // Write ${p.name}'s alert_test reg and check alert_cause.
  for (int i = 0; i < ${p.num_alerts}; ++i) {
    CHECK_DIF_OK(dif_${p.name}_alert_force(&${p.inst_name}, ${p.dif_alert_name} + i));

    // Verify that alert handler received it.
    exp_alert = ${p.top_alert_name} + i;
    CHECK_DIF_OK(dif_alert_handler_alert_is_cause(
        &alert_handler, exp_alert, &is_cause));
    CHECK(is_cause, "Expect alert %d!", exp_alert);

    // Clear alert cause register
    CHECK_DIF_OK(dif_alert_handler_alert_acknowledge(
        &alert_handler, exp_alert));
  }
  % if p.name in unsupported_peripherals:
#endif
  % endif
  % endif
  % endfor
}

bool test_main(void) {
  init_peripherals();
  alert_handler_config();
  trigger_alert_test();
  return true;
}
