12 #include "alert_handler_regs.h"
14 static_assert(ALERT_HANDLER_PARAM_N_CLASSES == 4,
15 "Expected four alert classes!");
16 static_assert(ALERT_HANDLER_PARAM_N_ESC_SEV == 4,
17 "Expected four escalation signals!");
18 static_assert(ALERT_HANDLER_PARAM_N_PHASES == 4,
19 "Expected four escalation phases!");
20 static_assert(ALERT_HANDLER_PARAM_N_LOC_ALERT == 7,
21 "Expected seven local alerts!");
24 static_assert(ALERT_HANDLER_ALERT_EN_SHADOWED_MULTIREG_COUNT &&
25 ALERT_HANDLER_ALERT_EN_SHADOWED_EN_A_FIELD_WIDTH == 1 &&
26 ALERT_HANDLER_ALERT_EN_SHADOWED_0_EN_A_0_BIT == 0,
27 "Expected alert enables to be multiregs with LSB at index 0!");
28 static_assert(ALERT_HANDLER_ALERT_CLASS_SHADOWED_MULTIREG_COUNT &&
29 ALERT_HANDLER_ALERT_CLASS_SHADOWED_CLASS_A_FIELD_WIDTH == 2 &&
30 ALERT_HANDLER_ALERT_CLASS_SHADOWED_0_CLASS_A_0_OFFSET == 0,
31 "Expected alert class CSRs to be multiregs with LSB at index 0!");
32 static_assert(ALERT_HANDLER_ALERT_REGWEN_MULTIREG_COUNT &&
33 ALERT_HANDLER_ALERT_REGWEN_EN_FIELD_WIDTH == 1 &&
34 ALERT_HANDLER_ALERT_REGWEN_0_EN_0_BIT == 0,
35 "Expected alert locks to be multiregs with LSB at index 0!");
36 static_assert(ALERT_HANDLER_ALERT_CAUSE_MULTIREG_COUNT &&
37 ALERT_HANDLER_ALERT_CAUSE_A_FIELD_WIDTH == 1 &&
38 ALERT_HANDLER_ALERT_CAUSE_0_A_0_BIT == 0,
39 "Expected alert causes to be multiregs with LSB at index 0!");
43 ALERT_HANDLER_LOC_ALERT_EN_SHADOWED_MULTIREG_COUNT &&
44 ALERT_HANDLER_LOC_ALERT_EN_SHADOWED_EN_LA_FIELD_WIDTH == 1 &&
45 ALERT_HANDLER_LOC_ALERT_EN_SHADOWED_0_EN_LA_0_BIT == 0,
46 "Expected local alert enables to be multiregs with LSB at index 0!");
48 ALERT_HANDLER_LOC_ALERT_CLASS_SHADOWED_MULTIREG_COUNT &&
49 ALERT_HANDLER_LOC_ALERT_CLASS_SHADOWED_CLASS_LA_FIELD_WIDTH == 2 &&
50 ALERT_HANDLER_LOC_ALERT_CLASS_SHADOWED_0_CLASS_LA_0_OFFSET == 0,
51 "Expected local alert class CSRs to be multiregs with LSB at index 0!");
53 ALERT_HANDLER_LOC_ALERT_REGWEN_MULTIREG_COUNT &&
54 ALERT_HANDLER_LOC_ALERT_REGWEN_EN_FIELD_WIDTH == 1 &&
55 ALERT_HANDLER_LOC_ALERT_REGWEN_0_EN_0_BIT == 0,
56 "Expected local alert locks to be multiregs with LSB at index 0!");
58 ALERT_HANDLER_LOC_ALERT_CAUSE_MULTIREG_COUNT &&
59 ALERT_HANDLER_LOC_ALERT_CAUSE_LA_FIELD_WIDTH == 1 &&
60 ALERT_HANDLER_LOC_ALERT_CAUSE_0_LA_0_BIT == 0,
61 "Expected local alert causes to be multiregs with LSB at index 0!");
65 ALERT_HANDLER_CLASSA_ACCUM_THRESH_SHADOWED_CLASSA_ACCUM_THRESH_SHADOWED_MASK <=
67 "Expected class A accumulator threshold field to be 16 bits.");
69 ALERT_HANDLER_CLASSB_ACCUM_THRESH_SHADOWED_CLASSB_ACCUM_THRESH_SHADOWED_MASK <=
71 "Expected class B accumulator threshold field to be 16 bits.");
73 ALERT_HANDLER_CLASSC_ACCUM_THRESH_SHADOWED_CLASSC_ACCUM_THRESH_SHADOWED_MASK <=
75 "Expected class C accumulator threshold field to be 16 bits.");
77 ALERT_HANDLER_CLASSD_ACCUM_THRESH_SHADOWED_CLASSD_ACCUM_THRESH_SHADOWED_MASK <=
79 "Expected class D accumulator threshold field to be 16 bits.");
84 #define LOC_ALERT_CAUSE_REGS_CASE_(loc_alert_, value_) \
86 cause_reg_offset = ALERT_HANDLER_LOC_ALERT_CAUSE_##value_##_REG_OFFSET; \
92 #define LOC_ALERT_REGWENS_CASE_(loc_alert_, value_) \
94 regwen_offset = ALERT_HANDLER_LOC_ALERT_REGWEN_##value_##_REG_OFFSET; \
100 #define ALERT_CLASS_REGWENS_CASE_(class_, value_) \
101 case kDifAlertHandlerClass##class_: \
102 regwen_offset = ALERT_HANDLER_CLASS##class_##_REGWEN_REG_OFFSET; \
108 #define ALERT_CLASS_CLEAR_REGWENS_CASE_(class_, value_) \
109 case kDifAlertHandlerClass##class_: \
110 regwen_offset = ALERT_HANDLER_CLASS##class_##_CLR_REGWEN_REG_OFFSET; \
121 uint32_t *classification) {
122 #define ALERT_CLASS_REGS_CASE_(class_, value_) \
123 case kDifAlertHandlerClass##class_: \
125 ALERT_HANDLER_ALERT_CLASS_SHADOWED_0_CLASS_A_0_VALUE_CLASS##class_; \
127 switch (alert_class) {
133 #undef ALERT_CLASS_REGS_CASE_
155 if (alert_handler == NULL || alert >= ALERT_HANDLER_PARAM_N_ALERTS ||
159 uint32_t classification;
160 if (!class_to_uint32(alert_class, &classification)) {
165 ptrdiff_t regwen_offset = ALERT_HANDLER_ALERT_REGWEN_0_REG_OFFSET +
166 (ptrdiff_t)alert * (ptrdiff_t)
sizeof(uint32_t);
167 if (!mmio_region_read32(alert_handler->
base_addr, regwen_offset)) {
172 ptrdiff_t class_reg_offset = ALERT_HANDLER_ALERT_CLASS_SHADOWED_0_REG_OFFSET +
173 (ptrdiff_t)alert * (ptrdiff_t)
sizeof(uint32_t);
174 mmio_region_write32_shadowed(alert_handler->
base_addr, class_reg_offset,
178 ptrdiff_t enable_reg_offset = ALERT_HANDLER_ALERT_EN_SHADOWED_0_REG_OFFSET +
179 (ptrdiff_t)alert * (ptrdiff_t)
sizeof(uint32_t);
180 mmio_region_write32_shadowed(alert_handler->
base_addr, enable_reg_offset,
185 mmio_region_write32(alert_handler->
base_addr, regwen_offset, 0);
200 uint32_t classification;
201 if (!class_to_uint32(alert_class, &classification)) {
205 #define LOC_ALERT_REGS_CASE_(loc_alert_, value_) \
207 enable_reg_offset = \
208 ALERT_HANDLER_LOC_ALERT_EN_SHADOWED_##value_##_REG_OFFSET; \
210 ALERT_HANDLER_LOC_ALERT_CLASS_SHADOWED_##value_##_REG_OFFSET; \
211 regwen_offset = ALERT_HANDLER_LOC_ALERT_REGWEN_##value_##_REG_OFFSET; \
215 ptrdiff_t enable_reg_offset;
216 ptrdiff_t class_reg_offset;
217 ptrdiff_t regwen_offset;
218 switch (local_alert) {
224 #undef LOC_ALERT_REGS_CASE_
227 if (!mmio_region_read32(alert_handler->
base_addr, regwen_offset)) {
232 mmio_region_write32_shadowed(alert_handler->
base_addr, class_reg_offset,
238 mmio_region_write32_shadowed(alert_handler->
base_addr, enable_reg_offset,
243 mmio_region_write32(alert_handler->
base_addr, regwen_offset, 0);
254 if (alert_handler == NULL ||
275 #define ALERT_CLASS_CONFIG_REGS_CASE_(class_, value_) \
276 case kDifAlertHandlerClass##class_: \
277 class_regwen_offset = ALERT_HANDLER_CLASS##class_##_REGWEN_REG_OFFSET; \
278 ctrl_reg_offset = ALERT_HANDLER_CLASS##class_##_CTRL_SHADOWED_REG_OFFSET; \
279 accum_thresh_reg_offset = \
280 ALERT_HANDLER_CLASS##class_##_ACCUM_THRESH_SHADOWED_REG_OFFSET; \
281 irq_deadline_reg_offset = \
282 ALERT_HANDLER_CLASS##class_##_TIMEOUT_CYC_SHADOWED_REG_OFFSET; \
283 phase0_cycles_reg_offset = \
284 ALERT_HANDLER_CLASS##class_##_PHASE0_CYC_SHADOWED_REG_OFFSET; \
285 phase1_cycles_reg_offset = \
286 ALERT_HANDLER_CLASS##class_##_PHASE1_CYC_SHADOWED_REG_OFFSET; \
287 phase2_cycles_reg_offset = \
288 ALERT_HANDLER_CLASS##class_##_PHASE2_CYC_SHADOWED_REG_OFFSET; \
289 phase3_cycles_reg_offset = \
290 ALERT_HANDLER_CLASS##class_##_PHASE3_CYC_SHADOWED_REG_OFFSET; \
291 crashdump_phase_reg_offset = \
292 ALERT_HANDLER_CLASS##class_##_CRASHDUMP_TRIGGER_SHADOWED_REG_OFFSET; \
295 ptrdiff_t class_regwen_offset;
296 ptrdiff_t ctrl_reg_offset;
297 ptrdiff_t accum_thresh_reg_offset;
298 ptrdiff_t irq_deadline_reg_offset;
299 ptrdiff_t phase0_cycles_reg_offset;
300 ptrdiff_t phase1_cycles_reg_offset;
301 ptrdiff_t phase2_cycles_reg_offset;
302 ptrdiff_t phase3_cycles_reg_offset;
303 ptrdiff_t crashdump_phase_reg_offset;
304 switch (alert_class) {
310 #undef ALERT_CLASS_CONFIG_REGS_CASE_
313 if (!mmio_region_read32(alert_handler->
base_addr, class_regwen_offset)) {
322 uint32_t ctrl_reg = 0;
327 ctrl_reg, ALERT_HANDLER_CLASSA_CTRL_SHADOWED_LOCK_BIT,
338 if (!is_valid_escalation_phase(phase)) {
353 signal_enable_bit = ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E0_BIT;
354 signal_map_field = ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E0_FIELD;
357 signal_enable_bit = ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E1_BIT;
358 signal_map_field = ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E1_FIELD;
361 signal_enable_bit = ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E2_BIT;
362 signal_map_field = ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E2_FIELD;
365 signal_enable_bit = ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E3_BIT;
366 signal_map_field = ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E3_FIELD;
377 if (signal == 0xFFFFFFFF) {
379 ctrl_reg, ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E0_BIT,
false);
381 ctrl_reg, ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E0_FIELD,
384 ctrl_reg, ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E1_BIT,
false);
386 ctrl_reg, ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E1_FIELD,
389 ctrl_reg, ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E2_BIT,
false);
391 ctrl_reg, ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E2_FIELD,
394 ctrl_reg, ALERT_HANDLER_CLASSA_CTRL_SHADOWED_EN_E3_BIT,
false);
396 ctrl_reg, ALERT_HANDLER_CLASSA_CTRL_SHADOWED_MAP_E3_FIELD,
401 ctrl_reg, signal_map_field,
407 mmio_region_write32_shadowed(
408 alert_handler->
base_addr, phase0_cycles_reg_offset,
412 mmio_region_write32_shadowed(
413 alert_handler->
base_addr, phase1_cycles_reg_offset,
417 mmio_region_write32_shadowed(
418 alert_handler->
base_addr, phase2_cycles_reg_offset,
422 mmio_region_write32_shadowed(
423 alert_handler->
base_addr, phase3_cycles_reg_offset,
432 mmio_region_write32_shadowed(alert_handler->
base_addr,
433 accum_thresh_reg_offset,
437 mmio_region_write32_shadowed(alert_handler->
base_addr,
438 irq_deadline_reg_offset,
442 mmio_region_write32_shadowed(alert_handler->
base_addr,
443 crashdump_phase_reg_offset,
448 mmio_region_write32_shadowed(alert_handler->
base_addr, ctrl_reg_offset,
453 mmio_region_write32(alert_handler->
base_addr, class_regwen_offset, 0);
462 if (alert_handler == NULL ||
464 ALERT_HANDLER_PING_TIMEOUT_CYC_SHADOWED_PING_TIMEOUT_CYC_SHADOWED_MASK ||
470 if (!mmio_region_read32(alert_handler->
base_addr,
471 ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET)) {
476 mmio_region_write32_shadowed(
478 ALERT_HANDLER_PING_TIMEOUT_CYC_SHADOWED_REG_OFFSET, ping_timeout);
484 mmio_region_write32_shadowed(
486 ALERT_HANDLER_PING_TIMER_EN_SHADOWED_REG_OFFSET, 1);
491 mmio_region_write32(alert_handler->
base_addr,
492 ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET, 0);
505 if (!mmio_region_read32(alert_handler->
base_addr,
506 ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET)) {
511 mmio_region_write32_shadowed(alert_handler->
base_addr,
512 ALERT_HANDLER_PING_TIMER_EN_SHADOWED_REG_OFFSET,
517 mmio_region_write32(alert_handler->
base_addr,
518 ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET, 0);
526 if (alert_handler == NULL || alert >= ALERT_HANDLER_PARAM_N_ALERTS) {
530 ptrdiff_t regwen_offset = ALERT_HANDLER_ALERT_REGWEN_0_REG_OFFSET +
531 (ptrdiff_t)alert * (ptrdiff_t)
sizeof(uint32_t);
532 mmio_region_write32(alert_handler->
base_addr, regwen_offset, 0);
540 if (alert_handler == NULL || alert >= ALERT_HANDLER_PARAM_N_ALERTS ||
545 ptrdiff_t regwen_offset = ALERT_HANDLER_ALERT_REGWEN_0_REG_OFFSET +
546 (ptrdiff_t)alert * (ptrdiff_t)
sizeof(uint32_t);
547 *is_locked = !mmio_region_read32(alert_handler->
base_addr, regwen_offset);
555 if (alert_handler == NULL) {
559 ptrdiff_t regwen_offset;
560 switch (local_alert) {
566 mmio_region_write32(alert_handler->
base_addr, regwen_offset, 0);
574 if (alert_handler == NULL || is_locked == NULL) {
578 ptrdiff_t regwen_offset;
579 switch (local_alert) {
585 *is_locked = !mmio_region_read32(alert_handler->
base_addr, regwen_offset);
593 if (alert_handler == NULL) {
597 ptrdiff_t regwen_offset;
598 switch (alert_class) {
604 mmio_region_write32(alert_handler->
base_addr, regwen_offset, 0);
612 if (alert_handler == NULL || is_locked == NULL) {
616 ptrdiff_t regwen_offset;
617 switch (alert_class) {
623 *is_locked = !mmio_region_read32(alert_handler->
base_addr, regwen_offset);
630 if (alert_handler == NULL) {
634 mmio_region_write32(alert_handler->
base_addr,
635 ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET, 0);
642 if (alert_handler == NULL || is_locked == NULL) {
646 *is_locked = !mmio_region_read32(alert_handler->
base_addr,
647 ALERT_HANDLER_PING_TIMER_REGWEN_REG_OFFSET);
655 if (alert_handler == NULL || is_cause == NULL ||
656 alert >= ALERT_HANDLER_PARAM_N_ALERTS) {
660 ptrdiff_t cause_reg_offset = ALERT_HANDLER_ALERT_CAUSE_0_REG_OFFSET +
661 (ptrdiff_t)alert * (ptrdiff_t)
sizeof(uint32_t);
662 *is_cause = mmio_region_read32(alert_handler->
base_addr, cause_reg_offset);
669 if (alert_handler == NULL || alert >= ALERT_HANDLER_PARAM_N_ALERTS) {
673 ptrdiff_t cause_reg_offset = ALERT_HANDLER_ALERT_CAUSE_0_REG_OFFSET +
674 (ptrdiff_t)alert * (ptrdiff_t)
sizeof(uint32_t);
675 mmio_region_write32(alert_handler->
base_addr, cause_reg_offset, 0x1);
683 if (alert_handler == NULL || is_cause == NULL) {
687 ptrdiff_t cause_reg_offset;
688 switch (local_alert) {
694 *is_cause = mmio_region_read32(alert_handler->
base_addr, cause_reg_offset);
702 if (alert_handler == NULL) {
706 ptrdiff_t cause_reg_offset;
707 switch (local_alert) {
713 mmio_region_write32(alert_handler->
base_addr, cause_reg_offset, 0x1);
721 if (alert_handler == NULL || can_clear == NULL) {
725 ptrdiff_t regwen_offset;
726 switch (alert_class) {
732 *can_clear = mmio_region_read32(alert_handler->
base_addr, regwen_offset);
740 if (alert_handler == NULL) {
744 ptrdiff_t regwen_offset;
745 switch (alert_class) {
751 mmio_region_write32(alert_handler->
base_addr, regwen_offset, 0);
759 if (alert_handler == NULL) {
763 #define ALERT_CLASS_CLEAR_CASE_(class_, value_) \
764 case kDifAlertHandlerClass##class_: \
765 reg_offset = ALERT_HANDLER_CLASS##class_##_CLR_SHADOWED_REG_OFFSET; \
768 ptrdiff_t reg_offset;
769 switch (alert_class) {
775 #undef ALERT_CLASS_CLEAR_CASE_
777 mmio_region_write32_shadowed(alert_handler->
base_addr, reg_offset, 0x1);
785 if (alert_handler == NULL || num_alerts == NULL) {
789 #define ALERT_CLASS_ACCUM_CASE_(class_, value_) \
790 case kDifAlertHandlerClass##class_: \
791 reg_offset = ALERT_HANDLER_CLASS##class_##_ACCUM_CNT_REG_OFFSET; \
793 ALERT_HANDLER_CLASS##class_##_ACCUM_CNT_CLASS##class_##_ACCUM_CNT_FIELD; \
796 ptrdiff_t reg_offset;
798 switch (alert_class) {
804 #undef ALERT_CLASS_ACCUM_CASE_
806 uint32_t reg = mmio_region_read32(alert_handler->
base_addr, reg_offset);
815 if (alert_handler == NULL || cycles == NULL) {
819 #define ALERT_CLASS_ESC_CNT_CASE_(class_, value_) \
820 case kDifAlertHandlerClass##class_: \
821 reg_offset = ALERT_HANDLER_CLASS##class_##_ESC_CNT_REG_OFFSET; \
824 ptrdiff_t reg_offset;
825 switch (alert_class) {
831 #undef ALERT_CLASS_ESC_CNT_CASE_
833 *cycles = mmio_region_read32(alert_handler->
base_addr, reg_offset);
842 if (alert_handler == NULL || state == NULL) {
846 #define ALERT_CLASS_STATE_CASE_(class_, value_) \
847 case kDifAlertHandlerClass##class_: \
848 reg_offset = ALERT_HANDLER_CLASS##class_##_STATE_REG_OFFSET; \
849 field = ALERT_HANDLER_CLASS##class_##_STATE_CLASS##class_##_STATE_FIELD; \
852 ptrdiff_t reg_offset;
854 switch (alert_class) {
860 #undef ALERT_CLASS_STATE_CASE_
862 uint32_t reg = mmio_region_read32(alert_handler->
base_addr, reg_offset);
864 case ALERT_HANDLER_CLASSA_STATE_CLASSA_STATE_VALUE_IDLE:
867 case ALERT_HANDLER_CLASSA_STATE_CLASSA_STATE_VALUE_TIMEOUT:
870 case ALERT_HANDLER_CLASSA_STATE_CLASSA_STATE_VALUE_FSMERROR:
873 case ALERT_HANDLER_CLASSA_STATE_CLASSA_STATE_VALUE_TERMINAL:
876 case ALERT_HANDLER_CLASSA_STATE_CLASSA_STATE_VALUE_PHASE0:
879 case ALERT_HANDLER_CLASSA_STATE_CLASSA_STATE_VALUE_PHASE1:
882 case ALERT_HANDLER_CLASSA_STATE_CLASSA_STATE_VALUE_PHASE2:
885 case ALERT_HANDLER_CLASSA_STATE_CLASSA_STATE_VALUE_PHASE3: