5#include "sw/device/lib/testing/alert_handler_testutils.h"
7#include "hw/top/dt/alert_handler.h"
8#include "hw/top/dt/api.h"
13#include "sw/device/lib/testing/test_framework/check.h"
15#include "hw/top/alert_handler_regs.h"
17#define MODULE_ID MAKE_MODULE_ID('a', 'h', 't')
19const char kAlertClassName[] = {
'A',
'B',
'C',
'D'};
20static_assert(
ARRAYSIZE(kAlertClassName) == ALERT_HANDLER_PARAM_N_CLASSES,
21 "Expected four alert classes!");
28static uint32_t get_next_n_bits(
30 int *word_index,
int *bit_index) {
31 CHECK(num_bits <= 32);
32 CHECK(*bit_index < 32);
33 uint32_t word = dump[*word_index] >> *bit_index;
36 if (*bit_index + num_bits > 32) {
37 word |= dump[(*word_index) + 1] << (32 - *bit_index);
39 if (*bit_index + num_bits >= 32) {
41 *bit_index = *bit_index + num_bits - 32;
43 *bit_index += num_bits;
45 uint32_t mask = (uint32_t)(((uint64_t)1 << num_bits) - 1);
50status_t alert_handler_testutils_info_parse(
52 alert_handler_testutils_info_t *info) {
55 for (
int i = 0; i < ALERT_HANDLER_PARAM_N_CLASSES; ++i) {
56 info->class_esc_state[i] =
57 get_next_n_bits(3, dump, &word_index, &bit_index);
59 for (
int i = 0; i < ALERT_HANDLER_PARAM_N_CLASSES; ++i) {
60 info->class_esc_cnt[i] = get_next_n_bits(32, dump, &word_index, &bit_index);
62 for (
int i = 0; i < ALERT_HANDLER_PARAM_N_CLASSES; ++i) {
63 info->class_accum_cnt[i] =
64 (uint16_t)get_next_n_bits(16, dump, &word_index, &bit_index);
66 info->loc_alert_cause =
67 (uint8_t)get_next_n_bits(7, dump, &word_index, &bit_index);
68 TRY_CHECK(word_index < dump_size);
69 for (
int i = 0; i < ALERT_HANDLER_PARAM_N_ALERTS; ++i) {
70 info->alert_cause[i] = get_next_n_bits(1, dump, &word_index, &bit_index);
72 TRY_CHECK(word_index < dump_size ||
73 (word_index == dump_size && bit_index == 0));
77void alert_handler_testutils_info_dump(
78 const alert_handler_testutils_info_t *info) {
80 LOG_INFO(
"esc_state [0]=%x, [1]=%x, [2]=%x, [3]=%x", info->class_esc_state[0],
81 info->class_esc_state[1], info->class_esc_state[2],
82 info->class_esc_state[3]);
83 LOG_INFO(
"esc_cnt [0]=0x%x, [1]=0x%x, [2]=0x%x, [3]=0x%x",
84 info->class_esc_cnt[0], info->class_esc_cnt[1],
85 info->class_esc_cnt[2], info->class_esc_cnt[3]);
86 LOG_INFO(
"accum_cnt [0]=0x%x, [1]=0x%x, [2]=0x%x, [3]=0x%x",
87 info->class_accum_cnt[0], info->class_accum_cnt[1],
88 info->class_accum_cnt[2], info->class_accum_cnt[3]);
89 LOG_INFO(
"loc_alert_cause=0x%x", info->loc_alert_cause);
94 for (
int i = 0; i < ALERT_HANDLER_PARAM_N_ALERTS; ++i) {
95 if (info->alert_cause[i]) {
100 if (set_count == 0) {
105status_t alert_handler_testutils_configure_all(
108 TRY_CHECK(alert_handler != NULL);
109 TRY_CHECK(dif_is_valid_toggle(locked));
129 ALERT_HANDLER_PING_TIMEOUT_CYC_SHADOWED_PING_TIMEOUT_CYC_SHADOWED_MASK);
133 TRY(dif_alert_handler_configure_alert(alert_handler, config.
alerts[i],
140 TRY(dif_alert_handler_configure_local_alert(
147 TRY(dif_alert_handler_configure_class(alert_handler, config.
classes[i],
153 TRY(dif_alert_handler_configure_ping_timer(alert_handler, config.
ping_timeout,
159status_t alert_handler_testutils_get_cycles_from_us(uint64_t microseconds,
161 uint64_t cycles_ = udiv64_slow(
166 TRY_CHECK(cycles_ < UINT32_MAX,
167 "The value 0x%08x%08x can't fit into the 32 bits timer counter.",
168 (uint32_t)(cycles_ >> 32), (uint32_t)cycles_);
169 *cycles = (uint32_t)cycles_;
173uint32_t alert_handler_testutils_cycle_rescaling_factor(
void) {
177static status_t alert_handler_class_info_log(
181 TRY(dif_alert_handler_get_class_state(alert_handler, alert_class, &state));
184 TRY(dif_alert_handler_get_accumulator(alert_handler, alert_class,
187 if (num_alerts > 0) {
188 LOG_INFO(
"Alert class %c state: %d, acc_cnt: %d",
189 kAlertClassName[alert_class], state, num_alerts);
192 alert < ALERT_HANDLER_PARAM_N_ALERTS; ++alert) {
194 TRY(dif_alert_handler_alert_is_cause(alert_handler, alert, &is_cause));
201 TRY(dif_alert_handler_escalation_can_clear(alert_handler, alert_class,
204 TRY(dif_alert_handler_escalation_clear(alert_handler, alert_class));
206 LOG_INFO(
"Alert class %c can't be cleared", kAlertClassName[alert_class]);
213static status_t alert_handler_class_log(
217 TRY(dif_alert_handler_get_class_state(alert_handler, alert_class, &state));
220 TRY(dif_alert_handler_get_accumulator(alert_handler, alert_class,
223 if (num_alerts > 0) {
224 LOG_INFO(
"Alert class %c state: %d, acc_cnt: %d",
225 kAlertClassName[alert_class], state, num_alerts);
227 alert < ALERT_HANDLER_PARAM_N_ALERTS; ++alert) {
229 TRY(dif_alert_handler_alert_is_cause(alert_handler, alert, &is_cause));
239status_t alert_handler_testutils_status_log(
241 TRY_CHECK(alert_handler != NULL);
244 alert_class < ALERT_HANDLER_PARAM_N_CLASSES; ++alert_class) {
245 TRY(alert_handler_class_log(alert_handler, alert_class));
251status_t alert_handler_testutils_dump_log(
const dif_rstmgr_t *rstmgr) {
252 TRY_CHECK(rstmgr != NULL);
256 alert_handler_testutils_info_t actual_info;
258 uint32_t log_count = 0;
260 CHECK_DIF_OK(dif_rstmgr_alert_info_dump_read(
262 CHECK(seg_size <= INT_MAX,
"seg_size must fit in int");
264 alert_handler_testutils_info_parse(dump, (
int)seg_size, &actual_info));
267 alert_class < ALERT_HANDLER_PARAM_N_CLASSES; ++alert_class) {
268 if (actual_info.class_esc_state[alert_class] != kCstateIdle) {
269 LOG_INFO(
"crashdump - Alert class %c state: %d, acc_cnt: %d, esc_cnt: %d",
270 kAlertClassName[alert_class],
271 actual_info.class_esc_state[alert_class],
272 actual_info.class_accum_cnt[alert_class],
273 actual_info.class_esc_cnt[alert_class]);
278 alert < ALERT_HANDLER_PARAM_N_ALERTS; ++alert) {
279 if (actual_info.alert_cause[alert]) {
280 LOG_INFO(
"crashdump - Alert %d is set", alert);
285 if (log_count == 0) {
286 LOG_INFO(
"crashdump - No alerts reported");
292status_t alert_handler_testutils_dump_enable(
294 TRY_CHECK(alert_handler != NULL);
295 TRY_CHECK(rstmgr != NULL);
297 uint32_t enable_count = 0;
299 alert_class < ALERT_HANDLER_PARAM_N_CLASSES; ++alert_class) {
301 TRY(dif_alert_handler_is_class_enabled(alert_handler, alert_class,
304 TRY(dif_alert_handler_crash_dump_trigger_set(