Software APIs
pinmux_unittest.cc
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include "sw/device/silicon_creator/lib/drivers/pinmux.h"
6 
7 #include "gtest/gtest.h"
10 #include "sw/device/lib/base/mock_abs_mmio.h"
12 #include "sw/device/silicon_creator/lib/base/mock_csr.h"
13 #include "sw/device/silicon_creator/lib/drivers/mock_otp.h"
14 #include "sw/device/silicon_creator/testing/rom_test.h"
15 
17 #include "otp_ctrl_regs.h"
18 #include "pinmux_regs.h"
19 
20 namespace pinmux_unittest {
21 namespace {
22 using ::testing::Return;
23 
24 class PinmuxTest : public rom_test::RomTest {
25  protected:
26  uint32_t base_ = TOP_EARLGREY_PINMUX_AON_BASE_ADDR;
27  rom_test::MockAbsMmio mmio_;
28  rom_test::MockOtp otp_;
29  mock_csr::MockCsr csr_;
30 };
31 
32 class InitTest : public PinmuxTest {
33  protected:
34  /**
35  * Set to track which peripheral inputs have already been configured.
36  */
37  std::set<top_earlgrey_pinmux_peripheral_in_t> configured_in_;
38 
39  /**
40  * Register the configuration of the input peripheral in the tracking
41  * set and return its computed address.
42  *
43  * Triggers a test failure if the input has already been registered.
44  */
46  EXPECT_TRUE(index >= 0 && index < kTopEarlgreyPinmuxPeripheralInLast);
47  EXPECT_TRUE(configured_in_.insert(index).second);
48  return base_ + PINMUX_MIO_PERIPH_INSEL_0_REG_OFFSET +
49  static_cast<uint32_t>(index) * sizeof(uint32_t);
50  }
51 
52  uint32_t RegPadAttr(top_earlgrey_muxed_pads_t pad) {
53  return base_ + PINMUX_MIO_PAD_ATTR_0_REG_OFFSET +
54  static_cast<uint32_t>(pad) * sizeof(uint32_t);
55  }
56 
57  /**
58  * Set to track which MIO outputs have already been configured.
59  */
60  std::set<top_earlgrey_pinmux_mio_out_t> configured_out_;
61 
62  /**
63  * Register the configuration of the MIO output in the tracking
64  * set and return its computed address.
65  *
66  * Triggers a test failure if the input has already been registered.
67  */
69  EXPECT_TRUE(index >= 0 && index < kTopEarlgreyPinmuxMioOutLast);
70  EXPECT_TRUE(configured_out_.insert(index).second);
71  return base_ + PINMUX_MIO_OUTSEL_0_REG_OFFSET +
72  static_cast<uint32_t>(index) * sizeof(uint32_t);
73  };
74 };
75 
76 TEST_F(InitTest, PadAttrPropagationDelay) {
77  const uint64_t kCpuClockPeriodNs = 1'000'000'000 / kClockFreqCpuHz;
78  const uint64_t kCpuCyclesIn5Micros = 5000 / kCpuClockPeriodNs;
79  EXPECT_EQ(PINMUX_PAD_ATTR_PROP_CYCLES, kCpuCyclesIn5Micros);
80 }
81 
82 TEST_F(InitTest, WithBootstrap) {
83  // The inputs that will be configured.
84  EXPECT_CALL(otp_,
85  read32(OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_BOOTSTRAP_DIS_OFFSET))
86  .WillOnce(Return(kHardenedBoolFalse));
87  EXPECT_ABS_WRITE32(RegPadAttr(kTopEarlgreyMuxedPadsIoc0),
88  {{PINMUX_MIO_PAD_ATTR_0_PULL_EN_0_BIT, 1}});
89  EXPECT_ABS_WRITE32(RegPadAttr(kTopEarlgreyMuxedPadsIoc1),
90  {{PINMUX_MIO_PAD_ATTR_0_PULL_EN_0_BIT, 1}});
91  EXPECT_ABS_WRITE32(RegPadAttr(kTopEarlgreyMuxedPadsIoc2),
92  {{PINMUX_MIO_PAD_ATTR_0_PULL_EN_0_BIT, 1}});
93  EXPECT_CSR_WRITE(CSR_REG_MCYCLE, 0);
94  for (size_t i = 0; i < 6; ++i) {
95  EXPECT_CSR_READ(CSR_REG_MCYCLE, i * 100);
96  }
97  EXPECT_ABS_WRITE32(RegInSel(kTopEarlgreyPinmuxPeripheralInGpioGpio22),
99  EXPECT_ABS_WRITE32(RegInSel(kTopEarlgreyPinmuxPeripheralInGpioGpio23),
101  EXPECT_ABS_WRITE32(RegInSel(kTopEarlgreyPinmuxPeripheralInGpioGpio24),
103 
104  // UART configuration: RX line pulled up, RX is IOC3, TX is IOC4.
105  EXPECT_ABS_WRITE32(RegPadAttr(kTopEarlgreyMuxedPadsIoc3),
106  {{PINMUX_MIO_PAD_ATTR_0_PULL_EN_0_BIT, 1},
107  {PINMUX_MIO_PAD_ATTR_0_PULL_SELECT_0_BIT, 1}});
108  EXPECT_ABS_WRITE32(RegInSel(kTopEarlgreyPinmuxPeripheralInUart0Rx),
110  EXPECT_ABS_WRITE32(RegOutSel(kTopEarlgreyPinmuxMioOutIoc4),
112 
113  pinmux_init();
114 }
115 
116 TEST_F(InitTest, WithoutBootstrap) {
117  // The inputs that will be configured.
118  EXPECT_CALL(otp_,
119  read32(OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_BOOTSTRAP_DIS_OFFSET))
120  .WillOnce(Return(kHardenedBoolTrue));
121 
122  // UART configuration: RX line pulled up, RX is IOC3, TX is IOC4.
123  EXPECT_ABS_WRITE32(RegPadAttr(kTopEarlgreyMuxedPadsIoc3),
124  {{PINMUX_MIO_PAD_ATTR_0_PULL_EN_0_BIT, 1},
125  {PINMUX_MIO_PAD_ATTR_0_PULL_SELECT_0_BIT, 1}});
126  EXPECT_ABS_WRITE32(RegInSel(kTopEarlgreyPinmuxPeripheralInUart0Rx),
128  EXPECT_ABS_WRITE32(RegOutSel(kTopEarlgreyPinmuxMioOutIoc4),
130 
131  pinmux_init();
132 }
133 
134 TEST_F(InitTest, Uart0TxOnly) {
135  // The outputs that will be configured.
136  EXPECT_ABS_WRITE32(RegOutSel(kTopEarlgreyPinmuxMioOutIoc4),
138 
139  pinmux_init_uart0_tx();
140 }
141 
142 } // namespace
143 } // namespace pinmux_unittest