| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| |
| #include "sw/device/lib/base/mock_mmio.h" |
| |
| #include "gtest/gtest.h" |
| #include "sw/device/lib/base/mmio.h" |
| |
| namespace { |
| using ::mock_mmio::LeInt; |
| using ::mock_mmio::MmioTest; |
| using ::testing::Test; |
| |
| /** |
| * Exercises the register |dev| by reading a value at offset 0x0, |
| * writing its complement to 0x4, and then writing it byte by byte |
| * back over itself, from MSB to LSB. |
| */ |
| uint32_t WriteTwice(mmio_region_t dev) { |
| auto value = mmio_region_read32(dev, 0x0); |
| mmio_region_write32(dev, 0x4, ~value); |
| mmio_region_write8(dev, 0x12, (value >> 24) & 0xff); |
| mmio_region_write8(dev, 0x8, (value >> 16) & 0xff); |
| mmio_region_write8(dev, 0x4, (value >> 8) & 0xff); |
| mmio_region_write8(dev, 0x0, value & 0xff); |
| return value; |
| } |
| |
| class MockMmioTest : public Test, public MmioTest {}; |
| |
| TEST_F(MockMmioTest, WriteTwice) { |
| EXPECT_READ32(0x0, 0xdeadbeef); |
| EXPECT_WRITE32(0x4, 0x21524110); |
| EXPECT_WRITE8(0x12, 0xde); |
| EXPECT_WRITE8(0x8, 0xad); |
| EXPECT_WRITE8(0x4, 0xbe); |
| EXPECT_WRITE8(0x0, 0xef); |
| |
| EXPECT_EQ(WriteTwice(dev().region()), 0xdeadbeef); |
| } |
| |
| // This test mostly exists to guard against |0x0| being interpreted as a NULL |
| // pointer literal. C++ overloading is unpredictable in choosing between T* and |
| // int here. |
| TEST_F(MockMmioTest, ExpectReadZero) { |
| EXPECT_READ8(0x0, 0x0); |
| EXPECT_EQ(mmio_region_read8(dev().region(), 0x0), 0x0); |
| } |
| |
| TEST_F(MockMmioTest, ExpectWithString) { |
| EXPECT_READ32(0xc, LeInt("*\0\0*")); |
| EXPECT_EQ(mmio_region_read32(dev().region(), 0xc), 0x2a00002a); |
| |
| EXPECT_WRITE32(0x12, LeInt("abcd")); |
| mmio_region_write32(dev().region(), 0x12, 0x64636261); |
| } |
| |
| TEST_F(MockMmioTest, ExpectWithBits) { |
| EXPECT_READ8(0xc, {{0x0, false}, {0x1, true}, {0x3, true}}); |
| EXPECT_EQ(mmio_region_read8(dev().region(), 0xc), 0b1010); |
| |
| EXPECT_WRITE32(0x12, {{0x0, 0xfe}, {0x8, 0xca}}); |
| mmio_region_write32(dev().region(), 0x12, 0xcafe); |
| } |
| |
| TEST_F(MockMmioTest, ExpectMask) { |
| EXPECT_MASK32(0x8, { |
| {0x0, 0xfff, 0xabc}, |
| {0x10, 0x1, 0x0}, |
| }); |
| |
| auto value = mmio_region_read32(dev().region(), 0x8); |
| // Set the first three nybbles. |
| value &= ~0xfff; |
| value |= 0xabc; |
| // Clear the 16th bit. |
| value &= ~(1 << 0x10); |
| mmio_region_write32(dev().region(), 0x8, value); |
| } |
| } // namespace |