9 #include "sw/device/lib/runtime/irq.h"
11 #include "sw/device/lib/testing/test_framework/check.h"
13 #include "sw/device/lib/testing/test_framework/status.h"
15 static_assert(kDtRvPlicCount == 1,
"This test expects exactly one rv_plic");
17 static const dt_rv_plic_t kTestRvPlic = (dt_rv_plic_t)0;
18 static const dt_uart_t kTestUart = (dt_uart_t)0;
24 static dif_rv_plic_t plic0;
25 static dif_uart_t uart0;
31 static volatile bool uart_rx_overflow_handled;
32 static volatile bool uart_tx_done_handled;
41 dt_uart_irq_t uart_irq = dt_uart_irq_from_plic_id(kTestUart, plic_irq_id);
44 case kDtUartIrqRxOverflow:
45 CHECK(!uart_rx_overflow_handled,
46 "UART RX overflow IRQ asserted more than once");
48 uart_rx_overflow_handled =
true;
50 case kDtUartIrqTxDone:
51 CHECK(!uart_tx_done_handled,
"UART TX done IRQ asserted more than once");
53 uart_tx_done_handled =
true;
57 test_status_set(kTestStatusFailed);
60 CHECK_DIF_OK(dif_uart_irq_acknowledge(&uart0, uart_irq));
70 void ottf_external_isr(uint32_t *exc_info) {
76 dt_instance_id_t inst_id = dt_plic_id_to_instance_id(plic_irq_id);
77 CHECK(inst_id == dt_uart_instance_id(kTestUart),
78 "Interrupt from incorrect peripheral: (exp: %d, obs: %s)",
79 dt_uart_instance_id(kTestUart), inst_id);
80 handle_uart_isr(plic_irq_id);
87 static void uart_initialise(dt_uart_t uart_id, dif_uart_t *uart) {
88 CHECK_DIF_OK(dif_uart_init_from_dt(uart_id, uart));
89 CHECK(
kUartBaudrate <= UINT32_MAX,
"kUartBaudrate must fit in uint32_t");
91 "kClockFreqPeripheralHz must fit in uint32_t");
106 static void uart_configure_irqs(dif_uart_t *uart) {
107 CHECK_DIF_OK(dif_uart_irq_set_enabled(&uart0, kDifUartIrqRxOverflow,
116 static void plic_configure_irqs(dif_rv_plic_t *plic) {
117 dt_plic_irq_id_t rx_ovf_irq =
118 dt_uart_irq_to_plic_id(kTestUart, kDtUartIrqRxOverflow);
119 dt_plic_irq_id_t tx_done_irq =
120 dt_uart_irq_to_plic_id(kTestUart, kDtUartIrqTxDone);
141 static void execute_test(dif_uart_t *uart) {
143 uart_rx_overflow_handled =
false;
144 CHECK_DIF_OK(dif_uart_irq_force(uart, kDifUartIrqRxOverflow,
true));
146 if (!uart_rx_overflow_handled) {
149 CHECK(uart_rx_overflow_handled,
"RX overflow IRQ has not been handled!");
152 uart_tx_done_handled =
false;
153 CHECK_DIF_OK(dif_uart_irq_force(uart, kDifUartIrqTxDone,
true));
155 if (!uart_tx_done_handled) {
158 CHECK(uart_tx_done_handled,
"TX done IRQ has not been handled!");
161 OTTF_DEFINE_TEST_CONFIG(.console.test_may_clobber =
true);
165 irq_global_ctrl(
true);
166 irq_external_ctrl(
true);
169 uart_initialise(kTestUart, &uart0);
171 CHECK_DIF_OK(dif_rv_plic_init_from_dt(kTestRvPlic, &plic0));
173 uart_configure_irqs(&uart0);
174 plic_configure_irqs(&plic0);
175 execute_test(&uart0);