Skip to content

Commit d516312

Browse files
committed
[silicon_creator,uart] Rewrite unittest using ibex mock
Now that the ibex library has a proper mock, we can more thorougly test the uart library. Signed-off-by: Amaury Pouly <[email protected]>
1 parent 79cb0a2 commit d516312

File tree

1 file changed

+46
-6
lines changed

1 file changed

+46
-6
lines changed

sw/device/silicon_creator/lib/drivers/uart_unittest.cc

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "sw/device/lib/base/hardened.h"
1111
#include "sw/device/lib/base/mmio.h"
1212
#include "sw/device/lib/base/mock_abs_mmio.h"
13+
#include "sw/device/silicon_creator/lib/drivers/mock_ibex.h"
1314
#include "sw/device/silicon_creator/testing/rom_test.h"
1415

1516
#include "hw/top/uart_regs.h" // Generated.
@@ -28,6 +29,7 @@ class UartTest : public rom_test::RomTest {
2829
protected:
2930
uint32_t base_ = TOP_EARLGREY_UART0_BASE_ADDR;
3031
rom_test::MockAbsMmio mmio_;
32+
rom_test::MockIbex ibex_;
3133

3234
void ExpectDeviceReset() {
3335
EXPECT_ABS_WRITE32(base_ + UART_CTRL_REG_OFFSET, 0);
@@ -106,39 +108,77 @@ TEST_F(BytesSendTest, SendByteBusy) {
106108
}
107109

108110
TEST_F(UartTest, RecvByte) {
111+
const uint32_t kTimeoutMs = 1;
112+
// The return value is irrelevant since the RX FIFO is not empty.
113+
EXPECT_CALL(ibex_, MCycle()).WillOnce(testing::Return(0));
114+
EXPECT_CALL(ibex_, IbexTimeToCycles(kTimeoutMs * 1000))
115+
.WillOnce(testing::Return(1));
109116
EXPECT_ABS_READ32(base_ + UART_STATUS_REG_OFFSET,
110117
{{UART_STATUS_RXEMPTY_BIT, false}});
111118
EXPECT_ABS_READ32(base_ + UART_RDATA_REG_OFFSET, 'A');
112-
int result = uart_getchar(1);
119+
int result = uart_getchar(kTimeoutMs);
113120
EXPECT_EQ(result, 'A');
114121
}
115122

116123
TEST_F(UartTest, RecvTimeout) {
124+
const uint32_t kTimeoutMs = 1;
125+
const uint32_t kTimeoutCycles = 42;
126+
const uint64_t kInitialMCycle = 0x123456789ab;
127+
EXPECT_CALL(ibex_, MCycle()).WillOnce(testing::Return(kInitialMCycle));
128+
EXPECT_CALL(ibex_, IbexTimeToCycles(kTimeoutMs * 1000))
129+
.WillOnce(testing::Return(kTimeoutCycles));
117130
// The uart receive function will keep polling the status register for RX FIFO
118131
// status. Return RXEMPTY every time.
119132
EXPECT_CALL(::rom_test::MockAbsMmio::Instance(),
120133
Read32(base_ + UART_STATUS_REG_OFFSET))
121-
.WillRepeatedly(testing::Return(
134+
.WillOnce(testing::Return(
135+
mock_mmio::ToInt<uint32_t>({{UART_STATUS_RXEMPTY_BIT, true}})));
136+
EXPECT_CALL(ibex_, MCycle())
137+
.WillOnce(testing::Return(kInitialMCycle + (kTimeoutCycles - 1) / 2));
138+
EXPECT_CALL(::rom_test::MockAbsMmio::Instance(),
139+
Read32(base_ + UART_STATUS_REG_OFFSET))
140+
.WillOnce(testing::Return(
122141
mock_mmio::ToInt<uint32_t>({{UART_STATUS_RXEMPTY_BIT, true}})));
142+
EXPECT_CALL(ibex_, MCycle())
143+
.WillOnce(testing::Return(kInitialMCycle + kTimeoutCycles + 1));
144+
123145
int result = uart_getchar(1);
124146
EXPECT_EQ(result, -1);
125147
}
126148

127149
TEST_F(UartTest, BreakDetect) {
150+
const uint32_t kTimeoutUs = 1;
151+
const uint32_t kTimeoutCycles = 42;
152+
const uint64_t kInitialMCycle = 0x123456789ab;
153+
EXPECT_CALL(ibex_, MCycle()).WillOnce(testing::Return(kInitialMCycle));
154+
EXPECT_CALL(ibex_, IbexTimeToCycles(kTimeoutUs))
155+
.WillOnce(testing::Return(kTimeoutCycles));
128156
// The break detect function will continuously poll the UART value register to
129157
// observe the sampled value on the RX line. A break condition over the
130158
// measured period will always return a value of zero.
131-
EXPECT_CALL(::rom_test::MockAbsMmio::Instance(),
132-
Read32(base_ + UART_VAL_REG_OFFSET))
133-
.WillRepeatedly(testing::Return(mock_mmio::ToInt<uint32_t>(0)));
134-
hardened_bool_t result = uart_break_detect(1);
159+
EXPECT_ABS_READ32(base_ + UART_VAL_REG_OFFSET, 0);
160+
EXPECT_CALL(ibex_, MCycle())
161+
.WillOnce(testing::Return(kInitialMCycle + (kTimeoutCycles - 1) / 2));
162+
EXPECT_ABS_READ32(base_ + UART_VAL_REG_OFFSET, 0);
163+
EXPECT_CALL(ibex_, MCycle())
164+
.WillOnce(testing::Return(kInitialMCycle + kTimeoutCycles + 1));
165+
hardened_bool_t result = uart_break_detect(kTimeoutUs);
135166
EXPECT_EQ(result, kHardenedBoolTrue);
136167
}
137168

138169
TEST_F(UartTest, NoBreakDetect) {
170+
const uint32_t kTimeoutUs = 1;
171+
const uint32_t kTimeoutCycles = 42;
172+
const uint64_t kInitialMCycle = 0x123456789ab;
173+
EXPECT_CALL(ibex_, MCycle()).WillOnce(testing::Return(kInitialMCycle));
174+
EXPECT_CALL(ibex_, IbexTimeToCycles(kTimeoutUs))
175+
.WillOnce(testing::Return(kTimeoutCycles));
139176
// The break detect function will continuously poll the UART value register to
140177
// observe the sampled value on the RX line. Any non-zero bit detected on the
141178
// RX line means we don't have a break condition.
179+
EXPECT_ABS_READ32(base_ + UART_VAL_REG_OFFSET, 0);
180+
EXPECT_CALL(ibex_, MCycle())
181+
.WillOnce(testing::Return(kInitialMCycle + (kTimeoutCycles - 1) / 2));
142182
EXPECT_ABS_READ32(base_ + UART_VAL_REG_OFFSET, 1);
143183
hardened_bool_t result = uart_break_detect(1);
144184
EXPECT_EQ(result, kHardenedBoolFalse);

0 commit comments

Comments
 (0)