Software APIs
mock_mmio_test.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/lib/base/mock_mmio.h"
6 
7 #include "gtest/gtest.h"
9 
10 namespace {
11 using ::mock_mmio::LeInt;
12 using ::mock_mmio::MmioTest;
13 using ::testing::Test;
14 
15 /**
16  * Exercises the register |dev| by reading a value at offset 0x0,
17  * writing its complement to 0x4, and then writing it byte by byte
18  * back over itself, from MSB to LSB.
19  */
20 uint32_t WriteTwice(mmio_region_t dev) {
21  auto value = mmio_region_read32(dev, 0x0);
22  mmio_region_write32(dev, 0x4, ~value);
23  mmio_region_write8(dev, 0x12, (value >> 24) & 0xff);
24  mmio_region_write8(dev, 0x8, (value >> 16) & 0xff);
25  mmio_region_write8(dev, 0x4, (value >> 8) & 0xff);
26  mmio_region_write8(dev, 0x0, value & 0xff);
27  return value;
28 }
29 
30 class MockMmioTest : public Test, public MmioTest {};
31 
32 TEST_F(MockMmioTest, WriteTwice) {
33  EXPECT_READ32(0x0, 0xdeadbeef);
34  EXPECT_WRITE32(0x4, 0x21524110);
35  EXPECT_WRITE8(0x12, 0xde);
36  EXPECT_WRITE8(0x8, 0xad);
37  EXPECT_WRITE8(0x4, 0xbe);
38  EXPECT_WRITE8(0x0, 0xef);
39 
40  EXPECT_EQ(WriteTwice(dev().region()), 0xdeadbeef);
41 }
42 
43 // This test mostly exists to guard against |0x0| being interpreted as a NULL
44 // pointer literal. C++ overloading is unpredictable in choosing between T* and
45 // int here.
46 TEST_F(MockMmioTest, ExpectReadZero) {
47  EXPECT_READ8(0x0, 0x0);
48  EXPECT_EQ(mmio_region_read8(dev().region(), 0x0), 0x0);
49 }
50 
51 TEST_F(MockMmioTest, ExpectWithString) {
52  EXPECT_READ32(0xc, LeInt("*\0\0*"));
53  EXPECT_EQ(mmio_region_read32(dev().region(), 0xc), 0x2a00002a);
54 
55  EXPECT_WRITE32(0x12, LeInt("abcd"));
56  mmio_region_write32(dev().region(), 0x12, 0x64636261);
57 }
58 
59 TEST_F(MockMmioTest, ExpectWithBits) {
60  EXPECT_READ8(0xc, {{0x0, false}, {0x1, true}, {0x3, true}});
61  EXPECT_EQ(mmio_region_read8(dev().region(), 0xc), 0b1010);
62 
63  EXPECT_WRITE32(0x12, {{0x0, 0xfe}, {0x8, 0xca}});
64  mmio_region_write32(dev().region(), 0x12, 0xcafe);
65 }
66 
67 TEST_F(MockMmioTest, ExpectMask) {
68  EXPECT_MASK32(0x8, {
69  {0x0, 0xfff, 0xabc},
70  {0x10, 0x1, 0x0},
71  });
72 
73  auto value = mmio_region_read32(dev().region(), 0x8);
74  // Set the first three nybbles.
75  value &= ~0xfff;
76  value |= 0xabc;
77  // Clear the 16th bit.
78  value &= ~(1 << 0x10);
79  mmio_region_write32(dev().region(), 0x8, value);
80 }
81 } // namespace