12 #include "gtest/gtest.h"
14 #include "sw/device/lib/base/mock_mmio.h"
17 #include "rv_timer_regs.h"
25 std::ostream &operator<<(std::ostream &os,
28 auto step =
static_cast<uint32_t
>(params.
tick_step);
29 return os <<
"{ .prescale = " << params.
prescale <<
", .tick_step = " << step
33 namespace dif_rv_timer_unittest {
35 using ::mock_mmio::LeInt;
36 using ::mock_mmio::MmioTest;
37 using ::mock_mmio::MockDevice;
39 constexpr uint32_t kFastClockSpeed = 2'000'000'000;
40 constexpr uint32_t kClockSpeed = 50'000'000;
41 constexpr uint32_t kSlowClockSpeed = 50;
43 constexpr uint32_t kSlowTimer = 1'000'000;
44 constexpr uint32_t kFastTimer = 120'000'000;
45 constexpr uint32_t kSluggishTimer = 3;
47 TEST(ApproximateParamsTest, Success) {
56 EXPECT_EQ(params, expected);
59 TEST(ApproximateParamsTest, WithStep) {
67 EXPECT_EQ(params, expected);
70 TEST(ApproximateParamsTest, UnrepresenableTooSlow) {
76 kFastClockSpeed, kSluggishTimer, ¶ms));
79 TEST(ApproximateParamsTest, UnrepresenableTooFast) {
84 kFastTimer, ¶ms));
87 TEST(ApproximateParamsTest, NullArgs) {
89 kFastTimer,
nullptr));
92 class TimerTest :
public testing::Test,
public MmioTest {
94 dif_rv_timer_t rv_timer_ = {.base_addr = dev().region()};
98 ptrdiff_t RegForHart(uint32_t hart, ptrdiff_t reg_offset) {
99 return 0x100 * hart + reg_offset;
102 constexpr uint32_t kAllOnes = std::numeric_limits<uint32_t>::max();
107 EXPECT_WRITE32(RV_TIMER_CTRL_REG_OFFSET, 0x0);
109 for (uint32_t hart_id = 0; hart_id < RV_TIMER_PARAM_N_HARTS; ++hart_id) {
110 EXPECT_WRITE32(RegForHart(0, RV_TIMER_INTR_ENABLE0_REG_OFFSET), 0x0);
111 EXPECT_WRITE32(RegForHart(0, RV_TIMER_INTR_STATE0_REG_OFFSET), kAllOnes);
113 for (uint32_t comp_id = 0; comp_id < RV_TIMER_PARAM_N_TIMERS; ++comp_id) {
114 EXPECT_WRITE32(RegForHart(0, RV_TIMER_COMPARE_UPPER0_0_REG_OFFSET),
116 EXPECT_WRITE32(RegForHart(0, RV_TIMER_COMPARE_LOWER0_0_REG_OFFSET),
118 EXPECT_WRITE32(RegForHart(0, RV_TIMER_COMPARE_UPPER0_0_REG_OFFSET),
122 EXPECT_WRITE32(RegForHart(0, RV_TIMER_TIMER_V_LOWER0_REG_OFFSET), 0x0);
123 EXPECT_WRITE32(RegForHart(0, RV_TIMER_TIMER_V_UPPER0_REG_OFFSET), 0x0);
134 RegForHart(0, RV_TIMER_CFG0_REG_OFFSET),
135 {{RV_TIMER_CFG0_PRESCALE_OFFSET, 400}, {RV_TIMER_CFG0_STEP_OFFSET, 25}});
138 &rv_timer_, 0, {.prescale = 400, .tick_step = 25}));
141 TEST_F(SetTickParamsTest, NullArgs) {
143 nullptr, 0, {.prescale = 400, .tick_step = 25}));
146 TEST_F(SetTickParamsTest, BadHartId) {
148 &rv_timer_, RV_TIMER_PARAM_N_HARTS, {.prescale = 400, .tick_step = 25}));
154 EXPECT_MASK32(RV_TIMER_CTRL_REG_OFFSET,
160 TEST_F(CounterSetEnabledTest, NullArgs) {
165 TEST_F(CounterSetEnabledTest, BadHartId) {
173 EXPECT_READ32(RegForHart(0, RV_TIMER_TIMER_V_UPPER0_REG_OFFSET), 0x0222'0222);
174 EXPECT_READ32(RegForHart(0, RV_TIMER_TIMER_V_LOWER0_REG_OFFSET), 0x0333'0333);
175 EXPECT_READ32(RegForHart(0, RV_TIMER_TIMER_V_UPPER0_REG_OFFSET), 0x0222'0222);
179 EXPECT_EQ(value, 0x0222'0222'0333'0333);
182 TEST_F(CounterReadTest, Overflow) {
183 EXPECT_READ32(RegForHart(0, RV_TIMER_TIMER_V_UPPER0_REG_OFFSET), 0x0222'0222);
184 EXPECT_READ32(RegForHart(0, RV_TIMER_TIMER_V_LOWER0_REG_OFFSET), 0x0333'0333);
185 EXPECT_READ32(RegForHart(0, RV_TIMER_TIMER_V_UPPER0_REG_OFFSET), 0x0222'0223);
187 EXPECT_READ32(RegForHart(0, RV_TIMER_TIMER_V_UPPER0_REG_OFFSET), 0x0222'0223);
188 EXPECT_READ32(RegForHart(0, RV_TIMER_TIMER_V_LOWER0_REG_OFFSET), 0x0333'0444);
189 EXPECT_READ32(RegForHart(0, RV_TIMER_TIMER_V_UPPER0_REG_OFFSET), 0x0222'0223);
193 EXPECT_EQ(value, 0x0222'0223'0333'0444);
196 TEST_F(CounterReadTest, NullArgs) {
202 TEST_F(CounterReadTest, BadHartId) {
211 EXPECT_READ32(RV_TIMER_CTRL_REG_OFFSET, 0x0000'0001);
212 EXPECT_WRITE32(RV_TIMER_CTRL_REG_OFFSET, 0x0000'0000);
213 EXPECT_WRITE32(RegForHart(0, RV_TIMER_TIMER_V_LOWER0_REG_OFFSET),
215 EXPECT_WRITE32(RegForHart(0, RV_TIMER_TIMER_V_UPPER0_REG_OFFSET),
217 EXPECT_WRITE32(RV_TIMER_CTRL_REG_OFFSET, 0x0000'0001);
219 uint64_t count = 0xCAFE'FEED'DEAD'BEEF;
223 TEST_F(CounterWriteTest, NullArgs) {
224 uint64_t count = 0xCAFE'FEED'DEAD'BEEF;
228 TEST_F(CounterWriteTest, BadHartId) {
229 uint64_t count = 0xCAFE'FEED'DEAD'BEEF;
237 auto lower_reg = RegForHart(0, RV_TIMER_COMPARE_LOWER0_0_REG_OFFSET);
238 auto upper_reg = RegForHart(0, RV_TIMER_COMPARE_UPPER0_0_REG_OFFSET);
240 EXPECT_WRITE32(upper_reg, kAllOnes);
241 EXPECT_WRITE32(lower_reg, 0x0444'0555);
242 EXPECT_WRITE32(upper_reg, 0x0222'0333);
247 TEST_F(ArmTest, NullArgs) {
251 TEST_F(ArmTest, BadHartIdBadCompId) {
253 0x0222'0333'0444'0555));
255 0x0222'0333'0444'0555));
257 RV_TIMER_PARAM_N_TIMERS,
258 0x0222'0333'0444'0555));