Skip to content

Commit 9baed2b

Browse files
committed
[testutils,uart] Move uart testutils to DT API
Signed-off-by: Robert Schilling <[email protected]>
1 parent 06f44d0 commit 9baed2b

File tree

6 files changed

+271
-342
lines changed

6 files changed

+271
-342
lines changed

sw/device/lib/testing/BUILD

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -535,8 +535,8 @@ cc_library(
535535
hdrs = ["uart_testutils.h"],
536536
target_compatible_with = [OPENTITAN_CPU],
537537
deps = [
538+
"//hw/top:dt",
538539
"//hw/top:uart_c_regs",
539-
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
540540
"//sw/device/lib/dif:pinmux",
541541
"//sw/device/lib/dif:uart",
542542
"//sw/device/lib/runtime:ibex",
@@ -638,7 +638,6 @@ cc_library(
638638

639639
# Some testutils are not multitop yet.
640640
TESTUTILS_EXCEPTIONS = [
641-
"uart",
642641
"rstmgr",
643642
]
644643

sw/device/lib/testing/uart_testutils.c

Lines changed: 96 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <stdbool.h>
99
#include <stdint.h>
1010

11+
#include "hw/top/dt/dt_pinmux.h"
1112
#include "sw/device/lib/base/mmio.h"
1213
#include "sw/device/lib/dif/dif_pinmux.h"
1314
#include "sw/device/lib/dif/dif_uart.h"
@@ -18,166 +19,124 @@
1819
#include "sw/device/lib/testing/test_framework/check.h"
1920

2021
#include "hw/top/uart_regs.h" // Generated.
21-
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
2222

2323
#define MODULE_ID MAKE_MODULE_ID('u', 't', 'u')
2424

2525
/**
26-
* This table stores the pins for all UART instances of Earlgrey.
26+
* Get the UART instance from index.
27+
*
28+
* @param uart_idx UART index (0-based).
29+
* @return UART DT instance, or kDtUartCount if invalid.
2730
*/
28-
static const pinmux_testutils_peripheral_pin_t kUartPinmuxPins[] = {
29-
// UART0.
30-
{
31-
.peripheral_in = kTopEarlgreyPinmuxPeripheralInUart0Rx,
32-
.outsel = kTopEarlgreyPinmuxOutselUart0Tx,
33-
},
34-
// UART1.
35-
{
36-
.peripheral_in = kTopEarlgreyPinmuxPeripheralInUart1Rx,
37-
.outsel = kTopEarlgreyPinmuxOutselUart1Tx,
38-
},
39-
// UART2.
40-
{
41-
.peripheral_in = kTopEarlgreyPinmuxPeripheralInUart2Rx,
42-
.outsel = kTopEarlgreyPinmuxOutselUart2Tx,
43-
},
44-
// UART3.
45-
{
46-
.peripheral_in = kTopEarlgreyPinmuxPeripheralInUart3Rx,
47-
.outsel = kTopEarlgreyPinmuxOutselUart3Tx,
48-
},
49-
};
31+
static dt_uart_t get_uart_instance(uint8_t uart_idx) {
32+
if (uart_idx >= kDtUartCount) {
33+
return kDtUartCount;
34+
}
35+
return (dt_uart_t)uart_idx;
36+
}
5037

5138
/**
52-
* This table stores UART pin mappings for synthesized platforms.
39+
* Get the appropriate pads for a UART instance and channel based on the
40+
* platform. This replicates the original behavior with different mappings for
41+
* DV vs synthesized platforms.
42+
*
43+
* @param uart_dt UART DT instance.
44+
* @param channel The channel to connect the UART to.
45+
* @param rx_pad Output parameter for RX pad.
46+
* @param tx_pad Output parameter for TX pad.
47+
* @return OK_STATUS if successful, error status otherwise.
5348
*/
54-
static const pinmux_testutils_mio_pin_t
55-
kUartSynthPins[kUartPinmuxChannelCount] = {
56-
[kUartPinmuxChannelConsole] =
57-
{
58-
.mio_out = kTopEarlgreyPinmuxMioOutIoc4,
59-
.insel = kTopEarlgreyPinmuxInselIoc3,
60-
},
61-
[kUartPinmuxChannelDut] = {
62-
.mio_out = kTopEarlgreyPinmuxMioOutIob5,
63-
.insel = kTopEarlgreyPinmuxInselIob4,
64-
}};
49+
static status_t get_uart_pads_for_channel(dt_uart_t uart_dt,
50+
uart_pinmux_channel_t channel,
51+
dt_pad_t *rx_pad, dt_pad_t *tx_pad) {
52+
#if defined(OPENTITAN_IS_DARJEELING)
53+
// Darjeeling only has UART0 and uses dedicated pads
54+
if (uart_dt != kDtUart0) {
55+
return INVALID_ARGUMENT();
56+
}
57+
*rx_pad = kDtPadUart0Rx;
58+
*tx_pad = kDtPadUart0Tx;
59+
#elif defined(OPENTITAN_IS_EARLGREY) || defined(OPENTITAN_IS_ENGLISHBREAKFAST)
60+
// For Earlgrey and EnglishBreakfast platforms
61+
// For DV platform, each UART has its own specific mapping
62+
if (kDeviceType == kDeviceSimDV) {
63+
switch (uart_dt) {
64+
case kDtUart0:
65+
*rx_pad = kDtPadIoc3;
66+
*tx_pad = kDtPadIoc4;
67+
break;
68+
case kDtUart1:
69+
*rx_pad = kDtPadIob4;
70+
*tx_pad = kDtPadIob5;
71+
break;
72+
case kDtUart2:
73+
*rx_pad = kDtPadIoa4;
74+
*tx_pad = kDtPadIoa5;
75+
break;
76+
case kDtUart3:
77+
*rx_pad = kDtPadIoa0;
78+
*tx_pad = kDtPadIoa1;
79+
break;
80+
default:
81+
return INVALID_ARGUMENT();
82+
}
83+
} else {
84+
// For synthesized platforms, use channel-based mapping
85+
switch (channel) {
86+
case kUartPinmuxChannelConsole:
87+
*rx_pad = kDtPadIoc3;
88+
*tx_pad = kDtPadIoc4;
89+
break;
90+
case kUartPinmuxChannelDut:
91+
*rx_pad = kDtPadIob4;
92+
*tx_pad = kDtPadIob5;
93+
break;
94+
default:
95+
return INVALID_ARGUMENT();
96+
}
97+
}
98+
#else
99+
return UNIMPLEMENTED();
100+
#endif
65101

66-
/**
67-
* The DV platform is handled separately at the moment: all four UARTs have
68-
* their own channels that they map to rather than using one channel for the
69-
* console and second for the DUT.
70-
*/
71-
static const pinmux_testutils_mio_pin_t kUartDvPins[4] = {
72-
// UART0.
73-
{
74-
.mio_out = kTopEarlgreyPinmuxMioOutIoc4,
75-
.insel = kTopEarlgreyPinmuxInselIoc3,
76-
},
77-
// UART1.
78-
{
79-
.mio_out = kTopEarlgreyPinmuxMioOutIob5,
80-
.insel = kTopEarlgreyPinmuxInselIob4,
81-
},
82-
// UART2.
83-
{
84-
.mio_out = kTopEarlgreyPinmuxMioOutIoa5,
85-
.insel = kTopEarlgreyPinmuxInselIoa4,
86-
},
87-
// UART3.
88-
{
89-
.mio_out = kTopEarlgreyPinmuxMioOutIoa1,
90-
.insel = kTopEarlgreyPinmuxInselIoa0,
91-
}};
92-
93-
static const uart_cfg_params_t kUartCfgParams[4] = {
94-
(uart_cfg_params_t){
95-
.base_addr = TOP_EARLGREY_UART0_BASE_ADDR,
96-
.peripheral_id = kTopEarlgreyPlicPeripheralUart0,
97-
.irq_tx_watermark_id = kTopEarlgreyPlicIrqIdUart0TxWatermark,
98-
.irq_tx_empty_id = kTopEarlgreyPlicIrqIdUart0TxEmpty,
99-
.irq_rx_watermark_id = kTopEarlgreyPlicIrqIdUart0RxWatermark,
100-
.irq_tx_done_id = kTopEarlgreyPlicIrqIdUart0TxDone,
101-
.irq_rx_overflow_id = kTopEarlgreyPlicIrqIdUart0RxOverflow,
102-
.irq_rx_frame_err_id = kTopEarlgreyPlicIrqIdUart0RxFrameErr,
103-
.irq_rx_break_err_id = kTopEarlgreyPlicIrqIdUart0RxBreakErr,
104-
.irq_rx_timeout_id = kTopEarlgreyPlicIrqIdUart0RxTimeout,
105-
.irq_rx_parity_err_id = kTopEarlgreyPlicIrqIdUart0RxParityErr,
106-
},
107-
(uart_cfg_params_t){
108-
.base_addr = TOP_EARLGREY_UART1_BASE_ADDR,
109-
.peripheral_id = kTopEarlgreyPlicPeripheralUart1,
110-
.irq_tx_watermark_id = kTopEarlgreyPlicIrqIdUart1TxWatermark,
111-
.irq_tx_empty_id = kTopEarlgreyPlicIrqIdUart1TxEmpty,
112-
.irq_rx_watermark_id = kTopEarlgreyPlicIrqIdUart1RxWatermark,
113-
.irq_tx_done_id = kTopEarlgreyPlicIrqIdUart1TxDone,
114-
.irq_rx_overflow_id = kTopEarlgreyPlicIrqIdUart1RxOverflow,
115-
.irq_rx_frame_err_id = kTopEarlgreyPlicIrqIdUart1RxFrameErr,
116-
.irq_rx_break_err_id = kTopEarlgreyPlicIrqIdUart1RxBreakErr,
117-
.irq_rx_timeout_id = kTopEarlgreyPlicIrqIdUart1RxTimeout,
118-
.irq_rx_parity_err_id = kTopEarlgreyPlicIrqIdUart1RxParityErr,
119-
},
120-
(uart_cfg_params_t){
121-
.base_addr = TOP_EARLGREY_UART2_BASE_ADDR,
122-
.peripheral_id = kTopEarlgreyPlicPeripheralUart2,
123-
.irq_tx_watermark_id = kTopEarlgreyPlicIrqIdUart2TxWatermark,
124-
.irq_tx_empty_id = kTopEarlgreyPlicIrqIdUart2TxEmpty,
125-
.irq_rx_watermark_id = kTopEarlgreyPlicIrqIdUart2RxWatermark,
126-
.irq_tx_done_id = kTopEarlgreyPlicIrqIdUart2TxDone,
127-
.irq_rx_overflow_id = kTopEarlgreyPlicIrqIdUart2RxOverflow,
128-
.irq_rx_frame_err_id = kTopEarlgreyPlicIrqIdUart2RxFrameErr,
129-
.irq_rx_break_err_id = kTopEarlgreyPlicIrqIdUart2RxBreakErr,
130-
.irq_rx_timeout_id = kTopEarlgreyPlicIrqIdUart2RxTimeout,
131-
.irq_rx_parity_err_id = kTopEarlgreyPlicIrqIdUart2RxParityErr,
132-
},
133-
(uart_cfg_params_t){
134-
.base_addr = TOP_EARLGREY_UART3_BASE_ADDR,
135-
.peripheral_id = kTopEarlgreyPlicPeripheralUart3,
136-
.irq_tx_watermark_id = kTopEarlgreyPlicIrqIdUart3TxWatermark,
137-
.irq_tx_empty_id = kTopEarlgreyPlicIrqIdUart3TxEmpty,
138-
.irq_rx_watermark_id = kTopEarlgreyPlicIrqIdUart3RxWatermark,
139-
.irq_tx_done_id = kTopEarlgreyPlicIrqIdUart3TxDone,
140-
.irq_rx_overflow_id = kTopEarlgreyPlicIrqIdUart3RxOverflow,
141-
.irq_rx_frame_err_id = kTopEarlgreyPlicIrqIdUart3RxFrameErr,
142-
.irq_rx_break_err_id = kTopEarlgreyPlicIrqIdUart3RxBreakErr,
143-
.irq_rx_timeout_id = kTopEarlgreyPlicIrqIdUart3RxTimeout,
144-
.irq_rx_parity_err_id = kTopEarlgreyPlicIrqIdUart3RxParityErr,
145-
}};
102+
return OK_STATUS();
103+
}
146104

147105
status_t uart_testutils_select_pinmux(const dif_pinmux_t *pinmux,
148106
uint8_t uart_idx,
149107
uart_pinmux_channel_t channel) {
150-
TRY_CHECK(channel < kUartPinmuxChannelCount &&
151-
uart_idx < ARRAYSIZE(kUartPinmuxPins),
152-
"Index out of bounds");
108+
TRY_CHECK(channel < kUartPinmuxChannelCount, "Channel out of bounds");
153109

154-
pinmux_testutils_mio_pin_t mio_pin = kDeviceType == kDeviceSimDV
155-
? kUartDvPins[uart_idx]
156-
: kUartSynthPins[channel];
110+
dt_uart_t uart_dt = get_uart_instance(uart_idx);
111+
TRY_CHECK(uart_dt < kDtUartCount, "UART index out of bounds");
157112

158-
TRY(dif_pinmux_input_select(pinmux, kUartPinmuxPins[uart_idx].peripheral_in,
159-
mio_pin.insel));
160-
TRY(dif_pinmux_output_select(pinmux, mio_pin.mio_out,
161-
kUartPinmuxPins[uart_idx].outsel));
113+
// Get peripheral I/O descriptions for RX and TX
114+
dt_periph_io_t rx_periph_io = dt_uart_periph_io(uart_dt, kDtUartPeriphIoRx);
115+
dt_periph_io_t tx_periph_io = dt_uart_periph_io(uart_dt, kDtUartPeriphIoTx);
162116

163-
return OK_STATUS();
164-
}
117+
// Get the appropriate pads for this UART instance and channel
118+
dt_pad_t rx_pad, tx_pad;
119+
TRY(get_uart_pads_for_channel(uart_dt, channel, &rx_pad, &tx_pad));
165120

166-
status_t uart_testutils_detach_pinmux(const dif_pinmux_t *pinmux,
167-
uint8_t uart_idx) {
168-
TRY_CHECK(uart_idx < ARRAYSIZE(kUartPinmuxPins), "Index out of bounds");
121+
// Connect RX input using low-level pinmux functions
122+
TRY(dif_pinmux_mio_select_input(pinmux, rx_periph_io, rx_pad));
169123

170-
TRY(dif_pinmux_input_select(pinmux, kUartPinmuxPins[uart_idx].peripheral_in,
171-
kTopEarlgreyPinmuxInselConstantZero));
124+
// Connect TX output using low-level pinmux functions
125+
TRY(dif_pinmux_mio_select_output(pinmux, tx_pad, tx_periph_io));
172126

173127
return OK_STATUS();
174128
}
175129

176-
status_t uart_testutils_cfg_params(uint8_t uart_idx,
177-
uart_cfg_params_t *params) {
178-
TRY_CHECK(uart_idx < ARRAYSIZE(kUartCfgParams), "Index out of bounds");
130+
status_t uart_testutils_detach_pinmux(const dif_pinmux_t *pinmux,
131+
uint8_t uart_idx) {
132+
dt_uart_t uart_dt = get_uart_instance(uart_idx);
133+
TRY_CHECK(uart_dt < kDtUartCount, "UART index out of bounds");
134+
135+
// Get peripheral I/O description for RX
136+
dt_periph_io_t rx_periph_io = dt_uart_periph_io(uart_dt, kDtUartPeriphIoRx);
179137

180-
*params = kUartCfgParams[uart_idx];
138+
// Disconnect RX input by connecting to constant zero using low-level function
139+
TRY(dif_pinmux_mio_select_input(pinmux, rx_periph_io, kDtPadConstantZero));
181140

182141
return OK_STATUS();
183142
}

sw/device/lib/testing/uart_testutils.h

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <stdint.h>
99

10+
#include "hw/top/dt/dt_uart.h"
1011
#include "sw/device/lib/base/status.h"
1112
#include "sw/device/lib/dif/dif_pinmux.h"
1213
#include "sw/device/lib/dif/dif_uart.h"
@@ -30,20 +31,6 @@ typedef enum uart_pinmux_channel {
3031
kUartPinmuxChannelCount,
3132
} uart_pinmux_channel_t;
3233

33-
typedef struct uart_cfg_params {
34-
uint32_t base_addr;
35-
uint32_t peripheral_id;
36-
uint32_t irq_tx_watermark_id;
37-
uint32_t irq_tx_empty_id;
38-
uint32_t irq_rx_watermark_id;
39-
uint32_t irq_tx_done_id;
40-
uint32_t irq_rx_overflow_id;
41-
uint32_t irq_rx_frame_err_id;
42-
uint32_t irq_rx_break_err_id;
43-
uint32_t irq_rx_timeout_id;
44-
uint32_t irq_rx_parity_err_id;
45-
} uart_cfg_params_t;
46-
4734
/**
4835
* Connect the uart pins to mio pins via pinmux based on the platform the test
4936
* is running.
@@ -69,14 +56,4 @@ OT_WARN_UNUSED_RESULT
6956
status_t uart_testutils_detach_pinmux(const dif_pinmux_t *pinmux,
7057
uint8_t uart_idx);
7158

72-
/**
73-
* Look up the configuration parameters for a given UART instance.
74-
*
75-
* @param uart_idx The index of the UART being configured.
76-
* @param[out] params Pointer to the struct to write the parameters to.
77-
* @return The result of the operation.
78-
*/
79-
OT_WARN_UNUSED_RESULT
80-
status_t uart_testutils_cfg_params(uint8_t uart_idx, uart_cfg_params_t *params);
81-
8259
#endif // OPENTITAN_SW_DEVICE_LIB_TESTING_UART_TESTUTILS_H_

sw/device/tests/BUILD

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7205,9 +7205,9 @@ opentitan_test(
72057205
verilator = verilator_params(tags = ["manual"]),
72067206
deps = [
72077207
"//hw/top:clkmgr_c_regs",
7208+
"//hw/top:dt",
72087209
"//hw/top:lc_ctrl_c_regs",
72097210
"//hw/top:pinmux_c_regs",
7210-
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
72117211
"//sw/device/lib/base:mmio",
72127212
"//sw/device/lib/dif:clkmgr",
72137213
"//sw/device/lib/dif:lc_ctrl",
@@ -7490,7 +7490,7 @@ opentitan_test(
74907490
# in CI/nightlies.
74917491
verilator = verilator_params(tags = ["manual"]),
74927492
deps = [
7493-
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
7493+
"//hw/top:dt",
74947494
"//sw/device/lib/base:mmio",
74957495
"//sw/device/lib/dif:rv_plic",
74967496
"//sw/device/lib/dif:uart",

0 commit comments

Comments
 (0)