[dif/alert_handler] Remove alert # limit and use new configuration multireg.
Signed-off-by: Timothy Trippel <ttrippel@google.com>
diff --git a/sw/device/lib/dif/dif_alert_handler.c b/sw/device/lib/dif/dif_alert_handler.c
index 840e5d4..b45bf11 100644
--- a/sw/device/lib/dif/dif_alert_handler.c
+++ b/sw/device/lib/dif/dif_alert_handler.c
@@ -23,9 +23,8 @@
return kDifAlertHandlerBadArg;
}
- // TODO: We currently don't support more than 16 alerts correctly.
- // See: #3826
- if (params.alert_count > 16) {
+ // Check we do not exceed maximum number of alerts supported by the hardware.
+ if (params.alert_count > ALERT_HANDLER_PARAM_N_ALERTS) {
return kDifAlertHandlerBadArg;
}
@@ -50,21 +49,28 @@
return false;
}
- uint32_t enable_reg = mmio_region_read32(
- handler->params.base_addr, ALERT_HANDLER_ALERT_EN_SHADOWED_0_REG_OFFSET);
- uint32_t alerts_reg =
- mmio_region_read32(handler->params.base_addr,
- ALERT_HANDLER_ALERT_CLASS_SHADOWED_0_REG_OFFSET);
-
for (int i = 0; i < class->alerts_len; ++i) {
if (class->alerts[i] >= handler->params.alert_count) {
return false;
}
- // Note: the value in alerts[i] corresponds directly to the bit index within
- // the register. (I.e., alert N has enable bit N).
- enable_reg = bitfield_bit32_write(enable_reg, class->alerts[i], true);
+ // Enable the alert.
+ // NOTE: the value in alerts[i] corresponds directly to the multireg index.
+ // (I.e., alert N has enable multireg N).
+ ptrdiff_t enable_reg_offset = ALERT_HANDLER_ALERT_EN_SHADOWED_0_REG_OFFSET +
+ class->alerts[i] * sizeof(uint32_t);
+ uint32_t enable_reg =
+ mmio_region_read32(handler->params.base_addr, enable_reg_offset);
+ // TODO: we would like to use the generated macro for the ENABLE BIT OFFSET
+ // below for the alert with the given index/ID, not just assume they are
+ // the same across all regs in the multireg. However, making this assumption
+ // for now.
+ enable_reg = bitfield_bit32_write(
+ enable_reg, ALERT_HANDLER_ALERT_EN_SHADOWED_0_EN_A_0_BIT, true);
+ mmio_region_write32_shadowed(handler->params.base_addr, enable_reg_offset,
+ enable_reg);
+ // Determine alert classification.
uint32_t classification;
switch (class->alert_class) {
case kDifAlertHandlerClassA:
@@ -87,27 +93,26 @@
return false;
}
- // TODO: Currently, we assume all fields are of equal width.
- // See: #3826
- uint32_t field_width = bitfield_popcount32(
- ALERT_HANDLER_ALERT_CLASS_SHADOWED_0_CLASS_A_0_MASK);
- uint32_t field_offset = field_width * class->alerts[i];
-
- alerts_reg = bitfield_field32_write(
- alerts_reg,
- (bitfield_field32_t){
- .mask = ALERT_HANDLER_ALERT_CLASS_SHADOWED_0_CLASS_A_0_MASK,
- .index = field_offset,
- },
+ // Classify the alert.
+ // NOTE: the value in alerts[i] corresponds directly to the multireg index.
+ // (I.e., alert N has enable multireg N).
+ ptrdiff_t class_reg_offset =
+ ALERT_HANDLER_ALERT_CLASS_SHADOWED_0_REG_OFFSET +
+ class->alerts[i] * sizeof(uint32_t);
+ uint32_t class_reg =
+ mmio_region_read32(handler->params.base_addr, class_reg_offset);
+ // TODO: we would like to use the generated macro for the BITFIELD
+ // below for the alert with the given index/ID, not just assume they are
+ // the same across all regs in the multireg.
+ class_reg = bitfield_field32_write(
+ class_reg, ALERT_HANDLER_ALERT_CLASS_SHADOWED_0_CLASS_A_0_FIELD,
classification);
+ mmio_region_write32_shadowed(handler->params.base_addr, class_reg_offset,
+ class_reg);
+
+ // TODO: support locking the alert class configuration.
}
- mmio_region_write32_shadowed(handler->params.base_addr,
- ALERT_HANDLER_ALERT_EN_SHADOWED_0_REG_OFFSET,
- enable_reg);
- mmio_region_write32_shadowed(handler->params.base_addr,
- ALERT_HANDLER_ALERT_CLASS_SHADOWED_0_REG_OFFSET,
- alerts_reg);
return true;
}
@@ -491,6 +496,11 @@
if (handler == NULL || is_locked == NULL) {
return kDifAlertHandlerBadArg;
}
+ // TODO(timothytrippel): more "locking" functionality has been added that
+ // can lock the ping-timer-en and ping-timer-cyc with the
+ // ping-timer-regwen, and likewise with the alert-en-x and alert-class-x
+ // registers. We need to check for this here, otherwise the alerts cannot be
+ // enabled.
uint32_t reg =
mmio_region_read32(handler->params.base_addr,
@@ -665,9 +675,12 @@
return kDifAlertHandlerBadArg;
}
- uint32_t reg = mmio_region_read32(handler->params.base_addr,
- ALERT_HANDLER_ALERT_CAUSE_0_REG_OFFSET);
- *is_cause = bitfield_bit32_read(reg, alert);
+ ptrdiff_t cause_reg_offset =
+ ALERT_HANDLER_ALERT_CAUSE_0_REG_OFFSET + alert * sizeof(uint32_t);
+ uint32_t cause_reg =
+ mmio_region_read32(handler->params.base_addr, cause_reg_offset);
+ *is_cause =
+ bitfield_bit32_read(cause_reg, ALERT_HANDLER_ALERT_CAUSE_0_A_0_BIT);
return kDifAlertHandlerOk;
}
diff --git a/sw/device/lib/dif/dif_alert_handler_unittest.cc b/sw/device/lib/dif/dif_alert_handler_unittest.cc
index a352dd6..29384ab 100644
--- a/sw/device/lib/dif/dif_alert_handler_unittest.cc
+++ b/sw/device/lib/dif/dif_alert_handler_unittest.cc
@@ -58,13 +58,9 @@
EXPECT_EQ(dif_alert_handler_init(params, nullptr), kDifAlertHandlerBadArg);
}
-INSTANTIATE_TEST_SUITE_P(
- InitTestSignalCounts, InitTest,
- testing::Values(1, 2, 12, 16
- // TODO: Enable these parameters once we can support them.
- // See: #3826
- // 24, 32,
- ));
+INSTANTIATE_TEST_SUITE_P(InitTestSignalCounts, InitTest,
+ testing::Values(1, 2, 12, 16, 24, 32, 64,
+ ALERT_HANDLER_PARAM_N_ALERTS));
class ConfigTest : public AlertTest {
// We provide our own dev_ member variable in this fixture, in order to
@@ -748,12 +744,12 @@
TEST_F(CauseTest, IsCause) {
bool flag;
- EXPECT_READ32(ALERT_HANDLER_ALERT_CAUSE_0_REG_OFFSET, {{0, true}, {5, true}});
+ EXPECT_READ32(ALERT_HANDLER_ALERT_CAUSE_5_REG_OFFSET, {{0, true}});
EXPECT_EQ(dif_alert_handler_alert_is_cause(&handler_, 5, &flag),
kDifAlertHandlerOk);
EXPECT_TRUE(flag);
- EXPECT_READ32(ALERT_HANDLER_ALERT_CAUSE_0_REG_OFFSET, {{0, true}, {5, true}});
+ EXPECT_READ32(ALERT_HANDLER_ALERT_CAUSE_6_REG_OFFSET, {{0, false}});
EXPECT_EQ(dif_alert_handler_alert_is_cause(&handler_, 6, &flag),
kDifAlertHandlerOk);
EXPECT_FALSE(flag);