blob: 6396fafb323e7fd8be35c7b041f85f9f1d4f80ce [file] [log] [blame]
// 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 <optional>
#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