| // Copyright 2021 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <gtest/gtest.h> |
| |
| #include "hps/dev.h" |
| #include "hps/hps_reg.h" |
| |
| using hps::DevInterface; |
| |
| namespace { |
| |
| static int const kBlockSizeBytes = 128; |
| |
| // Fake that implements a DevInterface. |
| // Setting fails_ will fail a read or write, and then decrement the |
| // fail count so that multiple retries will succeed after a set count. |
| // The cmd and len for each read and write are saved. |
| class DevInterfaceFake : public DevInterface { |
| public: |
| DevInterfaceFake() : fails_(0), cmd_(0), len_(0), reads_(0), writes_(0) {} |
| ~DevInterfaceFake() override = default; |
| bool ReadDevice(uint8_t cmd, uint8_t* data, size_t len) override { |
| ++reads_; |
| cmd_ = cmd; |
| len_ = len; |
| if (fails_ > 0) { |
| --fails_; |
| return false; |
| } |
| if (len == 2) { |
| data[0] = data_[0]; |
| data[1] = data_[1]; |
| } |
| return true; |
| } |
| bool WriteDevice(uint8_t cmd, const uint8_t* data, size_t len) override { |
| ++writes_; |
| cmd_ = cmd; |
| len_ = len; |
| if (fails_ > 0) { |
| --fails_; |
| return false; |
| } |
| if (len == 2) { |
| data_[0] = data[0]; |
| data_[1] = data[1]; |
| } |
| return true; |
| } |
| size_t BlockSizeBytes() override { return kBlockSizeBytes; } |
| |
| int fails_; // If non-zero, fail the request and decrement this count. |
| uint8_t cmd_; // Command byte of request. |
| size_t len_; // Length of request. |
| uint8_t data_[2]; // Data read or written. |
| int reads_; // Count of Read calls. |
| int writes_; // Count of Write calls. |
| }; |
| |
| class DevInterfaceTest : public testing::Test { |
| protected: |
| DevInterfaceFake dev_; |
| }; |
| |
| /* |
| * Check that a ReadReg reads the correct data. |
| */ |
| TEST_F(DevInterfaceTest, ReadReg) { |
| dev_.data_[0] = 0x12; |
| dev_.data_[1] = 0x34; |
| std::optional<uint16_t> d = dev_.ReadReg(hps::HpsReg::kMagic); |
| EXPECT_EQ(d, 0x1234); |
| EXPECT_EQ(dev_.len_, 2); |
| EXPECT_EQ(dev_.cmd_, 0x80); |
| dev_.data_[0] = 0x89; |
| dev_.data_[1] = 0xAB; |
| d = dev_.ReadReg(hps::HpsReg(32)); |
| EXPECT_EQ(d, 0x89AB); |
| EXPECT_EQ(dev_.cmd_, 0x80 | 32); |
| EXPECT_EQ(dev_.len_, 2); |
| EXPECT_EQ(dev_.reads_, 2); |
| } |
| |
| /* |
| * Check that a WriteReg writes the correct data. |
| */ |
| TEST_F(DevInterfaceTest, WriteReg) { |
| EXPECT_TRUE(dev_.WriteReg(hps::HpsReg::kMagic, 0x1234)); |
| EXPECT_EQ(dev_.data_[0], 0x12); |
| EXPECT_EQ(dev_.data_[1], 0x34); |
| EXPECT_EQ(dev_.len_, 2); |
| EXPECT_EQ(dev_.cmd_, 0x80); |
| EXPECT_TRUE(dev_.WriteReg(hps::HpsReg(32), 0x89AB)); |
| EXPECT_EQ(dev_.data_[0], 0x89); |
| EXPECT_EQ(dev_.data_[1], 0xAB); |
| EXPECT_EQ(dev_.cmd_, 0x80 | 32); |
| EXPECT_EQ(dev_.len_, 2); |
| EXPECT_EQ(dev_.writes_, 2); |
| } |
| |
| /* |
| * Verify that the correct block size is selected. |
| */ |
| TEST_F(DevInterfaceTest, BlockSize) { |
| EXPECT_EQ(dev_.BlockSizeBytes(), kBlockSizeBytes); |
| } |
| |
| } // namespace |