Skip to content

Commit 4faebab

Browse files
committed
[tests] Port alert_handler_ping_timeout_test to multitop
Signed-off-by: Robert Schilling <[email protected]>
1 parent 0469d01 commit 4faebab

File tree

2 files changed

+65
-45
lines changed

2 files changed

+65
-45
lines changed

sw/device/tests/BUILD

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,12 +353,13 @@ opentitan_test(
353353
exec_env = dicts.add(
354354
EARLGREY_TEST_ENVS,
355355
EARLGREY_SILICON_OWNER_ROM_EXT_ENVS,
356+
DARJEELING_TEST_ENVS,
356357
),
357358
fpga = fpga_params(timeout = "moderate"),
358359
verilator = verilator_params(timeout = "long"),
359360
deps = [
360361
"//hw/top:alert_handler_c_regs",
361-
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
362+
"//hw/top:dt",
362363
"//sw/device/lib/base:math",
363364
"//sw/device/lib/base:mmio",
364365
"//sw/device/lib/dif:alert_handler",

sw/device/tests/alert_handler_ping_timeout_test.c

Lines changed: 63 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -7,59 +7,67 @@
77
#include <stdbool.h>
88
#include <stdint.h>
99

10+
#include "hw/top/dt/dt_alert_handler.h"
11+
#include "hw/top/dt/dt_rv_plic.h"
12+
#include "sw/device/lib/base/macros.h"
1013
#include "sw/device/lib/base/math.h"
1114
#include "sw/device/lib/base/mmio.h"
1215
#include "sw/device/lib/dif/dif_alert_handler.h"
1316
#include "sw/device/lib/dif/dif_rv_plic.h"
1417
#include "sw/device/lib/runtime/irq.h"
1518
#include "sw/device/lib/runtime/log.h"
1619
#include "sw/device/lib/testing/alert_handler_testutils.h"
17-
#include "sw/device/lib/testing/rv_plic_testutils.h"
1820
#include "sw/device/lib/testing/test_framework/FreeRTOSConfig.h"
1921
#include "sw/device/lib/testing/test_framework/check.h"
2022
#include "sw/device/lib/testing/test_framework/ottf_main.h"
2123

2224
#include "hw/top/alert_handler_regs.h" // Generated.
23-
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
24-
#include "sw/device/lib/testing/autogen/isr_testutils.h"
2525

2626
OTTF_DEFINE_TEST_CONFIG();
2727

2828
static dif_rv_plic_t plic;
2929
static dif_alert_handler_t alert_handler;
30-
static const uint32_t kPlicTarget = kTopEarlgreyPlicTargetIbex0;
3130

32-
static plic_isr_ctx_t plic_ctx = {
33-
.rv_plic = &plic,
34-
.hart_id = kPlicTarget,
31+
enum {
32+
/**
33+
* PLIC target for the Ibex core.
34+
*/
35+
kDtRvPlicTargetIbex0 = 0,
3536
};
3637

3738
// Depends on the clock domain, sometimes alert handler will trigger a spurious
3839
// alert after the alert timeout. (Issue #2321)
3940
// So we allow class A interrupt to fire after the real timeout interrupt is
4041
// triggered.
41-
static alert_handler_isr_ctx_t alert_handler_ctx = {
42-
.alert_handler = &alert_handler,
43-
.plic_alert_handler_start_irq_id = kTopEarlgreyPlicIrqIdAlertHandlerClassa,
44-
.expected_irq = kDifAlertHandlerIrqClassb,
45-
.is_only_irq = false,
46-
};
42+
static volatile bool irq_fired = false;
4743

4844
/**
4945
* Initialize the peripherals used in this test.
5046
*/
5147
static void init_peripherals(void) {
52-
mmio_region_t base_addr =
53-
mmio_region_from_addr(TOP_EARLGREY_RV_PLIC_BASE_ADDR);
54-
CHECK_DIF_OK(dif_rv_plic_init(base_addr, &plic));
55-
56-
base_addr = mmio_region_from_addr(TOP_EARLGREY_ALERT_HANDLER_BASE_ADDR);
57-
CHECK_DIF_OK(dif_alert_handler_init(base_addr, &alert_handler));
48+
CHECK_DIF_OK(dif_rv_plic_init_from_dt(kDtRvPlic, &plic));
49+
CHECK_DIF_OK(dif_alert_handler_init_from_dt(kDtAlertHandler, &alert_handler));
5850

5951
// Enable all the alert_handler interrupts used in this test.
60-
rv_plic_testutils_irq_range_enable(&plic, kPlicTarget,
61-
kTopEarlgreyPlicIrqIdAlertHandlerClassa,
62-
kTopEarlgreyPlicIrqIdAlertHandlerClassd);
52+
dt_plic_irq_id_t classa_irq = dt_alert_handler_irq_to_plic_id(
53+
kDtAlertHandler, kDtAlertHandlerIrqClassa);
54+
dt_plic_irq_id_t classb_irq = dt_alert_handler_irq_to_plic_id(
55+
kDtAlertHandler, kDtAlertHandlerIrqClassb);
56+
dt_plic_irq_id_t classc_irq = dt_alert_handler_irq_to_plic_id(
57+
kDtAlertHandler, kDtAlertHandlerIrqClassc);
58+
dt_plic_irq_id_t classd_irq = dt_alert_handler_irq_to_plic_id(
59+
kDtAlertHandler, kDtAlertHandlerIrqClassd);
60+
61+
dt_plic_irq_id_t irq_ids[] = {classa_irq, classb_irq, classc_irq, classd_irq};
62+
for (size_t i = 0; i < ARRAYSIZE(irq_ids); ++i) {
63+
CHECK_DIF_OK(
64+
dif_rv_plic_irq_set_priority(&plic, irq_ids[i], /*priority=*/1u));
65+
CHECK_DIF_OK(dif_rv_plic_irq_set_enabled(
66+
&plic, irq_ids[i], kDtRvPlicTargetIbex0, kDifToggleEnabled));
67+
}
68+
69+
CHECK_DIF_OK(dif_rv_plic_target_set_threshold(&plic, kDtRvPlicTargetIbex0,
70+
/*threshold=*/0u));
6371
}
6472

6573
/**
@@ -129,37 +137,48 @@ static void alert_handler_config(void) {
129137
* line to the CPU, which results in a call to this OTTF ISR. This ISR
130138
* overrides the default OTTF implementation.
131139
*/
132-
void ottf_external_isr(uint32_t *exc_info) {
133-
top_earlgrey_plic_peripheral_t peripheral_serviced;
134-
dif_alert_handler_irq_t irq_serviced;
135-
isr_testutils_alert_handler_isr(plic_ctx, alert_handler_ctx,
136-
&peripheral_serviced, &irq_serviced);
137-
CHECK(peripheral_serviced == kTopEarlgreyPlicPeripheralAlertHandler,
138-
"Interrupt from unexpected peripheral: %d", peripheral_serviced);
139-
140-
// Only interrupts from class B alerts are expected for this test. Report the
141-
// unexpected class.
142-
CHECK(irq_serviced == kDifAlertHandlerIrqClassb,
143-
"Interrupt from unexpected class: Class %c", 'A' + irq_serviced);
144-
// Disable the interrupt after seeing a single ping timeout.
145-
CHECK_DIF_OK(dif_alert_handler_irq_set_enabled(
146-
&alert_handler, kDifAlertHandlerIrqClassb, kDifToggleDisabled));
140+
bool ottf_handle_irq(uint32_t *exc_info, dt_instance_id_t inst_id,
141+
dif_rv_plic_irq_id_t plic_irq_id) {
142+
// Check if this is the alert handler peripheral
143+
if (inst_id != dt_alert_handler_instance_id(kDtAlertHandler)) {
144+
return false;
145+
}
146+
147+
// Convert PLIC IRQ ID to alert handler IRQ
148+
dt_alert_handler_irq_t irq =
149+
dt_alert_handler_irq_from_plic_id(kDtAlertHandler, plic_irq_id);
150+
151+
// Acknowledge the interrupt
152+
CHECK_DIF_OK(dif_alert_handler_irq_acknowledge(&alert_handler, irq));
153+
154+
// We expect Class B interrupt primarily, but may see Class A due to timing
155+
// (Issue #2321 - spurious alerts after timeout)
156+
if (irq == kDtAlertHandlerIrqClassb) {
157+
irq_fired = true;
158+
// Disable the interrupt after seeing the ping timeout
159+
CHECK_DIF_OK(dif_alert_handler_irq_set_enabled(
160+
&alert_handler, kDifAlertHandlerIrqClassb, kDifToggleDisabled));
161+
} else if (irq == kDtAlertHandlerIrqClassa) {
162+
// Allow Class A as per Issue #2321
163+
LOG_INFO("Received spurious Class A interrupt (expected per Issue #2321)");
164+
} else {
165+
CHECK(false, "Interrupt from unexpected class: %d", irq);
166+
}
167+
168+
return true;
147169
}
148170

149171
bool test_main(void) {
150172
init_peripherals();
151173

152-
// Stop Ibex from servicing interrupts just before WFI, which would lead to a
153-
// long sleep if the test changes to only handle a single ping timeout.
154-
irq_global_ctrl(false);
174+
// Enable interrupts globally
175+
irq_global_ctrl(true);
155176
irq_external_ctrl(true);
156177

157178
alert_handler_config();
158179

159-
wait_for_interrupt();
160-
161-
// Enable the external IRQ at Ibex to jump to servicing it.
162-
irq_global_ctrl(true);
180+
// Wait for the ping timeout interrupt to fire
181+
ATOMIC_WAIT_FOR_INTERRUPT(irq_fired);
163182

164183
// Check local alert cause.
165184
bool is_cause;

0 commit comments

Comments
 (0)