blob: 4f5c6750fd4890bfcd7be972797a78f841e73c41 [file] [log] [blame] [edit]
#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_DETERMINISTIC_BMC_I2C_WALKER_I2C_WALKER_INTERFACE_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_DETERMINISTIC_BMC_I2C_WALKER_I2C_WALKER_INTERFACE_H_
#include <cstdint>
#include <optional>
#include <ostream>
#include <string>
#include <tuple>
#include <vector>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
namespace deterministic_bmc {
// Interface for walking the I2C bus. Implementations of this interface are
// expected to be thread-safe.
class I2cWalkerInterface {
public:
struct HardwareInfo {
// The resolved logical bus number of the i2c device. std::nullopt if any
// error occurred during the i2c walk.
std::optional<uint32_t> logical_bus;
// The address of the i2c device.
uint32_t address;
// The barepath of the i2c device.
std::string barepath;
// The part number of the i2c device.
std::string part_number;
// The serial number of the i2c device.
std::string serial_number;
// If not_found_info is nullopt, it means the i2c device is found and the
// HardwareInfo is valid.
// If not_found_info is not nullopt, it means the i2c device is expected to
// be valid but encountered error during i2c walk on sysfs of the real
// machine. This information will be used to indicate missing expected i2c
// devices.
struct NotFoundInfo {
// The status of the error. We will use NotFoundError to indicate i2c
// sysfs work issues. The message in the status will be more informative
// about what actually went wrong. Currently, major issues are:
// 1. Root bus or mux path does not exist.
// 2. Mux model mismatch.
// 3. Invalid symlink: symlink file itself does not exist or not a
// symlink.
// 4. fail to read symlink.
// 5. Invalid bus id.
absl::Status status;
uint32_t physical_bus;
std::string mux_model;
uint32_t mux_address;
uint32_t channel;
friend std::ostream& operator<<(std::ostream& os,
const NotFoundInfo& info);
bool operator==(const NotFoundInfo& other) const {
return std::tie(status, physical_bus, mux_model, mux_address,
channel) == std::tie(other.status, other.physical_bus,
other.mux_model, other.mux_address,
other.channel);
}
};
std::optional<NotFoundInfo> not_found_info;
friend std::ostream& operator<<(std::ostream& os, const HardwareInfo& info);
bool operator==(const HardwareInfo& other) const {
return std::tie(logical_bus, address, barepath, part_number,
serial_number, not_found_info) ==
std::tie(other.logical_bus, other.address, other.barepath,
other.part_number, other.serial_number,
other.not_found_info);
}
};
virtual ~I2cWalkerInterface() = default;
// Read the physical i2c topology information from the uhmm offline config and
// return a list of i2c devices with logical addresses.
virtual absl::StatusOr<std::vector<HardwareInfo>> GetLogicalI2cAddresses()
const = 0;
};
// The ostream operator for NotFoundInfo.
inline std::ostream& operator<<(
std::ostream& os,
const I2cWalkerInterface::HardwareInfo::NotFoundInfo& info) {
os << "physical_bus: " << info.physical_bus
<< ", mux_model: " << info.mux_model
<< ", mux_address: " << info.mux_address << ", channel: " << info.channel
<< ", status: " << info.status;
return os;
}
// The ostream operator for HardwareInfo.
inline std::ostream& operator<<(std::ostream& os,
const I2cWalkerInterface::HardwareInfo& info) {
os << "logical_bus: "
<< (info.logical_bus.has_value() ? absl::StrCat(info.logical_bus.value())
: "no_resolved_bus")
<< ", address: " << info.address << ", barepath: " << info.barepath
<< ", part_number: " << info.part_number
<< ", serial_number: " << info.serial_number << ", not_found_info: ";
if (info.not_found_info.has_value()) {
os << info.not_found_info.value();
} else {
os << "N/A";
}
return os;
}
} // namespace deterministic_bmc
#endif // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_DETERMINISTIC_BMC_I2C_WALKER_I2C_WALKER_INTERFACE_H_